diff options
author | Rob Mensching <rob@firegiant.com> | 2022-03-30 10:35:02 -0700 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2022-03-30 14:12:12 -0700 |
commit | 5d08e0a4bbf4e4ba28300b8bace1089b64b198d7 (patch) | |
tree | 1cf7d1f79d45cc3acc32f19cabb1efedd7a4a3dc | |
parent | c86a2148f6dd7bfcd6637b6e1c9e7b5a9b53a996 (diff) | |
download | wix-5d08e0a4bbf4e4ba28300b8bace1089b64b198d7.tar.gz wix-5d08e0a4bbf4e4ba28300b8bace1089b64b198d7.tar.bz2 wix-5d08e0a4bbf4e4ba28300b8bace1089b64b198d7.zip |
Implement IWindowsInstallerDecompileExtensions
Update Util extension to validate extension model and fix some small
issues in MSI decompiling.
Fixes 6367
46 files changed, 1644 insertions, 1390 deletions
diff --git a/src/api/wix/WixToolset.Extensibility/BaseWindowsInstallerBackendBinderExtension.cs b/src/api/wix/WixToolset.Extensibility/BaseWindowsInstallerBackendBinderExtension.cs index e48579d7..a54f05fc 100644 --- a/src/api/wix/WixToolset.Extensibility/BaseWindowsInstallerBackendBinderExtension.cs +++ b/src/api/wix/WixToolset.Extensibility/BaseWindowsInstallerBackendBinderExtension.cs | |||
@@ -4,7 +4,6 @@ namespace WixToolset.Extensibility | |||
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.Collections.Generic; | 6 | using System.Collections.Generic; |
7 | using System.Linq; | ||
8 | using WixToolset.Data; | 7 | using WixToolset.Data; |
9 | using WixToolset.Data.Symbols; | 8 | using WixToolset.Data.Symbols; |
10 | using WixToolset.Data.WindowsInstaller; | 9 | using WixToolset.Data.WindowsInstaller; |
@@ -12,7 +11,7 @@ namespace WixToolset.Extensibility | |||
12 | using WixToolset.Extensibility.Services; | 11 | using WixToolset.Extensibility.Services; |
13 | 12 | ||
14 | /// <summary> | 13 | /// <summary> |
15 | /// Base class for creating a preprocessor extension. | 14 | /// Base class for creating a windows installer backend extension. |
16 | /// </summary> | 15 | /// </summary> |
17 | public abstract class BaseWindowsInstallerBackendBinderExtension : IWindowsInstallerBackendBinderExtension | 16 | public abstract class BaseWindowsInstallerBackendBinderExtension : IWindowsInstallerBackendBinderExtension |
18 | { | 17 | { |
@@ -39,7 +38,10 @@ namespace WixToolset.Extensibility | |||
39 | /// <summary> | 38 | /// <summary> |
40 | /// Creates a resolved cabinet result. | 39 | /// Creates a resolved cabinet result. |
41 | /// </summary> | 40 | /// </summary> |
42 | protected IResolvedCabinet CreateResolvedCabinet() => this.Context.ServiceProvider.GetService<IResolvedCabinet>(); | 41 | protected IResolvedCabinet CreateResolvedCabinet() |
42 | { | ||
43 | return this.Context.ServiceProvider.GetService<IResolvedCabinet>(); | ||
44 | } | ||
43 | 45 | ||
44 | /// <summary> | 46 | /// <summary> |
45 | /// See <see cref="IWindowsInstallerBackendBinderExtension.PreBackendBind(IBindContext)"/> | 47 | /// See <see cref="IWindowsInstallerBackendBinderExtension.PreBackendBind(IBindContext)"/> |
diff --git a/src/api/wix/WixToolset.Extensibility/BaseWindowsInstallerDecompilerExtension.cs b/src/api/wix/WixToolset.Extensibility/BaseWindowsInstallerDecompilerExtension.cs new file mode 100644 index 00000000..8072cd88 --- /dev/null +++ b/src/api/wix/WixToolset.Extensibility/BaseWindowsInstallerDecompilerExtension.cs | |||
@@ -0,0 +1,77 @@ | |||
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 | |||
3 | namespace WixToolset.Extensibility | ||
4 | { | ||
5 | using System.Collections.Generic; | ||
6 | using WixToolset.Data; | ||
7 | using WixToolset.Data.WindowsInstaller; | ||
8 | using WixToolset.Extensibility.Data; | ||
9 | using WixToolset.Extensibility.Services; | ||
10 | |||
11 | /// <summary> | ||
12 | /// Base class for creating a windows installer decompiler extensions. | ||
13 | /// </summary> | ||
14 | public abstract class BaseWindowsInstallerDecompilerExtension : IWindowsInstallerDecompilerExtension | ||
15 | { | ||
16 | /// <summary> | ||
17 | /// Context for use by the extension. | ||
18 | /// </summary> | ||
19 | protected IWindowsInstallerDecompileContext Context { get; private set; } | ||
20 | |||
21 | /// <summary> | ||
22 | /// Messaging for use by the extension. | ||
23 | /// </summary> | ||
24 | protected IMessaging Messaging { get; private set; } | ||
25 | |||
26 | /// <summary> | ||
27 | /// Decompiler helper for use by the extension. | ||
28 | /// </summary> | ||
29 | protected IWindowsInstallerDecompilerHelper DecompilerHelper { get; private set; } | ||
30 | |||
31 | /// <summary> | ||
32 | /// See <see cref="IWindowsInstallerDecompilerExtension.TableDefinitions"/> | ||
33 | /// </summary> | ||
34 | public virtual IReadOnlyCollection<TableDefinition> TableDefinitions { get; } | ||
35 | |||
36 | /// <summary> | ||
37 | /// See <see cref="IWindowsInstallerDecompilerExtension.PostDecompile(IWindowsInstallerDecompileResult)"/> | ||
38 | /// </summary> | ||
39 | public virtual void PreDecompile(IWindowsInstallerDecompileContext context) | ||
40 | { | ||
41 | this.Context = context; | ||
42 | |||
43 | this.Messaging = context.ServiceProvider.GetService<IMessaging>(); | ||
44 | |||
45 | this.DecompilerHelper = context.ServiceProvider.GetService<IWindowsInstallerDecompilerHelper>(); | ||
46 | } | ||
47 | |||
48 | /// <summary> | ||
49 | /// See <see cref="IWindowsInstallerDecompilerExtension.PreDecompileTables(TableIndexedCollection)"/> | ||
50 | /// </summary> | ||
51 | public virtual void PreDecompileTables(TableIndexedCollection tables) | ||
52 | { | ||
53 | } | ||
54 | |||
55 | /// <summary> | ||
56 | /// See <see cref="IWindowsInstallerDecompilerExtension.TryDecompileTable(Table)"/> | ||
57 | /// </summary> | ||
58 | public virtual bool TryDecompileTable(Table table) | ||
59 | { | ||
60 | return false; | ||
61 | } | ||
62 | |||
63 | /// <summary> | ||
64 | /// See <see cref="IWindowsInstallerDecompilerExtension.PostDecompileTables(TableIndexedCollection)"/> | ||
65 | /// </summary> | ||
66 | public virtual void PostDecompileTables(TableIndexedCollection tables) | ||
67 | { | ||
68 | } | ||
69 | |||
70 | /// <summary> | ||
71 | /// See <see cref="IWindowsInstallerDecompilerExtension.PostDecompile(IWindowsInstallerDecompileResult)"/> | ||
72 | /// </summary> | ||
73 | public virtual void PostDecompile(IWindowsInstallerDecompileResult result) | ||
74 | { | ||
75 | } | ||
76 | } | ||
77 | } | ||
diff --git a/src/api/wix/WixToolset.Extensibility/Data/IWindowsInstallerDecompileContext.cs b/src/api/wix/WixToolset.Extensibility/Data/IWindowsInstallerDecompileContext.cs index f744121a..27d30a5a 100644 --- a/src/api/wix/WixToolset.Extensibility/Data/IWindowsInstallerDecompileContext.cs +++ b/src/api/wix/WixToolset.Extensibility/Data/IWindowsInstallerDecompileContext.cs | |||
@@ -7,7 +7,7 @@ namespace WixToolset.Extensibility.Data | |||
7 | using WixToolset.Data; | 7 | using WixToolset.Data; |
8 | 8 | ||
9 | /// <summary> | 9 | /// <summary> |
10 | /// The context used to decompile Windows Installer packages. | 10 | /// The context used to decompile a Windows Installer database. |
11 | /// </summary> | 11 | /// </summary> |
12 | public interface IWindowsInstallerDecompileContext | 12 | public interface IWindowsInstallerDecompileContext |
13 | { | 13 | { |
@@ -32,6 +32,16 @@ namespace WixToolset.Extensibility.Data | |||
32 | IReadOnlyCollection<IWindowsInstallerDecompilerExtension> Extensions { get; set; } | 32 | IReadOnlyCollection<IWindowsInstallerDecompilerExtension> Extensions { get; set; } |
33 | 33 | ||
34 | /// <summary> | 34 | /// <summary> |
35 | /// Collection of extension data to use during decompiling. | ||
36 | /// </summary> | ||
37 | IReadOnlyCollection<IExtensionData> ExtensionData { get; set; } | ||
38 | |||
39 | /// <summary> | ||
40 | /// Symbol definition creator used to load extension data. | ||
41 | /// </summary> | ||
42 | ISymbolDefinitionCreator SymbolDefinitionCreator { get; set; } | ||
43 | |||
44 | /// <summary> | ||
35 | /// Gets or sets the folder where content is extracted. | 45 | /// Gets or sets the folder where content is extracted. |
36 | /// </summary> | 46 | /// </summary> |
37 | string ExtractFolder { get; set; } | 47 | string ExtractFolder { get; set; } |
diff --git a/src/api/wix/WixToolset.Extensibility/Data/IWindowsInstallerDecompileResult.cs b/src/api/wix/WixToolset.Extensibility/Data/IWindowsInstallerDecompileResult.cs index 3b1dd815..724dd7fc 100644 --- a/src/api/wix/WixToolset.Extensibility/Data/IWindowsInstallerDecompileResult.cs +++ b/src/api/wix/WixToolset.Extensibility/Data/IWindowsInstallerDecompileResult.cs | |||
@@ -6,13 +6,24 @@ namespace WixToolset.Extensibility.Data | |||
6 | using System.Xml.Linq; | 6 | using System.Xml.Linq; |
7 | using WixToolset.Data; | 7 | using WixToolset.Data; |
8 | 8 | ||
9 | #pragma warning disable 1591 // TODO: add documentation | 9 | /// <summary> |
10 | /// The result from decompiling a Windows Installer database. | ||
11 | /// </summary> | ||
10 | public interface IWindowsInstallerDecompileResult | 12 | public interface IWindowsInstallerDecompileResult |
11 | { | 13 | { |
14 | /// <summary> | ||
15 | /// Decompiled document. | ||
16 | /// </summary> | ||
12 | XDocument Document { get; set; } | 17 | XDocument Document { get; set; } |
13 | 18 | ||
14 | IReadOnlyCollection<string> ExtractedFilePaths { get; set; } | 19 | /// <summary> |
20 | /// Extracted paths. | ||
21 | /// </summary> | ||
22 | IList<string> ExtractedFilePaths { get; set; } | ||
15 | 23 | ||
24 | /// <summary> | ||
25 | /// Decompiled platform. | ||
26 | /// </summary> | ||
16 | Platform? Platform { get; set; } | 27 | Platform? Platform { get; set; } |
17 | } | 28 | } |
18 | } | 29 | } |
diff --git a/src/api/wix/WixToolset.Extensibility/DecompilerExtension.cs b/src/api/wix/WixToolset.Extensibility/DecompilerExtension.cs deleted file mode 100644 index b492cf3a..00000000 --- a/src/api/wix/WixToolset.Extensibility/DecompilerExtension.cs +++ /dev/null | |||
@@ -1,61 +0,0 @@ | |||
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 | |||
3 | namespace WixToolset.Extensibility | ||
4 | { | ||
5 | using WixToolset.Data; | ||
6 | |||
7 | #if BRING_BACK_LATER | ||
8 | /// <summary> | ||
9 | /// Base class for creating a decompiler extension. | ||
10 | /// </summary> | ||
11 | public abstract class DecompilerExtension : IDecompilerExtension | ||
12 | { | ||
13 | /// <summary> | ||
14 | /// Gets or sets the decompiler core for the extension. | ||
15 | /// </summary> | ||
16 | /// <value>The decompiler core for the extension.</value> | ||
17 | public IDecompilerCore Core { get; set; } | ||
18 | |||
19 | /// <summary> | ||
20 | /// Gets the table definitions this extension decompiles. | ||
21 | /// </summary> | ||
22 | /// <value>Table definitions this extension decompiles.</value> | ||
23 | public virtual TableDefinitionCollection TableDefinitions { get; protected set; } | ||
24 | |||
25 | /// <summary> | ||
26 | /// Gets the library that this decompiler wants removed from the decomipiled output. | ||
27 | /// </summary> | ||
28 | /// <param name="tableDefinitions">The table definitions to use while loading the library.</param> | ||
29 | /// <returns>The library for this extension or null if there is no library to be removed.</returns> | ||
30 | public virtual Library GetLibraryToRemove(TableDefinitionCollection tableDefinitions) | ||
31 | { | ||
32 | return null; | ||
33 | } | ||
34 | |||
35 | /// <summary> | ||
36 | /// Called at the beginning of the decompilation of a database. | ||
37 | /// </summary> | ||
38 | /// <param name="tables">The collection of all tables.</param> | ||
39 | public virtual void Initialize(TableIndexedCollection tables) | ||
40 | { | ||
41 | } | ||
42 | |||
43 | /// <summary> | ||
44 | /// Decompiles an extension table. | ||
45 | /// </summary> | ||
46 | /// <param name="table">The table to decompile.</param> | ||
47 | public virtual void DecompileTable(Table table) | ||
48 | { | ||
49 | this.Core.UnexpectedTable(table); | ||
50 | } | ||
51 | |||
52 | /// <summary> | ||
53 | /// Finalize decompilation. | ||
54 | /// </summary> | ||
55 | /// <param name="tables">The collection of all tables.</param> | ||
56 | public virtual void Finish(TableIndexedCollection tables) | ||
57 | { | ||
58 | } | ||
59 | } | ||
60 | #endif | ||
61 | } | ||
diff --git a/src/api/wix/WixToolset.Extensibility/IWindowsInstallerDecompilerExtension.cs b/src/api/wix/WixToolset.Extensibility/IWindowsInstallerDecompilerExtension.cs index add5f886..f7d54799 100644 --- a/src/api/wix/WixToolset.Extensibility/IWindowsInstallerDecompilerExtension.cs +++ b/src/api/wix/WixToolset.Extensibility/IWindowsInstallerDecompilerExtension.cs | |||
@@ -2,21 +2,45 @@ | |||
2 | 2 | ||
3 | namespace WixToolset.Extensibility | 3 | namespace WixToolset.Extensibility |
4 | { | 4 | { |
5 | using WixToolset.Data; | 5 | using System.Collections.Generic; |
6 | using WixToolset.Data.WindowsInstaller; | 6 | using WixToolset.Data.WindowsInstaller; |
7 | using WixToolset.Extensibility.Data; | 7 | using WixToolset.Extensibility.Data; |
8 | 8 | ||
9 | /// <summary> | 9 | /// <summary> |
10 | /// Interface all binder extensions implement. | 10 | /// Interface all windows installer decompiler extensions implement. |
11 | /// </summary> | 11 | /// </summary> |
12 | public interface IWindowsInstallerDecompilerExtension | 12 | public interface IWindowsInstallerDecompilerExtension |
13 | { | 13 | { |
14 | /// <summary> | 14 | /// <summary> |
15 | /// Gets the table definitions this extension decompiles. | ||
16 | /// </summary> | ||
17 | /// <value>Table definitions this extension decompiles.</value> | ||
18 | IReadOnlyCollection<TableDefinition> TableDefinitions { get; } | ||
19 | |||
20 | /// <summary> | ||
15 | /// Called before decompiling occurs. | 21 | /// Called before decompiling occurs. |
16 | /// </summary> | 22 | /// </summary> |
23 | /// <param name="context">Decompile context.</param> | ||
17 | void PreDecompile(IWindowsInstallerDecompileContext context); | 24 | void PreDecompile(IWindowsInstallerDecompileContext context); |
18 | 25 | ||
19 | // TODO: Redesign this interface to be useful. | 26 | /// <summary> |
27 | /// Called before decompiling occurs. | ||
28 | /// </summary> | ||
29 | /// <param name="tables">The collection of all tables.</param> | ||
30 | void PreDecompileTables(TableIndexedCollection tables); | ||
31 | |||
32 | /// <summary> | ||
33 | /// Try to decompile an extension table. | ||
34 | /// </summary> | ||
35 | /// <param name="table">The table to decompile.</param> | ||
36 | /// <returns>True if the table was decompiled, false otherwise.</returns> | ||
37 | bool TryDecompileTable(Table table); | ||
38 | |||
39 | /// <summary> | ||
40 | /// After decompilation tables. | ||
41 | /// </summary> | ||
42 | /// <param name="tables">The collection of all tables.</param> | ||
43 | void PostDecompileTables(TableIndexedCollection tables); | ||
20 | 44 | ||
21 | /// <summary> | 45 | /// <summary> |
22 | /// Called after all output changes occur and right before the output is bound into its final format. | 46 | /// Called after all output changes occur and right before the output is bound into its final format. |
diff --git a/src/api/wix/WixToolset.Extensibility/Services/IWindowsInstallerDecompilerHelper.cs b/src/api/wix/WixToolset.Extensibility/Services/IWindowsInstallerDecompilerHelper.cs new file mode 100644 index 00000000..1f5ac47a --- /dev/null +++ b/src/api/wix/WixToolset.Extensibility/Services/IWindowsInstallerDecompilerHelper.cs | |||
@@ -0,0 +1,180 @@ | |||
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 | |||
3 | namespace WixToolset.Extensibility.Services | ||
4 | { | ||
5 | using System.Xml.Linq; | ||
6 | using WixToolset.Data.WindowsInstaller; | ||
7 | |||
8 | /// <summary> | ||
9 | /// Interface provided to help Windows Installer decompiler extensions. | ||
10 | /// </summary> | ||
11 | public interface IWindowsInstallerDecompilerHelper | ||
12 | { | ||
13 | /// <summary> | ||
14 | /// Gets or sets the root element of the decompiled output. | ||
15 | /// </summary> | ||
16 | XElement RootElement { get; set; } | ||
17 | |||
18 | /// <summary> | ||
19 | /// Creates an element from the standard WiX Toolset namespace and adds it to the root document. | ||
20 | /// </summary> | ||
21 | /// <param name="name">Name of the element to create and add.</param> | ||
22 | /// <param name="content">Optional content to add to the new element.</param> | ||
23 | /// <returns>Element in the standard namespace.</returns> | ||
24 | XElement AddElementToRoot(string name, params object[] content); | ||
25 | |||
26 | /// <summary> | ||
27 | /// Creates an element with the specified name and adds it to the root document. | ||
28 | /// </summary> | ||
29 | /// <param name="name">Name of the element to create and add.</param> | ||
30 | /// <param name="content">Optional content to add to the new element.</param> | ||
31 | /// <returns>Element in the standard namespace.</returns> | ||
32 | XElement AddElementToRoot(XName name, params object[] content); | ||
33 | |||
34 | /// <summary> | ||
35 | /// Adds an existing element to the root document. | ||
36 | /// </summary> | ||
37 | /// <param name="element">Element to add.</param> | ||
38 | /// <returns>Same element provided.</returns> | ||
39 | XElement AddElementToRoot(XElement element); | ||
40 | |||
41 | /// <summary> | ||
42 | /// Creates an element from the standard WiX Toolset namespace. | ||
43 | /// </summary> | ||
44 | /// <param name="name">Name of the element to create.</param> | ||
45 | /// <param name="content">Optional content to add to the new element.</param> | ||
46 | /// <returns>Element in the standard namespace.</returns> | ||
47 | XElement CreateElement(string name, params object[] content); | ||
48 | |||
49 | /// <summary> | ||
50 | /// Get an element index by a row's table and primary keys. | ||
51 | /// </summary> | ||
52 | /// <param name="row">Row to get element.</param> | ||
53 | /// <returns>Element indexed for the row or null if not found.</returns> | ||
54 | XElement GetIndexedElement(Row row); | ||
55 | |||
56 | /// <summary> | ||
57 | /// Get an element index by table and primary key. | ||
58 | /// </summary> | ||
59 | /// <param name="table">Table name for indexed element.</param> | ||
60 | /// <param name="primaryKey">Primary key for indexed element.</param> | ||
61 | /// <returns>Element indexed for the table and primary key or null if not found.</returns> | ||
62 | XElement GetIndexedElement(string table, string primaryKey); | ||
63 | |||
64 | /// <summary> | ||
65 | /// Get an element index by table and primary keys. | ||
66 | /// </summary> | ||
67 | /// <param name="table">Table name for indexed element.</param> | ||
68 | /// <param name="primaryKey1">Primary key for first column indexed element.</param> | ||
69 | /// <param name="primaryKey2">Primary key for second column indexed element.</param> | ||
70 | /// <returns>Element indexed for the table and primary keys or null if not found.</returns> | ||
71 | XElement GetIndexedElement(string table, string primaryKey1, string primaryKey2); | ||
72 | |||
73 | /// <summary> | ||
74 | /// Get an element index by table and primary keys. | ||
75 | /// </summary> | ||
76 | /// <param name="table">Table name for indexed element.</param> | ||
77 | /// <param name="primaryKey1">Primary key for first column indexed element.</param> | ||
78 | /// <param name="primaryKey2">Primary key for second column indexed element.</param> | ||
79 | /// <param name="primaryKey3">Primary key for third column indexed element.</param> | ||
80 | /// <returns>Element indexed for the table and primary keys or null if not found.</returns> | ||
81 | XElement GetIndexedElement(string table, string primaryKey1, string primaryKey2, string primaryKey3); | ||
82 | |||
83 | /// <summary> | ||
84 | /// Get an element index by table and primary keys. | ||
85 | /// </summary> | ||
86 | /// <param name="table">Table name for indexed element.</param> | ||
87 | /// <param name="primaryKeys">Primary keys for indexed element.</param> | ||
88 | /// <returns>Element indexed for the table and primary keys or null if not found.</returns> | ||
89 | XElement GetIndexedElement(string table, string[] primaryKeys); | ||
90 | |||
91 | /// <summary> | ||
92 | /// Try to get an element index by a row's table and primary keys. | ||
93 | /// </summary> | ||
94 | /// <param name="row">Row to get element.</param> | ||
95 | /// <param name="element">Element indexed for the row.</param> | ||
96 | /// <returns>True if the element was index otherwise false.</returns> | ||
97 | bool TryGetIndexedElement(Row row, out XElement element); | ||
98 | |||
99 | /// <summary> | ||
100 | /// Try to get an element index by table name and primary key. | ||
101 | /// </summary> | ||
102 | /// <param name="table">Table name for indexed element.</param> | ||
103 | /// <param name="primaryKey">Primary key for indexed element.</param> | ||
104 | /// <param name="element">Element indexed for the table and primary key.</param> | ||
105 | /// <returns>True if the element was index otherwise false.</returns> | ||
106 | bool TryGetIndexedElement(string table, string primaryKey, out XElement element); | ||
107 | |||
108 | /// <summary> | ||
109 | /// Try to get an element index by table name and primary keys. | ||
110 | /// </summary> | ||
111 | /// <param name="table">Table name for indexed element.</param> | ||
112 | /// <param name="primaryKey1">First column's primary key for indexed element.</param> | ||
113 | /// <param name="primaryKey2">Second column's primary key for indexed element.</param> | ||
114 | /// <param name="element">Element indexed for the table and primary key.</param> | ||
115 | /// <returns>True if the element was index otherwise false.</returns> | ||
116 | bool TryGetIndexedElement(string table, string primaryKey1, string primaryKey2, out XElement element); | ||
117 | |||
118 | /// <summary> | ||
119 | /// Try to get an element index by table name and primary keys. | ||
120 | /// </summary> | ||
121 | /// <param name="table">Table name for indexed element.</param> | ||
122 | /// <param name="primaryKey1">First column's primary key for indexed element.</param> | ||
123 | /// <param name="primaryKey2">Second column's primary key for indexed element.</param> | ||
124 | /// <param name="primaryKey3">Third column's primary key for indexed element.</param> | ||
125 | /// <param name="element">Element indexed for the table and primary key.</param> | ||
126 | /// <returns>True if the element was index otherwise false.</returns> | ||
127 | bool TryGetIndexedElement(string table, string primaryKey1, string primaryKey2, string primaryKey3, out XElement element); | ||
128 | |||
129 | /// <summary> | ||
130 | /// Try to get an element index by table name and primary keys. | ||
131 | /// </summary> | ||
132 | /// <param name="table">Table name for indexed element.</param> | ||
133 | /// <param name="primaryKeys">Primary keys for indexed element.</param> | ||
134 | /// <param name="element">Element indexed for the table and primary key.</param> | ||
135 | /// <returns>True if the element was index otherwise false.</returns> | ||
136 | bool TryGetIndexedElement(string table, string[] primaryKeys, out XElement element); | ||
137 | |||
138 | /// <summary> | ||
139 | /// Index an element by a row's table and primary keys. | ||
140 | /// </summary> | ||
141 | /// <param name="row">Row to index element.</param> | ||
142 | /// <param name="element">Element to index.</param> | ||
143 | void IndexElement(Row row, XElement element); | ||
144 | |||
145 | /// <summary> | ||
146 | /// Index an element by table and primary key. | ||
147 | /// </summary> | ||
148 | /// <param name="table">Table name to index element.</param> | ||
149 | /// <param name="primaryKey">Primary key to index element.</param> | ||
150 | /// <param name="element">Element to index.</param> | ||
151 | void IndexElement(string table, string primaryKey, XElement element); | ||
152 | |||
153 | /// <summary> | ||
154 | /// Index an element by table and primary keys. | ||
155 | /// </summary> | ||
156 | /// <param name="table">Table name to index element.</param> | ||
157 | /// <param name="primaryKey1">First column's primary key to index element.</param> | ||
158 | /// <param name="primaryKey2">Second column's primary key to index element.</param> | ||
159 | /// <param name="element">Element to index.</param> | ||
160 | void IndexElement(string table, string primaryKey1, string primaryKey2, XElement element); | ||
161 | |||
162 | /// <summary> | ||
163 | /// Index an element by table and primary keys. | ||
164 | /// </summary> | ||
165 | /// <param name="table">Table name to index element.</param> | ||
166 | /// <param name="primaryKey1">First column's primary key to index element.</param> | ||
167 | /// <param name="primaryKey2">Second column's primary key to index element.</param> | ||
168 | /// <param name="primaryKey3">Third column's primary key to index element.</param> | ||
169 | /// <param name="element">Element to index.</param> | ||
170 | void IndexElement(string table, string primaryKey1, string primaryKey2, string primaryKey3, XElement element); | ||
171 | |||
172 | /// <summary> | ||
173 | /// Index an element by table and primary keys. | ||
174 | /// </summary> | ||
175 | /// <param name="table">Table name to index element.</param> | ||
176 | /// <param name="primaryKeys">Column's primary key to index element.</param> | ||
177 | /// <param name="element">Element to index.</param> | ||
178 | void IndexElement(string table, string[] primaryKeys, XElement element); | ||
179 | } | ||
180 | } | ||
diff --git a/src/ext/Util/Util.wixext.sln b/src/ext/Util/Util.wixext.sln index 259a8164..0168dab9 100644 --- a/src/ext/Util/Util.wixext.sln +++ b/src/ext/Util/Util.wixext.sln | |||
@@ -1,7 +1,7 @@ | |||
1 |  | 1 |  |
2 | Microsoft Visual Studio Solution File, Format Version 12.00 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 |
3 | # Visual Studio Version 16 | 3 | # Visual Studio Version 17 |
4 | VisualStudioVersion = 16.0.30204.135 | 4 | VisualStudioVersion = 17.1.32228.430 |
5 | MinimumVisualStudioVersion = 15.0.26124.0 | 5 | MinimumVisualStudioVersion = 15.0.26124.0 |
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "utilbe", "be\utilbe.vcxproj", "{630C1EE7-2517-4A8C-83E3-DA1150308B58}" | 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "utilbe", "be\utilbe.vcxproj", "{630C1EE7-2517-4A8C-83E3-DA1150308B58}" |
7 | EndProject | 7 | EndProject |
diff --git a/src/ext/Util/Util.wixext.v3.ncrunchsolution b/src/ext/Util/Util.wixext.v3.ncrunchsolution new file mode 100644 index 00000000..10420ac9 --- /dev/null +++ b/src/ext/Util/Util.wixext.v3.ncrunchsolution | |||
@@ -0,0 +1,6 @@ | |||
1 | <SolutionConfiguration> | ||
2 | <Settings> | ||
3 | <AllowParallelTestExecution>True</AllowParallelTestExecution> | ||
4 | <SolutionConfigured>True</SolutionConfigured> | ||
5 | </Settings> | ||
6 | </SolutionConfiguration> \ No newline at end of file | ||
diff --git a/src/ext/Util/test/WixToolsetTest.Util/UtilExtensionFixture.cs b/src/ext/Util/test/WixToolsetTest.Util/UtilExtensionFixture.cs index 883f9794..d2a4e34b 100644 --- a/src/ext/Util/test/WixToolsetTest.Util/UtilExtensionFixture.cs +++ b/src/ext/Util/test/WixToolsetTest.Util/UtilExtensionFixture.cs | |||
@@ -6,8 +6,6 @@ namespace WixToolsetTest.Util | |||
6 | using System.Linq; | 6 | using System.Linq; |
7 | using WixBuildTools.TestSupport; | 7 | using WixBuildTools.TestSupport; |
8 | using WixToolset.Core.TestPackage; | 8 | using WixToolset.Core.TestPackage; |
9 | using WixToolset.Data; | ||
10 | using WixToolset.Data.Symbols; | ||
11 | using WixToolset.Util; | 9 | using WixToolset.Util; |
12 | using Xunit; | 10 | using Xunit; |
13 | 11 | ||
@@ -56,6 +54,18 @@ namespace WixToolsetTest.Util | |||
56 | } | 54 | } |
57 | 55 | ||
58 | [Fact] | 56 | [Fact] |
57 | public void CanRoundtripFileShare() | ||
58 | { | ||
59 | var folder = TestData.Get(@"TestData", "UsingFileShare"); | ||
60 | var build = new Builder(folder, typeof(UtilExtensionFactory), new[] { folder }); | ||
61 | var output = Path.Combine(folder, "decompile.xml"); | ||
62 | |||
63 | build.BuildAndDecompileAndBuild(Build, Decompile, output); | ||
64 | File.Exists(output); | ||
65 | } | ||
66 | |||
67 | |||
68 | [Fact] | ||
59 | public void CanBuildCloseApplication() | 69 | public void CanBuildCloseApplication() |
60 | { | 70 | { |
61 | var folder = TestData.Get(@"TestData\CloseApplication"); | 71 | var folder = TestData.Get(@"TestData\CloseApplication"); |
@@ -313,5 +323,11 @@ namespace WixToolsetTest.Util | |||
313 | var result = WixRunner.Execute(newArgs.ToArray()); | 323 | var result = WixRunner.Execute(newArgs.ToArray()); |
314 | result.AssertSuccess(); | 324 | result.AssertSuccess(); |
315 | } | 325 | } |
326 | |||
327 | private static void Decompile(string[] args) | ||
328 | { | ||
329 | var result = WixRunner.Execute(args); | ||
330 | result.AssertSuccess(); | ||
331 | } | ||
316 | } | 332 | } |
317 | } | 333 | } |
diff --git a/src/ext/Util/wixext/UtilCompiler.cs b/src/ext/Util/wixext/UtilCompiler.cs index 45079150..09a90928 100644 --- a/src/ext/Util/wixext/UtilCompiler.cs +++ b/src/ext/Util/wixext/UtilCompiler.cs | |||
@@ -19,7 +19,7 @@ namespace WixToolset.Util | |||
19 | /// <summary> | 19 | /// <summary> |
20 | /// The compiler for the WiX Toolset Utility Extension. | 20 | /// The compiler for the WiX Toolset Utility Extension. |
21 | /// </summary> | 21 | /// </summary> |
22 | public sealed class UtilCompiler : BaseCompilerExtension | 22 | internal sealed class UtilCompiler : BaseCompilerExtension |
23 | { | 23 | { |
24 | // user creation attributes definitions (from sca.h) | 24 | // user creation attributes definitions (from sca.h) |
25 | internal const int UserDontExpirePasswrd = 0x00000001; | 25 | internal const int UserDontExpirePasswrd = 0x00000001; |
@@ -37,7 +37,7 @@ namespace WixToolset.Util | |||
37 | 37 | ||
38 | private static readonly Regex FindPropertyBrackets = new Regex(@"\[(?!\\|\])|(?<!\[\\\]|\[\\|\\\[)\]", RegexOptions.ExplicitCapture | RegexOptions.Compiled); | 38 | private static readonly Regex FindPropertyBrackets = new Regex(@"\[(?!\\|\])|(?<!\[\\\]|\[\\|\\\[)\]", RegexOptions.ExplicitCapture | RegexOptions.Compiled); |
39 | 39 | ||
40 | public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/util"; | 40 | public override XNamespace Namespace => UtilConstants.Namespace; |
41 | 41 | ||
42 | /// <summary> | 42 | /// <summary> |
43 | /// Types of Internet shortcuts. | 43 | /// Types of Internet shortcuts. |
@@ -94,13 +94,10 @@ namespace WixToolset.Util | |||
94 | var createFolderId = context["DirectoryId"]; | 94 | var createFolderId = context["DirectoryId"]; |
95 | var createFolderComponentId = context["ComponentId"]; | 95 | var createFolderComponentId = context["ComponentId"]; |
96 | 96 | ||
97 | // If this doesn't parse successfully, something really odd is going on, so let the exception get thrown | ||
98 | var createFolderWin64 = Boolean.Parse(context["Win64"]); | ||
99 | |||
100 | switch (element.Name.LocalName) | 97 | switch (element.Name.LocalName) |
101 | { | 98 | { |
102 | case "PermissionEx": | 99 | case "PermissionEx": |
103 | this.ParsePermissionExElement(intermediate, section, element, createFolderId, createFolderComponentId, createFolderWin64, "CreateFolder"); | 100 | this.ParsePermissionExElement(intermediate, section, element, createFolderId, createFolderComponentId, "CreateFolder"); |
104 | break; | 101 | break; |
105 | default: | 102 | default: |
106 | this.ParseHelper.UnexpectedElement(parentElement, element); | 103 | this.ParseHelper.UnexpectedElement(parentElement, element); |
@@ -159,16 +156,13 @@ namespace WixToolset.Util | |||
159 | var fileId = context["FileId"]; | 156 | var fileId = context["FileId"]; |
160 | var fileComponentId = context["ComponentId"]; | 157 | var fileComponentId = context["ComponentId"]; |
161 | 158 | ||
162 | // If this doesn't parse successfully, something really odd is going on, so let the exception get thrown | ||
163 | var fileWin64 = Boolean.Parse(context["Win64"]); | ||
164 | |||
165 | switch (element.Name.LocalName) | 159 | switch (element.Name.LocalName) |
166 | { | 160 | { |
167 | case "PerfCounter": | 161 | case "PerfCounter": |
168 | this.ParsePerfCounterElement(intermediate, section, element, fileComponentId, fileId); | 162 | this.ParsePerfCounterElement(intermediate, section, element, fileComponentId, fileId); |
169 | break; | 163 | break; |
170 | case "PermissionEx": | 164 | case "PermissionEx": |
171 | this.ParsePermissionExElement(intermediate, section, element, fileId, fileComponentId, fileWin64, "File"); | 165 | this.ParsePermissionExElement(intermediate, section, element, fileId, fileComponentId, "File"); |
172 | break; | 166 | break; |
173 | case "PerfCounterManifest": | 167 | case "PerfCounterManifest": |
174 | this.ParsePerfCounterManifestElement(intermediate, section, element, fileComponentId, fileId); | 168 | this.ParsePerfCounterManifestElement(intermediate, section, element, fileComponentId, fileId); |
@@ -177,7 +171,7 @@ namespace WixToolset.Util | |||
177 | this.ParseEventManifestElement(intermediate, section, element, fileComponentId, fileId); | 171 | this.ParseEventManifestElement(intermediate, section, element, fileComponentId, fileId); |
178 | break; | 172 | break; |
179 | case "FormatFile": | 173 | case "FormatFile": |
180 | this.ParseFormatFileElement(intermediate, section, element, fileId, fileWin64); | 174 | this.ParseFormatFileElement(intermediate, section, element, fileId); |
181 | break; | 175 | break; |
182 | default: | 176 | default: |
183 | this.ParseHelper.UnexpectedElement(parentElement, element); | 177 | this.ParseHelper.UnexpectedElement(parentElement, element); |
@@ -296,13 +290,10 @@ namespace WixToolset.Util | |||
296 | var registryId = context["RegistryId"]; | 290 | var registryId = context["RegistryId"]; |
297 | var registryComponentId = context["ComponentId"]; | 291 | var registryComponentId = context["ComponentId"]; |
298 | 292 | ||
299 | // If this doesn't parse successfully, something really odd is going on, so let the exception get thrown | ||
300 | var registryWin64 = Boolean.Parse(context["Win64"]); | ||
301 | |||
302 | switch (element.Name.LocalName) | 293 | switch (element.Name.LocalName) |
303 | { | 294 | { |
304 | case "PermissionEx": | 295 | case "PermissionEx": |
305 | this.ParsePermissionExElement(intermediate, section, element, registryId, registryComponentId, registryWin64, "Registry"); | 296 | this.ParsePermissionExElement(intermediate, section, element, registryId, registryComponentId, "Registry"); |
306 | break; | 297 | break; |
307 | default: | 298 | default: |
308 | this.ParseHelper.UnexpectedElement(parentElement, element); | 299 | this.ParseHelper.UnexpectedElement(parentElement, element); |
@@ -314,13 +305,10 @@ namespace WixToolset.Util | |||
314 | var serviceInstallName = context["ServiceInstallName"]; | 305 | var serviceInstallName = context["ServiceInstallName"]; |
315 | var serviceInstallComponentId = context["ServiceInstallComponentId"]; | 306 | var serviceInstallComponentId = context["ServiceInstallComponentId"]; |
316 | 307 | ||
317 | // If this doesn't parse successfully, something really odd is going on, so let the exception get thrown | ||
318 | var serviceInstallWin64 = Boolean.Parse(context["Win64"]); | ||
319 | |||
320 | switch (element.Name.LocalName) | 308 | switch (element.Name.LocalName) |
321 | { | 309 | { |
322 | case "PermissionEx": | 310 | case "PermissionEx": |
323 | this.ParsePermissionExElement(intermediate, section, element, serviceInstallId, serviceInstallComponentId, serviceInstallWin64, "ServiceInstall"); | 311 | this.ParsePermissionExElement(intermediate, section, element, serviceInstallId, serviceInstallComponentId, "ServiceInstall"); |
324 | break; | 312 | break; |
325 | case "ServiceConfig": | 313 | case "ServiceConfig": |
326 | this.ParseServiceConfigElement(intermediate, section, element, serviceInstallComponentId, "ServiceInstall", serviceInstallName); | 314 | this.ParseServiceConfigElement(intermediate, section, element, serviceInstallComponentId, "ServiceInstall", serviceInstallName); |
@@ -536,7 +524,6 @@ namespace WixToolset.Util | |||
536 | private void ParseComponentSearchRefElement(Intermediate intermediate, IntermediateSection section, XElement element) | 524 | private void ParseComponentSearchRefElement(Intermediate intermediate, IntermediateSection section, XElement element) |
537 | { | 525 | { |
538 | var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); | 526 | var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); |
539 | string refId = null; | ||
540 | 527 | ||
541 | foreach (var attrib in element.Attributes()) | 528 | foreach (var attrib in element.Attributes()) |
542 | { | 529 | { |
@@ -545,7 +532,7 @@ namespace WixToolset.Util | |||
545 | switch (attrib.Name.LocalName) | 532 | switch (attrib.Name.LocalName) |
546 | { | 533 | { |
547 | case "Id": | 534 | case "Id": |
548 | refId = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | 535 | var refId = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); |
549 | this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.WixComponentSearch, refId); | 536 | this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.WixComponentSearch, refId); |
550 | break; | 537 | break; |
551 | default: | 538 | default: |
@@ -2284,7 +2271,7 @@ namespace WixToolset.Util | |||
2284 | /// <param name="element">Element to parse.</param> | 2271 | /// <param name="element">Element to parse.</param> |
2285 | /// <param name="fileId">Identifier of referenced file.</param> | 2272 | /// <param name="fileId">Identifier of referenced file.</param> |
2286 | /// <param name="win64">Flag to determine whether the component is 64-bit.</param> | 2273 | /// <param name="win64">Flag to determine whether the component is 64-bit.</param> |
2287 | private void ParseFormatFileElement(Intermediate intermediate, IntermediateSection section, XElement element, string fileId, bool win64) | 2274 | private void ParseFormatFileElement(Intermediate intermediate, IntermediateSection section, XElement element, string fileId) |
2288 | { | 2275 | { |
2289 | var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); | 2276 | var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); |
2290 | string binaryId = null; | 2277 | string binaryId = null; |
@@ -2415,7 +2402,6 @@ namespace WixToolset.Util | |||
2415 | ComponentRef = componentId, | 2402 | ComponentRef = componentId, |
2416 | }); | 2403 | }); |
2417 | } | 2404 | } |
2418 | |||
2419 | } | 2405 | } |
2420 | 2406 | ||
2421 | this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4ConfigureEventManifestRegister", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64); | 2407 | this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4ConfigureEventManifestRegister", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64); |
@@ -2435,7 +2421,7 @@ namespace WixToolset.Util | |||
2435 | /// <param name="componentId">Identifier of component, used to determine install state.</param> | 2421 | /// <param name="componentId">Identifier of component, used to determine install state.</param> |
2436 | /// <param name="win64">Flag to determine whether the component is 64-bit.</param> | 2422 | /// <param name="win64">Flag to determine whether the component is 64-bit.</param> |
2437 | /// <param name="tableName">Name of table that contains objectId.</param> | 2423 | /// <param name="tableName">Name of table that contains objectId.</param> |
2438 | private void ParsePermissionExElement(Intermediate intermediate, IntermediateSection section, XElement element, string objectId, string componentId, bool win64, string tableName) | 2424 | private void ParsePermissionExElement(Intermediate intermediate, IntermediateSection section, XElement element, string objectId, string componentId, string tableName) |
2439 | { | 2425 | { |
2440 | var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); | 2426 | var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); |
2441 | var bits = new BitArray(32); | 2427 | var bits = new BitArray(32); |
@@ -2623,7 +2609,7 @@ namespace WixToolset.Util | |||
2623 | 2609 | ||
2624 | if (null == id) | 2610 | if (null == id) |
2625 | { | 2611 | { |
2626 | id = this.ParseHelper.CreateIdentifier("wps", variable, condition, after, (productCode == null ? upgradeCode : productCode), attributes.ToString()); | 2612 | id = this.ParseHelper.CreateIdentifier("wps", variable, condition, after, productCode ?? upgradeCode, attributes.ToString()); |
2627 | } | 2613 | } |
2628 | 2614 | ||
2629 | this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); | 2615 | this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); |
diff --git a/src/ext/Util/wixext/UtilConstants.cs b/src/ext/Util/wixext/UtilConstants.cs index 28ff368f..93616e44 100644 --- a/src/ext/Util/wixext/UtilConstants.cs +++ b/src/ext/Util/wixext/UtilConstants.cs | |||
@@ -2,11 +2,32 @@ | |||
2 | 2 | ||
3 | namespace WixToolset.Util | 3 | namespace WixToolset.Util |
4 | { | 4 | { |
5 | using System.Xml.Linq; | ||
6 | |||
5 | /// <summary> | 7 | /// <summary> |
6 | /// Constants used by Utility Extension. | 8 | /// Constants used by Utility Extension. |
7 | /// </summary> | 9 | /// </summary> |
8 | internal static class UtilConstants | 10 | internal static class UtilConstants |
9 | { | 11 | { |
12 | internal static readonly XNamespace Namespace = "http://wixtoolset.org/schemas/v4/wxs/util"; | ||
13 | |||
14 | internal static readonly XName CloseApplicationName = Namespace + "CloseApplication"; | ||
15 | internal static readonly XName EventManifestName = Namespace + "EventManifest"; | ||
16 | internal static readonly XName FileShareName = Namespace + "FileShare"; | ||
17 | internal static readonly XName FileSharePermissionName = Namespace + "FileSharePermission"; | ||
18 | internal static readonly XName GroupName = Namespace + "Group"; | ||
19 | internal static readonly XName GroupRefName = Namespace + "GroupRef"; | ||
20 | internal static readonly XName InternetShortcutName = Namespace + "InternetShortcut"; | ||
21 | internal static readonly XName PerfCounterName = Namespace + "PerfCounter"; | ||
22 | internal static readonly XName PerfCounterManifestName = Namespace + "PerfCounterManifest"; | ||
23 | internal static readonly XName PermissionExName = Namespace + "PermissionEx"; | ||
24 | internal static readonly XName RemoveFolderExName = Namespace + "RemoveFolderEx"; | ||
25 | internal static readonly XName RestartResourceName = Namespace + "RestartResource"; | ||
26 | internal static readonly XName ServiceConfigName = Namespace + "ServiceConfig"; | ||
27 | internal static readonly XName UserName = Namespace + "User"; | ||
28 | internal static readonly XName XmlConfigName = Namespace + "XmlConfig"; | ||
29 | internal static readonly XName XmlFileName = Namespace + "XmlFile"; | ||
30 | |||
10 | internal static readonly string[] FilePermissions = { "Read", "Write", "Append", "ReadExtendedAttributes", "WriteExtendedAttributes", "Execute", null, "ReadAttributes", "WriteAttributes" }; | 31 | internal static readonly string[] FilePermissions = { "Read", "Write", "Append", "ReadExtendedAttributes", "WriteExtendedAttributes", "Execute", null, "ReadAttributes", "WriteAttributes" }; |
11 | internal static readonly string[] FolderPermissions = { "Read", "CreateFile", "CreateChild", "ReadExtendedAttributes", "WriteExtendedAttributes", "Traverse", "DeleteChild", "ReadAttributes", "WriteAttributes" }; | 32 | internal static readonly string[] FolderPermissions = { "Read", "CreateFile", "CreateChild", "ReadExtendedAttributes", "WriteExtendedAttributes", "Traverse", "DeleteChild", "ReadAttributes", "WriteAttributes" }; |
12 | internal static readonly string[] GenericPermissions = { "GenericAll", "GenericExecute", "GenericWrite", "GenericRead" }; | 33 | internal static readonly string[] GenericPermissions = { "GenericAll", "GenericExecute", "GenericWrite", "GenericRead" }; |
diff --git a/src/ext/Util/wixext/UtilDecompiler.cs b/src/ext/Util/wixext/UtilDecompiler.cs index 9ef3390f..7d95fcef 100644 --- a/src/ext/Util/wixext/UtilDecompiler.cs +++ b/src/ext/Util/wixext/UtilDecompiler.cs | |||
@@ -1,48 +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. | 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 | ||
3 | namespace WixToolset.Extensions | 3 | namespace WixToolset.Util |
4 | { | 4 | { |
5 | #if TODO_CONSIDER_DECOMPILER | ||
6 | using System; | 5 | using System; |
7 | using System.IO; | 6 | using System.IO; |
8 | using System.Text; | 7 | using System.Text; |
9 | using System.Collections; | 8 | using System.Collections; |
10 | using System.Diagnostics; | 9 | using System.Diagnostics; |
11 | using System.Globalization; | ||
12 | 10 | ||
13 | using Util = WixToolset.Extensions.Serialize.Util; | ||
14 | using WixToolset.Data; | 11 | using WixToolset.Data; |
15 | using WixToolset.Extensibility; | 12 | using WixToolset.Extensibility; |
16 | using Wix = WixToolset.Data.Serialize; | 13 | using WixToolset.Data.WindowsInstaller; |
14 | using System.Collections.Generic; | ||
15 | using System.Xml.Linq; | ||
16 | using WixToolset.Util.Symbols; | ||
17 | 17 | ||
18 | /// <summary> | 18 | /// <summary> |
19 | /// The decompiler for the WiX Toolset Utility Extension. | 19 | /// The decompiler for the WiX Toolset Utility Extension. |
20 | /// </summary> | 20 | /// </summary> |
21 | public sealed class UtilDecompiler : DecompilerExtension | 21 | internal sealed class UtilDecompiler : BaseWindowsInstallerDecompilerExtension |
22 | { | 22 | { |
23 | /// <summary> | 23 | public override IReadOnlyCollection<TableDefinition> TableDefinitions => UtilTableDefinitions.All; |
24 | /// Creates a decompiler for Utility Extension. | ||
25 | /// </summary> | ||
26 | public UtilDecompiler() | ||
27 | { | ||
28 | this.TableDefinitions = UtilExtensionData.GetExtensionTableDefinitions(); | ||
29 | } | ||
30 | |||
31 | /// <summary> | ||
32 | /// Get the extensions library to be removed. | ||
33 | /// </summary> | ||
34 | /// <param name="tableDefinitions">Table definitions for library.</param> | ||
35 | /// <returns>Library to remove from decompiled output.</returns> | ||
36 | public override Library GetLibraryToRemove(TableDefinitionCollection tableDefinitions) | ||
37 | { | ||
38 | return UtilExtensionData.GetExtensionLibrary(tableDefinitions); | ||
39 | } | ||
40 | 24 | ||
41 | /// <summary> | 25 | /// <summary> |
42 | /// Called at the beginning of the decompilation of a database. | 26 | /// Called at the beginning of the decompilation of a database. |
43 | /// </summary> | 27 | /// </summary> |
44 | /// <param name="tables">The collection of all tables.</param> | 28 | /// <param name="tables">The collection of all tables.</param> |
45 | public override void Initialize(TableIndexedCollection tables) | 29 | public override void PreDecompileTables(TableIndexedCollection tables) |
46 | { | 30 | { |
47 | this.CleanupSecureCustomProperties(tables); | 31 | this.CleanupSecureCustomProperties(tables); |
48 | this.CleanupInternetShortcutRemoveFileTables(tables); | 32 | this.CleanupInternetShortcutRemoveFileTables(tables); |
@@ -61,24 +45,22 @@ namespace WixToolset.Extensions | |||
61 | /// <param name="tables">The collection of all tables.</param> | 45 | /// <param name="tables">The collection of all tables.</param> |
62 | private void CleanupSecureCustomProperties(TableIndexedCollection tables) | 46 | private void CleanupSecureCustomProperties(TableIndexedCollection tables) |
63 | { | 47 | { |
64 | Table propertyTable = tables["Property"]; | 48 | var propertyTable = tables["Property"]; |
65 | 49 | ||
66 | if (null != propertyTable) | 50 | if (null != propertyTable) |
67 | { | 51 | { |
68 | foreach (Row row in propertyTable.Rows) | 52 | foreach (var row in propertyTable.Rows) |
69 | { | 53 | { |
70 | if ("SecureCustomProperties" == row[0].ToString()) | 54 | if ("SecureCustomProperties" == row[0].ToString()) |
71 | { | 55 | { |
72 | StringBuilder remainingProperties = new StringBuilder(); | 56 | var remainingProperties = new StringBuilder(); |
73 | string[] secureCustomProperties = row[1].ToString().Split(';'); | 57 | var secureCustomProperties = row[1].ToString().Split(';'); |
74 | foreach (string property in secureCustomProperties) | 58 | foreach (var property in secureCustomProperties) |
75 | { | 59 | { |
76 | if (property.StartsWith("WIX_SUITE_", StringComparison.Ordinal) || property.StartsWith("WIX_DIR_", StringComparison.Ordinal) | 60 | if (property.StartsWith("WIX_SUITE_", StringComparison.Ordinal) || property.StartsWith("WIX_DIR_", StringComparison.Ordinal) |
77 | || property.StartsWith("WIX_ACCOUNT_", StringComparison.Ordinal)) | 61 | || property.StartsWith("WIX_ACCOUNT_", StringComparison.Ordinal)) |
78 | { | 62 | { |
79 | Wix.PropertyRef propertyRef = new Wix.PropertyRef(); | 63 | this.DecompilerHelper.AddElementToRoot("PropertyRef", new XAttribute("Id", property)); |
80 | propertyRef.Id = property; | ||
81 | this.Core.RootElement.AddChild(propertyRef); | ||
82 | } | 64 | } |
83 | else | 65 | else |
84 | { | 66 | { |
@@ -104,21 +86,21 @@ namespace WixToolset.Extensions | |||
104 | private void CleanupInternetShortcutRemoveFileTables(TableIndexedCollection tables) | 86 | private void CleanupInternetShortcutRemoveFileTables(TableIndexedCollection tables) |
105 | { | 87 | { |
106 | // index the WixInternetShortcut table | 88 | // index the WixInternetShortcut table |
107 | Table wixInternetShortcutTable = tables["WixInternetShortcut"]; | 89 | var wixInternetShortcutTable = tables["WixInternetShortcut"]; |
108 | Hashtable wixInternetShortcuts = new Hashtable(); | 90 | var wixInternetShortcuts = new Hashtable(); |
109 | if (null != wixInternetShortcutTable) | 91 | if (null != wixInternetShortcutTable) |
110 | { | 92 | { |
111 | foreach (Row row in wixInternetShortcutTable.Rows) | 93 | foreach (var row in wixInternetShortcutTable.Rows) |
112 | { | 94 | { |
113 | wixInternetShortcuts.Add(row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), row); | 95 | wixInternetShortcuts.Add(row.GetPrimaryKey(), row); |
114 | } | 96 | } |
115 | } | 97 | } |
116 | 98 | ||
117 | // remove the RemoveFile rows with primary keys that match the WixInternetShortcut table's | 99 | // remove the RemoveFile rows with primary keys that match the WixInternetShortcut table's |
118 | Table removeFileTable = tables["RemoveFile"]; | 100 | var removeFileTable = tables["RemoveFile"]; |
119 | if (null != removeFileTable) | 101 | if (null != removeFileTable) |
120 | { | 102 | { |
121 | for (int i = removeFileTable.Rows.Count - 1; 0 <= i; i--) | 103 | for (var i = removeFileTable.Rows.Count - 1; 0 <= i; i--) |
122 | { | 104 | { |
123 | if (null != wixInternetShortcuts[removeFileTable.Rows[i][0]]) | 105 | if (null != wixInternetShortcuts[removeFileTable.Rows[i][0]]) |
124 | { | 106 | { |
@@ -132,69 +114,86 @@ namespace WixToolset.Extensions | |||
132 | /// Decompiles an extension table. | 114 | /// Decompiles an extension table. |
133 | /// </summary> | 115 | /// </summary> |
134 | /// <param name="table">The table to decompile.</param> | 116 | /// <param name="table">The table to decompile.</param> |
135 | public override void DecompileTable(Table table) | 117 | public override bool TryDecompileTable(Table table) |
136 | { | 118 | { |
137 | switch (table.Name) | 119 | switch (table.Name) |
138 | { | 120 | { |
139 | case "WixCloseApplication": | 121 | case "WixCloseApplication": |
122 | case "Wix4CloseApplication": | ||
140 | this.DecompileWixCloseApplicationTable(table); | 123 | this.DecompileWixCloseApplicationTable(table); |
141 | break; | 124 | break; |
142 | case "WixRemoveFolderEx": | 125 | case "WixRemoveFolderEx": |
126 | case "Wix4RemoveFolderEx": | ||
143 | this.DecompileWixRemoveFolderExTable(table); | 127 | this.DecompileWixRemoveFolderExTable(table); |
144 | break; | 128 | break; |
145 | case "WixRestartResource": | 129 | case "WixRestartResource": |
130 | case "Wix4RestartResource": | ||
146 | this.DecompileWixRestartResourceTable(table); | 131 | this.DecompileWixRestartResourceTable(table); |
147 | break; | 132 | break; |
148 | case "FileShare": | 133 | case "FileShare": |
134 | case "Wix4FileShare": | ||
149 | this.DecompileFileShareTable(table); | 135 | this.DecompileFileShareTable(table); |
150 | break; | 136 | break; |
151 | case "FileSharePermissions": | 137 | case "FileSharePermissions": |
138 | case "Wix4FileSharePermissions": | ||
152 | this.DecompileFileSharePermissionsTable(table); | 139 | this.DecompileFileSharePermissionsTable(table); |
153 | break; | 140 | break; |
154 | case "WixInternetShortcut": | 141 | case "WixInternetShortcut": |
142 | case "Wix4InternetShortcut": | ||
155 | this.DecompileWixInternetShortcutTable(table); | 143 | this.DecompileWixInternetShortcutTable(table); |
156 | break; | 144 | break; |
157 | case "Group": | 145 | case "Group": |
146 | case "Wix4Group": | ||
158 | this.DecompileGroupTable(table); | 147 | this.DecompileGroupTable(table); |
159 | break; | 148 | break; |
160 | case "Perfmon": | 149 | case "Perfmon": |
150 | case "Wix4Perfmon": | ||
161 | this.DecompilePerfmonTable(table); | 151 | this.DecompilePerfmonTable(table); |
162 | break; | 152 | break; |
163 | case "PerfmonManifest": | 153 | case "PerfmonManifest": |
154 | case "Wix4PerfmonManifest": | ||
164 | this.DecompilePerfmonManifestTable(table); | 155 | this.DecompilePerfmonManifestTable(table); |
165 | break; | 156 | break; |
166 | case "EventManifest": | 157 | case "EventManifest": |
158 | case "Wix4EventManifest": | ||
167 | this.DecompileEventManifestTable(table); | 159 | this.DecompileEventManifestTable(table); |
168 | break; | 160 | break; |
169 | case "SecureObjects": | 161 | case "SecureObjects": |
162 | case "Wix4SecureObjects": | ||
170 | this.DecompileSecureObjectsTable(table); | 163 | this.DecompileSecureObjectsTable(table); |
171 | break; | 164 | break; |
172 | case "ServiceConfig": | 165 | case "ServiceConfig": |
166 | case "Wix4ServiceConfig": | ||
173 | this.DecompileServiceConfigTable(table); | 167 | this.DecompileServiceConfigTable(table); |
174 | break; | 168 | break; |
175 | case "User": | 169 | case "User": |
170 | case "Wix4User": | ||
176 | this.DecompileUserTable(table); | 171 | this.DecompileUserTable(table); |
177 | break; | 172 | break; |
178 | case "UserGroup": | 173 | case "UserGroup": |
174 | case "Wix4UserGroup": | ||
179 | this.DecompileUserGroupTable(table); | 175 | this.DecompileUserGroupTable(table); |
180 | break; | 176 | break; |
181 | case "XmlConfig": | 177 | case "XmlConfig": |
178 | case "Wix4XmlConfig": | ||
182 | this.DecompileXmlConfigTable(table); | 179 | this.DecompileXmlConfigTable(table); |
183 | break; | 180 | break; |
184 | case "XmlFile": | 181 | case "XmlFile": |
182 | case "Wix4XmlFile": | ||
185 | // XmlFile decompilation has been moved to FinalizeXmlFileTable function | 183 | // XmlFile decompilation has been moved to FinalizeXmlFileTable function |
186 | break; | 184 | break; |
187 | default: | 185 | default: |
188 | base.DecompileTable(table); | 186 | return false; |
189 | break; | ||
190 | } | 187 | } |
188 | |||
189 | return true; | ||
191 | } | 190 | } |
192 | 191 | ||
193 | /// <summary> | 192 | /// <summary> |
194 | /// Finalize decompilation. | 193 | /// Finalize decompilation. |
195 | /// </summary> | 194 | /// </summary> |
196 | /// <param name="tables">The collection of all tables.</param> | 195 | /// <param name="tables">The collection of all tables.</param> |
197 | public override void Finish(TableIndexedCollection tables) | 196 | public override void PostDecompileTables(TableIndexedCollection tables) |
198 | { | 197 | { |
199 | this.FinalizePerfmonTable(tables); | 198 | this.FinalizePerfmonTable(tables); |
200 | this.FinalizePerfmonManifestTable(tables); | 199 | this.FinalizePerfmonManifestTable(tables); |
@@ -211,49 +210,21 @@ namespace WixToolset.Extensions | |||
211 | /// <param name="table">The table to decompile.</param> | 210 | /// <param name="table">The table to decompile.</param> |
212 | private void DecompileWixCloseApplicationTable(Table table) | 211 | private void DecompileWixCloseApplicationTable(Table table) |
213 | { | 212 | { |
214 | foreach (Row row in table.Rows) | 213 | foreach (var row in table.Rows) |
215 | { | 214 | { |
216 | Util.CloseApplication closeApplication = new Util.CloseApplication(); | 215 | var attribute = row.FieldAsNullableInteger(4) ?? 0x2; |
217 | 216 | ||
218 | closeApplication.Id = (string)row[0]; | 217 | this.DecompilerHelper.AddElementToRoot(UtilConstants.CloseApplicationName, |
219 | 218 | new XAttribute("Id", row.FieldAsString(0)), | |
220 | closeApplication.Target = (string)row[1]; | 219 | new XAttribute("Target", row.FieldAsString(1)), |
221 | 220 | AttributeIfNotNull("Description", row, 2), | |
222 | if (null != row[2]) | 221 | AttributeIfNotNull("Content", row, 3), |
223 | { | 222 | AttributeIfNotNull("CloseMessage", 0x1 == (attribute & 0x1)), |
224 | closeApplication.Description = (string)row[2]; | 223 | AttributeIfNotNull("RebootPrompt", 0x2 == (attribute & 0x2)), |
225 | } | 224 | AttributeIfNotNull("ElevatedCloseMessage", 0x4 == (attribute & 0x4)), |
226 | 225 | NumericAttributeIfNotNull("Sequence", row, 5), | |
227 | if (null != row[3]) | 226 | NumericAttributeIfNotNull("Property", row, 6) |
228 | { | 227 | ); |
229 | closeApplication.Content = (string)row[3]; | ||
230 | } | ||
231 | |||
232 | // set defaults | ||
233 | closeApplication.CloseMessage = Util.YesNoType.no; | ||
234 | closeApplication.RebootPrompt = Util.YesNoType.yes; | ||
235 | closeApplication.ElevatedCloseMessage = Util.YesNoType.no; | ||
236 | |||
237 | if (null != row[4]) | ||
238 | { | ||
239 | int attribute = (int)row[4]; | ||
240 | |||
241 | closeApplication.CloseMessage = (0x1 == (attribute & 0x1)) ? Util.YesNoType.yes : Util.YesNoType.no; | ||
242 | closeApplication.RebootPrompt = (0x2 == (attribute & 0x2)) ? Util.YesNoType.yes : Util.YesNoType.no; | ||
243 | closeApplication.ElevatedCloseMessage = (0x4 == (attribute & 0x4)) ? Util.YesNoType.yes : Util.YesNoType.no; | ||
244 | } | ||
245 | |||
246 | if (null != row[5]) | ||
247 | { | ||
248 | closeApplication.Sequence = (int)row[5]; | ||
249 | } | ||
250 | |||
251 | if (null != row[6]) | ||
252 | { | ||
253 | closeApplication.Property = (string)row[6]; | ||
254 | } | ||
255 | |||
256 | this.Core.RootElement.AddChild(closeApplication); | ||
257 | } | 228 | } |
258 | } | 229 | } |
259 | 230 | ||
@@ -263,43 +234,45 @@ namespace WixToolset.Extensions | |||
263 | /// <param name="table">The table to decompile.</param> | 234 | /// <param name="table">The table to decompile.</param> |
264 | private void DecompileWixRemoveFolderExTable(Table table) | 235 | private void DecompileWixRemoveFolderExTable(Table table) |
265 | { | 236 | { |
266 | foreach (Row row in table.Rows) | 237 | foreach (var row in table.Rows) |
267 | { | 238 | { |
268 | // Set the Id even if auto-generated previously. | 239 | var on = String.Empty; |
269 | Util.RemoveFolderEx removeFolder = new Util.RemoveFolderEx(); | 240 | var installMode = row.FieldAsInteger(3); |
270 | removeFolder.Id = (string)row[0]; | 241 | switch (installMode) |
271 | removeFolder.Property = (string)row[2]; | ||
272 | |||
273 | int installMode = (int)row[3]; | ||
274 | switch ((UtilCompiler.WixRemoveFolderExOn)installMode) | ||
275 | { | 242 | { |
276 | case UtilCompiler.WixRemoveFolderExOn.Install: | 243 | case (int)WixRemoveFolderExInstallMode.Install: |
277 | removeFolder.On = Util.RemoveFolderEx.OnType.install; | 244 | on = "install"; |
278 | break; | 245 | break; |
279 | 246 | ||
280 | case UtilCompiler.WixRemoveFolderExOn.Uninstall: | 247 | case (int)WixRemoveFolderExInstallMode.Uninstall: |
281 | removeFolder.On = Util.RemoveFolderEx.OnType.uninstall; | 248 | on = "uninstall"; |
282 | break; | 249 | break; |
283 | 250 | ||
284 | case UtilCompiler.WixRemoveFolderExOn.Both: | 251 | case (int)WixRemoveFolderExInstallMode.Both: |
285 | removeFolder.On = Util.RemoveFolderEx.OnType.both; | 252 | on = "both"; |
286 | break; | 253 | break; |
287 | 254 | ||
288 | default: | 255 | default: |
289 | this.Core.OnMessage(WixWarnings.UnrepresentableColumnValue(row.SourceLineNumbers, table.Name, "InstallMode", installMode)); | 256 | this.Messaging.Write(WarningMessages.UnrepresentableColumnValue(row.SourceLineNumbers, table.Name, "InstallMode", installMode)); |
290 | break; | 257 | break; |
291 | } | 258 | } |
292 | 259 | ||
260 | var removeFolder = new XElement(UtilConstants.RemoveFolderExName, | ||
261 | AttributeIfNotNull("Id", row, 0), | ||
262 | AttributeIfNotNull("Property", row, 2), | ||
263 | AttributeIfNotNull("On", on) | ||
264 | ); | ||
265 | |||
293 | // Add to the appropriate Component or section element. | 266 | // Add to the appropriate Component or section element. |
294 | string componentId = (string)row[1]; | 267 | var componentId = row.FieldAsString(1); |
295 | Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", componentId); | 268 | |
296 | if (null != component) | 269 | if (this.DecompilerHelper.TryGetIndexedElement("Component", componentId, out var component)) |
297 | { | 270 | { |
298 | component.AddChild(removeFolder); | 271 | component.Add(removeFolder); |
299 | } | 272 | } |
300 | else | 273 | else |
301 | { | 274 | { |
302 | this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", componentId, "Component")); | 275 | this.Messaging.Write(WarningMessages.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(), "Component_", componentId, "Component")); |
303 | } | 276 | } |
304 | } | 277 | } |
305 | } | 278 | } |
@@ -310,53 +283,51 @@ namespace WixToolset.Extensions | |||
310 | /// <param name="table">The table to decompile.</param> | 283 | /// <param name="table">The table to decompile.</param> |
311 | private void DecompileWixRestartResourceTable(Table table) | 284 | private void DecompileWixRestartResourceTable(Table table) |
312 | { | 285 | { |
313 | foreach (Row row in table.Rows) | 286 | foreach (var row in table.Rows) |
314 | { | 287 | { |
315 | // Set the Id even if auto-generated previously. | 288 | var restartResource = new XElement(UtilConstants.RestartResourceName, |
316 | Util.RestartResource restartResource = new Util.RestartResource(); | 289 | new XAttribute("Id", row.FieldAsString(0))); |
317 | restartResource.Id = (string)row[0]; | ||
318 | 290 | ||
319 | // Determine the resource type and set accordingly. | 291 | // Determine the resource type and set accordingly. |
320 | string resource = (string)row[2]; | 292 | var resource = row.FieldAsString(2); |
321 | int attributes = (int)row[3]; | 293 | var attributes = row.FieldAsInteger(3); |
322 | UtilCompiler.WixRestartResourceAttributes type = (UtilCompiler.WixRestartResourceAttributes)(attributes & (int)UtilCompiler.WixRestartResourceAttributes.TypeMask); | 294 | var type = (WixRestartResourceAttributes)attributes; |
323 | 295 | ||
324 | switch (type) | 296 | switch (type) |
325 | { | 297 | { |
326 | case UtilCompiler.WixRestartResourceAttributes.Filename: | 298 | case WixRestartResourceAttributes.Filename: |
327 | restartResource.Path = resource; | 299 | restartResource.Add(new XAttribute("Path", resource)); |
328 | break; | 300 | break; |
329 | 301 | ||
330 | case UtilCompiler.WixRestartResourceAttributes.ProcessName: | 302 | case WixRestartResourceAttributes.ProcessName: |
331 | restartResource.ProcessName = resource; | 303 | restartResource.Add(new XAttribute("ProcessName", resource)); |
332 | break; | 304 | break; |
333 | 305 | ||
334 | case UtilCompiler.WixRestartResourceAttributes.ServiceName: | 306 | case WixRestartResourceAttributes.ServiceName: |
335 | restartResource.ServiceName = resource; | 307 | restartResource.Add(new XAttribute("ServiceName", resource)); |
336 | break; | 308 | break; |
337 | 309 | ||
338 | default: | 310 | default: |
339 | this.Core.OnMessage(WixWarnings.UnrepresentableColumnValue(row.SourceLineNumbers, table.Name, "Attributes", attributes)); | 311 | this.Messaging.Write(WarningMessages.UnrepresentableColumnValue(row.SourceLineNumbers, table.Name, "Attributes", attributes)); |
340 | break; | 312 | break; |
341 | } | 313 | } |
342 | 314 | ||
343 | // Add to the appropriate Component or section element. | 315 | // Add to the appropriate Component or section element. |
344 | string componentId = (string)row[1]; | 316 | var componentId = row.FieldAsString(1); |
345 | if (!String.IsNullOrEmpty(componentId)) | 317 | if (!String.IsNullOrEmpty(componentId)) |
346 | { | 318 | { |
347 | Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", componentId); | 319 | if (this.DecompilerHelper.TryGetIndexedElement("Component", componentId, out var component)) |
348 | if (null != component) | ||
349 | { | 320 | { |
350 | component.AddChild(restartResource); | 321 | component.Add(restartResource); |
351 | } | 322 | } |
352 | else | 323 | else |
353 | { | 324 | { |
354 | this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", componentId, "Component")); | 325 | this.Messaging.Write(WarningMessages.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(), "Component_", componentId, "Component")); |
355 | } | 326 | } |
356 | } | 327 | } |
357 | else | 328 | else |
358 | { | 329 | { |
359 | this.Core.RootElement.AddChild(restartResource); | 330 | this.DecompilerHelper.AddElementToRoot(restartResource); |
360 | } | 331 | } |
361 | } | 332 | } |
362 | } | 333 | } |
@@ -367,33 +338,28 @@ namespace WixToolset.Extensions | |||
367 | /// <param name="table">The table to decompile.</param> | 338 | /// <param name="table">The table to decompile.</param> |
368 | private void DecompileFileShareTable(Table table) | 339 | private void DecompileFileShareTable(Table table) |
369 | { | 340 | { |
370 | foreach (Row row in table.Rows) | 341 | foreach (var row in table.Rows) |
371 | { | 342 | { |
372 | Util.FileShare fileShare = new Util.FileShare(); | 343 | var fileShare = new XElement(UtilConstants.FileShareName, |
373 | 344 | new XAttribute("Id", row.FieldAsString(0)), | |
374 | fileShare.Id = (string)row[0]; | 345 | new XAttribute("Name", row.FieldAsString(1)), |
375 | 346 | AttributeIfNotNull("Description", row, 3) | |
376 | fileShare.Name = (string)row[1]; | 347 | ); |
377 | |||
378 | if (null != row[3]) | ||
379 | { | ||
380 | fileShare.Description = (string)row[3]; | ||
381 | } | ||
382 | 348 | ||
383 | // the Directory_ column is set by the parent Component | 349 | // the Directory_ column is set by the parent Component |
384 | 350 | ||
385 | // the User_ and Permissions columns are deprecated | 351 | // the User_ and Permissions columns are deprecated |
386 | 352 | ||
387 | Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]); | 353 | if (this.DecompilerHelper.TryGetIndexedElement("Component", row.FieldAsString(2), out var component)) |
388 | if (null != component) | ||
389 | { | 354 | { |
390 | component.AddChild(fileShare); | 355 | component.Add(fileShare); |
391 | } | 356 | } |
392 | else | 357 | else |
393 | { | 358 | { |
394 | this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component")); | 359 | this.Messaging.Write(WarningMessages.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(), "Component_", (string)row[2], "Component")); |
395 | } | 360 | } |
396 | this.Core.IndexElement(row, fileShare); | 361 | |
362 | this.DecompilerHelper.IndexElement(row, fileShare); | ||
397 | } | 363 | } |
398 | } | 364 | } |
399 | 365 | ||
@@ -403,111 +369,21 @@ namespace WixToolset.Extensions | |||
403 | /// <param name="table">The table to decompile.</param> | 369 | /// <param name="table">The table to decompile.</param> |
404 | private void DecompileFileSharePermissionsTable(Table table) | 370 | private void DecompileFileSharePermissionsTable(Table table) |
405 | { | 371 | { |
406 | foreach (Row row in table.Rows) | 372 | foreach (var row in table.Rows) |
407 | { | 373 | { |
408 | Util.FileSharePermission fileSharePermission = new Util.FileSharePermission(); | 374 | var fileSharePermission = new XElement(UtilConstants.FileSharePermissionName, |
409 | 375 | new XAttribute("User", row.FieldAsString(1))); | |
410 | fileSharePermission.User = (string)row[1]; | ||
411 | |||
412 | string[] specialPermissions = UtilConstants.FolderPermissions; | ||
413 | int permissions = (int)row[2]; | ||
414 | for (int i = 0; i < 32; i++) | ||
415 | { | ||
416 | if (0 != ((permissions >> i) & 1)) | ||
417 | { | ||
418 | string name = null; | ||
419 | 376 | ||
420 | if (16 > i && specialPermissions.Length > i) | 377 | this.AddPermissionAttributes(fileSharePermission, row, 2, UtilConstants.FolderPermissions); |
421 | { | ||
422 | name = specialPermissions[i]; | ||
423 | } | ||
424 | else if (28 > i && UtilConstants.StandardPermissions.Length > (i - 16)) | ||
425 | { | ||
426 | name = UtilConstants.StandardPermissions[i - 16]; | ||
427 | } | ||
428 | else if (0 <= (i - 28) && UtilConstants.GenericPermissions.Length > (i - 28)) | ||
429 | { | ||
430 | name = UtilConstants.GenericPermissions[i - 28]; | ||
431 | } | ||
432 | |||
433 | if (null == name) | ||
434 | { | ||
435 | this.Core.OnMessage(WixWarnings.UnknownPermission(row.SourceLineNumbers, row.Table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), i)); | ||
436 | } | ||
437 | else | ||
438 | { | ||
439 | switch (name) | ||
440 | { | ||
441 | case "ChangePermission": | ||
442 | fileSharePermission.ChangePermission = Util.YesNoType.yes; | ||
443 | break; | ||
444 | case "CreateChild": | ||
445 | fileSharePermission.CreateChild = Util.YesNoType.yes; | ||
446 | break; | ||
447 | case "CreateFile": | ||
448 | fileSharePermission.CreateFile = Util.YesNoType.yes; | ||
449 | break; | ||
450 | case "Delete": | ||
451 | fileSharePermission.Delete = Util.YesNoType.yes; | ||
452 | break; | ||
453 | case "DeleteChild": | ||
454 | fileSharePermission.DeleteChild = Util.YesNoType.yes; | ||
455 | break; | ||
456 | case "GenericAll": | ||
457 | fileSharePermission.GenericAll = Util.YesNoType.yes; | ||
458 | break; | ||
459 | case "GenericExecute": | ||
460 | fileSharePermission.GenericExecute = Util.YesNoType.yes; | ||
461 | break; | ||
462 | case "GenericRead": | ||
463 | fileSharePermission.GenericRead = Util.YesNoType.yes; | ||
464 | break; | ||
465 | case "GenericWrite": | ||
466 | fileSharePermission.GenericWrite = Util.YesNoType.yes; | ||
467 | break; | ||
468 | case "Read": | ||
469 | fileSharePermission.Read = Util.YesNoType.yes; | ||
470 | break; | ||
471 | case "ReadAttributes": | ||
472 | fileSharePermission.ReadAttributes = Util.YesNoType.yes; | ||
473 | break; | ||
474 | case "ReadExtendedAttributes": | ||
475 | fileSharePermission.ReadExtendedAttributes = Util.YesNoType.yes; | ||
476 | break; | ||
477 | case "ReadPermission": | ||
478 | fileSharePermission.ReadPermission = Util.YesNoType.yes; | ||
479 | break; | ||
480 | case "Synchronize": | ||
481 | fileSharePermission.Synchronize = Util.YesNoType.yes; | ||
482 | break; | ||
483 | case "TakeOwnership": | ||
484 | fileSharePermission.TakeOwnership = Util.YesNoType.yes; | ||
485 | break; | ||
486 | case "Traverse": | ||
487 | fileSharePermission.Traverse = Util.YesNoType.yes; | ||
488 | break; | ||
489 | case "WriteAttributes": | ||
490 | fileSharePermission.WriteAttributes = Util.YesNoType.yes; | ||
491 | break; | ||
492 | case "WriteExtendedAttributes": | ||
493 | fileSharePermission.WriteExtendedAttributes = Util.YesNoType.yes; | ||
494 | break; | ||
495 | default: | ||
496 | Debug.Fail(String.Format("Unknown permission '{0}'.", name)); | ||
497 | break; | ||
498 | } | ||
499 | } | ||
500 | } | ||
501 | } | ||
502 | 378 | ||
503 | Util.FileShare fileShare = (Util.FileShare)this.Core.GetIndexedElement("FileShare", (string)row[0]); | 379 | if (this.DecompilerHelper.TryGetIndexedElement("Wix4FileShare", row.FieldAsString(0), out var fileShare) || |
504 | if (null != fileShare) | 380 | this.DecompilerHelper.TryGetIndexedElement("FileShare", row.FieldAsString(0), out fileShare)) |
505 | { | 381 | { |
506 | fileShare.AddChild(fileSharePermission); | 382 | fileShare.Add(fileSharePermission); |
507 | } | 383 | } |
508 | else | 384 | else |
509 | { | 385 | { |
510 | this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "FileShare_", (string)row[0], "FileShare")); | 386 | this.Messaging.Write(WarningMessages.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(), "FileShare_", (string)row[0], "Wix4FileShare")); |
511 | } | 387 | } |
512 | } | 388 | } |
513 | } | 389 | } |
@@ -518,25 +394,18 @@ namespace WixToolset.Extensions | |||
518 | /// <param name="table">The table to decompile.</param> | 394 | /// <param name="table">The table to decompile.</param> |
519 | private void DecompileGroupTable(Table table) | 395 | private void DecompileGroupTable(Table table) |
520 | { | 396 | { |
521 | foreach (Row row in table.Rows) | 397 | foreach (var row in table.Rows) |
522 | { | 398 | { |
523 | Util.Group group = new Util.Group(); | ||
524 | |||
525 | group.Id = (string)row[0]; | ||
526 | |||
527 | if (null != row[1]) | 399 | if (null != row[1]) |
528 | { | 400 | { |
529 | this.Core.OnMessage(WixWarnings.UnrepresentableColumnValue(row.SourceLineNumbers, table.Name, "Component_", (string)row[1])); | 401 | this.Messaging.Write(WarningMessages.UnrepresentableColumnValue(row.SourceLineNumbers, table.Name, "Component_", (string)row[1])); |
530 | } | 402 | } |
531 | 403 | ||
532 | group.Name = (string)row[2]; | 404 | this.DecompilerHelper.AddElementToRoot(UtilConstants.GroupName, |
533 | 405 | new XAttribute("Id", row.FieldAsString(0)), | |
534 | if (null != row[3]) | 406 | new XAttribute("Name", row.FieldAsString(1)), |
535 | { | 407 | AttributeIfNotNull("Domain", row, 3) |
536 | group.Domain = (string)row[3]; | 408 | ); |
537 | } | ||
538 | |||
539 | this.Core.RootElement.AddChild(group); | ||
540 | } | 409 | } |
541 | } | 410 | } |
542 | 411 | ||
@@ -546,39 +415,41 @@ namespace WixToolset.Extensions | |||
546 | /// <param name="table">The table to decompile.</param> | 415 | /// <param name="table">The table to decompile.</param> |
547 | private void DecompileWixInternetShortcutTable(Table table) | 416 | private void DecompileWixInternetShortcutTable(Table table) |
548 | { | 417 | { |
549 | foreach (Row row in table.Rows) | 418 | foreach (var row in table.Rows) |
550 | { | 419 | { |
551 | Util.InternetShortcut internetShortcut = new Util.InternetShortcut(); | 420 | var type = String.Empty; |
552 | internetShortcut.Id = (string)row[0]; | 421 | var shortcutType = (UtilCompiler.InternetShortcutType)row.FieldAsInteger(5); |
553 | internetShortcut.Directory = (string)row[2]; | ||
554 | // remove .lnk/.url extension because compiler extension adds it back for us | ||
555 | internetShortcut.Name = Path.ChangeExtension((string)row[3], null); | ||
556 | internetShortcut.Target = (string)row[4]; | ||
557 | internetShortcut.IconFile = (string)row[6]; | ||
558 | internetShortcut.IconIndex = (int)row[7]; | ||
559 | |||
560 | UtilCompiler.InternetShortcutType shortcutType = (UtilCompiler.InternetShortcutType)row[5]; | ||
561 | switch (shortcutType) | 422 | switch (shortcutType) |
562 | { | 423 | { |
563 | case UtilCompiler.InternetShortcutType.Link: | 424 | case UtilCompiler.InternetShortcutType.Link: |
564 | internetShortcut.Type = Util.InternetShortcut.TypeType.link; | 425 | type = "link"; |
565 | break; | 426 | break; |
566 | case UtilCompiler.InternetShortcutType.Url: | 427 | case UtilCompiler.InternetShortcutType.Url: |
567 | internetShortcut.Type = Util.InternetShortcut.TypeType.url; | 428 | type = "url"; |
568 | break; | 429 | break; |
569 | } | 430 | } |
570 | 431 | ||
571 | Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]); | 432 | var internetShortcut = new XElement(UtilConstants.InternetShortcutName, |
572 | if (null != component) | 433 | new XAttribute("Id", row.FieldAsString(0)), |
434 | new XAttribute("Directory", row.FieldAsString(2)), | ||
435 | new XAttribute("Name", Path.GetFileNameWithoutExtension(row.FieldAsString(3))), // remove .lnk/.url extension because compiler extension adds it back for us | ||
436 | new XAttribute("Type", type), | ||
437 | new XAttribute("Target", row.FieldAsString(4)), | ||
438 | new XAttribute("IconFile", row.FieldAsString(6)), | ||
439 | NumericAttributeIfNotNull("IconIndex", row, 7) | ||
440 | ); | ||
441 | |||
442 | var componentId = row.FieldAsString(1); | ||
443 | if (this.DecompilerHelper.TryGetIndexedElement("Component", componentId, out var component)) | ||
573 | { | 444 | { |
574 | component.AddChild(internetShortcut); | 445 | component.Add(internetShortcut); |
575 | } | 446 | } |
576 | else | 447 | else |
577 | { | 448 | { |
578 | this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component")); | 449 | this.Messaging.Write(WarningMessages.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(), "Component_", componentId, "Component")); |
579 | } | 450 | } |
580 | 451 | ||
581 | this.Core.IndexElement(row, internetShortcut); | 452 | this.DecompilerHelper.IndexElement(row, internetShortcut); |
582 | } | 453 | } |
583 | } | 454 | } |
584 | 455 | ||
@@ -588,54 +459,48 @@ namespace WixToolset.Extensions | |||
588 | /// <param name="table">The table to decompile.</param> | 459 | /// <param name="table">The table to decompile.</param> |
589 | private void DecompilePerfmonTable(Table table) | 460 | private void DecompilePerfmonTable(Table table) |
590 | { | 461 | { |
591 | foreach (Row row in table.Rows) | 462 | foreach (var row in table.Rows) |
592 | { | 463 | { |
593 | Util.PerfCounter perfCounter = new Util.PerfCounter(); | 464 | this.DecompilerHelper.IndexElement(row, new XElement(UtilConstants.PerfCounterName, new XAttribute("Name", row.FieldAsString(2)))); |
594 | |||
595 | perfCounter.Name = (string)row[2]; | ||
596 | |||
597 | this.Core.IndexElement(row, perfCounter); | ||
598 | } | 465 | } |
599 | } | 466 | } |
600 | 467 | ||
601 | /// <summary> | 468 | /// <summary> |
602 | /// Decompile the PerfmonManifest table. | 469 | /// Decompile the PerfmonManifest table. |
603 | /// </summary> | 470 | /// </summary> |
604 | /// <param name="table">The table to decompile.</param> | 471 | /// <param name="table">The table to decompile.</param> |
605 | private void DecompilePerfmonManifestTable(Table table) | 472 | private void DecompilePerfmonManifestTable(Table table) |
606 | { | 473 | { |
607 | foreach (Row row in table.Rows) | 474 | foreach (var row in table.Rows) |
608 | { | 475 | { |
609 | Util.PerfCounterManifest perfCounterManifest = new Util.PerfCounterManifest(); | 476 | this.DecompilerHelper.IndexElement(row, new XElement(UtilConstants.PerfCounterManifestName, new XAttribute("ResourceFileDirectory", row.FieldAsString(2)))); |
610 | |||
611 | perfCounterManifest.ResourceFileDirectory = (string)row[2]; | ||
612 | |||
613 | this.Core.IndexElement(row, perfCounterManifest); | ||
614 | } | 477 | } |
615 | } | 478 | } |
616 | 479 | ||
617 | /// <summary> | 480 | /// <summary> |
618 | /// Decompile the EventManifest table. | 481 | /// Decompile the EventManifest table. |
619 | /// </summary> | 482 | /// </summary> |
620 | /// <param name="table">The table to decompile.</param> | 483 | /// <param name="table">The table to decompile.</param> |
621 | private void DecompileEventManifestTable(Table table) | 484 | private void DecompileEventManifestTable(Table table) |
622 | { | 485 | { |
623 | foreach (Row row in table.Rows) | 486 | foreach (var row in table.Rows) |
624 | { | 487 | { |
625 | Util.EventManifest eventManifest = new Util.EventManifest(); | 488 | this.DecompilerHelper.IndexElement(row, new XElement(UtilConstants.EventManifestName)); |
626 | this.Core.IndexElement(row, eventManifest); | ||
627 | } | 489 | } |
628 | } | 490 | } |
629 | 491 | ||
630 | /// <summary> | 492 | /// <summary> |
631 | /// Decompile the SecureObjects table. | 493 | /// Decompile the SecureObjects table. |
632 | /// </summary> | 494 | /// </summary> |
633 | /// <param name="table">The table to decompile.</param> | 495 | /// <param name="table">The table to decompile.</param> |
634 | private void DecompileSecureObjectsTable(Table table) | 496 | private void DecompileSecureObjectsTable(Table table) |
635 | { | 497 | { |
636 | foreach (Row row in table.Rows) | 498 | foreach (var row in table.Rows) |
637 | { | 499 | { |
638 | Util.PermissionEx permissionEx = new Util.PermissionEx(); | 500 | var permissionEx = new XElement(UtilConstants.PermissionExName, |
501 | AttributeIfNotNull("Domain", row, 2), | ||
502 | AttributeIfNotNull("User", row, 3) | ||
503 | ); | ||
639 | 504 | ||
640 | string[] specialPermissions; | 505 | string[] specialPermissions; |
641 | switch ((string)row[1]) | 506 | switch ((string)row[1]) |
@@ -653,155 +518,13 @@ namespace WixToolset.Extensions | |||
653 | specialPermissions = UtilConstants.ServicePermissions; | 518 | specialPermissions = UtilConstants.ServicePermissions; |
654 | break; | 519 | break; |
655 | default: | 520 | default: |
656 | this.Core.OnMessage(WixWarnings.IllegalColumnValue(row.SourceLineNumbers, row.Table.Name, row.Fields[1].Column.Name, row[1])); | 521 | this.Messaging.Write(WarningMessages.IllegalColumnValue(row.SourceLineNumbers, row.Table.Name, row.Fields[1].Column.Name, row[1])); |
657 | return; | 522 | return; |
658 | } | 523 | } |
659 | 524 | ||
660 | int permissionBits = (int)row[4]; | 525 | this.AddPermissionAttributes(permissionEx, row, 4, specialPermissions); |
661 | for (int i = 0; i < 32; i++) | ||
662 | { | ||
663 | if (0 != ((permissionBits >> i) & 1)) | ||
664 | { | ||
665 | string name = null; | ||
666 | 526 | ||
667 | if (16 > i && specialPermissions.Length > i) | 527 | this.DecompilerHelper.IndexElement(row, permissionEx); |
668 | { | ||
669 | name = specialPermissions[i]; | ||
670 | } | ||
671 | else if (28 > i && UtilConstants.StandardPermissions.Length > (i - 16)) | ||
672 | { | ||
673 | name = UtilConstants.StandardPermissions[i - 16]; | ||
674 | } | ||
675 | else if (0 <= (i - 28) && UtilConstants.GenericPermissions.Length > (i - 28)) | ||
676 | { | ||
677 | name = UtilConstants.GenericPermissions[i - 28]; | ||
678 | } | ||
679 | |||
680 | if (null == name) | ||
681 | { | ||
682 | this.Core.OnMessage(WixWarnings.UnknownPermission(row.SourceLineNumbers, row.Table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), i)); | ||
683 | } | ||
684 | else | ||
685 | { | ||
686 | switch (name) | ||
687 | { | ||
688 | case "Append": | ||
689 | permissionEx.Append = Util.YesNoType.yes; | ||
690 | break; | ||
691 | case "ChangePermission": | ||
692 | permissionEx.ChangePermission = Util.YesNoType.yes; | ||
693 | break; | ||
694 | case "CreateChild": | ||
695 | permissionEx.CreateChild = Util.YesNoType.yes; | ||
696 | break; | ||
697 | case "CreateFile": | ||
698 | permissionEx.CreateFile = Util.YesNoType.yes; | ||
699 | break; | ||
700 | case "CreateLink": | ||
701 | permissionEx.CreateLink = Util.YesNoType.yes; | ||
702 | break; | ||
703 | case "CreateSubkeys": | ||
704 | permissionEx.CreateSubkeys = Util.YesNoType.yes; | ||
705 | break; | ||
706 | case "Delete": | ||
707 | permissionEx.Delete = Util.YesNoType.yes; | ||
708 | break; | ||
709 | case "DeleteChild": | ||
710 | permissionEx.DeleteChild = Util.YesNoType.yes; | ||
711 | break; | ||
712 | case "EnumerateSubkeys": | ||
713 | permissionEx.EnumerateSubkeys = Util.YesNoType.yes; | ||
714 | break; | ||
715 | case "Execute": | ||
716 | permissionEx.Execute = Util.YesNoType.yes; | ||
717 | break; | ||
718 | case "GenericAll": | ||
719 | permissionEx.GenericAll = Util.YesNoType.yes; | ||
720 | break; | ||
721 | case "GenericExecute": | ||
722 | permissionEx.GenericExecute = Util.YesNoType.yes; | ||
723 | break; | ||
724 | case "GenericRead": | ||
725 | permissionEx.GenericRead = Util.YesNoType.yes; | ||
726 | break; | ||
727 | case "GenericWrite": | ||
728 | permissionEx.GenericWrite = Util.YesNoType.yes; | ||
729 | break; | ||
730 | case "Notify": | ||
731 | permissionEx.Notify = Util.YesNoType.yes; | ||
732 | break; | ||
733 | case "Read": | ||
734 | permissionEx.Read = Util.YesNoType.yes; | ||
735 | break; | ||
736 | case "ReadAttributes": | ||
737 | permissionEx.ReadAttributes = Util.YesNoType.yes; | ||
738 | break; | ||
739 | case "ReadExtendedAttributes": | ||
740 | permissionEx.ReadExtendedAttributes = Util.YesNoType.yes; | ||
741 | break; | ||
742 | case "ReadPermission": | ||
743 | permissionEx.ReadPermission = Util.YesNoType.yes; | ||
744 | break; | ||
745 | case "ServiceChangeConfig": | ||
746 | permissionEx.ServiceChangeConfig = Util.YesNoType.yes; | ||
747 | break; | ||
748 | case "ServiceEnumerateDependents": | ||
749 | permissionEx.ServiceEnumerateDependents = Util.YesNoType.yes; | ||
750 | break; | ||
751 | case "ServiceInterrogate": | ||
752 | permissionEx.ServiceInterrogate = Util.YesNoType.yes; | ||
753 | break; | ||
754 | case "ServicePauseContinue": | ||
755 | permissionEx.ServicePauseContinue = Util.YesNoType.yes; | ||
756 | break; | ||
757 | case "ServiceQueryConfig": | ||
758 | permissionEx.ServiceQueryConfig = Util.YesNoType.yes; | ||
759 | break; | ||
760 | case "ServiceQueryStatus": | ||
761 | permissionEx.ServiceQueryStatus = Util.YesNoType.yes; | ||
762 | break; | ||
763 | case "ServiceStart": | ||
764 | permissionEx.ServiceStart = Util.YesNoType.yes; | ||
765 | break; | ||
766 | case "ServiceStop": | ||
767 | permissionEx.ServiceStop = Util.YesNoType.yes; | ||
768 | break; | ||
769 | case "ServiceUserDefinedControl": | ||
770 | permissionEx.ServiceUserDefinedControl = Util.YesNoType.yes; | ||
771 | break; | ||
772 | case "Synchronize": | ||
773 | permissionEx.Synchronize = Util.YesNoType.yes; | ||
774 | break; | ||
775 | case "TakeOwnership": | ||
776 | permissionEx.TakeOwnership = Util.YesNoType.yes; | ||
777 | break; | ||
778 | case "Traverse": | ||
779 | permissionEx.Traverse = Util.YesNoType.yes; | ||
780 | break; | ||
781 | case "Write": | ||
782 | permissionEx.Write = Util.YesNoType.yes; | ||
783 | break; | ||
784 | case "WriteAttributes": | ||
785 | permissionEx.WriteAttributes = Util.YesNoType.yes; | ||
786 | break; | ||
787 | case "WriteExtendedAttributes": | ||
788 | permissionEx.WriteExtendedAttributes = Util.YesNoType.yes; | ||
789 | break; | ||
790 | default: | ||
791 | throw new InvalidOperationException(String.Format("Unknown permission attribute '{0}'.", name)); | ||
792 | } | ||
793 | } | ||
794 | } | ||
795 | } | ||
796 | |||
797 | if (null != row[2]) | ||
798 | { | ||
799 | permissionEx.Domain = (string)row[2]; | ||
800 | } | ||
801 | |||
802 | permissionEx.User = (string)row[3]; | ||
803 | |||
804 | this.Core.IndexElement(row, permissionEx); | ||
805 | } | 528 | } |
806 | } | 529 | } |
807 | 530 | ||
@@ -811,90 +534,20 @@ namespace WixToolset.Extensions | |||
811 | /// <param name="table">The table to decompile.</param> | 534 | /// <param name="table">The table to decompile.</param> |
812 | private void DecompileServiceConfigTable(Table table) | 535 | private void DecompileServiceConfigTable(Table table) |
813 | { | 536 | { |
814 | foreach (Row row in table.Rows) | 537 | foreach (var row in table.Rows) |
815 | { | 538 | { |
816 | Util.ServiceConfig serviceConfig = new Util.ServiceConfig(); | 539 | var serviceConfig = new XElement(UtilConstants.ServiceConfigName, |
817 | 540 | new XAttribute("ServiceName", row.FieldAsString(0)), | |
818 | serviceConfig.ServiceName = (string)row[0]; | 541 | AttributeIfNotNull("FirstFailureActionType", row, 3), |
819 | 542 | AttributeIfNotNull("SecondFailureActionType", row, 4), | |
820 | switch ((string)row[3]) | 543 | AttributeIfNotNull("ThirdFailureActionType", row, 5), |
821 | { | 544 | NumericAttributeIfNotNull("ResetPeriodInDays", row, 6), |
822 | case "none": | 545 | NumericAttributeIfNotNull("RestartServiceDelayInSeconds", row, 7), |
823 | serviceConfig.FirstFailureActionType = Util.ServiceConfig.FirstFailureActionTypeType.none; | 546 | AttributeIfNotNull("ProgramCommandLine", row, 8), |
824 | break; | 547 | AttributeIfNotNull("RebootMessage", row, 9) |
825 | case "reboot": | 548 | ); |
826 | serviceConfig.FirstFailureActionType = Util.ServiceConfig.FirstFailureActionTypeType.reboot; | 549 | |
827 | break; | 550 | this.DecompilerHelper.IndexElement(row, serviceConfig); |
828 | case "restart": | ||
829 | serviceConfig.FirstFailureActionType = Util.ServiceConfig.FirstFailureActionTypeType.restart; | ||
830 | break; | ||
831 | case "runCommand": | ||
832 | serviceConfig.FirstFailureActionType = Util.ServiceConfig.FirstFailureActionTypeType.runCommand; | ||
833 | break; | ||
834 | default: | ||
835 | this.Core.OnMessage(WixWarnings.IllegalColumnValue(row.SourceLineNumbers, table.Name, row.Fields[3].Column.Name, row[3])); | ||
836 | break; | ||
837 | } | ||
838 | |||
839 | switch ((string)row[4]) | ||
840 | { | ||
841 | case "none": | ||
842 | serviceConfig.SecondFailureActionType = Util.ServiceConfig.SecondFailureActionTypeType.none; | ||
843 | break; | ||
844 | case "reboot": | ||
845 | serviceConfig.SecondFailureActionType = Util.ServiceConfig.SecondFailureActionTypeType.reboot; | ||
846 | break; | ||
847 | case "restart": | ||
848 | serviceConfig.SecondFailureActionType = Util.ServiceConfig.SecondFailureActionTypeType.restart; | ||
849 | break; | ||
850 | case "runCommand": | ||
851 | serviceConfig.SecondFailureActionType = Util.ServiceConfig.SecondFailureActionTypeType.runCommand; | ||
852 | break; | ||
853 | default: | ||
854 | this.Core.OnMessage(WixWarnings.IllegalColumnValue(row.SourceLineNumbers, table.Name, row.Fields[4].Column.Name, row[4])); | ||
855 | break; | ||
856 | } | ||
857 | |||
858 | switch ((string)row[5]) | ||
859 | { | ||
860 | case "none": | ||
861 | serviceConfig.ThirdFailureActionType = Util.ServiceConfig.ThirdFailureActionTypeType.none; | ||
862 | break; | ||
863 | case "reboot": | ||
864 | serviceConfig.ThirdFailureActionType = Util.ServiceConfig.ThirdFailureActionTypeType.reboot; | ||
865 | break; | ||
866 | case "restart": | ||
867 | serviceConfig.ThirdFailureActionType = Util.ServiceConfig.ThirdFailureActionTypeType.restart; | ||
868 | break; | ||
869 | case "runCommand": | ||
870 | serviceConfig.ThirdFailureActionType = Util.ServiceConfig.ThirdFailureActionTypeType.runCommand; | ||
871 | break; | ||
872 | default: | ||
873 | this.Core.OnMessage(WixWarnings.IllegalColumnValue(row.SourceLineNumbers, table.Name, row.Fields[5].Column.Name, row[5])); | ||
874 | break; | ||
875 | } | ||
876 | |||
877 | if (null != row[6]) | ||
878 | { | ||
879 | serviceConfig.ResetPeriodInDays = (int)row[6]; | ||
880 | } | ||
881 | |||
882 | if (null != row[7]) | ||
883 | { | ||
884 | serviceConfig.RestartServiceDelayInSeconds = (int)row[7]; | ||
885 | } | ||
886 | |||
887 | if (null != row[8]) | ||
888 | { | ||
889 | serviceConfig.ProgramCommandLine = (string)row[8]; | ||
890 | } | ||
891 | |||
892 | if (null != row[9]) | ||
893 | { | ||
894 | serviceConfig.RebootMessage = (string)row[9]; | ||
895 | } | ||
896 | |||
897 | this.Core.IndexElement(row, serviceConfig); | ||
898 | } | 551 | } |
899 | } | 552 | } |
900 | 553 | ||
@@ -904,97 +557,58 @@ namespace WixToolset.Extensions | |||
904 | /// <param name="table">The table to decompile.</param> | 557 | /// <param name="table">The table to decompile.</param> |
905 | private void DecompileUserTable(Table table) | 558 | private void DecompileUserTable(Table table) |
906 | { | 559 | { |
907 | foreach (Row row in table.Rows) | 560 | foreach (var row in table.Rows) |
908 | { | 561 | { |
909 | Util.User user = new Util.User(); | 562 | var attributes = row.FieldAsNullableInteger(5) ?? 0; |
910 | 563 | ||
911 | user.Id = (string)row[0]; | 564 | var user = new XElement(UtilConstants.UserName, |
912 | 565 | new XAttribute("Id", row.FieldAsString(0)), | |
913 | user.Name = (string)row[2]; | 566 | new XAttribute("Name", row.FieldAsString(2)), |
914 | 567 | AttributeIfNotNull("Domain", row, 3), | |
915 | if (null != row[3]) | 568 | AttributeIfNotNull("Password", row, 4), |
569 | AttributeIfTrue("PasswordNeverExpires", UtilCompiler.UserDontExpirePasswrd == (attributes & UtilCompiler.UserDontExpirePasswrd)), | ||
570 | AttributeIfTrue("CanNotChangePassword", UtilCompiler.UserPasswdCantChange == (attributes & UtilCompiler.UserPasswdCantChange)), | ||
571 | AttributeIfTrue("PasswordExpired", UtilCompiler.UserPasswdChangeReqdOnLogin == (attributes & UtilCompiler.UserPasswdChangeReqdOnLogin)), | ||
572 | AttributeIfTrue("Disabled", UtilCompiler.UserDisableAccount == (attributes & UtilCompiler.UserDisableAccount)), | ||
573 | AttributeIfTrue("FailIfExists", UtilCompiler.UserFailIfExists == (attributes & UtilCompiler.UserFailIfExists)), | ||
574 | AttributeIfTrue("UpdateIfExists", UtilCompiler.UserUpdateIfExists == (attributes & UtilCompiler.UserUpdateIfExists)), | ||
575 | AttributeIfTrue("LogonAsService", UtilCompiler.UserLogonAsService == (attributes & UtilCompiler.UserLogonAsService)), | ||
576 | AttributeIfTrue("LogonAsService", UtilCompiler.UserLogonAsService == (attributes & UtilCompiler.UserLogonAsService)) | ||
577 | ); | ||
578 | |||
579 | if (UtilCompiler.UserDontRemoveOnUninstall == (attributes & UtilCompiler.UserDontRemoveOnUninstall)) | ||
916 | { | 580 | { |
917 | user.Domain = (string)row[3]; | 581 | user.Add(new XAttribute("RemoveOnUninstall", "no")); |
918 | } | 582 | } |
919 | 583 | ||
920 | if (null != row[4]) | 584 | if (UtilCompiler.UserDontCreateUser == (attributes & UtilCompiler.UserDontCreateUser)) |
921 | { | 585 | { |
922 | user.Password = (string)row[4]; | 586 | user.Add(new XAttribute("CreateUser", "no")); |
923 | } | 587 | } |
924 | 588 | ||
925 | if (null != row[5]) | 589 | if (UtilCompiler.UserNonVital == (attributes & UtilCompiler.UserNonVital)) |
926 | { | 590 | { |
927 | int attributes = (int)row[5]; | 591 | user.Add(new XAttribute("Vital", "no")); |
928 | |||
929 | if (UtilCompiler.UserDontExpirePasswrd == (attributes & UtilCompiler.UserDontExpirePasswrd)) | ||
930 | { | ||
931 | user.PasswordNeverExpires = Util.YesNoType.yes; | ||
932 | } | ||
933 | |||
934 | if (UtilCompiler.UserPasswdCantChange == (attributes & UtilCompiler.UserPasswdCantChange)) | ||
935 | { | ||
936 | user.CanNotChangePassword = Util.YesNoType.yes; | ||
937 | } | ||
938 | |||
939 | if (UtilCompiler.UserPasswdChangeReqdOnLogin == (attributes & UtilCompiler.UserPasswdChangeReqdOnLogin)) | ||
940 | { | ||
941 | user.PasswordExpired = Util.YesNoType.yes; | ||
942 | } | ||
943 | |||
944 | if (UtilCompiler.UserDisableAccount == (attributes & UtilCompiler.UserDisableAccount)) | ||
945 | { | ||
946 | user.Disabled = Util.YesNoType.yes; | ||
947 | } | ||
948 | |||
949 | if (UtilCompiler.UserFailIfExists == (attributes & UtilCompiler.UserFailIfExists)) | ||
950 | { | ||
951 | user.FailIfExists = Util.YesNoType.yes; | ||
952 | } | ||
953 | |||
954 | if (UtilCompiler.UserUpdateIfExists == (attributes & UtilCompiler.UserUpdateIfExists)) | ||
955 | { | ||
956 | user.UpdateIfExists = Util.YesNoType.yes; | ||
957 | } | ||
958 | |||
959 | if (UtilCompiler.UserLogonAsService == (attributes & UtilCompiler.UserLogonAsService)) | ||
960 | { | ||
961 | user.LogonAsService = Util.YesNoType.yes; | ||
962 | } | ||
963 | |||
964 | if (UtilCompiler.UserDontRemoveOnUninstall == (attributes & UtilCompiler.UserDontRemoveOnUninstall)) | ||
965 | { | ||
966 | user.RemoveOnUninstall = Util.YesNoType.no; | ||
967 | } | ||
968 | |||
969 | if (UtilCompiler.UserDontCreateUser == (attributes & UtilCompiler.UserDontCreateUser)) | ||
970 | { | ||
971 | user.CreateUser = Util.YesNoType.no; | ||
972 | } | ||
973 | |||
974 | if (UtilCompiler.UserNonVital == (attributes & UtilCompiler.UserNonVital)) | ||
975 | { | ||
976 | user.Vital = Util.YesNoType.no; | ||
977 | } | ||
978 | } | 592 | } |
979 | 593 | ||
980 | if (null != row[1]) | 594 | var componentId = row.FieldAsString(1); |
595 | if (!String.IsNullOrEmpty(componentId)) | ||
981 | { | 596 | { |
982 | Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]); | 597 | if (this.DecompilerHelper.TryGetIndexedElement("Component", componentId, out var component)) |
983 | |||
984 | if (null != component) | ||
985 | { | 598 | { |
986 | component.AddChild(user); | 599 | component.Add(user); |
987 | } | 600 | } |
988 | else | 601 | else |
989 | { | 602 | { |
990 | this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component")); | 603 | this.Messaging.Write(WarningMessages.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(), "Component_", componentId, "Component")); |
991 | } | 604 | } |
992 | } | 605 | } |
993 | else | 606 | else |
994 | { | 607 | { |
995 | this.Core.RootElement.AddChild(user); | 608 | this.DecompilerHelper.AddElementToRoot(user); |
996 | } | 609 | } |
997 | this.Core.IndexElement(row, user); | 610 | |
611 | this.DecompilerHelper.IndexElement(row, user); | ||
998 | } | 612 | } |
999 | } | 613 | } |
1000 | 614 | ||
@@ -1004,21 +618,16 @@ namespace WixToolset.Extensions | |||
1004 | /// <param name="table">The table to decompile.</param> | 618 | /// <param name="table">The table to decompile.</param> |
1005 | private void DecompileUserGroupTable(Table table) | 619 | private void DecompileUserGroupTable(Table table) |
1006 | { | 620 | { |
1007 | foreach (Row row in table.Rows) | 621 | foreach (var row in table.Rows) |
1008 | { | 622 | { |
1009 | Util.User user = (Util.User)this.Core.GetIndexedElement("User", (string)row[0]); | 623 | var userId = row.FieldAsString(0); |
1010 | 624 | if (this.DecompilerHelper.TryGetIndexedElement("User", userId, out var user)) | |
1011 | if (null != user) | ||
1012 | { | 625 | { |
1013 | Util.GroupRef groupRef = new Util.GroupRef(); | 626 | user.Add(new XElement(UtilConstants.GroupRefName, new XAttribute("Id", row.FieldAsString(1)))); |
1014 | |||
1015 | groupRef.Id = (string)row[1]; | ||
1016 | |||
1017 | user.AddChild(groupRef); | ||
1018 | } | 627 | } |
1019 | else | 628 | else |
1020 | { | 629 | { |
1021 | this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Group_", (string)row[0], "Group")); | 630 | this.Messaging.Write(WarningMessages.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(), "Group_", userId, "Group")); |
1022 | } | 631 | } |
1023 | } | 632 | } |
1024 | } | 633 | } |
@@ -1029,75 +638,58 @@ namespace WixToolset.Extensions | |||
1029 | /// <param name="table">The table to decompile.</param> | 638 | /// <param name="table">The table to decompile.</param> |
1030 | private void DecompileXmlConfigTable(Table table) | 639 | private void DecompileXmlConfigTable(Table table) |
1031 | { | 640 | { |
1032 | foreach (Row row in table.Rows) | 641 | foreach (var row in table.Rows) |
1033 | { | 642 | { |
1034 | Util.XmlConfig xmlConfig = new Util.XmlConfig(); | 643 | var flags = row.FieldAsNullableInteger(6) ?? 0; |
1035 | 644 | string node = null; | |
1036 | xmlConfig.Id = (string)row[0]; | 645 | string action = null; |
1037 | 646 | string on = null; | |
1038 | xmlConfig.File = (string)row[1]; | ||
1039 | |||
1040 | xmlConfig.ElementPath = (string)row[2]; | ||
1041 | |||
1042 | if (null != row[3]) | ||
1043 | { | ||
1044 | xmlConfig.VerifyPath = (string)row[3]; | ||
1045 | } | ||
1046 | |||
1047 | if (null != row[4]) | ||
1048 | { | ||
1049 | xmlConfig.Name = (string)row[4]; | ||
1050 | } | ||
1051 | |||
1052 | if (null != row[5]) | ||
1053 | { | ||
1054 | xmlConfig.Value = (string)row[5]; | ||
1055 | } | ||
1056 | |||
1057 | int flags = (int)row[6]; | ||
1058 | 647 | ||
1059 | if (0x1 == (flags & 0x1)) | 648 | if (0x1 == (flags & 0x1)) |
1060 | { | 649 | { |
1061 | xmlConfig.Node = Util.XmlConfig.NodeType.element; | 650 | node = "element"; |
1062 | } | 651 | } |
1063 | else if (0x2 == (flags & 0x2)) | 652 | else if (0x2 == (flags & 0x2)) |
1064 | { | 653 | { |
1065 | xmlConfig.Node = Util.XmlConfig.NodeType.value; | 654 | node = "value"; |
1066 | } | 655 | } |
1067 | else if (0x4 == (flags & 0x4)) | 656 | else if (0x4 == (flags & 0x4)) |
1068 | { | 657 | { |
1069 | xmlConfig.Node = Util.XmlConfig.NodeType.document; | 658 | node = "document"; |
1070 | } | 659 | } |
1071 | 660 | ||
1072 | if (0x10 == (flags & 0x10)) | 661 | if (0x10 == (flags & 0x10)) |
1073 | { | 662 | { |
1074 | xmlConfig.Action = Util.XmlConfig.ActionType.create; | 663 | action = "create"; |
1075 | } | 664 | } |
1076 | else if (0x20 == (flags & 0x20)) | 665 | else if (0x20 == (flags & 0x20)) |
1077 | { | 666 | { |
1078 | xmlConfig.Action = Util.XmlConfig.ActionType.delete; | 667 | action = "delete"; |
1079 | } | 668 | } |
1080 | 669 | ||
1081 | if (0x100 == (flags & 0x100)) | 670 | if (0x100 == (flags & 0x100)) |
1082 | { | 671 | { |
1083 | xmlConfig.On = Util.XmlConfig.OnType.install; | 672 | on = "install"; |
1084 | } | 673 | } |
1085 | else if (0x200 == (flags & 0x200)) | 674 | else if (0x200 == (flags & 0x200)) |
1086 | { | 675 | { |
1087 | xmlConfig.On = Util.XmlConfig.OnType.uninstall; | 676 | on = "uninstall"; |
1088 | } | ||
1089 | |||
1090 | if (0x00001000 == (flags & 0x00001000)) | ||
1091 | { | ||
1092 | xmlConfig.PreserveModifiedDate = Util.YesNoType.yes; | ||
1093 | } | ||
1094 | |||
1095 | if (null != row[8]) | ||
1096 | { | ||
1097 | xmlConfig.Sequence = (int)row[8]; | ||
1098 | } | 677 | } |
1099 | 678 | ||
1100 | this.Core.IndexElement(row, xmlConfig); | 679 | var xmlConfig = new XElement(UtilConstants.XmlConfigName, |
680 | new XAttribute("Id", row.FieldAsString(0)), | ||
681 | new XAttribute("File", row.FieldAsString(1)), | ||
682 | new XAttribute("ElementPath", row.FieldAsString(2)), | ||
683 | AttributeIfNotNull("VerifyPath", row, 3), | ||
684 | AttributeIfNotNull("Name", row, 4), | ||
685 | AttributeIfNotNull("Node", node), | ||
686 | AttributeIfNotNull("Action", action), | ||
687 | AttributeIfNotNull("On", on), | ||
688 | AttributeIfTrue("PreserveModifiedDate", 0x00001000 == (flags & 0x00001000)), | ||
689 | NumericAttributeIfNotNull("Sequence", row, 8) | ||
690 | ); | ||
691 | |||
692 | this.DecompilerHelper.IndexElement(row, xmlConfig); | ||
1101 | } | 693 | } |
1102 | } | 694 | } |
1103 | 695 | ||
@@ -1114,34 +706,30 @@ namespace WixToolset.Extensions | |||
1114 | /// </remarks> | 706 | /// </remarks> |
1115 | private void FinalizePerfmonTable(TableIndexedCollection tables) | 707 | private void FinalizePerfmonTable(TableIndexedCollection tables) |
1116 | { | 708 | { |
1117 | Table perfmonTable = tables["Perfmon"]; | 709 | if (tables.TryGetTable("Perfmon", out var perfmonTable)) |
1118 | |||
1119 | if (null != perfmonTable) | ||
1120 | { | 710 | { |
1121 | foreach (Row row in perfmonTable.Rows) | 711 | foreach (var row in perfmonTable.Rows) |
1122 | { | 712 | { |
1123 | string formattedFile = (string)row[1]; | 713 | var formattedFile = row.FieldAsString(1); |
1124 | Util.PerfCounter perfCounter = (Util.PerfCounter)this.Core.GetIndexedElement(row); | ||
1125 | 714 | ||
1126 | // try to "de-format" the File column's value to determine the proper parent File element | 715 | // try to "de-format" the File column's value to determine the proper parent File element |
1127 | if ((formattedFile.StartsWith("[#", StringComparison.Ordinal) || formattedFile.StartsWith("[!", StringComparison.Ordinal)) | 716 | if ((formattedFile.StartsWith("[#", StringComparison.Ordinal) || formattedFile.StartsWith("[!", StringComparison.Ordinal)) |
1128 | && formattedFile.EndsWith("]", StringComparison.Ordinal)) | 717 | && formattedFile.EndsWith("]", StringComparison.Ordinal)) |
1129 | { | 718 | { |
1130 | string fileId = formattedFile.Substring(2, formattedFile.Length - 3); | 719 | var fileId = formattedFile.Substring(2, formattedFile.Length - 3); |
1131 | 720 | if (this.DecompilerHelper.TryGetIndexedElement("File", fileId, out var file)) | |
1132 | Wix.File file = (Wix.File)this.Core.GetIndexedElement("File", fileId); | ||
1133 | if (null != file) | ||
1134 | { | 721 | { |
1135 | file.AddChild(perfCounter); | 722 | var perfCounter = this.DecompilerHelper.GetIndexedElement(row); |
723 | file.Add(perfCounter); | ||
1136 | } | 724 | } |
1137 | else | 725 | else |
1138 | { | 726 | { |
1139 | this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, perfmonTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "File", formattedFile, "File")); | 727 | this.Messaging.Write(WarningMessages.ExpectedForeignRow(row.SourceLineNumbers, perfmonTable.Name, row.GetPrimaryKey(), "File", formattedFile, "File")); |
1140 | } | 728 | } |
1141 | } | 729 | } |
1142 | else | 730 | else |
1143 | { | 731 | { |
1144 | this.Core.OnMessage(UtilErrors.IllegalFileValueInPerfmonOrManifest(formattedFile, "Perfmon")); | 732 | this.Messaging.Write(UtilErrors.IllegalFileValueInPerfmonOrManifest(formattedFile, "Perfmon")); |
1145 | } | 733 | } |
1146 | } | 734 | } |
1147 | } | 735 | } |
@@ -1153,34 +741,33 @@ namespace WixToolset.Extensions | |||
1153 | /// <param name="tables">The collection of all tables.</param> | 741 | /// <param name="tables">The collection of all tables.</param> |
1154 | private void FinalizePerfmonManifestTable(TableIndexedCollection tables) | 742 | private void FinalizePerfmonManifestTable(TableIndexedCollection tables) |
1155 | { | 743 | { |
1156 | Table perfmonManifestTable = tables["PerfmonManifest"]; | 744 | if (tables.TryGetTable("PerfmonManifest", out var perfmonManifestTable)) |
1157 | |||
1158 | if (null != perfmonManifestTable) | ||
1159 | { | 745 | { |
1160 | foreach (Row row in perfmonManifestTable.Rows) | 746 | foreach (var row in perfmonManifestTable.Rows) |
1161 | { | 747 | { |
1162 | string formattedFile = (string)row[1]; | 748 | var formattedFile = row.FieldAsString(1); |
1163 | Util.PerfCounterManifest perfCounterManifest = (Util.PerfCounterManifest)this.Core.GetIndexedElement(row); | ||
1164 | 749 | ||
1165 | // try to "de-format" the File column's value to determine the proper parent File element | 750 | // try to "de-format" the File column's value to determine the proper parent File element |
1166 | if ((formattedFile.StartsWith("[#", StringComparison.Ordinal) || formattedFile.StartsWith("[!", StringComparison.Ordinal)) | 751 | if ((formattedFile.StartsWith("[#", StringComparison.Ordinal) || formattedFile.StartsWith("[!", StringComparison.Ordinal)) |
1167 | && formattedFile.EndsWith("]", StringComparison.Ordinal)) | 752 | && formattedFile.EndsWith("]", StringComparison.Ordinal)) |
1168 | { | 753 | { |
1169 | string fileId = formattedFile.Substring(2, formattedFile.Length - 3); | 754 | var perfCounterManifest = this.DecompilerHelper.GetIndexedElement(row); |
755 | var fileId = formattedFile.Substring(2, formattedFile.Length - 3); | ||
1170 | 756 | ||
1171 | Wix.File file = (Wix.File)this.Core.GetIndexedElement("File", fileId); | 757 | if (this.DecompilerHelper.TryGetIndexedElement("File", fileId, out var file)) |
1172 | if (null != file) | ||
1173 | { | 758 | { |
1174 | file.AddChild(perfCounterManifest); | 759 | file.Add(perfCounterManifest); |
1175 | } | 760 | } |
1176 | else | 761 | else |
1177 | { | 762 | { |
1178 | this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, perfCounterManifest.ResourceFileDirectory, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "File", formattedFile, "File")); | 763 | var resourceFileDirectory = perfCounterManifest.Attribute("ResourceFileDirectory")?.Value; |
764 | |||
765 | this.Messaging.Write(WarningMessages.ExpectedForeignRow(row.SourceLineNumbers, resourceFileDirectory, row.GetPrimaryKey(), "File", formattedFile, "File")); | ||
1179 | } | 766 | } |
1180 | } | 767 | } |
1181 | else | 768 | else |
1182 | { | 769 | { |
1183 | this.Core.OnMessage(UtilErrors.IllegalFileValueInPerfmonOrManifest(formattedFile, "PerfmonManifest")); | 770 | this.Messaging.Write(UtilErrors.IllegalFileValueInPerfmonOrManifest(formattedFile, "PerfmonManifest")); |
1184 | } | 771 | } |
1185 | } | 772 | } |
1186 | } | 773 | } |
@@ -1196,64 +783,61 @@ namespace WixToolset.Extensions | |||
1196 | /// </remarks> | 783 | /// </remarks> |
1197 | private void FinalizeSecureObjectsTable(TableIndexedCollection tables) | 784 | private void FinalizeSecureObjectsTable(TableIndexedCollection tables) |
1198 | { | 785 | { |
1199 | Table createFolderTable = tables["CreateFolder"]; | 786 | var createFolderElementsByDirectoryId = new Dictionary<string, List<XElement>>(); |
1200 | Table secureObjectsTable = tables["SecureObjects"]; | ||
1201 | |||
1202 | Hashtable createFolders = new Hashtable(); | ||
1203 | 787 | ||
1204 | // index the CreateFolder table because the foreign key to this table from the | 788 | // index the CreateFolder table because the foreign key to this table from the |
1205 | // LockPermissions table is only part of the primary key of this table | 789 | // LockPermissions table is only part of the primary key of this table |
1206 | if (null != createFolderTable) | 790 | if (tables.TryGetTable("CreateFolder", out var createFolderTable)) |
1207 | { | 791 | { |
1208 | foreach (Row row in createFolderTable.Rows) | 792 | foreach (var row in createFolderTable.Rows) |
1209 | { | 793 | { |
1210 | Wix.CreateFolder createFolder = (Wix.CreateFolder)this.Core.GetIndexedElement(row); | 794 | var directoryId = row.FieldAsString(0); |
1211 | string directoryId = (string)row[0]; | ||
1212 | 795 | ||
1213 | if (!createFolders.Contains(directoryId)) | 796 | if (!createFolderElementsByDirectoryId.TryGetValue(directoryId, out var createFolderElements)) |
1214 | { | 797 | { |
1215 | createFolders.Add(directoryId, new ArrayList()); | 798 | createFolderElements = new List<XElement>(); |
799 | createFolderElementsByDirectoryId.Add(directoryId, createFolderElements); | ||
1216 | } | 800 | } |
1217 | ((ArrayList)createFolders[directoryId]).Add(createFolder); | 801 | |
802 | var createFolder = this.DecompilerHelper.GetIndexedElement(row); | ||
803 | createFolderElements.Add(createFolder); | ||
1218 | } | 804 | } |
1219 | } | 805 | } |
1220 | 806 | ||
1221 | if (null != secureObjectsTable) | 807 | if (tables.TryGetTable("SecureObjects", out var secureObjectsTable)) |
1222 | { | 808 | { |
1223 | foreach (Row row in secureObjectsTable.Rows) | 809 | foreach (var row in secureObjectsTable.Rows) |
1224 | { | 810 | { |
1225 | string id = (string)row[0]; | 811 | var id = row.FieldAsString(0); |
1226 | string table = (string)row[1]; | 812 | var table = row.FieldAsString(1); |
1227 | 813 | ||
1228 | Util.PermissionEx permissionEx = (Util.PermissionEx)this.Core.GetIndexedElement(row); | 814 | var permissionEx = this.DecompilerHelper.GetIndexedElement(row); |
1229 | 815 | ||
1230 | if ("CreateFolder" == table) | 816 | if (table == "CreateFolder") |
1231 | { | 817 | { |
1232 | ArrayList createFolderElements = (ArrayList)createFolders[id]; | 818 | if (createFolderElementsByDirectoryId.TryGetValue(id, out var createFolderElements)) |
1233 | |||
1234 | if (null != createFolderElements) | ||
1235 | { | 819 | { |
1236 | foreach (Wix.CreateFolder createFolder in createFolderElements) | 820 | foreach (var createFolder in createFolderElements) |
1237 | { | 821 | { |
1238 | createFolder.AddChild(permissionEx); | 822 | createFolder.Add(permissionEx); |
1239 | } | 823 | } |
1240 | } | 824 | } |
1241 | else | 825 | else |
1242 | { | 826 | { |
1243 | this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, "SecureObjects", row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "LockObject", id, table)); | 827 | this.Messaging.Write(WarningMessages.ExpectedForeignRow(row.SourceLineNumbers, "SecureObjects", row.GetPrimaryKey(), "LockObject", id, table)); |
1244 | } | 828 | } |
1245 | } | 829 | } |
1246 | else | 830 | else |
1247 | { | 831 | { |
1248 | Wix.IParentElement parentElement = (Wix.IParentElement)this.Core.GetIndexedElement(table, id); | 832 | var parentElement = this.DecompilerHelper.GetIndexedElement(table, id); |
1249 | 833 | ||
1250 | if (null != parentElement) | 834 | if (parentElement != null) |
1251 | { | 835 | { |
1252 | parentElement.AddChild(permissionEx); | 836 | parentElement.Add(permissionEx); |
1253 | } | 837 | } |
1254 | else | 838 | else |
1255 | { | 839 | { |
1256 | this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, "SecureObjects", row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "LockObject", id, table)); | 840 | this.Messaging.Write(WarningMessages.ExpectedForeignRow(row.SourceLineNumbers, "SecureObjects", row.GetPrimaryKey(), "LockObject", id, table)); |
1257 | } | 841 | } |
1258 | } | 842 | } |
1259 | } | 843 | } |
@@ -1270,10 +854,8 @@ namespace WixToolset.Extensions | |||
1270 | /// </remarks> | 854 | /// </remarks> |
1271 | private void FinalizeServiceConfigTable(TableIndexedCollection tables) | 855 | private void FinalizeServiceConfigTable(TableIndexedCollection tables) |
1272 | { | 856 | { |
1273 | Table serviceConfigTable = tables["ServiceConfig"]; | 857 | //var serviceInstalls = new Hashtable(); |
1274 | Table serviceInstallTable = tables["ServiceInstall"]; | 858 | var serviceInstallElementsByName = new Dictionary<string, List<XElement>>(); |
1275 | |||
1276 | Hashtable serviceInstalls = new Hashtable(); | ||
1277 | 859 | ||
1278 | // index the ServiceInstall table because the foreign key used by the ServiceConfig | 860 | // index the ServiceInstall table because the foreign key used by the ServiceConfig |
1279 | // table is actually the ServiceInstall.Name, not the ServiceInstall.ServiceInstall | 861 | // table is actually the ServiceInstall.Name, not the ServiceInstall.ServiceInstall |
@@ -1281,55 +863,54 @@ namespace WixToolset.Extensions | |||
1281 | // decompiler must assume there could be multiple matches and add the ServiceConfig to each | 863 | // decompiler must assume there could be multiple matches and add the ServiceConfig to each |
1282 | // TODO: the Component column information should be taken into acount to accurately identify | 864 | // TODO: the Component column information should be taken into acount to accurately identify |
1283 | // the correct column to use | 865 | // the correct column to use |
1284 | if (null != serviceInstallTable) | 866 | if (tables.TryGetTable("ServiceInstall", out var serviceInstallTable)) |
1285 | { | 867 | { |
1286 | foreach (Row row in serviceInstallTable.Rows) | 868 | foreach (var row in serviceInstallTable.Rows) |
1287 | { | 869 | { |
1288 | string name = (string)row[1]; | 870 | var name = row.FieldAsString(1); |
1289 | Wix.ServiceInstall serviceInstall = (Wix.ServiceInstall)this.Core.GetIndexedElement(row); | ||
1290 | 871 | ||
1291 | if (!serviceInstalls.Contains(name)) | 872 | if (!serviceInstallElementsByName.TryGetValue(name, out var serviceInstallElements)) |
1292 | { | 873 | { |
1293 | serviceInstalls.Add(name, new ArrayList()); | 874 | serviceInstallElements = new List<XElement>(); |
875 | serviceInstallElementsByName.Add(name, serviceInstallElements); | ||
1294 | } | 876 | } |
1295 | 877 | ||
1296 | ((ArrayList)serviceInstalls[name]).Add(serviceInstall); | 878 | var serviceInstall = this.DecompilerHelper.GetIndexedElement(row); |
879 | serviceInstallElements.Add(serviceInstall); | ||
1297 | } | 880 | } |
1298 | } | 881 | } |
1299 | 882 | ||
1300 | if (null != serviceConfigTable) | 883 | if (tables.TryGetTable("ServiceConfig", out var serviceConfigTable)) |
1301 | { | 884 | { |
1302 | foreach (Row row in serviceConfigTable.Rows) | 885 | foreach (var row in serviceConfigTable.Rows) |
1303 | { | 886 | { |
1304 | Util.ServiceConfig serviceConfig = (Util.ServiceConfig)this.Core.GetIndexedElement(row); | 887 | var serviceConfig = this.DecompilerHelper.GetIndexedElement(row); |
1305 | 888 | ||
1306 | if (0 == (int)row[2]) | 889 | if (row.FieldAsInteger(2) == 0) |
1307 | { | 890 | { |
1308 | Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[1]); | 891 | var componentId = row.FieldAsString(1); |
1309 | 892 | if (this.DecompilerHelper.TryGetIndexedElement("Component", componentId, out var component)) | |
1310 | if (null != component) | ||
1311 | { | 893 | { |
1312 | component.AddChild(serviceConfig); | 894 | component.Add(serviceConfig); |
1313 | } | 895 | } |
1314 | else | 896 | else |
1315 | { | 897 | { |
1316 | this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, serviceConfigTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[1], "Component")); | 898 | this.Messaging.Write(WarningMessages.ExpectedForeignRow(row.SourceLineNumbers, serviceConfigTable.Name, row.GetPrimaryKey(), "Component_", componentId, "Component")); |
1317 | } | 899 | } |
1318 | } | 900 | } |
1319 | else | 901 | else |
1320 | { | 902 | { |
1321 | ArrayList serviceInstallElements = (ArrayList)serviceInstalls[row[0]]; | 903 | var name = row.FieldAsString(0); |
1322 | 904 | if (serviceInstallElementsByName.TryGetValue(name, out var serviceInstallElements)) | |
1323 | if (null != serviceInstallElements) | ||
1324 | { | 905 | { |
1325 | foreach (Wix.ServiceInstall serviceInstall in serviceInstallElements) | 906 | foreach (var serviceInstall in serviceInstallElements) |
1326 | { | 907 | { |
1327 | serviceInstall.AddChild(serviceConfig); | 908 | serviceInstall.Add(serviceConfig); |
1328 | } | 909 | } |
1329 | } | 910 | } |
1330 | else | 911 | else |
1331 | { | 912 | { |
1332 | this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, serviceConfigTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "ServiceName", (string)row[0], "ServiceInstall")); | 913 | this.Messaging.Write(WarningMessages.ExpectedForeignRow(row.SourceLineNumbers, serviceConfigTable.Name, row.GetPrimaryKey(), "ServiceName", name, "ServiceInstall")); |
1333 | } | 914 | } |
1334 | } | 915 | } |
1335 | } | 916 | } |
@@ -1342,38 +923,34 @@ namespace WixToolset.Extensions | |||
1342 | /// <param name="tables">Collection of all tables.</param> | 923 | /// <param name="tables">Collection of all tables.</param> |
1343 | private void FinalizeXmlConfigTable(TableIndexedCollection tables) | 924 | private void FinalizeXmlConfigTable(TableIndexedCollection tables) |
1344 | { | 925 | { |
1345 | Table xmlConfigTable = tables["XmlConfig"]; | 926 | if (tables.TryGetTable("XmlConfig", out var xmlConfigTable)) |
1346 | |||
1347 | if (null != xmlConfigTable) | ||
1348 | { | 927 | { |
1349 | foreach (Row row in xmlConfigTable.Rows) | 928 | foreach (var row in xmlConfigTable.Rows) |
1350 | { | 929 | { |
1351 | Util.XmlConfig xmlConfig = (Util.XmlConfig)this.Core.GetIndexedElement(row); | 930 | var xmlConfig = this.DecompilerHelper.GetIndexedElement(row); |
1352 | 931 | ||
1353 | if (null == row[6] || 0 == (int)row[6]) | 932 | if (null == row[6] || 0 == (int)row[6]) |
1354 | { | 933 | { |
1355 | Util.XmlConfig parentXmlConfig = (Util.XmlConfig)this.Core.GetIndexedElement("XmlConfig", (string)row[2]); | 934 | var id = row.FieldAsString(2); |
1356 | 935 | if (this.DecompilerHelper.TryGetIndexedElement("XmlConfig", id, out var parentXmlConfig)) | |
1357 | if (null != parentXmlConfig) | ||
1358 | { | 936 | { |
1359 | parentXmlConfig.AddChild(xmlConfig); | 937 | parentXmlConfig.Add(xmlConfig); |
1360 | } | 938 | } |
1361 | else | 939 | else |
1362 | { | 940 | { |
1363 | this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, xmlConfigTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "ElementPath", (string)row[2], "XmlConfig")); | 941 | this.Messaging.Write(WarningMessages.ExpectedForeignRow(row.SourceLineNumbers, xmlConfigTable.Name, row.GetPrimaryKey(), "ElementPath", (string)row[2], "XmlConfig")); |
1364 | } | 942 | } |
1365 | } | 943 | } |
1366 | else | 944 | else |
1367 | { | 945 | { |
1368 | Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[7]); | 946 | var componentId = row.FieldAsString(7); |
1369 | 947 | if (this.DecompilerHelper.TryGetIndexedElement("Component", componentId, out var component)) | |
1370 | if (null != component) | ||
1371 | { | 948 | { |
1372 | component.AddChild(xmlConfig); | 949 | component.Add(xmlConfig); |
1373 | } | 950 | } |
1374 | else | 951 | else |
1375 | { | 952 | { |
1376 | this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, xmlConfigTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[7], "Component")); | 953 | this.Messaging.Write(WarningMessages.ExpectedForeignRow(row.SourceLineNumbers, xmlConfigTable.Name, row.GetPrimaryKey(), "Component_", componentId, "Component")); |
1377 | } | 954 | } |
1378 | } | 955 | } |
1379 | } | 956 | } |
@@ -1391,113 +968,88 @@ namespace WixToolset.Extensions | |||
1391 | /// </remarks> | 968 | /// </remarks> |
1392 | private void FinalizeXmlFileTable(TableIndexedCollection tables) | 969 | private void FinalizeXmlFileTable(TableIndexedCollection tables) |
1393 | { | 970 | { |
1394 | Table xmlFileTable = tables["XmlFile"]; | 971 | if (tables.TryGetTable("XmlFile", out var xmlFileTable)) |
1395 | Table eventManifestTable = tables["EventManifest"]; | ||
1396 | |||
1397 | if (null != xmlFileTable) | ||
1398 | { | 972 | { |
1399 | foreach (Row row in xmlFileTable.Rows) | 973 | var eventManifestTable = tables["EventManifest"]; |
974 | |||
975 | foreach (var row in xmlFileTable.Rows) | ||
1400 | { | 976 | { |
1401 | bool bManifestGenerated = false; | 977 | var manifestGenerated = false; |
1402 | string xmlFileConfigId = (string)row[0]; | 978 | var xmlFileConfigId = (string)row[0]; |
1403 | if (null != eventManifestTable) | 979 | if (null != eventManifestTable) |
1404 | { | 980 | { |
1405 | foreach (Row emrow in eventManifestTable.Rows) | 981 | foreach (var emrow in eventManifestTable.Rows) |
1406 | { | 982 | { |
1407 | string formattedFile = (string)emrow[1]; | 983 | var formattedFile = (string)emrow[1]; |
1408 | if ((formattedFile.StartsWith("[#", StringComparison.Ordinal) || formattedFile.StartsWith("[!", StringComparison.Ordinal)) | 984 | if ((formattedFile.StartsWith("[#", StringComparison.Ordinal) || formattedFile.StartsWith("[!", StringComparison.Ordinal)) |
1409 | && formattedFile.EndsWith("]", StringComparison.Ordinal)) | 985 | && formattedFile.EndsWith("]", StringComparison.Ordinal)) |
1410 | { | 986 | { |
1411 | string fileId = formattedFile.Substring(2, formattedFile.Length - 3); | 987 | var fileId = formattedFile.Substring(2, formattedFile.Length - 3); |
1412 | if (String.Equals(String.Concat("Config_", fileId, "ResourceFile"), xmlFileConfigId)) | 988 | if (String.Equals(String.Concat("Config_", fileId, "ResourceFile"), xmlFileConfigId)) |
1413 | { | 989 | { |
1414 | Util.EventManifest eventManifest = (Util.EventManifest)this.Core.GetIndexedElement(emrow); | 990 | if (this.DecompilerHelper.TryGetIndexedElement(emrow, out var eventManifest)) |
1415 | if (null != eventManifest) | ||
1416 | { | 991 | { |
1417 | eventManifest.ResourceFile = (string)row[4]; | 992 | eventManifest.Add(new XAttribute("ResourceFile", row.FieldAsString(4))); |
1418 | } | 993 | } |
1419 | bManifestGenerated = true; | 994 | manifestGenerated = true; |
1420 | } | 995 | } |
1421 | 996 | ||
1422 | else if (String.Equals(String.Concat("Config_", fileId, "MessageFile"), xmlFileConfigId)) | 997 | else if (String.Equals(String.Concat("Config_", fileId, "MessageFile"), xmlFileConfigId)) |
1423 | { | 998 | { |
1424 | Util.EventManifest eventManifest = (Util.EventManifest)this.Core.GetIndexedElement(emrow); | 999 | if (this.DecompilerHelper.TryGetIndexedElement(emrow, out var eventManifest)) |
1425 | if (null != eventManifest) | ||
1426 | { | 1000 | { |
1427 | eventManifest.MessageFile = (string)row[4]; | 1001 | eventManifest.Add(new XAttribute("MessageFile", row.FieldAsString(4))); |
1428 | } | 1002 | } |
1429 | bManifestGenerated = true; | 1003 | manifestGenerated = true; |
1430 | } | 1004 | } |
1431 | } | 1005 | } |
1432 | } | 1006 | } |
1433 | } | 1007 | } |
1434 | 1008 | ||
1435 | if (true == bManifestGenerated) | 1009 | if (manifestGenerated) |
1436 | continue; | ||
1437 | |||
1438 | Util.XmlFile xmlFile = new Util.XmlFile(); | ||
1439 | |||
1440 | xmlFile.Id = (string)row[0]; | ||
1441 | xmlFile.File = (string)row[1]; | ||
1442 | xmlFile.ElementPath = (string)row[2]; | ||
1443 | |||
1444 | if (null != row[3]) | ||
1445 | { | ||
1446 | xmlFile.Name = (string)row[3]; | ||
1447 | } | ||
1448 | |||
1449 | if (null != row[4]) | ||
1450 | { | 1010 | { |
1451 | xmlFile.Value = (string)row[4]; | 1011 | continue; |
1452 | } | 1012 | } |
1453 | 1013 | ||
1454 | int flags = (int)row[5]; | 1014 | var action = "setValue"; |
1015 | var flags = row.FieldAsInteger(5); | ||
1455 | if (0x1 == (flags & 0x1) && 0x2 == (flags & 0x2)) | 1016 | if (0x1 == (flags & 0x1) && 0x2 == (flags & 0x2)) |
1456 | { | 1017 | { |
1457 | this.Core.OnMessage(WixWarnings.IllegalColumnValue(row.SourceLineNumbers, xmlFileTable.Name, row.Fields[5].Column.Name, row[5])); | 1018 | this.Messaging.Write(WarningMessages.IllegalColumnValue(row.SourceLineNumbers, xmlFileTable.Name, row.Fields[5].Column.Name, row[5])); |
1458 | } | 1019 | } |
1459 | else if (0x1 == (flags & 0x1)) | 1020 | else if (0x1 == (flags & 0x1)) |
1460 | { | 1021 | { |
1461 | xmlFile.Action = Util.XmlFile.ActionType.createElement; | 1022 | action = "createElement"; |
1462 | } | 1023 | } |
1463 | else if (0x2 == (flags & 0x2)) | 1024 | else if (0x2 == (flags & 0x2)) |
1464 | { | 1025 | { |
1465 | xmlFile.Action = Util.XmlFile.ActionType.deleteValue; | 1026 | action = "deleteValue"; |
1466 | } | ||
1467 | else | ||
1468 | { | ||
1469 | xmlFile.Action = Util.XmlFile.ActionType.setValue; | ||
1470 | } | ||
1471 | |||
1472 | if (0x100 == (flags & 0x100)) | ||
1473 | { | ||
1474 | xmlFile.SelectionLanguage = Util.XmlFile.SelectionLanguageType.XPath; | ||
1475 | } | ||
1476 | |||
1477 | if (0x00001000 == (flags & 0x00001000)) | ||
1478 | { | ||
1479 | xmlFile.PreserveModifiedDate = Util.YesNoType.yes; | ||
1480 | } | 1027 | } |
1481 | 1028 | ||
1482 | if (0x00010000 == (flags & 0x00010000)) | 1029 | var selectionLanguage = (0x100 == (flags & 0x100)) ? "XPath" : null; |
1483 | { | 1030 | var preserveModifiedDate = 0x00001000 == (flags & 0x00001000); |
1484 | xmlFile.Permanent = Util.YesNoType.yes; | 1031 | var permanent = 0x00010000 == (flags & 0x00010000); |
1485 | } | ||
1486 | 1032 | ||
1487 | if (null != row[7]) | 1033 | if (this.DecompilerHelper.TryGetIndexedElement("Component", row.FieldAsString(6), out var component)) |
1488 | { | 1034 | { |
1489 | xmlFile.Sequence = (int)row[7]; | 1035 | var xmlFile = new XElement(UtilConstants.XmlFileName, |
1490 | } | 1036 | AttributeIfNotNull("Id", row, 0), |
1491 | 1037 | AttributeIfNotNull("File", row, 1), | |
1492 | Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[6]); | 1038 | AttributeIfNotNull("ElementPath", row, 2), |
1493 | 1039 | AttributeIfNotNull("Name", row, 3), | |
1494 | if (null != component) | 1040 | AttributeIfNotNull("Value", row, 4), |
1495 | { | 1041 | AttributeIfNotNull("Action", action), |
1496 | component.AddChild(xmlFile); | 1042 | AttributeIfNotNull("SelectionLanguage", selectionLanguage), |
1043 | AttributeIfTrue("PreserveModifiedDate", preserveModifiedDate), | ||
1044 | AttributeIfTrue("Permanent", permanent), | ||
1045 | NumericAttributeIfNotNull("Sequence", row, 7) | ||
1046 | ); | ||
1047 | |||
1048 | component.Add(xmlFile); | ||
1497 | } | 1049 | } |
1498 | else | 1050 | else |
1499 | { | 1051 | { |
1500 | this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, xmlFileTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[6], "Component")); | 1052 | this.Messaging.Write(WarningMessages.ExpectedForeignRow(row.SourceLineNumbers, xmlFileTable.Name, row.GetPrimaryKey(), "Component_", (string)row[6], "Component")); |
1501 | } | 1053 | } |
1502 | } | 1054 | } |
1503 | } | 1055 | } |
@@ -1510,34 +1062,122 @@ namespace WixToolset.Extensions | |||
1510 | /// <param name="tables">The collection of all tables.</param> | 1062 | /// <param name="tables">The collection of all tables.</param> |
1511 | private void FinalizeEventManifestTable(TableIndexedCollection tables) | 1063 | private void FinalizeEventManifestTable(TableIndexedCollection tables) |
1512 | { | 1064 | { |
1513 | Table eventManifestTable = tables["EventManifest"]; | 1065 | if (tables.TryGetTable("EventManifest", out var eventManifestTable)) |
1514 | |||
1515 | if (null != eventManifestTable) | ||
1516 | { | 1066 | { |
1517 | foreach (Row row in eventManifestTable.Rows) | 1067 | foreach (var row in eventManifestTable.Rows) |
1518 | { | 1068 | { |
1519 | string formattedFile = (string)row[1]; | 1069 | var eventManifest = this.DecompilerHelper.GetIndexedElement(row); |
1520 | Util.EventManifest eventManifest = (Util.EventManifest)this.Core.GetIndexedElement(row); | 1070 | var formattedFile = row.FieldAsString(1); |
1521 | 1071 | ||
1522 | // try to "de-format" the File column's value to determine the proper parent File element | 1072 | // try to "de-format" the File column's value to determine the proper parent File element |
1523 | if ((formattedFile.StartsWith("[#", StringComparison.Ordinal) || formattedFile.StartsWith("[!", StringComparison.Ordinal)) | 1073 | if ((formattedFile.StartsWith("[#", StringComparison.Ordinal) || formattedFile.StartsWith("[!", StringComparison.Ordinal)) |
1524 | && formattedFile.EndsWith("]", StringComparison.Ordinal)) | 1074 | && formattedFile.EndsWith("]", StringComparison.Ordinal)) |
1525 | { | 1075 | { |
1526 | string fileId = formattedFile.Substring(2, formattedFile.Length - 3); | 1076 | var fileId = formattedFile.Substring(2, formattedFile.Length - 3); |
1527 | 1077 | ||
1528 | Wix.File file = (Wix.File)this.Core.GetIndexedElement("File", fileId); | 1078 | if (this.DecompilerHelper.TryGetIndexedElement("File", fileId, out var file)) |
1529 | if (null != file) | ||
1530 | { | 1079 | { |
1531 | file.AddChild(eventManifest); | 1080 | file.Add(eventManifest); |
1532 | } | 1081 | } |
1533 | } | 1082 | } |
1534 | else | 1083 | else |
1535 | { | 1084 | { |
1536 | this.Core.OnMessage(UtilErrors.IllegalFileValueInPerfmonOrManifest(formattedFile, "EventManifest")); | 1085 | this.Messaging.Write(UtilErrors.IllegalFileValueInPerfmonOrManifest(formattedFile, "EventManifest")); |
1086 | } | ||
1087 | } | ||
1088 | } | ||
1089 | } | ||
1090 | |||
1091 | private void AddPermissionAttributes(XElement element, Row row, int column, string[] specialPermissions) | ||
1092 | { | ||
1093 | var permissions = row.FieldAsInteger(column); | ||
1094 | for (var i = 0; i < 32; i++) | ||
1095 | { | ||
1096 | if (0 != ((permissions >> i) & 1)) | ||
1097 | { | ||
1098 | string name = null; | ||
1099 | |||
1100 | if (16 > i && specialPermissions.Length > i) | ||
1101 | { | ||
1102 | name = specialPermissions[i]; | ||
1103 | } | ||
1104 | else if (28 > i && UtilConstants.StandardPermissions.Length > (i - 16)) | ||
1105 | { | ||
1106 | name = UtilConstants.StandardPermissions[i - 16]; | ||
1107 | } | ||
1108 | else if (0 <= (i - 28) && UtilConstants.GenericPermissions.Length > (i - 28)) | ||
1109 | { | ||
1110 | name = UtilConstants.GenericPermissions[i - 28]; | ||
1111 | } | ||
1112 | |||
1113 | if (!String.IsNullOrEmpty(name)) | ||
1114 | { | ||
1115 | element.Add(new XAttribute(name, "yes")); | ||
1116 | } | ||
1117 | else | ||
1118 | { | ||
1119 | this.Messaging.Write(WarningMessages.UnknownPermission(row.SourceLineNumbers, row.Table.Name, row.GetPrimaryKey(), i)); | ||
1537 | } | 1120 | } |
1538 | } | 1121 | } |
1539 | } | 1122 | } |
1540 | } | 1123 | } |
1124 | |||
1125 | private static XAttribute AttributeIfNotNull(string name, string value) | ||
1126 | { | ||
1127 | return value == null ? null : new XAttribute(name, value); | ||
1128 | } | ||
1129 | |||
1130 | private static XAttribute AttributeIfNotNull(string name, bool value) | ||
1131 | { | ||
1132 | return new XAttribute(name, value ? "yes" : "no"); | ||
1133 | } | ||
1134 | |||
1135 | private static XAttribute AttributeIfNotNull(string name, Row row, int field) | ||
1136 | { | ||
1137 | if (row[field] != null) | ||
1138 | { | ||
1139 | return new XAttribute(name, row.FieldAsString(field)); | ||
1140 | } | ||
1141 | |||
1142 | return null; | ||
1143 | } | ||
1144 | |||
1145 | private static XAttribute NumericAttributeIfNotNull(string name, Row row, int field) | ||
1146 | { | ||
1147 | if (row[field] != null) | ||
1148 | { | ||
1149 | return new XAttribute(name, row.FieldAsInteger(field)); | ||
1150 | } | ||
1151 | |||
1152 | return null; | ||
1153 | } | ||
1154 | |||
1155 | private static XAttribute AttributeIfTrue(string name, bool value) | ||
1156 | { | ||
1157 | return value ? new XAttribute(name, "yes") : null; | ||
1158 | } | ||
1159 | } | ||
1160 | |||
1161 | internal static class XElementExtensions | ||
1162 | { | ||
1163 | public static XElement AttributeIfNotNull(this XElement element, string name, Row row, int field) | ||
1164 | { | ||
1165 | if (row[field] != null) | ||
1166 | { | ||
1167 | element.Add(new XAttribute(name, row.FieldAsString(field))); | ||
1168 | } | ||
1169 | |||
1170 | return element; | ||
1171 | } | ||
1172 | |||
1173 | public static XElement NumericAttributeIfNotNull(this XElement element, string name, Row row, int field) | ||
1174 | { | ||
1175 | if (row[field] != null) | ||
1176 | { | ||
1177 | element.Add(new XAttribute(name, row.FieldAsInteger(field))); | ||
1178 | } | ||
1179 | |||
1180 | return element; | ||
1181 | } | ||
1541 | } | 1182 | } |
1542 | #endif | ||
1543 | } | 1183 | } |
diff --git a/src/ext/Util/wixext/UtilExtensionFactory.cs b/src/ext/Util/wixext/UtilExtensionFactory.cs index 08352813..d9bf575c 100644 --- a/src/ext/Util/wixext/UtilExtensionFactory.cs +++ b/src/ext/Util/wixext/UtilExtensionFactory.cs | |||
@@ -11,6 +11,7 @@ namespace WixToolset.Util | |||
11 | protected override IReadOnlyCollection<Type> ExtensionTypes => new[] | 11 | protected override IReadOnlyCollection<Type> ExtensionTypes => new[] |
12 | { | 12 | { |
13 | typeof(UtilCompiler), | 13 | typeof(UtilCompiler), |
14 | typeof(UtilDecompiler), | ||
14 | typeof(UtilExtensionData), | 15 | typeof(UtilExtensionData), |
15 | typeof(UtilWindowsInstallerBackendBinderExtension), | 16 | typeof(UtilWindowsInstallerBackendBinderExtension), |
16 | }; | 17 | }; |
diff --git a/src/ext/Util/wixext/UtilTableDefinitions.cs b/src/ext/Util/wixext/UtilTableDefinitions.cs index c5ecab87..57c18b6c 100644 --- a/src/ext/Util/wixext/UtilTableDefinitions.cs +++ b/src/ext/Util/wixext/UtilTableDefinitions.cs | |||
@@ -85,7 +85,7 @@ namespace WixToolset.Util | |||
85 | UtilSymbolDefinitions.FileSharePermissions, | 85 | UtilSymbolDefinitions.FileSharePermissions, |
86 | new[] | 86 | new[] |
87 | { | 87 | { |
88 | new ColumnDefinition("FileShare_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "FileShare", keyColumn: 1, description: "FileShare that these premissions are to be applied to.", modularizeType: ColumnModularizeType.Column), | 88 | new ColumnDefinition("FileShare_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "Wix4FileShare", keyColumn: 1, description: "FileShare that these premissions are to be applied to.", modularizeType: ColumnModularizeType.Column), |
89 | new ColumnDefinition("User_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "Wix4User", description: "User that these premissions are to apply to.", modularizeType: ColumnModularizeType.Column), | 89 | new ColumnDefinition("User_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "Wix4User", description: "User that these premissions are to apply to.", modularizeType: ColumnModularizeType.Column), |
90 | new ColumnDefinition("Permissions", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Unknown, description: "Permissions int, as in EXPLICIT_ACCESS.grfAccessPermissions in MSDN"), | 90 | new ColumnDefinition("Permissions", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Unknown, description: "Permissions int, as in EXPLICIT_ACCESS.grfAccessPermissions in MSDN"), |
91 | }, | 91 | }, |
diff --git a/src/internal/WixBuildTools.TestSupport/Builder.cs b/src/internal/WixBuildTools.TestSupport/Builder.cs index ef0de8c9..31df0084 100644 --- a/src/internal/WixBuildTools.TestSupport/Builder.cs +++ b/src/internal/WixBuildTools.TestSupport/Builder.cs | |||
@@ -66,5 +66,93 @@ namespace WixBuildTools.TestSupport | |||
66 | return Query.QueryDatabase(outputPath, tables); | 66 | return Query.QueryDatabase(outputPath, tables); |
67 | } | 67 | } |
68 | } | 68 | } |
69 | |||
70 | public void BuildAndDecompileAndBuild(Action<string[]> buildFunc, Action<string[]> decompileFunc, string decompilePath) | ||
71 | { | ||
72 | var sourceFiles = Directory.GetFiles(this.SourceFolder, "*.wxs"); | ||
73 | var wxlFiles = Directory.GetFiles(this.SourceFolder, "*.wxl"); | ||
74 | |||
75 | using (var fs = new DisposableFileSystem()) | ||
76 | { | ||
77 | var intermediateFolder = fs.GetFolder(); | ||
78 | var outputFolder = Path.Combine(intermediateFolder, "bin"); | ||
79 | var decompileExtractFolder = Path.Combine(intermediateFolder, "decompiled", "extract"); | ||
80 | var decompileIntermediateFolder = Path.Combine(intermediateFolder, "decompiled", "obj"); | ||
81 | var decompileBuildFolder = Path.Combine(intermediateFolder, "decompiled", "bin"); | ||
82 | var outputPath = Path.Combine(outputFolder, this.OutputFile); | ||
83 | var decompileBuildPath = Path.Combine(decompileBuildFolder, this.OutputFile); | ||
84 | |||
85 | // First build. | ||
86 | var firstBuildArgs = new List<string> | ||
87 | { | ||
88 | "build", | ||
89 | "-o", outputPath, | ||
90 | "-intermediateFolder", intermediateFolder, | ||
91 | }; | ||
92 | |||
93 | if (this.ExtensionType != null) | ||
94 | { | ||
95 | firstBuildArgs.Add("-ext"); | ||
96 | firstBuildArgs.Add(Path.GetFullPath(new Uri(this.ExtensionType.Assembly.CodeBase).LocalPath)); | ||
97 | } | ||
98 | |||
99 | firstBuildArgs.AddRange(sourceFiles); | ||
100 | |||
101 | foreach (var wxlFile in wxlFiles) | ||
102 | { | ||
103 | firstBuildArgs.Add("-loc"); | ||
104 | firstBuildArgs.Add(wxlFile); | ||
105 | } | ||
106 | |||
107 | foreach (var bindPath in this.BindPaths) | ||
108 | { | ||
109 | firstBuildArgs.Add("-bindpath"); | ||
110 | firstBuildArgs.Add(bindPath); | ||
111 | } | ||
112 | |||
113 | buildFunc(firstBuildArgs.ToArray()); | ||
114 | |||
115 | // Decompile built output. | ||
116 | var decompileArgs = new List<string> | ||
117 | { | ||
118 | "msi", "decompile", | ||
119 | outputPath, | ||
120 | "-intermediateFolder", decompileIntermediateFolder, | ||
121 | "-x", decompileExtractFolder, | ||
122 | "-o", decompilePath | ||
123 | }; | ||
124 | |||
125 | if (this.ExtensionType != null) | ||
126 | { | ||
127 | decompileArgs.Add("-ext"); | ||
128 | decompileArgs.Add(Path.GetFullPath(new Uri(this.ExtensionType.Assembly.CodeBase).LocalPath)); | ||
129 | } | ||
130 | |||
131 | decompileFunc(decompileArgs.ToArray()); | ||
132 | |||
133 | // Build decompiled output. | ||
134 | var secondBuildArgs = new List<string> | ||
135 | { | ||
136 | "build", | ||
137 | decompilePath, | ||
138 | "-o", decompileBuildPath, | ||
139 | "-intermediateFolder", decompileIntermediateFolder | ||
140 | }; | ||
141 | |||
142 | if (this.ExtensionType != null) | ||
143 | { | ||
144 | secondBuildArgs.Add("-ext"); | ||
145 | secondBuildArgs.Add(Path.GetFullPath(new Uri(this.ExtensionType.Assembly.CodeBase).LocalPath)); | ||
146 | } | ||
147 | |||
148 | secondBuildArgs.Add("-bindpath"); | ||
149 | secondBuildArgs.Add(outputFolder); | ||
150 | |||
151 | secondBuildArgs.Add("-bindpath"); | ||
152 | secondBuildArgs.Add(decompileExtractFolder); | ||
153 | |||
154 | buildFunc(secondBuildArgs.ToArray()); | ||
155 | } | ||
156 | } | ||
69 | } | 157 | } |
70 | } | 158 | } |
diff --git a/src/wix/WixToolset.Core.Burn/BurnExtensionFactory.cs b/src/wix/WixToolset.Core.Burn/BurnExtensionFactory.cs index eca94f77..6d2e97ba 100644 --- a/src/wix/WixToolset.Core.Burn/BurnExtensionFactory.cs +++ b/src/wix/WixToolset.Core.Burn/BurnExtensionFactory.cs | |||
@@ -22,7 +22,7 @@ namespace WixToolset.Core.Burn | |||
22 | { | 22 | { |
23 | extension = new BurnExtensionCommandLine(this.ServiceProvider); | 23 | extension = new BurnExtensionCommandLine(this.ServiceProvider); |
24 | } | 24 | } |
25 | if (extensionType == typeof(IBackendFactory)) | 25 | else if (extensionType == typeof(IBackendFactory)) |
26 | { | 26 | { |
27 | extension = new BurnBackendFactory(); | 27 | extension = new BurnBackendFactory(); |
28 | } | 28 | } |
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/CommandLine/DecompilerSubcommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/CommandLine/DecompilerSubcommand.cs index 19d1c738..0f806c95 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/CommandLine/DecompilerSubcommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/CommandLine/DecompilerSubcommand.cs | |||
@@ -66,11 +66,16 @@ namespace WixToolset.Core.WindowsInstaller.CommandLine | |||
66 | this.OutputPath = Path.ChangeExtension(this.InputPath, ".wxs"); | 66 | this.OutputPath = Path.ChangeExtension(this.InputPath, ".wxs"); |
67 | } | 67 | } |
68 | 68 | ||
69 | var extensionManager = this.ServiceProvider.GetService<IExtensionManager>(); | ||
70 | var creator = this.ServiceProvider.GetService<ISymbolDefinitionCreator>(); | ||
71 | |||
69 | var context = this.ServiceProvider.GetService<IWindowsInstallerDecompileContext>(); | 72 | var context = this.ServiceProvider.GetService<IWindowsInstallerDecompileContext>(); |
70 | context.Extensions = this.ServiceProvider.GetService<IExtensionManager>().GetServices<IWindowsInstallerDecompilerExtension>(); | 73 | context.Extensions = extensionManager.GetServices<IWindowsInstallerDecompilerExtension>(); |
74 | context.ExtensionData = extensionManager.GetServices<IExtensionData>(); | ||
71 | context.DecompilePath = this.InputPath; | 75 | context.DecompilePath = this.InputPath; |
72 | context.DecompileType = decompileType; | 76 | context.DecompileType = decompileType; |
73 | context.IntermediateFolder = this.IntermediateFolder; | 77 | context.IntermediateFolder = this.IntermediateFolder; |
78 | context.SymbolDefinitionCreator = creator; | ||
74 | context.OutputPath = this.OutputPath; | 79 | context.OutputPath = this.OutputPath; |
75 | 80 | ||
76 | context.ExtractFolder = this.ExportBasePath ?? this.IntermediateFolder; | 81 | context.ExtractFolder = this.ExportBasePath ?? this.IntermediateFolder; |
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Decompile/DecompileMsiOrMsmCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Decompile/DecompileMsiOrMsmCommand.cs deleted file mode 100644 index 5001828d..00000000 --- a/src/wix/WixToolset.Core.WindowsInstaller/Decompile/DecompileMsiOrMsmCommand.cs +++ /dev/null | |||
@@ -1,91 +0,0 @@ | |||
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 | |||
3 | namespace WixToolset.Core.WindowsInstaller.Decompile | ||
4 | { | ||
5 | using System; | ||
6 | using System.Collections.Generic; | ||
7 | using System.ComponentModel; | ||
8 | using System.IO; | ||
9 | using System.Linq; | ||
10 | using WixToolset.Core.Native.Msi; | ||
11 | using WixToolset.Core.WindowsInstaller.Unbind; | ||
12 | using WixToolset.Data; | ||
13 | using WixToolset.Data.WindowsInstaller; | ||
14 | using WixToolset.Extensibility.Data; | ||
15 | using WixToolset.Extensibility.Services; | ||
16 | |||
17 | internal class DecompileMsiOrMsmCommand | ||
18 | { | ||
19 | public DecompileMsiOrMsmCommand(IWindowsInstallerDecompileContext context) | ||
20 | { | ||
21 | this.Context = context; | ||
22 | this.Messaging = context.ServiceProvider.GetService<IMessaging>(); | ||
23 | } | ||
24 | |||
25 | private IWindowsInstallerDecompileContext Context { get; } | ||
26 | |||
27 | private IMessaging Messaging { get; } | ||
28 | |||
29 | public IWindowsInstallerDecompileResult Execute() | ||
30 | { | ||
31 | var result = this.Context.ServiceProvider.GetService<IWindowsInstallerDecompileResult>(); | ||
32 | |||
33 | try | ||
34 | { | ||
35 | using (var database = new Database(this.Context.DecompilePath, OpenDatabase.ReadOnly)) | ||
36 | { | ||
37 | // Delete the directory and its files to prevent cab extraction failure due to an existing file. | ||
38 | if (Directory.Exists(this.Context.ExtractFolder)) | ||
39 | { | ||
40 | Directory.Delete(this.Context.ExtractFolder, true); | ||
41 | } | ||
42 | |||
43 | var backendHelper = this.Context.ServiceProvider.GetService<IBackendHelper>(); | ||
44 | |||
45 | var unbindCommand = new UnbindDatabaseCommand(this.Messaging, backendHelper, database, this.Context.DecompilePath, this.Context.DecompileType, this.Context.ExtractFolder, this.Context.IntermediateFolder, this.Context.IsAdminImage, suppressDemodularization: false, skipSummaryInfo: false); | ||
46 | var output = unbindCommand.Execute(); | ||
47 | var extractedFilePaths = new List<string>(unbindCommand.ExportedFiles); | ||
48 | |||
49 | var decompiler = new Decompiler(this.Messaging, backendHelper, this.Context.Extensions, this.Context.BaseSourcePath, this.Context.SuppressCustomTables, this.Context.SuppressDroppingEmptyTables, this.Context.SuppressRelativeActionSequencing, this.Context.SuppressUI, this.Context.TreatProductAsModule); | ||
50 | result.Document = decompiler.Decompile(output); | ||
51 | |||
52 | result.Platform = GetPlatformFromOutput(output); | ||
53 | |||
54 | // extract the files from the cabinets | ||
55 | if (!String.IsNullOrEmpty(this.Context.ExtractFolder) && !this.Context.SuppressExtractCabinets) | ||
56 | { | ||
57 | var fileDirectory = String.IsNullOrEmpty(this.Context.CabinetExtractFolder) ? Path.Combine(this.Context.ExtractFolder, "File") : this.Context.CabinetExtractFolder; | ||
58 | |||
59 | var extractCommand = new ExtractCabinetsCommand(output, database, this.Context.DecompilePath, fileDirectory, this.Context.IntermediateFolder, this.Context.TreatProductAsModule); | ||
60 | extractCommand.Execute(); | ||
61 | |||
62 | extractedFilePaths.AddRange(extractCommand.ExtractedFiles); | ||
63 | result.ExtractedFilePaths = extractedFilePaths; | ||
64 | } | ||
65 | else | ||
66 | { | ||
67 | result.ExtractedFilePaths = new string[0]; | ||
68 | } | ||
69 | } | ||
70 | } | ||
71 | catch (Win32Exception e) | ||
72 | { | ||
73 | if (0x6E == e.NativeErrorCode) // ERROR_OPEN_FAILED | ||
74 | { | ||
75 | throw new WixException(ErrorMessages.OpenDatabaseFailed(this.Context.DecompilePath)); | ||
76 | } | ||
77 | |||
78 | throw; | ||
79 | } | ||
80 | |||
81 | return result; | ||
82 | } | ||
83 | |||
84 | private static Platform? GetPlatformFromOutput(WindowsInstallerData output) | ||
85 | { | ||
86 | var template = output.Tables["_SummaryInformation"]?.Rows.SingleOrDefault(row => row.FieldAsInteger(0) == 7)?.FieldAsString(1); | ||
87 | |||
88 | return Decompiler.GetPlatformFromTemplateSummaryInformation(template?.Split(';')); | ||
89 | } | ||
90 | } | ||
91 | } | ||
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Decompile/Decompiler.cs b/src/wix/WixToolset.Core.WindowsInstaller/Decompile/Decompiler.cs index 4ccfaaa5..0bd152f2 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Decompile/Decompiler.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Decompile/Decompiler.cs | |||
@@ -43,11 +43,14 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
43 | /// <summary> | 43 | /// <summary> |
44 | /// Creates a new decompiler object with a default set of table definitions. | 44 | /// Creates a new decompiler object with a default set of table definitions. |
45 | /// </summary> | 45 | /// </summary> |
46 | public Decompiler(IMessaging messaging, IBackendHelper backendHelper, IEnumerable<IWindowsInstallerDecompilerExtension> extensions, string baseSourcePath, bool suppressCustomTables, bool suppressDroppingEmptyTables, bool suppressRelativeActionSequencing, bool suppressUI, bool treatProductAsModule) | 46 | public Decompiler(IMessaging messaging, IBackendHelper backendHelper, IWindowsInstallerDecompilerHelper decompilerHelper, IEnumerable<IWindowsInstallerDecompilerExtension> extensions, IEnumerable<IExtensionData> extensionData, ISymbolDefinitionCreator creator, string baseSourcePath, bool suppressCustomTables, bool suppressDroppingEmptyTables, bool suppressRelativeActionSequencing, bool suppressUI, bool treatProductAsModule) |
47 | { | 47 | { |
48 | this.Messaging = messaging; | 48 | this.Messaging = messaging; |
49 | this.BackendHelper = backendHelper; | 49 | this.BackendHelper = backendHelper; |
50 | this.DecompilerHelper = decompilerHelper; | ||
50 | this.Extensions = extensions; | 51 | this.Extensions = extensions; |
52 | this.ExtensionData = extensionData; | ||
53 | this.SymbolDefinitionCreator = creator; | ||
51 | this.BaseSourcePath = baseSourcePath ?? "SourceDir"; | 54 | this.BaseSourcePath = baseSourcePath ?? "SourceDir"; |
52 | this.SuppressCustomTables = suppressCustomTables; | 55 | this.SuppressCustomTables = suppressCustomTables; |
53 | this.SuppressDroppingEmptyTables = suppressDroppingEmptyTables; | 56 | this.SuppressDroppingEmptyTables = suppressDroppingEmptyTables; |
@@ -65,8 +68,14 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
65 | 68 | ||
66 | private IBackendHelper BackendHelper { get; } | 69 | private IBackendHelper BackendHelper { get; } |
67 | 70 | ||
71 | private IWindowsInstallerDecompilerHelper DecompilerHelper { get; } | ||
72 | |||
68 | private IEnumerable<IWindowsInstallerDecompilerExtension> Extensions { get; } | 73 | private IEnumerable<IWindowsInstallerDecompilerExtension> Extensions { get; } |
69 | 74 | ||
75 | private IEnumerable<IExtensionData> ExtensionData { get; } | ||
76 | |||
77 | private ISymbolDefinitionCreator SymbolDefinitionCreator { get; } | ||
78 | |||
70 | private Dictionary<string, IWindowsInstallerDecompilerExtension> ExtensionsByTableName { get; } | 79 | private Dictionary<string, IWindowsInstallerDecompilerExtension> ExtensionsByTableName { get; } |
71 | 80 | ||
72 | private string BaseSourcePath { get; } | 81 | private string BaseSourcePath { get; } |
@@ -87,8 +96,6 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
87 | 96 | ||
88 | private bool Compressed { get; set; } | 97 | private bool Compressed { get; set; } |
89 | 98 | ||
90 | private XElement RootElement { get; set; } | ||
91 | |||
92 | private TableDefinitionCollection TableDefinitions { get; } | 99 | private TableDefinitionCollection TableDefinitions { get; } |
93 | 100 | ||
94 | private bool ShortNames { get; set; } | 101 | private bool ShortNames { get; set; } |
@@ -101,8 +108,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
101 | { | 108 | { |
102 | if (null == this.uiElement) | 109 | if (null == this.uiElement) |
103 | { | 110 | { |
104 | this.uiElement = new XElement(Names.UIElement); | 111 | this.uiElement = this.DecompilerHelper.AddElementToRoot(new XElement(Names.UIElement)); |
105 | this.RootElement.Add(this.uiElement); | ||
106 | } | 112 | } |
107 | 113 | ||
108 | return this.uiElement; | 114 | return this.uiElement; |
@@ -111,8 +117,6 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
111 | 117 | ||
112 | private Dictionary<string, XElement> Singletons { get; } = new Dictionary<string, XElement>(); | 118 | private Dictionary<string, XElement> Singletons { get; } = new Dictionary<string, XElement>(); |
113 | 119 | ||
114 | private Dictionary<string, XElement> IndexedElements { get; } = new Dictionary<string, XElement>(); | ||
115 | |||
116 | private Dictionary<string, XElement> PatchTargetFiles { get; } = new Dictionary<string, XElement>(); | 120 | private Dictionary<string, XElement> PatchTargetFiles { get; } = new Dictionary<string, XElement>(); |
117 | 121 | ||
118 | /// <summary> | 122 | /// <summary> |
@@ -122,13 +126,23 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
122 | /// <returns>The serialized WiX source code.</returns> | 126 | /// <returns>The serialized WiX source code.</returns> |
123 | public XDocument Decompile(WindowsInstallerData output) | 127 | public XDocument Decompile(WindowsInstallerData output) |
124 | { | 128 | { |
125 | if (null == output) | 129 | this.OutputType = output.Type; |
130 | |||
131 | switch (this.OutputType) | ||
126 | { | 132 | { |
127 | throw new ArgumentNullException(nameof(output)); | 133 | case OutputType.Module: |
134 | this.DecompilerHelper.RootElement = new XElement(Names.ModuleElement); | ||
135 | break; | ||
136 | case OutputType.PatchCreation: | ||
137 | this.DecompilerHelper.RootElement = new XElement(Names.PatchCreationElement); | ||
138 | break; | ||
139 | case OutputType.Product: | ||
140 | this.DecompilerHelper.RootElement = new XElement(Names.PackageElement); | ||
141 | break; | ||
142 | default: | ||
143 | throw new InvalidOperationException("Unknown output type."); | ||
128 | } | 144 | } |
129 | 145 | ||
130 | this.OutputType = output.Type; | ||
131 | |||
132 | // collect the table definitions from the output | 146 | // collect the table definitions from the output |
133 | this.TableDefinitions.Clear(); | 147 | this.TableDefinitions.Clear(); |
134 | foreach (var table in output.Tables) | 148 | foreach (var table in output.Tables) |
@@ -146,30 +160,11 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
146 | } | 160 | } |
147 | 161 | ||
148 | // add any missing extension table definitions | 162 | // add any missing extension table definitions |
149 | #if TODO_DECOMPILER_EXTENSIONS | ||
150 | foreach (var extension in this.Extensions) | 163 | foreach (var extension in this.Extensions) |
151 | { | 164 | { |
152 | this.AddExtension(extension); | 165 | this.AddExtensionTableDefinitions(extension); |
153 | } | ||
154 | #endif | ||
155 | |||
156 | switch (this.OutputType) | ||
157 | { | ||
158 | case OutputType.Module: | ||
159 | this.RootElement = new XElement(Names.ModuleElement); | ||
160 | break; | ||
161 | case OutputType.PatchCreation: | ||
162 | this.RootElement = new XElement(Names.PatchCreationElement); | ||
163 | break; | ||
164 | case OutputType.Product: | ||
165 | this.RootElement = new XElement(Names.PackageElement); | ||
166 | break; | ||
167 | default: | ||
168 | throw new InvalidOperationException("Unknown output type."); | ||
169 | } | 166 | } |
170 | 167 | ||
171 | var xWix = new XElement(Names.WixElement, this.RootElement); | ||
172 | |||
173 | // try to decompile the database file | 168 | // try to decompile the database file |
174 | // stop processing if an error previously occurred | 169 | // stop processing if an error previously occurred |
175 | if (this.Messaging.EncounteredError) | 170 | if (this.Messaging.EncounteredError) |
@@ -192,16 +187,14 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
192 | this.FinalizeDecompile(output.Tables); | 187 | this.FinalizeDecompile(output.Tables); |
193 | 188 | ||
194 | // return the XML document only if decompilation completed successfully | 189 | // return the XML document only if decompilation completed successfully |
195 | var document = new XDocument(xWix); | 190 | return this.Messaging.EncounteredError ? null : new XDocument(new XElement(Names.WixElement, this.DecompilerHelper.RootElement)); |
196 | return this.Messaging.EncounteredError ? null : document; | ||
197 | } | 191 | } |
198 | 192 | ||
199 | #if TODO_DECOMPILER_EXTENSIONS | 193 | private void AddExtensionTableDefinitions(IWindowsInstallerDecompilerExtension extension) |
200 | private void AddExtension(IWindowsInstallerBackendDecompilerExtension extension) | ||
201 | { | 194 | { |
202 | if (null != extension.TableDefinitions) | 195 | if (null != extension.TableDefinitions) |
203 | { | 196 | { |
204 | foreach (TableDefinition tableDefinition in extension.TableDefinitions) | 197 | foreach (var tableDefinition in extension.TableDefinitions) |
205 | { | 198 | { |
206 | if (!this.ExtensionsByTableName.ContainsKey(tableDefinition.Name)) | 199 | if (!this.ExtensionsByTableName.ContainsKey(tableDefinition.Name)) |
207 | { | 200 | { |
@@ -214,7 +207,6 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
214 | } | 207 | } |
215 | } | 208 | } |
216 | } | 209 | } |
217 | #endif | ||
218 | 210 | ||
219 | internal static Platform? GetPlatformFromTemplateSummaryInformation(string[] template) | 211 | internal static Platform? GetPlatformFromTemplateSummaryInformation(string[] template) |
220 | { | 212 | { |
@@ -234,75 +226,10 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
234 | return null; | 226 | return null; |
235 | } | 227 | } |
236 | 228 | ||
237 | /// <summary> | ||
238 | /// Gets the element corresponding to the row it came from. | ||
239 | /// </summary> | ||
240 | /// <param name="row">The row corresponding to the element.</param> | ||
241 | /// <returns>The indexed element.</returns> | ||
242 | private XElement GetIndexedElement(Row row) | ||
243 | { | ||
244 | return this.GetIndexedElement(row.TableDefinition.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter)); | ||
245 | } | ||
246 | |||
247 | /// <summary> | ||
248 | /// Gets the element corresponding to the primary key of the given table. | ||
249 | /// </summary> | ||
250 | /// <param name="table">The table corresponding to the element.</param> | ||
251 | /// <param name="primaryKey">The primary key corresponding to the element.</param> | ||
252 | /// <returns>The indexed element.</returns> | ||
253 | private XElement GetIndexedElement(string table, params string[] primaryKey) | ||
254 | { | ||
255 | return this.TryGetIndexedElement(table, out var element, primaryKey) ? element : null; | ||
256 | } | ||
257 | |||
258 | /// <summary> | ||
259 | /// Tries to get the element corresponding to the primary key of the given table. | ||
260 | /// </summary> | ||
261 | /// <param name="row">The table corresponding to the element.</param> | ||
262 | /// <param name="xElement">The indexed element.</param> | ||
263 | /// <returns>Whether the element was found.</returns> | ||
264 | private bool TryGetIndexedElement(Row row, out XElement xElement) | ||
265 | { | ||
266 | return this.TryGetIndexedElement(row.TableDefinition.Name, out xElement, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter)); | ||
267 | } | ||
268 | |||
269 | /// <summary> | ||
270 | /// Tries to get the element corresponding to the primary key of the given table. | ||
271 | /// </summary> | ||
272 | /// <param name="table">The table corresponding to the element.</param> | ||
273 | /// <param name="xElement">The indexed element.</param> | ||
274 | /// <param name="primaryKey">The primary key corresponding to the element.</param> | ||
275 | /// <returns>Whether the element was found.</returns> | ||
276 | private bool TryGetIndexedElement(string table, out XElement xElement, params string[] primaryKey) | ||
277 | { | ||
278 | return this.IndexedElements.TryGetValue(String.Concat(table, ':', String.Join(DecompilerConstants.PrimaryKeyDelimiterString, primaryKey)), out xElement); | ||
279 | } | ||
280 | |||
281 | /// <summary> | ||
282 | /// Index an element by its corresponding row. | ||
283 | /// </summary> | ||
284 | /// <param name="row">The row corresponding to the element.</param> | ||
285 | /// <param name="element">The element to index.</param> | ||
286 | private void IndexElement(Row row, XElement element) | ||
287 | { | ||
288 | this.IndexedElements.Add(String.Concat(row.TableDefinition.Name, ':', row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter)), element); | ||
289 | } | ||
290 | |||
291 | /// <summary> | ||
292 | /// Index an element by its corresponding row. | ||
293 | /// </summary> | ||
294 | /// <param name="element">The element to index.</param> | ||
295 | /// <param name="table"></param> | ||
296 | /// <param name="primaryKey"></param> | ||
297 | private void IndexElement(XElement element, string table, params string[] primaryKey) | ||
298 | { | ||
299 | this.IndexedElements.Add(String.Concat(table, ':', String.Join(DecompilerConstants.PrimaryKeyDelimiterString, primaryKey)), element); | ||
300 | } | ||
301 | |||
302 | private Dictionary<string, List<XElement>> IndexTableOneToMany(IEnumerable<Row> rows, int column = 0) | 229 | private Dictionary<string, List<XElement>> IndexTableOneToMany(IEnumerable<Row> rows, int column = 0) |
303 | { | 230 | { |
304 | return rows | 231 | return rows |
305 | .ToLookup(row => row.FieldAsString(column), row => this.GetIndexedElement(row)) | 232 | .ToLookup(row => row.FieldAsString(column), row => this.DecompilerHelper.GetIndexedElement(row)) |
306 | .ToDictionary(lookup => lookup.Key, lookup => lookup.ToList()); | 233 | .ToDictionary(lookup => lookup.Key, lookup => lookup.ToList()); |
307 | } | 234 | } |
308 | 235 | ||
@@ -319,7 +246,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
319 | private void AddChildToParent(string parentName, XElement xChild, Row row, int column) | 246 | private void AddChildToParent(string parentName, XElement xChild, Row row, int column) |
320 | { | 247 | { |
321 | var key = row.FieldAsString(column); | 248 | var key = row.FieldAsString(column); |
322 | if (this.TryGetIndexedElement(parentName, out var xParent, key)) | 249 | if (this.DecompilerHelper.TryGetIndexedElement(parentName, key, out var xParent)) |
323 | { | 250 | { |
324 | xParent.Add(xChild); | 251 | xParent.Add(xChild); |
325 | } | 252 | } |
@@ -419,7 +346,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
419 | { | 346 | { |
420 | XElement xAction; | 347 | XElement xAction; |
421 | 348 | ||
422 | if (this.TryGetIndexedElement("CustomAction", out var _, actionSymbol.Action)) // custom action | 349 | if (this.DecompilerHelper.TryGetIndexedElement("CustomAction", actionSymbol.Action, out var _)) // custom action |
423 | { | 350 | { |
424 | xAction = new XElement(Names.CustomElement, | 351 | xAction = new XElement(Names.CustomElement, |
425 | new XAttribute("Action", actionSymbol.Action), | 352 | new XAttribute("Action", actionSymbol.Action), |
@@ -455,7 +382,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
455 | break; | 382 | break; |
456 | } | 383 | } |
457 | } | 384 | } |
458 | else if (this.TryGetIndexedElement("Dialog", out var _, actionSymbol.Action)) // dialog | 385 | else if (this.DecompilerHelper.TryGetIndexedElement("Dialog", actionSymbol.Action, out var _)) // dialog |
459 | { | 386 | { |
460 | xAction = new XElement(Names.CustomElement, | 387 | xAction = new XElement(Names.CustomElement, |
461 | new XAttribute("Dialog", actionSymbol.Action), | 388 | new XAttribute("Dialog", actionSymbol.Action), |
@@ -495,7 +422,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
495 | { | 422 | { |
496 | xSequence = new XElement(Names.WxsNamespace + sequenceTable); | 423 | xSequence = new XElement(Names.WxsNamespace + sequenceTable); |
497 | 424 | ||
498 | this.RootElement.Add(xSequence); | 425 | this.DecompilerHelper.AddElementToRoot(xSequence); |
499 | this.Singletons.Add(sequenceTable, xSequence); | 426 | this.Singletons.Add(sequenceTable, xSequence); |
500 | } | 427 | } |
501 | 428 | ||
@@ -669,14 +596,12 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
669 | /// <returns>The property element.</returns> | 596 | /// <returns>The property element.</returns> |
670 | private XElement EnsureProperty(string id) | 597 | private XElement EnsureProperty(string id) |
671 | { | 598 | { |
672 | XElement xProperty; | 599 | if (!this.DecompilerHelper.TryGetIndexedElement("Property", id, out var xProperty)) |
673 | |||
674 | if (!this.TryGetIndexedElement("Property", out xProperty, id)) | ||
675 | { | 600 | { |
676 | xProperty = new XElement(Names.PropertyElement, new XAttribute("Id", id)); | 601 | xProperty = new XElement(Names.PropertyElement, new XAttribute("Id", id)); |
677 | 602 | ||
678 | this.RootElement.Add(xProperty); | 603 | this.DecompilerHelper.AddElementToRoot(xProperty); |
679 | this.IndexElement(xProperty, "Property", id); | 604 | this.DecompilerHelper.IndexElement("Property", id, xProperty); |
680 | } | 605 | } |
681 | 606 | ||
682 | return xProperty; | 607 | return xProperty; |
@@ -713,6 +638,11 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
713 | this.FinalizeSequenceTables(tables); | 638 | this.FinalizeSequenceTables(tables); |
714 | this.FinalizeVerbTable(tables); | 639 | this.FinalizeVerbTable(tables); |
715 | } | 640 | } |
641 | |||
642 | foreach (var extension in this.Extensions) | ||
643 | { | ||
644 | extension.PostDecompileTables(tables); | ||
645 | } | ||
716 | } | 646 | } |
717 | 647 | ||
718 | /// <summary> | 648 | /// <summary> |
@@ -743,7 +673,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
743 | { | 673 | { |
744 | foreach (var row in controlTable.Rows) | 674 | foreach (var row in controlTable.Rows) |
745 | { | 675 | { |
746 | var xControl = this.GetIndexedElement(row); | 676 | var xControl = this.DecompilerHelper.GetIndexedElement(row); |
747 | 677 | ||
748 | if ("CheckBox" == row.FieldAsString(2)) | 678 | if ("CheckBox" == row.FieldAsString(2)) |
749 | { | 679 | { |
@@ -791,9 +721,9 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
791 | { | 721 | { |
792 | // Add the TARGETDIR StandardDirectory if a component is directly parented there. | 722 | // Add the TARGETDIR StandardDirectory if a component is directly parented there. |
793 | if (componentTable.Rows.Any(row => row.FieldAsString(2) == "TARGETDIR") | 723 | if (componentTable.Rows.Any(row => row.FieldAsString(2) == "TARGETDIR") |
794 | && this.TryGetIndexedElement("Directory", out var xDirectory, "TARGETDIR")) | 724 | && this.DecompilerHelper.TryGetIndexedElement("Directory", "TARGETDIR", out var xDirectory)) |
795 | { | 725 | { |
796 | this.RootElement.Add(xDirectory); | 726 | this.DecompilerHelper.AddElementToRoot(xDirectory); |
797 | } | 727 | } |
798 | 728 | ||
799 | foreach (var row in componentTable.Rows) | 729 | foreach (var row in componentTable.Rows) |
@@ -803,12 +733,12 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
803 | 733 | ||
804 | if (String.IsNullOrEmpty(keyPath)) | 734 | if (String.IsNullOrEmpty(keyPath)) |
805 | { | 735 | { |
806 | var xComponent = this.GetIndexedElement("Component", row.FieldAsString(0)); | 736 | var xComponent = this.DecompilerHelper.GetIndexedElement("Component", row.FieldAsString(0)); |
807 | xComponent.SetAttributeValue("KeyPath", "yes"); | 737 | xComponent.SetAttributeValue("KeyPath", "yes"); |
808 | } | 738 | } |
809 | else if (WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath == (attributes & WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath)) | 739 | else if (WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath == (attributes & WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath)) |
810 | { | 740 | { |
811 | if (this.TryGetIndexedElement("Registry", out var xRegistry, keyPath)) | 741 | if (this.DecompilerHelper.TryGetIndexedElement("Registry", keyPath, out var xRegistry)) |
812 | { | 742 | { |
813 | if (xRegistry.Name.LocalName == "RegistryValue") | 743 | if (xRegistry.Name.LocalName == "RegistryValue") |
814 | { | 744 | { |
@@ -826,7 +756,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
826 | } | 756 | } |
827 | else if (WindowsInstallerConstants.MsidbComponentAttributesODBCDataSource == (attributes & WindowsInstallerConstants.MsidbComponentAttributesODBCDataSource)) | 757 | else if (WindowsInstallerConstants.MsidbComponentAttributesODBCDataSource == (attributes & WindowsInstallerConstants.MsidbComponentAttributesODBCDataSource)) |
828 | { | 758 | { |
829 | if (this.TryGetIndexedElement("ODBCDataSource", out var xOdbcDataSource, keyPath)) | 759 | if (this.DecompilerHelper.TryGetIndexedElement("ODBCDataSource", keyPath, out var xOdbcDataSource)) |
830 | { | 760 | { |
831 | xOdbcDataSource.SetAttributeValue("KeyPath", "yes"); | 761 | xOdbcDataSource.SetAttributeValue("KeyPath", "yes"); |
832 | } | 762 | } |
@@ -837,7 +767,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
837 | } | 767 | } |
838 | else | 768 | else |
839 | { | 769 | { |
840 | if (this.TryGetIndexedElement("File", out var xFile, keyPath)) | 770 | if (this.DecompilerHelper.TryGetIndexedElement("File", keyPath, out var xFile)) |
841 | { | 771 | { |
842 | xFile.SetAttributeValue("KeyPath", "yes"); | 772 | xFile.SetAttributeValue("KeyPath", "yes"); |
843 | } | 773 | } |
@@ -854,8 +784,8 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
854 | { | 784 | { |
855 | foreach (FileRow fileRow in fileTable.Rows) | 785 | foreach (FileRow fileRow in fileTable.Rows) |
856 | { | 786 | { |
857 | if (this.TryGetIndexedElement("Component", out var xComponent, fileRow.Component) | 787 | if (this.DecompilerHelper.TryGetIndexedElement("Component", fileRow.Component, out var xComponent) |
858 | && this.TryGetIndexedElement(fileRow, out var xFile)) | 788 | && this.DecompilerHelper.TryGetIndexedElement(fileRow, out var xFile)) |
859 | { | 789 | { |
860 | xComponent.Add(xFile); | 790 | xComponent.Add(xFile); |
861 | } | 791 | } |
@@ -871,8 +801,8 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
871 | { | 801 | { |
872 | foreach (var row in odbcDataSourceTable.Rows) | 802 | foreach (var row in odbcDataSourceTable.Rows) |
873 | { | 803 | { |
874 | if (this.TryGetIndexedElement("Component", out var xComponent, row.FieldAsString(1)) | 804 | if (this.DecompilerHelper.TryGetIndexedElement("Component", row.FieldAsString(1), out var xComponent) |
875 | && this.TryGetIndexedElement(row, out var xOdbcDataSource)) | 805 | && this.DecompilerHelper.TryGetIndexedElement(row, out var xOdbcDataSource)) |
876 | { | 806 | { |
877 | xComponent.Add(xOdbcDataSource); | 807 | xComponent.Add(xOdbcDataSource); |
878 | } | 808 | } |
@@ -888,8 +818,8 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
888 | { | 818 | { |
889 | foreach (var row in registryTable.Rows) | 819 | foreach (var row in registryTable.Rows) |
890 | { | 820 | { |
891 | if (this.TryGetIndexedElement("Component", out var xComponent, row.FieldAsString(5)) | 821 | if (this.DecompilerHelper.TryGetIndexedElement("Component", row.FieldAsString(5), out var xComponent) |
892 | && this.TryGetIndexedElement(row, out var xRegistry)) | 822 | && this.DecompilerHelper.TryGetIndexedElement(row, out var xRegistry)) |
893 | { | 823 | { |
894 | xComponent.Add(xRegistry); | 824 | xComponent.Add(xRegistry); |
895 | } | 825 | } |
@@ -927,10 +857,10 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
927 | { | 857 | { |
928 | foreach (var dialogRow in dialogTable.Rows) | 858 | foreach (var dialogRow in dialogTable.Rows) |
929 | { | 859 | { |
930 | var xDialog = this.GetIndexedElement(dialogRow); | 860 | var xDialog = this.DecompilerHelper.GetIndexedElement(dialogRow); |
931 | var dialogId = dialogRow.FieldAsString(0); | 861 | var dialogId = dialogRow.FieldAsString(0); |
932 | 862 | ||
933 | if (!this.TryGetIndexedElement("Control", out var xControl, dialogId, dialogRow.FieldAsString(7))) | 863 | if (!this.DecompilerHelper.TryGetIndexedElement("Control", dialogId, dialogRow.FieldAsString(7), out var xControl)) |
934 | { | 864 | { |
935 | this.Messaging.Write(WarningMessages.ExpectedForeignRow(dialogRow.SourceLineNumbers, "Dialog", dialogRow.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Dialog", dialogId, "Control_First", dialogRow.FieldAsString(7), "Control")); | 865 | this.Messaging.Write(WarningMessages.ExpectedForeignRow(dialogRow.SourceLineNumbers, "Dialog", dialogRow.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Dialog", dialogId, "Control_First", dialogRow.FieldAsString(7), "Control")); |
936 | } | 866 | } |
@@ -949,7 +879,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
949 | var controlNext = controlRow.FieldAsString(10); | 879 | var controlNext = controlRow.FieldAsString(10); |
950 | if (!String.IsNullOrEmpty(controlNext)) | 880 | if (!String.IsNullOrEmpty(controlNext)) |
951 | { | 881 | { |
952 | if (this.TryGetIndexedElement("Control", out xControl, dialogId, controlNext)) | 882 | if (this.DecompilerHelper.TryGetIndexedElement("Control", dialogId, controlNext, out xControl)) |
953 | { | 883 | { |
954 | // looped back to the first control in the dialog | 884 | // looped back to the first control in the dialog |
955 | if (addedControls.Contains(xControl)) | 885 | if (addedControls.Contains(xControl)) |
@@ -972,7 +902,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
972 | var controlDefault = dialogRow.FieldAsString(8); | 902 | var controlDefault = dialogRow.FieldAsString(8); |
973 | if (!String.IsNullOrEmpty(controlDefault)) | 903 | if (!String.IsNullOrEmpty(controlDefault)) |
974 | { | 904 | { |
975 | if (this.TryGetIndexedElement("Control", out var xDefaultControl, dialogId, controlDefault)) | 905 | if (this.DecompilerHelper.TryGetIndexedElement("Control", dialogId, controlDefault, out var xDefaultControl)) |
976 | { | 906 | { |
977 | xDefaultControl.SetAttributeValue("Default", "yes"); | 907 | xDefaultControl.SetAttributeValue("Default", "yes"); |
978 | } | 908 | } |
@@ -986,7 +916,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
986 | var controlCancel = dialogRow.FieldAsString(8); | 916 | var controlCancel = dialogRow.FieldAsString(8); |
987 | if (!String.IsNullOrEmpty(controlCancel)) | 917 | if (!String.IsNullOrEmpty(controlCancel)) |
988 | { | 918 | { |
989 | if (this.TryGetIndexedElement("Control", out var xCancelControl, dialogId, controlCancel)) | 919 | if (this.DecompilerHelper.TryGetIndexedElement("Control", dialogId, controlCancel, out var xCancelControl)) |
990 | { | 920 | { |
991 | xCancelControl.SetAttributeValue("Cancel", "yes"); | 921 | xCancelControl.SetAttributeValue("Cancel", "yes"); |
992 | } | 922 | } |
@@ -1004,13 +934,13 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1004 | foreach (var controlRow in controlTable.Rows) | 934 | foreach (var controlRow in controlTable.Rows) |
1005 | { | 935 | { |
1006 | var dialogId = controlRow.FieldAsString(0); | 936 | var dialogId = controlRow.FieldAsString(0); |
1007 | if (!this.TryGetIndexedElement("Dialog", out var xDialog, dialogId)) | 937 | if (!this.DecompilerHelper.TryGetIndexedElement("Dialog", dialogId, out var xDialog)) |
1008 | { | 938 | { |
1009 | this.Messaging.Write(WarningMessages.ExpectedForeignRow(controlRow.SourceLineNumbers, "Control", controlRow.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Dialog_", dialogId, "Dialog")); | 939 | this.Messaging.Write(WarningMessages.ExpectedForeignRow(controlRow.SourceLineNumbers, "Control", controlRow.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Dialog_", dialogId, "Dialog")); |
1010 | continue; | 940 | continue; |
1011 | } | 941 | } |
1012 | 942 | ||
1013 | var xControl = this.GetIndexedElement(controlRow); | 943 | var xControl = this.DecompilerHelper.GetIndexedElement(controlRow); |
1014 | if (!addedControls.Contains(xControl)) | 944 | if (!addedControls.Contains(xControl)) |
1015 | { | 945 | { |
1016 | xControl.SetAttributeValue("TabSkip", "yes"); | 946 | xControl.SetAttributeValue("TabSkip", "yes"); |
@@ -1035,11 +965,11 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1035 | { | 965 | { |
1036 | foreach (var row in duplicateFileTable.Rows) | 966 | foreach (var row in duplicateFileTable.Rows) |
1037 | { | 967 | { |
1038 | var xCopyFile = this.GetIndexedElement(row); | 968 | var xCopyFile = this.DecompilerHelper.GetIndexedElement(row); |
1039 | var destination = row.FieldAsString(4); | 969 | var destination = row.FieldAsString(4); |
1040 | if (!String.IsNullOrEmpty(destination)) | 970 | if (!String.IsNullOrEmpty(destination)) |
1041 | { | 971 | { |
1042 | if (this.TryGetIndexedElement("Directory", out var _, destination)) | 972 | if (this.DecompilerHelper.TryGetIndexedElement("Directory", destination, out var _)) |
1043 | { | 973 | { |
1044 | xCopyFile.SetAttributeValue("DestinationDirectory", destination); | 974 | xCopyFile.SetAttributeValue("DestinationDirectory", destination); |
1045 | } | 975 | } |
@@ -1056,11 +986,11 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1056 | { | 986 | { |
1057 | foreach (var row in moveFileTable.Rows) | 987 | foreach (var row in moveFileTable.Rows) |
1058 | { | 988 | { |
1059 | var xCopyFile = this.GetIndexedElement(row); | 989 | var xCopyFile = this.DecompilerHelper.GetIndexedElement(row); |
1060 | var source = row.FieldAsString(4); | 990 | var source = row.FieldAsString(4); |
1061 | if (!String.IsNullOrEmpty(source)) | 991 | if (!String.IsNullOrEmpty(source)) |
1062 | { | 992 | { |
1063 | if (this.TryGetIndexedElement("Directory", out var _, source)) | 993 | if (this.DecompilerHelper.TryGetIndexedElement("Directory", source, out var _)) |
1064 | { | 994 | { |
1065 | xCopyFile.SetAttributeValue("SourceDirectory", source); | 995 | xCopyFile.SetAttributeValue("SourceDirectory", source); |
1066 | } | 996 | } |
@@ -1071,7 +1001,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1071 | } | 1001 | } |
1072 | 1002 | ||
1073 | var destination = row.FieldAsString(5); | 1003 | var destination = row.FieldAsString(5); |
1074 | if (this.TryGetIndexedElement("Directory", out var _, destination)) | 1004 | if (this.DecompilerHelper.TryGetIndexedElement("Directory", destination, out var _)) |
1075 | { | 1005 | { |
1076 | xCopyFile.SetAttributeValue("DestinationDirectory", destination); | 1006 | xCopyFile.SetAttributeValue("DestinationDirectory", destination); |
1077 | } | 1007 | } |
@@ -1134,7 +1064,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1134 | // TODO: warn about mismatch between columns | 1064 | // TODO: warn about mismatch between columns |
1135 | } | 1065 | } |
1136 | 1066 | ||
1137 | this.IndexElement(row, xProtectRange); | 1067 | this.DecompilerHelper.IndexElement(row, xProtectRange); |
1138 | } | 1068 | } |
1139 | } | 1069 | } |
1140 | 1070 | ||
@@ -1144,8 +1074,8 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1144 | { | 1074 | { |
1145 | foreach (var row in externalFilesTable.Rows) | 1075 | foreach (var row in externalFilesTable.Rows) |
1146 | { | 1076 | { |
1147 | if (this.TryGetIndexedElement(row, out var xExternalFile) | 1077 | if (this.DecompilerHelper.TryGetIndexedElement(row, out var xExternalFile) |
1148 | && this.TryGetIndexedElement("FamilyFileRanges", out var xProtectRange, row.FieldAsString(0), row.FieldAsString(0))) | 1078 | && this.DecompilerHelper.TryGetIndexedElement("FamilyFileRanges", row.FieldAsString(0), row.FieldAsString(0), out var xProtectRange)) |
1149 | { | 1079 | { |
1150 | xExternalFile.Add(xProtectRange); | 1080 | xExternalFile.Add(xProtectRange); |
1151 | usedProtectRanges.Add(xProtectRange); | 1081 | usedProtectRanges.Add(xProtectRange); |
@@ -1178,7 +1108,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1178 | continue; | 1108 | continue; |
1179 | } | 1109 | } |
1180 | 1110 | ||
1181 | if (this.TryGetIndexedElement("FamilyFileRanges", out var xProtectRange, upgradedImagesRow.FieldAsString(4), row.FieldAsString(1))) | 1111 | if (this.DecompilerHelper.TryGetIndexedElement("FamilyFileRanges", upgradedImagesRow.FieldAsString(4), row.FieldAsString(1), out var xProtectRange)) |
1182 | { | 1112 | { |
1183 | xTargetFile.Add(xProtectRange); | 1113 | xTargetFile.Add(xProtectRange); |
1184 | usedProtectRanges.Add(xProtectRange); | 1114 | usedProtectRanges.Add(xProtectRange); |
@@ -1190,7 +1120,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1190 | { | 1120 | { |
1191 | foreach (var row in familyFileRangesTable.Rows) | 1121 | foreach (var row in familyFileRangesTable.Rows) |
1192 | { | 1122 | { |
1193 | var xProtectRange = this.GetIndexedElement(row); | 1123 | var xProtectRange = this.DecompilerHelper.GetIndexedElement(row); |
1194 | 1124 | ||
1195 | if (!usedProtectRanges.Contains(xProtectRange)) | 1125 | if (!usedProtectRanges.Contains(xProtectRange)) |
1196 | { | 1126 | { |
@@ -1276,7 +1206,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1276 | // set the disk identifiers and sources for files | 1206 | // set the disk identifiers and sources for files |
1277 | foreach (var fileRow in tables["File"]?.Rows.Cast<FileRow>() ?? Enumerable.Empty<FileRow>()) | 1207 | foreach (var fileRow in tables["File"]?.Rows.Cast<FileRow>() ?? Enumerable.Empty<FileRow>()) |
1278 | { | 1208 | { |
1279 | var xFile = this.GetIndexedElement("File", fileRow.File); | 1209 | var xFile = this.DecompilerHelper.GetIndexedElement("File", fileRow.File); |
1280 | 1210 | ||
1281 | // Don't bother processing files that are orphaned (and won't show up in the output anyway) | 1211 | // Don't bother processing files that are orphaned (and won't show up in the output anyway) |
1282 | if (null != xFile.Parent) | 1212 | if (null != xFile.Parent) |
@@ -1328,7 +1258,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1328 | // set the file assemblies and manifests | 1258 | // set the file assemblies and manifests |
1329 | foreach (var row in tables["MsiAssembly"]?.Rows ?? Enumerable.Empty<Row>()) | 1259 | foreach (var row in tables["MsiAssembly"]?.Rows ?? Enumerable.Empty<Row>()) |
1330 | { | 1260 | { |
1331 | if (this.TryGetIndexedElement("Component", out var xComponent, row.FieldAsString(0))) | 1261 | if (this.DecompilerHelper.TryGetIndexedElement("Component", row.FieldAsString(0), out var xComponent)) |
1332 | { | 1262 | { |
1333 | foreach (var xFile in xComponent.Elements(Names.FileElement).Where(x => x.Attribute("KeyPath")?.Value == "yes")) | 1263 | foreach (var xFile in xComponent.Elements(Names.FileElement).Where(x => x.Attribute("KeyPath")?.Value == "yes")) |
1334 | { | 1264 | { |
@@ -1346,8 +1276,8 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1346 | // nest the TypeLib elements | 1276 | // nest the TypeLib elements |
1347 | foreach (var row in tables["TypeLib"]?.Rows ?? Enumerable.Empty<Row>()) | 1277 | foreach (var row in tables["TypeLib"]?.Rows ?? Enumerable.Empty<Row>()) |
1348 | { | 1278 | { |
1349 | var xComponent = this.GetIndexedElement("Component", row.FieldAsString(2)); | 1279 | var xComponent = this.DecompilerHelper.GetIndexedElement("Component", row.FieldAsString(2)); |
1350 | var xTypeLib = this.GetIndexedElement(row); | 1280 | var xTypeLib = this.DecompilerHelper.GetIndexedElement(row); |
1351 | 1281 | ||
1352 | foreach (var xFile in xComponent.Elements(Names.FileElement).Where(x => x.Attribute("KeyPath")?.Value == "yes")) | 1282 | foreach (var xFile in xComponent.Elements(Names.FileElement).Where(x => x.Attribute("KeyPath")?.Value == "yes")) |
1353 | { | 1283 | { |
@@ -1374,7 +1304,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1374 | var mimeRef = row.FieldAsString(3); | 1304 | var mimeRef = row.FieldAsString(3); |
1375 | if (null != mimeRef) | 1305 | if (null != mimeRef) |
1376 | { | 1306 | { |
1377 | if (this.TryGetIndexedElement("MIME", out var xMime, mimeRef)) | 1307 | if (this.DecompilerHelper.TryGetIndexedElement("MIME", mimeRef, out var xMime)) |
1378 | { | 1308 | { |
1379 | xMime.SetAttributeValue("Default", "yes"); | 1309 | xMime.SetAttributeValue("Default", "yes"); |
1380 | } | 1310 | } |
@@ -1389,7 +1319,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1389 | 1319 | ||
1390 | foreach (var row in tables["MIME"]?.Rows ?? Enumerable.Empty<Row>()) | 1320 | foreach (var row in tables["MIME"]?.Rows ?? Enumerable.Empty<Row>()) |
1391 | { | 1321 | { |
1392 | var xMime = this.GetIndexedElement(row); | 1322 | var xMime = this.DecompilerHelper.GetIndexedElement(row); |
1393 | 1323 | ||
1394 | if (extensionsByExtensionId.TryGetValue(row.FieldAsString(1), out var xExtensions)) | 1324 | if (extensionsByExtensionId.TryGetValue(row.FieldAsString(1), out var xExtensions)) |
1395 | { | 1325 | { |
@@ -1427,9 +1357,9 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1427 | foreach (var row in classRows) | 1357 | foreach (var row in classRows) |
1428 | { | 1358 | { |
1429 | var clsid = row.FieldAsString(0); | 1359 | var clsid = row.FieldAsString(0); |
1430 | var xClass = this.GetIndexedElement(row); | 1360 | var xClass = this.DecompilerHelper.GetIndexedElement(row); |
1431 | 1361 | ||
1432 | if (this.TryGetIndexedElement("ProgId", out var xProgId, row.FieldAsString(3))) | 1362 | if (this.DecompilerHelper.TryGetIndexedElement("ProgId", row.FieldAsString(3), out var xProgId)) |
1433 | { | 1363 | { |
1434 | if (addedProgIds.TryGetValue(xProgId, out var progid)) | 1364 | if (addedProgIds.TryGetValue(xProgId, out var progid)) |
1435 | { | 1365 | { |
@@ -1451,7 +1381,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1451 | foreach (var row in tables["ProgId"]?.Rows ?? Enumerable.Empty<Row>()) | 1381 | foreach (var row in tables["ProgId"]?.Rows ?? Enumerable.Empty<Row>()) |
1452 | { | 1382 | { |
1453 | var clsid = row.FieldAsString(2); | 1383 | var clsid = row.FieldAsString(2); |
1454 | var xProgId = this.GetIndexedElement(row); | 1384 | var xProgId = this.DecompilerHelper.GetIndexedElement(row); |
1455 | 1385 | ||
1456 | if (!addedProgIds.ContainsKey(xProgId) && null != clsid && null == xProgId.Parent) | 1386 | if (!addedProgIds.ContainsKey(xProgId) && null != clsid && null == xProgId.Parent) |
1457 | { | 1387 | { |
@@ -1475,7 +1405,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1475 | 1405 | ||
1476 | foreach (var row in tables["Extension"]?.Rows?.Where(row => row.FieldAsString(2) != null) ?? Enumerable.Empty<Row>()) | 1406 | foreach (var row in tables["Extension"]?.Rows?.Where(row => row.FieldAsString(2) != null) ?? Enumerable.Empty<Row>()) |
1477 | { | 1407 | { |
1478 | var xProgId = this.GetIndexedElement("ProgId", row.FieldAsString(2)); | 1408 | var xProgId = this.DecompilerHelper.GetIndexedElement("ProgId", row.FieldAsString(2)); |
1479 | 1409 | ||
1480 | // Haven't added the progId yet and it doesn't have a parent progId | 1410 | // Haven't added the progId yet and it doesn't have a parent progId |
1481 | if (!addedProgIds.ContainsKey(xProgId) && null == xProgId.Parent) | 1411 | if (!addedProgIds.ContainsKey(xProgId) && null == xProgId.Parent) |
@@ -1510,7 +1440,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1510 | var bits = row.FieldAsInteger(1); | 1440 | var bits = row.FieldAsInteger(1); |
1511 | if (WindowsInstallerConstants.MsidbCustomActionTypeHideTarget == (bits & WindowsInstallerConstants.MsidbCustomActionTypeHideTarget) | 1441 | if (WindowsInstallerConstants.MsidbCustomActionTypeHideTarget == (bits & WindowsInstallerConstants.MsidbCustomActionTypeHideTarget) |
1512 | && WindowsInstallerConstants.MsidbCustomActionTypeInScript == (bits & WindowsInstallerConstants.MsidbCustomActionTypeInScript) | 1442 | && WindowsInstallerConstants.MsidbCustomActionTypeInScript == (bits & WindowsInstallerConstants.MsidbCustomActionTypeInScript) |
1513 | && this.TryGetIndexedElement("Property", out var xProperty, row.FieldAsString(0)) | 1443 | && this.DecompilerHelper.TryGetIndexedElement("Property", row.FieldAsString(0), out var xProperty) |
1514 | && String.IsNullOrEmpty(xProperty.Attribute("Value")?.Value) | 1444 | && String.IsNullOrEmpty(xProperty.Attribute("Value")?.Value) |
1515 | && xProperty.Attribute("Secure")?.Value != "yes" | 1445 | && xProperty.Attribute("Secure")?.Value != "yes" |
1516 | && xProperty.Attribute("SuppressModularization")?.Value != "yes") | 1446 | && xProperty.Attribute("SuppressModularization")?.Value != "yes") |
@@ -1531,10 +1461,10 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1531 | { | 1461 | { |
1532 | foreach (var row in tables["RemoveFile"]?.Rows ?? Enumerable.Empty<Row>()) | 1462 | foreach (var row in tables["RemoveFile"]?.Rows ?? Enumerable.Empty<Row>()) |
1533 | { | 1463 | { |
1534 | var xRemove = this.GetIndexedElement(row); | 1464 | var xRemove = this.DecompilerHelper.GetIndexedElement(row); |
1535 | var property = row.FieldAsString(3); | 1465 | var property = row.FieldAsString(3); |
1536 | 1466 | ||
1537 | if (this.TryGetIndexedElement("Directory", out var _, property)) | 1467 | if (this.DecompilerHelper.TryGetIndexedElement("Directory", property, out var _)) |
1538 | { | 1468 | { |
1539 | xRemove.SetAttributeValue("Directory", property); | 1469 | xRemove.SetAttributeValue("Directory", property); |
1540 | } | 1470 | } |
@@ -1562,7 +1492,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1562 | { | 1492 | { |
1563 | var id = row.FieldAsString(0); | 1493 | var id = row.FieldAsString(0); |
1564 | var table = row.FieldAsString(1); | 1494 | var table = row.FieldAsString(1); |
1565 | var xPermission = this.GetIndexedElement(row); | 1495 | var xPermission = this.DecompilerHelper.GetIndexedElement(row); |
1566 | 1496 | ||
1567 | if ("CreateFolder" == table) | 1497 | if ("CreateFolder" == table) |
1568 | { | 1498 | { |
@@ -1580,7 +1510,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1580 | } | 1510 | } |
1581 | else | 1511 | else |
1582 | { | 1512 | { |
1583 | if (this.TryGetIndexedElement(table, out var xParent, id)) | 1513 | if (this.DecompilerHelper.TryGetIndexedElement(table, id, out var xParent)) |
1584 | { | 1514 | { |
1585 | xParent.Add(xPermission); | 1515 | xParent.Add(xPermission); |
1586 | } | 1516 | } |
@@ -1651,12 +1581,12 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1651 | { | 1581 | { |
1652 | var appSearches = IndexTable(tables["AppSearch"], keyColumn: 1, dataColumn: 0); | 1582 | var appSearches = IndexTable(tables["AppSearch"], keyColumn: 1, dataColumn: 0); |
1653 | var ccpSearches = IndexTable(tables["CCPSearch"], keyColumn: 0, dataColumn: null); | 1583 | var ccpSearches = IndexTable(tables["CCPSearch"], keyColumn: 0, dataColumn: null); |
1654 | var drLocators = tables["DrLocator"]?.Rows.ToDictionary(row => this.GetIndexedElement(row), row => row); | 1584 | var drLocators = tables["DrLocator"]?.Rows.ToDictionary(row => this.DecompilerHelper.GetIndexedElement(row), row => row); |
1655 | 1585 | ||
1656 | var xComplianceCheck = new XElement(Names.ComplianceCheckElement); | 1586 | var xComplianceCheck = new XElement(Names.ComplianceCheckElement); |
1657 | if (ccpSearches.Keys.Any(ccpSignature => !appSearches.ContainsKey(ccpSignature))) | 1587 | if (ccpSearches.Keys.Any(ccpSignature => !appSearches.ContainsKey(ccpSignature))) |
1658 | { | 1588 | { |
1659 | this.RootElement.Add(xComplianceCheck); | 1589 | this.DecompilerHelper.AddElementToRoot(xComplianceCheck); |
1660 | } | 1590 | } |
1661 | 1591 | ||
1662 | // index the locator tables by their signatures | 1592 | // index the locator tables by their signatures |
@@ -1703,7 +1633,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1703 | foreach (var locatorRow in locatorRows) | 1633 | foreach (var locatorRow in locatorRows) |
1704 | { | 1634 | { |
1705 | var used = true; | 1635 | var used = true; |
1706 | var xSearch = this.GetIndexedElement(locatorRow); | 1636 | var xSearch = this.DecompilerHelper.GetIndexedElement(locatorRow); |
1707 | 1637 | ||
1708 | if ("Signature" == locatorRow.TableDefinition.Name && 0 < xSignatureSearches.Count) | 1638 | if ("Signature" == locatorRow.TableDefinition.Name && 0 < xSignatureSearches.Count) |
1709 | { | 1639 | { |
@@ -1791,7 +1721,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1791 | { | 1721 | { |
1792 | if ("DrLocator" == parentLocatorRow.TableDefinition.Name) | 1722 | if ("DrLocator" == parentLocatorRow.TableDefinition.Name) |
1793 | { | 1723 | { |
1794 | var xParentSearch = this.GetIndexedElement(parentLocatorRow); | 1724 | var xParentSearch = this.DecompilerHelper.GetIndexedElement(parentLocatorRow); |
1795 | 1725 | ||
1796 | if (xParentSearch.HasElements) | 1726 | if (xParentSearch.HasElements) |
1797 | { | 1727 | { |
@@ -1824,7 +1754,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1824 | } | 1754 | } |
1825 | else if ("RegLocator" == parentLocatorRow.TableDefinition.Name) | 1755 | else if ("RegLocator" == parentLocatorRow.TableDefinition.Name) |
1826 | { | 1756 | { |
1827 | var xParentSearch = this.GetIndexedElement(parentLocatorRow); | 1757 | var xParentSearch = this.DecompilerHelper.GetIndexedElement(parentLocatorRow); |
1828 | 1758 | ||
1829 | xParentSearch.Add(xSearch); | 1759 | xParentSearch.Add(xSearch); |
1830 | xUsedSearches.Add(xSearch); | 1760 | xUsedSearches.Add(xSearch); |
@@ -1982,11 +1912,11 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
1982 | 1912 | ||
1983 | foreach (var row in shortcutTable.Rows) | 1913 | foreach (var row in shortcutTable.Rows) |
1984 | { | 1914 | { |
1985 | var xShortcut = this.GetIndexedElement(row); | 1915 | var xShortcut = this.DecompilerHelper.GetIndexedElement(row); |
1986 | 1916 | ||
1987 | var target = row.FieldAsString(4); | 1917 | var target = row.FieldAsString(4); |
1988 | 1918 | ||
1989 | if (this.TryGetIndexedElement("Feature", out var _, target)) | 1919 | if (this.DecompilerHelper.TryGetIndexedElement("Feature", target, out var _)) |
1990 | { | 1920 | { |
1991 | xShortcut.SetAttributeValue("Advertise", "yes"); | 1921 | xShortcut.SetAttributeValue("Advertise", "yes"); |
1992 | this.SetPrimaryFeature(row, 4, 3); | 1922 | this.SetPrimaryFeature(row, 4, 3); |
@@ -2301,7 +2231,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
2301 | xMajorUpgrade.SetAttributeValue("Schedule", scheduledType); | 2231 | xMajorUpgrade.SetAttributeValue("Schedule", scheduledType); |
2302 | } | 2232 | } |
2303 | 2233 | ||
2304 | this.RootElement.Add(xMajorUpgrade); | 2234 | this.DecompilerHelper.AddElementToRoot(xMajorUpgrade); |
2305 | } | 2235 | } |
2306 | } | 2236 | } |
2307 | } | 2237 | } |
@@ -2326,7 +2256,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
2326 | { | 2256 | { |
2327 | if (xExtensions.TryGetValue(row.FieldAsString(0), out var xVerbExtensions)) | 2257 | if (xExtensions.TryGetValue(row.FieldAsString(0), out var xVerbExtensions)) |
2328 | { | 2258 | { |
2329 | var xVerb = this.GetIndexedElement(row); | 2259 | var xVerb = this.DecompilerHelper.GetIndexedElement(row); |
2330 | 2260 | ||
2331 | foreach (var xVerbExtension in xVerbExtensions) | 2261 | foreach (var xVerbExtension in xVerbExtensions) |
2332 | { | 2262 | { |
@@ -2351,8 +2281,9 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
2351 | var sourcePath = new StringBuilder(); | 2281 | var sourcePath = new StringBuilder(); |
2352 | 2282 | ||
2353 | var component = xFile.Parent; | 2283 | var component = xFile.Parent; |
2284 | var xDirectory = component.Parent; | ||
2354 | 2285 | ||
2355 | for (var xDirectory = component.Parent; null != xDirectory && xDirectory.Name.LocalName == "Directory"; xDirectory = xDirectory.Parent) | 2286 | while (xDirectory?.Name.LocalName == "Directory") |
2356 | { | 2287 | { |
2357 | string name; | 2288 | string name; |
2358 | 2289 | ||
@@ -2387,6 +2318,14 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
2387 | sourcePath.Insert(0, Path.DirectorySeparatorChar); | 2318 | sourcePath.Insert(0, Path.DirectorySeparatorChar); |
2388 | sourcePath.Insert(0, name); | 2319 | sourcePath.Insert(0, name); |
2389 | } | 2320 | } |
2321 | |||
2322 | xDirectory = xDirectory.Parent; | ||
2323 | } | ||
2324 | |||
2325 | if (xDirectory?.Name.LocalName == "StandardDirectory" && WindowsInstallerStandard.TryGetStandardDirectory(xDirectory.Attribute("Id").Value, out var standardDirectory)) | ||
2326 | { | ||
2327 | sourcePath.Insert(0, Path.DirectorySeparatorChar); | ||
2328 | sourcePath.Insert(0, standardDirectory.Name); | ||
2390 | } | 2329 | } |
2391 | 2330 | ||
2392 | return sourcePath.ToString(); | 2331 | return sourcePath.ToString(); |
@@ -2470,13 +2409,13 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
2470 | this.ShortNames = false; | 2409 | this.ShortNames = false; |
2471 | 2410 | ||
2472 | this.Singletons.Clear(); | 2411 | this.Singletons.Clear(); |
2473 | this.IndexedElements.Clear(); | 2412 | //this.IndexedElements.Clear(); |
2474 | this.PatchTargetFiles.Clear(); | 2413 | this.PatchTargetFiles.Clear(); |
2475 | 2414 | ||
2476 | // set the codepage if its not neutral (0) | 2415 | // set the codepage if its not neutral (0) |
2477 | if (0 != codepage) | 2416 | if (0 != codepage) |
2478 | { | 2417 | { |
2479 | this.RootElement.SetAttributeValue("Codepage", codepage); | 2418 | this.DecompilerHelper.RootElement.SetAttributeValue("Codepage", codepage); |
2480 | } | 2419 | } |
2481 | 2420 | ||
2482 | if (this.OutputType == OutputType.Module) | 2421 | if (this.OutputType == OutputType.Module) |
@@ -2484,44 +2423,51 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
2484 | var table = tables["_SummaryInformation"]; | 2423 | var table = tables["_SummaryInformation"]; |
2485 | var row = table.Rows.SingleOrDefault(r => r.FieldAsInteger(0) == 9); | 2424 | var row = table.Rows.SingleOrDefault(r => r.FieldAsInteger(0) == 9); |
2486 | this.ModularizationGuid = row?.FieldAsString(1); | 2425 | this.ModularizationGuid = row?.FieldAsString(1); |
2487 | this.RootElement.SetAttributeValue("Guid", this.ModularizationGuid); | 2426 | this.DecompilerHelper.RootElement.SetAttributeValue("Guid", this.ModularizationGuid); |
2427 | } | ||
2428 | |||
2429 | this.RemoveExtensionDataFromTables(tables); | ||
2430 | |||
2431 | foreach (var extension in this.Extensions) | ||
2432 | { | ||
2433 | extension.PreDecompileTables(tables); | ||
2488 | } | 2434 | } |
2435 | } | ||
2436 | |||
2437 | private void RemoveExtensionDataFromTables(TableIndexedCollection tables) | ||
2438 | { | ||
2439 | var tableDefinitionBySymbolDefinitionName = this.TableDefinitions.Where(t => t.SymbolDefinition != null).ToDictionary(t => t.SymbolDefinition.Name); | ||
2489 | 2440 | ||
2490 | // index the rows from the extension libraries | 2441 | // index the rows from the extension libraries |
2491 | var indexedExtensionTables = new Dictionary<string, HashSet<string>>(); | 2442 | var indexedExtensionTables = new Dictionary<string, HashSet<string>>(); |
2492 | #if TODO_DECOMPILER_EXTENSIONS | 2443 | foreach (var extension in this.ExtensionData) |
2493 | foreach (var extension in this.Extensions) | ||
2494 | { | 2444 | { |
2495 | // Get the optional library from the extension with the rows to be removed. | 2445 | // Get the optional library from the extension with the rows to be removed. |
2496 | var library = extension.GetLibraryToRemove(this.tableDefinitions); | 2446 | var library = extension.GetLibrary(this.SymbolDefinitionCreator); |
2497 | if (library != null) | 2447 | if (library != null) |
2498 | { | 2448 | { |
2499 | foreach (var row in library.Sections.SelectMany(s => s.Tables).SelectMany(t => t.Rows)) | 2449 | foreach (var symbol in library.Sections.SelectMany(s => s.Symbols)) |
2500 | { | 2450 | { |
2501 | string primaryKey; | 2451 | if (this.TryGetPrimaryKeyFromSymbol(tableDefinitionBySymbolDefinitionName, symbol, out var tableName, out var primaryKey)) |
2502 | string tableName; | ||
2503 | |||
2504 | // the Actions table needs to be handled specially | ||
2505 | if (table.Name == "WixAction") | ||
2506 | { | 2452 | { |
2507 | primaryKey = row.FieldAsString(1); | 2453 | //// the Actions table needs to be handled specially |
2508 | tableName = row.FieldAsString(0); | 2454 | //if (table.Name == "WixAction") |
2509 | 2455 | //{ | |
2510 | if (this.outputType == OutputType.Module) | 2456 | // primaryKey = symbol.FieldAsString(1); |
2511 | { | 2457 | // tableName = symbol.FieldAsString(0); |
2512 | tableName = "Module" + tableName; | 2458 | |
2513 | } | 2459 | // if (this.outputType == OutputType.Module) |
2514 | } | 2460 | // { |
2515 | else | 2461 | // tableName = "Module" + tableName; |
2516 | { | 2462 | // } |
2517 | primaryKey = row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter); | 2463 | //} |
2518 | tableName = table.Name; | 2464 | //else |
2519 | } | 2465 | //{ |
2520 | 2466 | // primaryKey = symbol.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter); | |
2521 | if (primaryKey != null) | 2467 | // tableName = table.Name; |
2522 | { | 2468 | //} |
2523 | HashSet<string> indexedExtensionRows; | 2469 | |
2524 | if (!indexedExtensionTables.TryGetValue(tableName, out indexedExtensionRows)) | 2470 | if (!indexedExtensionTables.TryGetValue(tableName, out var indexedExtensionRows)) |
2525 | { | 2471 | { |
2526 | indexedExtensionRows = new HashSet<string>(); | 2472 | indexedExtensionRows = new HashSet<string>(); |
2527 | indexedExtensionTables.Add(tableName, indexedExtensionRows); | 2473 | indexedExtensionTables.Add(tableName, indexedExtensionRows); |
@@ -2532,7 +2478,6 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
2532 | } | 2478 | } |
2533 | } | 2479 | } |
2534 | } | 2480 | } |
2535 | #endif | ||
2536 | 2481 | ||
2537 | // remove the rows from the extension libraries (to allow full round-tripping) | 2482 | // remove the rows from the extension libraries (to allow full round-tripping) |
2538 | foreach (var kvp in indexedExtensionTables) | 2483 | foreach (var kvp in indexedExtensionTables) |
@@ -2540,8 +2485,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
2540 | var tableName = kvp.Key; | 2485 | var tableName = kvp.Key; |
2541 | var indexedExtensionRows = kvp.Value; | 2486 | var indexedExtensionRows = kvp.Value; |
2542 | 2487 | ||
2543 | var table = tables[tableName]; | 2488 | if (tables.TryGetTable(tableName, out var table)) |
2544 | if (null != table) | ||
2545 | { | 2489 | { |
2546 | var originalRows = new RowDictionary<Row>(table); | 2490 | var originalRows = new RowDictionary<Row>(table); |
2547 | 2491 | ||
@@ -2550,7 +2494,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
2550 | 2494 | ||
2551 | foreach (var row in originalRows.Values) | 2495 | foreach (var row in originalRows.Values) |
2552 | { | 2496 | { |
2553 | if (!indexedExtensionRows.Contains(row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter))) | 2497 | if (!indexedExtensionRows.Contains(row.GetPrimaryKey())) |
2554 | { | 2498 | { |
2555 | table.Rows.Add(row); | 2499 | table.Rows.Add(row); |
2556 | } | 2500 | } |
@@ -2559,6 +2503,55 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
2559 | } | 2503 | } |
2560 | } | 2504 | } |
2561 | 2505 | ||
2506 | private bool TryGetPrimaryKeyFromSymbol(Dictionary<string, TableDefinition> tableDefinitionBySymbolDefinitionName, IntermediateSymbol symbol, out string tableName, out string primaryKey) | ||
2507 | { | ||
2508 | tableName = null; | ||
2509 | primaryKey = null; | ||
2510 | |||
2511 | if (symbol is WixActionSymbol actionSymbol) | ||
2512 | { | ||
2513 | tableName = actionSymbol.SequenceTable.WindowsInstallerTableName(); | ||
2514 | primaryKey = actionSymbol.Action; | ||
2515 | return true; | ||
2516 | } | ||
2517 | |||
2518 | if (!tableDefinitionBySymbolDefinitionName.TryGetValue(symbol.Definition.Name, out var tableDefinition)) | ||
2519 | { | ||
2520 | return false; | ||
2521 | } | ||
2522 | |||
2523 | tableName = tableDefinition.Name; | ||
2524 | |||
2525 | if (tableDefinition.SymbolIdIsPrimaryKey) | ||
2526 | { | ||
2527 | primaryKey = symbol.Id.Id; | ||
2528 | } | ||
2529 | else | ||
2530 | { | ||
2531 | var sb = new StringBuilder(); | ||
2532 | |||
2533 | for (var i = 0; i < symbol.Fields.Length && i < tableDefinition.Columns.Length; ++i) | ||
2534 | { | ||
2535 | var column = tableDefinition.Columns[i]; | ||
2536 | var field = symbol.Fields[i]; | ||
2537 | |||
2538 | if (column.PrimaryKey) | ||
2539 | { | ||
2540 | if (sb.Length > 0) | ||
2541 | { | ||
2542 | sb.Append('/'); | ||
2543 | } | ||
2544 | |||
2545 | sb.Append(field.AsString()); | ||
2546 | } | ||
2547 | } | ||
2548 | |||
2549 | primaryKey = sb.ToString(); | ||
2550 | } | ||
2551 | |||
2552 | return true; | ||
2553 | } | ||
2554 | |||
2562 | /// <summary> | 2555 | /// <summary> |
2563 | /// Decompile the tables. | 2556 | /// Decompile the tables. |
2564 | /// </summary> | 2557 | /// </summary> |
@@ -2581,7 +2574,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
2581 | // empty tables may be kept with EnsureTable if the user set the proper option | 2574 | // empty tables may be kept with EnsureTable if the user set the proper option |
2582 | if (0 == table.Rows.Count && this.SuppressDroppingEmptyTables) | 2575 | if (0 == table.Rows.Count && this.SuppressDroppingEmptyTables) |
2583 | { | 2576 | { |
2584 | this.RootElement.Add(new XElement(Names.EnsureTableElement, new XAttribute("Id", table.Name))); | 2577 | this.DecompilerHelper.AddElementToRoot(new XElement(Names.EnsureTableElement, new XAttribute("Id", table.Name))); |
2585 | } | 2578 | } |
2586 | 2579 | ||
2587 | switch (table.Name) | 2580 | switch (table.Name) |
@@ -2901,14 +2894,11 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
2901 | break; | 2894 | break; |
2902 | 2895 | ||
2903 | default: | 2896 | default: |
2904 | #if TODO_DECOMPILER_EXTENSIONS | 2897 | if (this.ExtensionsByTableName.TryGetValue(table.Name, out var extension)) |
2905 | if (this.ExtensionsByTableName.TryGetValue(table.Name, out var extension) | 2898 | { |
2906 | { | 2899 | extension.TryDecompileTable(table); |
2907 | extension.DecompileTable(table); | 2900 | } |
2908 | } | 2901 | else if (!this.SuppressCustomTables) |
2909 | else | ||
2910 | #endif | ||
2911 | if (!this.SuppressCustomTables) | ||
2912 | { | 2902 | { |
2913 | this.DecompileCustomTable(table); | 2903 | this.DecompileCustomTable(table); |
2914 | } | 2904 | } |
@@ -3039,7 +3029,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
3039 | break; | 3029 | break; |
3040 | case 3: | 3030 | case 3: |
3041 | { | 3031 | { |
3042 | var productName = this.RootElement.Attribute("Name")?.Value; | 3032 | var productName = this.DecompilerHelper.RootElement.Attribute("Name")?.Value; |
3043 | if (value != productName) | 3033 | if (value != productName) |
3044 | { | 3034 | { |
3045 | xSummaryInformation.SetAttributeValue("Description", value); | 3035 | xSummaryInformation.SetAttributeValue("Description", value); |
@@ -3048,7 +3038,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
3048 | } | 3038 | } |
3049 | case 4: | 3039 | case 4: |
3050 | { | 3040 | { |
3051 | var productManufacturer = this.RootElement.Attribute("Manufacturer")?.Value; | 3041 | var productManufacturer = this.DecompilerHelper.RootElement.Attribute("Manufacturer")?.Value; |
3052 | if (value != productManufacturer) | 3042 | if (value != productManufacturer) |
3053 | { | 3043 | { |
3054 | xSummaryInformation.SetAttributeValue("Manufacturer", value); | 3044 | xSummaryInformation.SetAttributeValue("Manufacturer", value); |
@@ -3065,7 +3055,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
3065 | var template = value.Split(';'); | 3055 | var template = value.Split(';'); |
3066 | if (0 < template.Length && 0 < template[template.Length - 1].Length) | 3056 | if (0 < template.Length && 0 < template[template.Length - 1].Length) |
3067 | { | 3057 | { |
3068 | this.RootElement.SetAttributeValue("Language", template[template.Length - 1]); | 3058 | this.DecompilerHelper.RootElement.SetAttributeValue("Language", template[template.Length - 1]); |
3069 | } | 3059 | } |
3070 | break; | 3060 | break; |
3071 | case 14: | 3061 | case 14: |
@@ -3073,7 +3063,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
3073 | // Default InstallerVersion. | 3063 | // Default InstallerVersion. |
3074 | if (installerVersion != 500) | 3064 | if (installerVersion != 500) |
3075 | { | 3065 | { |
3076 | this.RootElement.SetAttributeValue("InstallerVersion", installerVersion); | 3066 | this.DecompilerHelper.RootElement.SetAttributeValue("InstallerVersion", installerVersion); |
3077 | } | 3067 | } |
3078 | break; | 3068 | break; |
3079 | case 15: | 3069 | case 15: |
@@ -3083,29 +3073,24 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
3083 | this.ShortNames = true; | 3073 | this.ShortNames = true; |
3084 | if (OutputType.Product == this.OutputType) | 3074 | if (OutputType.Product == this.OutputType) |
3085 | { | 3075 | { |
3086 | this.RootElement.SetAttributeValue("ShortNames", "yes"); | 3076 | this.DecompilerHelper.RootElement.SetAttributeValue("ShortNames", "yes"); |
3087 | } | 3077 | } |
3088 | } | 3078 | } |
3089 | 3079 | ||
3090 | if (0x2 == (wordCount & 0x2)) | 3080 | if (0x2 == (wordCount & 0x2)) |
3091 | { | 3081 | { |
3092 | this.Compressed = true; | 3082 | this.Compressed = true; |
3093 | |||
3094 | if (OutputType.Product == this.OutputType) | ||
3095 | { | ||
3096 | this.RootElement.SetAttributeValue("Compressed", "yes"); | ||
3097 | } | ||
3098 | } | 3083 | } |
3099 | 3084 | ||
3100 | if (OutputType.Product == this.OutputType) | 3085 | if (OutputType.Product == this.OutputType) |
3101 | { | 3086 | { |
3102 | if (0x8 == (wordCount & 0x8)) | 3087 | if (0x8 == (wordCount & 0x8)) |
3103 | { | 3088 | { |
3104 | this.RootElement.SetAttributeValue("Scope", "perUser"); | 3089 | this.DecompilerHelper.RootElement.SetAttributeValue("Scope", "perUser"); |
3105 | } | 3090 | } |
3106 | else | 3091 | else |
3107 | { | 3092 | { |
3108 | var xAllUsers = this.RootElement.Elements(Names.PropertyElement).SingleOrDefault(p => p.Attribute("Id")?.Value == "ALLUSERS"); | 3093 | var xAllUsers = this.DecompilerHelper.RootElement.Elements(Names.PropertyElement).SingleOrDefault(p => p.Attribute("Id")?.Value == "ALLUSERS"); |
3109 | if (xAllUsers?.Attribute("Value")?.Value == "1") | 3094 | if (xAllUsers?.Attribute("Value")?.Value == "1") |
3110 | { | 3095 | { |
3111 | xAllUsers?.Remove(); | 3096 | xAllUsers?.Remove(); |
@@ -3118,9 +3103,14 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
3118 | } | 3103 | } |
3119 | } | 3104 | } |
3120 | 3105 | ||
3106 | if (OutputType.Product == this.OutputType && !this.Compressed) | ||
3107 | { | ||
3108 | this.DecompilerHelper.RootElement.SetAttributeValue("Compressed", "no"); | ||
3109 | } | ||
3110 | |||
3121 | if (xSummaryInformation.HasAttributes) | 3111 | if (xSummaryInformation.HasAttributes) |
3122 | { | 3112 | { |
3123 | this.RootElement.Add(xSummaryInformation); | 3113 | this.DecompilerHelper.AddElementToRoot(xSummaryInformation); |
3124 | } | 3114 | } |
3125 | } | 3115 | } |
3126 | else | 3116 | else |
@@ -3173,7 +3163,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
3173 | } | 3163 | } |
3174 | } | 3164 | } |
3175 | 3165 | ||
3176 | this.RootElement.Add(xPatchInformation); | 3166 | this.DecompilerHelper.AddElementToRoot(xPatchInformation); |
3177 | } | 3167 | } |
3178 | } | 3168 | } |
3179 | 3169 | ||
@@ -3212,8 +3202,8 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
3212 | row.IsColumnNull(5) || row.FieldAsInteger(5) != 1 ? null : new XAttribute("ActivateAtStorage", "yes"), | 3202 | row.IsColumnNull(5) || row.FieldAsInteger(5) != 1 ? null : new XAttribute("ActivateAtStorage", "yes"), |
3213 | row.IsColumnNull(6) || row.FieldAsInteger(6) != 1 ? null : new XAttribute("RunAsInteractiveUser", "yes")); | 3203 | row.IsColumnNull(6) || row.FieldAsInteger(6) != 1 ? null : new XAttribute("RunAsInteractiveUser", "yes")); |
3214 | 3204 | ||
3215 | this.RootElement.Add(appId); | 3205 | this.DecompilerHelper.AddElementToRoot(appId); |
3216 | this.IndexElement(row, appId); | 3206 | this.DecompilerHelper.IndexElement(row, appId); |
3217 | } | 3207 | } |
3218 | } | 3208 | } |
3219 | 3209 | ||
@@ -3239,7 +3229,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
3239 | SetControlAttributes(bbControlRow.Attributes, xControl); | 3229 | SetControlAttributes(bbControlRow.Attributes, xControl); |
3240 | } | 3230 | } |
3241 | 3231 | ||
3242 | if (this.TryGetIndexedElement("Billboard", out var xBillboard, bbControlRow.Billboard)) | 3232 | if (this.DecompilerHelper.TryGetIndexedElement("Billboard", bbControlRow.Billboard, out var xBillboard)) |
3243 | { | 3233 | { |
3244 | xBillboard.Add(xControl); | 3234 | xBillboard.Add(xControl); |
3245 | } | 3235 | } |
@@ -3264,7 +3254,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
3264 | new XAttribute("Id", row.FieldAsString(0)), | 3254 | new XAttribute("Id", row.FieldAsString(0)), |
3265 | new XAttribute("Feature", row.FieldAsString(1))); | 3255 | new XAttribute("Feature", row.FieldAsString(1))); |
3266 | 3256 | ||
3267 | this.IndexElement(row, xBillboard); | 3257 | this.DecompilerHelper.IndexElement(row, xBillboard); |
3268 | billboards.Add(String.Format(CultureInfo.InvariantCulture, "{0}|{1:0000000000}", row[0], row[3]), row); | 3258 | billboards.Add(String.Format(CultureInfo.InvariantCulture, "{0}|{1:0000000000}", row[0], row[3]), row); |
3269 | } | 3259 | } |
3270 | 3260 | ||
@@ -3272,7 +3262,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
3272 | 3262 | ||
3273 | foreach (var row in billboards.Values) | 3263 | foreach (var row in billboards.Values) |
3274 | { | 3264 | { |
3275 | var xBillboard = this.GetIndexedElement(row); | 3265 | var xBillboard = this.DecompilerHelper.GetIndexedElement(row); |
3276 | 3266 | ||
3277 | if (!billboardActions.TryGetValue(row.FieldAsString(2), out var xBillboardAction)) | 3267 | if (!billboardActions.TryGetValue(row.FieldAsString(2), out var xBillboardAction)) |
3278 | { | 3268 | { |
@@ -3299,7 +3289,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
3299 | new XAttribute("Id", row.FieldAsString(0)), | 3289 | new XAttribute("Id", row.FieldAsString(0)), |
3300 | new XAttribute("SourceFile", row.FieldAsString(1))); | 3290 | new XAttribute("SourceFile", row.FieldAsString(1))); |
3301 | 3291 | ||
3302 | this.RootElement.Add(xBinary); | 3292 | this.DecompilerHelper.AddElementToRoot(xBinary); |
3303 | } | 3293 | } |
3304 | } | 3294 | } |
3305 | 3295 | ||
@@ -3311,7 +3301,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
3311 | { | 3301 | { |
3312 | foreach (var row in table.Rows) | 3302 | foreach (var row in table.Rows) |
3313 | { | 3303 | { |
3314 | if (this.TryGetIndexedElement("File", out var xFile, row.FieldAsString(0))) | 3304 | if (this.DecompilerHelper.TryGetIndexedElement("File", row.FieldAsString(0), out var xFile)) |
3315 | { | 3305 | { |
3316 | xFile.SetAttributeValue("BindPath", row.FieldAsString(1)); | 3306 | xFile.SetAttributeValue("BindPath", row.FieldAsString(1)); |
3317 | } | 3307 | } |
@@ -3389,7 +3379,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
3389 | } | 3379 | } |
3390 | 3380 | ||
3391 | this.AddChildToParent("Component", xClass, row, 2); | 3381 | this.AddChildToParent("Component", xClass, row, 2); |
3392 | this.IndexElement(row, xClass); | 3382 | this.DecompilerHelper.IndexElement(row, xClass); |
3393 | } | 3383 | } |
3394 | } | 3384 | } |
3395 | 3385 | ||
@@ -3656,7 +3646,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
3656 | } | 3646 | } |
3657 | } | 3647 | } |
3658 | 3648 | ||
3659 | this.IndexElement(controlRow, xControl); | 3649 | this.DecompilerHelper.IndexElement(controlRow, xControl); |
3660 | } | 3650 | } |
3661 | } | 3651 | } |
3662 | 3652 | ||
@@ -3668,7 +3658,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
3668 | { | 3658 | { |
3669 | foreach (var row in table.Rows) | 3659 | foreach (var row in table.Rows) |
3670 | { | 3660 | { |
3671 | if (this.TryGetIndexedElement("Control", out var xControl, row.FieldAsString(0), row.FieldAsString(1))) | 3661 | if (this.DecompilerHelper.TryGetIndexedElement("Control", row.FieldAsString(0), row.FieldAsString(1), out var xControl)) |
3672 | { | 3662 | { |
3673 | switch (row.FieldAsString(2)) | 3663 | switch (row.FieldAsString(2)) |
3674 | { | 3664 | { |
@@ -3730,14 +3720,14 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
3730 | 3720 | ||
3731 | controlEvents.Add(String.Format(CultureInfo.InvariantCulture, "{0}|{1}|{2:0000000000}|{3}|{4}|{5}", row.FieldAsString(0), row.FieldAsString(1), row.FieldAsNullableInteger(5) ?? 0, row.FieldAsString(2), row.FieldAsString(3), row.FieldAsString(4)), row); | 3721 | controlEvents.Add(String.Format(CultureInfo.InvariantCulture, "{0}|{1}|{2:0000000000}|{3}|{4}|{5}", row.FieldAsString(0), row.FieldAsString(1), row.FieldAsNullableInteger(5) ?? 0, row.FieldAsString(2), row.FieldAsString(3), row.FieldAsString(4)), row); |
3732 | 3722 | ||
3733 | this.IndexElement(row, xPublish); | 3723 | this.DecompilerHelper.IndexElement(row, xPublish); |
3734 | } | 3724 | } |
3735 | 3725 | ||
3736 | foreach (var row in controlEvents.Values) | 3726 | foreach (var row in controlEvents.Values) |
3737 | { | 3727 | { |
3738 | if (this.TryGetIndexedElement("Control", out var xControl, row.FieldAsString(0), row.FieldAsString(1))) | 3728 | if (this.DecompilerHelper.TryGetIndexedElement("Control", row.FieldAsString(0), row.FieldAsString(1), out var xControl)) |
3739 | { | 3729 | { |
3740 | var xPublish = this.GetIndexedElement(row); | 3730 | var xPublish = this.DecompilerHelper.GetIndexedElement(row); |
3741 | xControl.Add(xPublish); | 3731 | xControl.Add(xPublish); |
3742 | } | 3732 | } |
3743 | else | 3733 | else |
@@ -3928,7 +3918,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
3928 | xCustomTable.Add(xRow); | 3918 | xCustomTable.Add(xRow); |
3929 | } | 3919 | } |
3930 | 3920 | ||
3931 | this.RootElement.Add(xCustomTable); | 3921 | this.DecompilerHelper.AddElementToRoot(xCustomTable); |
3932 | } | 3922 | } |
3933 | } | 3923 | } |
3934 | 3924 | ||
@@ -3944,7 +3934,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
3944 | new XAttribute("Directory", row.FieldAsString(0))); | 3934 | new XAttribute("Directory", row.FieldAsString(0))); |
3945 | 3935 | ||
3946 | this.AddChildToParent("Component", xCreateFolder, row, 1); | 3936 | this.AddChildToParent("Component", xCreateFolder, row, 1); |
3947 | this.IndexElement(row, xCreateFolder); | 3937 | this.DecompilerHelper.IndexElement(row, xCreateFolder); |
3948 | } | 3938 | } |
3949 | } | 3939 | } |
3950 | 3940 | ||
@@ -4115,8 +4105,8 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
4115 | xCustomAction.SetAttributeValue("PatchUninstall", "yes"); | 4105 | xCustomAction.SetAttributeValue("PatchUninstall", "yes"); |
4116 | } | 4106 | } |
4117 | 4107 | ||
4118 | this.RootElement.Add(xCustomAction); | 4108 | this.DecompilerHelper.AddElementToRoot(xCustomAction); |
4119 | this.IndexElement(row, xCustomAction); | 4109 | this.DecompilerHelper.IndexElement(row, xCustomAction); |
4120 | } | 4110 | } |
4121 | } | 4111 | } |
4122 | 4112 | ||
@@ -4148,7 +4138,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
4148 | } | 4138 | } |
4149 | } | 4139 | } |
4150 | 4140 | ||
4151 | this.IndexElement(row, xComponentSearch); | 4141 | this.DecompilerHelper.IndexElement(row, xComponentSearch); |
4152 | } | 4142 | } |
4153 | } | 4143 | } |
4154 | 4144 | ||
@@ -4162,7 +4152,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
4162 | { | 4152 | { |
4163 | if (!row.IsColumnNull(1)) | 4153 | if (!row.IsColumnNull(1)) |
4164 | { | 4154 | { |
4165 | if (this.TryGetIndexedElement("Component", out var xComponent, row.FieldAsString(0))) | 4155 | if (this.DecompilerHelper.TryGetIndexedElement("Component", row.FieldAsString(0), out var xComponent)) |
4166 | { | 4156 | { |
4167 | xComponent.SetAttributeValue("ComPlusFlags", row.FieldAsInteger(1)); | 4157 | xComponent.SetAttributeValue("ComPlusFlags", row.FieldAsInteger(1)); |
4168 | } | 4158 | } |
@@ -4247,7 +4237,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
4247 | } | 4237 | } |
4248 | 4238 | ||
4249 | this.AddChildToParent("Directory", xComponent, row, 2); | 4239 | this.AddChildToParent("Directory", xComponent, row, 2); |
4250 | this.IndexElement(row, xComponent); | 4240 | this.DecompilerHelper.IndexElement(row, xComponent); |
4251 | } | 4241 | } |
4252 | } | 4242 | } |
4253 | 4243 | ||
@@ -4259,7 +4249,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
4259 | { | 4249 | { |
4260 | foreach (var row in table.Rows) | 4250 | foreach (var row in table.Rows) |
4261 | { | 4251 | { |
4262 | if (this.TryGetIndexedElement("Feature", out var xFeature, row.FieldAsString(0))) | 4252 | if (this.DecompilerHelper.TryGetIndexedElement("Feature", row.FieldAsString(0), out var xFeature)) |
4263 | { | 4253 | { |
4264 | var xLevel = new XElement(Names.LevelElement, | 4254 | var xLevel = new XElement(Names.LevelElement, |
4265 | row.IsColumnNull(2) ? null : new XAttribute("Condition", row.FieldAsString(2)), | 4255 | row.IsColumnNull(2) ? null : new XAttribute("Condition", row.FieldAsString(2)), |
@@ -4303,7 +4293,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
4303 | !row.IsColumnNull(6) ? new XAttribute("Title", row.FieldAsString(6)) : null); | 4293 | !row.IsColumnNull(6) ? new XAttribute("Title", row.FieldAsString(6)) : null); |
4304 | 4294 | ||
4305 | this.UIElement.Add(xDialog); | 4295 | this.UIElement.Add(xDialog); |
4306 | this.IndexElement(row, xDialog); | 4296 | this.DecompilerHelper.IndexElement(row, xDialog); |
4307 | } | 4297 | } |
4308 | } | 4298 | } |
4309 | 4299 | ||
@@ -4367,13 +4357,13 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
4367 | } | 4357 | } |
4368 | } | 4358 | } |
4369 | 4359 | ||
4370 | this.IndexElement(row, xDirectory); | 4360 | this.DecompilerHelper.IndexElement(row, xDirectory); |
4371 | } | 4361 | } |
4372 | 4362 | ||
4373 | // nest the directories | 4363 | // nest the directories |
4374 | foreach (var row in table.Rows) | 4364 | foreach (var row in table.Rows) |
4375 | { | 4365 | { |
4376 | var xDirectory = this.GetIndexedElement(row); | 4366 | var xDirectory = this.DecompilerHelper.GetIndexedElement(row); |
4377 | 4367 | ||
4378 | var id = row.FieldAsString(0); | 4368 | var id = row.FieldAsString(0); |
4379 | 4369 | ||
@@ -4383,26 +4373,26 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
4383 | } | 4373 | } |
4384 | else if (row.IsColumnNull(1) || WindowsInstallerStandard.IsStandardDirectory(id)) | 4374 | else if (row.IsColumnNull(1) || WindowsInstallerStandard.IsStandardDirectory(id)) |
4385 | { | 4375 | { |
4386 | this.RootElement.Add(xDirectory); | 4376 | this.DecompilerHelper.AddElementToRoot(xDirectory); |
4387 | } | 4377 | } |
4388 | else | 4378 | else |
4389 | { | 4379 | { |
4390 | var parentDirectoryId = row.FieldAsString(1); | 4380 | var parentDirectoryId = row.FieldAsString(1); |
4391 | 4381 | ||
4392 | if (!this.TryGetIndexedElement("Directory", out var xParentDirectory, parentDirectoryId)) | 4382 | if (!this.DecompilerHelper.TryGetIndexedElement("Directory", parentDirectoryId, out var xParentDirectory)) |
4393 | { | 4383 | { |
4394 | this.Messaging.Write(WarningMessages.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Directory_Parent", row.FieldAsString(1), "Directory")); | 4384 | this.Messaging.Write(WarningMessages.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Directory_Parent", row.FieldAsString(1), "Directory")); |
4395 | } | 4385 | } |
4396 | else if (xParentDirectory == xDirectory) // another way to specify a root directory | 4386 | else if (xParentDirectory == xDirectory) // another way to specify a root directory |
4397 | { | 4387 | { |
4398 | this.RootElement.Add(xDirectory); | 4388 | this.DecompilerHelper.AddElementToRoot(xDirectory); |
4399 | } | 4389 | } |
4400 | else | 4390 | else |
4401 | { | 4391 | { |
4402 | // TARGETDIR is omitted but if this directory is a first-generation descendant, add it as a root. | 4392 | // TARGETDIR is omitted but if this directory is a first-generation descendant, add it as a root. |
4403 | if (parentDirectoryId == "TARGETDIR") | 4393 | if (parentDirectoryId == "TARGETDIR") |
4404 | { | 4394 | { |
4405 | this.RootElement.Add(xDirectory); | 4395 | this.DecompilerHelper.AddElementToRoot(xDirectory); |
4406 | } | 4396 | } |
4407 | else | 4397 | else |
4408 | { | 4398 | { |
@@ -4426,7 +4416,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
4426 | XAttributeIfNotNull("Path", row, 2), | 4416 | XAttributeIfNotNull("Path", row, 2), |
4427 | XAttributeIfNotNull("Depth", row, 3)); | 4417 | XAttributeIfNotNull("Depth", row, 3)); |
4428 | 4418 | ||
4429 | this.IndexElement(row, xDirectorySearch); | 4419 | this.DecompilerHelper.IndexElement(row, xDirectorySearch); |
4430 | } | 4420 | } |
4431 | } | 4421 | } |
4432 | 4422 | ||
@@ -4459,7 +4449,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
4459 | // destination directory/property is set in FinalizeDuplicateMoveFileTables | 4449 | // destination directory/property is set in FinalizeDuplicateMoveFileTables |
4460 | 4450 | ||
4461 | this.AddChildToParent("Component", xCopyFile, row, 1); | 4451 | this.AddChildToParent("Component", xCopyFile, row, 1); |
4462 | this.IndexElement(row, xCopyFile); | 4452 | this.DecompilerHelper.IndexElement(row, xCopyFile); |
4463 | } | 4453 | } |
4464 | } | 4454 | } |
4465 | 4455 | ||
@@ -4570,7 +4560,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
4570 | new XAttribute("Event", row.FieldAsString(2)), | 4560 | new XAttribute("Event", row.FieldAsString(2)), |
4571 | new XAttribute("Attribute", row.FieldAsString(3))); | 4561 | new XAttribute("Attribute", row.FieldAsString(3))); |
4572 | 4562 | ||
4573 | if (this.TryGetIndexedElement("Control", out var xControl, row.FieldAsString(0), row.FieldAsString(1))) | 4563 | if (this.DecompilerHelper.TryGetIndexedElement("Control", row.FieldAsString(0), row.FieldAsString(1), out var xControl)) |
4574 | { | 4564 | { |
4575 | xControl.Add(xSubscribe); | 4565 | xControl.Add(xSubscribe); |
4576 | } | 4566 | } |
@@ -4595,7 +4585,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
4595 | 4585 | ||
4596 | if (!row.IsColumnNull(3)) | 4586 | if (!row.IsColumnNull(3)) |
4597 | { | 4587 | { |
4598 | if (this.TryGetIndexedElement("MIME", out var xMime, row.FieldAsString(3))) | 4588 | if (this.DecompilerHelper.TryGetIndexedElement("MIME", row.FieldAsString(3), out var xMime)) |
4599 | { | 4589 | { |
4600 | xMime.SetAttributeValue("Default", "yes"); | 4590 | xMime.SetAttributeValue("Default", "yes"); |
4601 | } | 4591 | } |
@@ -4614,7 +4604,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
4614 | this.AddChildToParent("Component", xExtension, row, 1); | 4604 | this.AddChildToParent("Component", xExtension, row, 1); |
4615 | } | 4605 | } |
4616 | 4606 | ||
4617 | this.IndexElement(row, xExtension); | 4607 | this.DecompilerHelper.IndexElement(row, xExtension); |
4618 | } | 4608 | } |
4619 | } | 4609 | } |
4620 | 4610 | ||
@@ -4682,7 +4672,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
4682 | } | 4672 | } |
4683 | 4673 | ||
4684 | this.AddChildToParent("ImageFamilies", xExternalFile, row, 0); | 4674 | this.AddChildToParent("ImageFamilies", xExternalFile, row, 0); |
4685 | this.IndexElement(row, xExternalFile); | 4675 | this.DecompilerHelper.IndexElement(row, xExternalFile); |
4686 | } | 4676 | } |
4687 | } | 4677 | } |
4688 | 4678 | ||
@@ -4761,7 +4751,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
4761 | feature.SetAttributeValue("Absent", "disallow"); | 4751 | feature.SetAttributeValue("Absent", "disallow"); |
4762 | } | 4752 | } |
4763 | 4753 | ||
4764 | this.IndexElement(row, feature); | 4754 | this.DecompilerHelper.IndexElement(row, feature); |
4765 | 4755 | ||
4766 | // sort the features by their display column (and append the identifier to ensure unique keys) | 4756 | // sort the features by their display column (and append the identifier to ensure unique keys) |
4767 | sortedFeatures.Add(String.Format(CultureInfo.InvariantCulture, "{0:00000}|{1}", row.FieldAsInteger(4), row[0]), row); | 4757 | sortedFeatures.Add(String.Format(CultureInfo.InvariantCulture, "{0:00000}|{1}", row.FieldAsInteger(4), row[0]), row); |
@@ -4770,15 +4760,15 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
4770 | // nest the features | 4760 | // nest the features |
4771 | foreach (var row in sortedFeatures.Values) | 4761 | foreach (var row in sortedFeatures.Values) |
4772 | { | 4762 | { |
4773 | var xFeature = this.GetIndexedElement("Feature", row.FieldAsString(0)); | 4763 | var xFeature = this.DecompilerHelper.GetIndexedElement("Feature", row.FieldAsString(0)); |
4774 | 4764 | ||
4775 | if (row.IsColumnNull(1)) | 4765 | if (row.IsColumnNull(1)) |
4776 | { | 4766 | { |
4777 | this.RootElement.Add(xFeature); | 4767 | this.DecompilerHelper.AddElementToRoot(xFeature); |
4778 | } | 4768 | } |
4779 | else | 4769 | else |
4780 | { | 4770 | { |
4781 | if (this.TryGetIndexedElement("Feature", out var xParentFeature, row.FieldAsString(1))) | 4771 | if (this.DecompilerHelper.TryGetIndexedElement("Feature", row.FieldAsString(1), out var xParentFeature)) |
4782 | { | 4772 | { |
4783 | if (xParentFeature == xFeature) | 4773 | if (xParentFeature == xFeature) |
4784 | { | 4774 | { |
@@ -4809,7 +4799,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
4809 | new XAttribute("Id", row.FieldAsString(1))); | 4799 | new XAttribute("Id", row.FieldAsString(1))); |
4810 | 4800 | ||
4811 | this.AddChildToParent("Feature", xComponentRef, row, 0); | 4801 | this.AddChildToParent("Feature", xComponentRef, row, 0); |
4812 | this.IndexElement(row, xComponentRef); | 4802 | this.DecompilerHelper.IndexElement(row, xComponentRef); |
4813 | } | 4803 | } |
4814 | } | 4804 | } |
4815 | 4805 | ||
@@ -4855,7 +4845,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
4855 | xFile.SetAttributeValue("Compressed", "yes"); | 4845 | xFile.SetAttributeValue("Compressed", "yes"); |
4856 | } | 4846 | } |
4857 | 4847 | ||
4858 | this.IndexElement(fileRow, xFile); | 4848 | this.DecompilerHelper.IndexElement(fileRow, xFile); |
4859 | } | 4849 | } |
4860 | } | 4850 | } |
4861 | 4851 | ||
@@ -4882,7 +4872,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
4882 | { | 4872 | { |
4883 | foreach (var row in table.Rows) | 4873 | foreach (var row in table.Rows) |
4884 | { | 4874 | { |
4885 | if (this.TryGetIndexedElement("File", out var xFile, row.FieldAsString(0))) | 4875 | if (this.DecompilerHelper.TryGetIndexedElement("File", row.FieldAsString(0), out var xFile)) |
4886 | { | 4876 | { |
4887 | if (!row.IsColumnNull(1)) | 4877 | if (!row.IsColumnNull(1)) |
4888 | { | 4878 | { |
@@ -4912,7 +4902,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
4912 | new XAttribute("Id", row.FieldAsString(0)), | 4902 | new XAttribute("Id", row.FieldAsString(0)), |
4913 | new XAttribute("SourceFile", row.FieldAsString(1))); | 4903 | new XAttribute("SourceFile", row.FieldAsString(1))); |
4914 | 4904 | ||
4915 | this.RootElement.Add(icon); | 4905 | this.DecompilerHelper.AddElementToRoot(icon); |
4916 | } | 4906 | } |
4917 | } | 4907 | } |
4918 | 4908 | ||
@@ -4932,8 +4922,8 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
4932 | row.IsColumnNull(4) ? null : new XAttribute("DiskPrompt", row.FieldAsString(4)), | 4922 | row.IsColumnNull(4) ? null : new XAttribute("DiskPrompt", row.FieldAsString(4)), |
4933 | row.IsColumnNull(5) ? null : new XAttribute("VolumeLabel", row.FieldAsString(5))); | 4923 | row.IsColumnNull(5) ? null : new XAttribute("VolumeLabel", row.FieldAsString(5))); |
4934 | 4924 | ||
4935 | this.RootElement.Add(family); | 4925 | this.DecompilerHelper.AddElementToRoot(family); |
4936 | this.IndexElement(row, family); | 4926 | this.DecompilerHelper.IndexElement(row, family); |
4937 | } | 4927 | } |
4938 | } | 4928 | } |
4939 | 4929 | ||
@@ -5035,7 +5025,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
5035 | } | 5025 | } |
5036 | } | 5026 | } |
5037 | 5027 | ||
5038 | this.IndexElement(row, xIniFileSearch); | 5028 | this.DecompilerHelper.IndexElement(row, xIniFileSearch); |
5039 | } | 5029 | } |
5040 | } | 5030 | } |
5041 | 5031 | ||
@@ -5071,7 +5061,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
5071 | new XAttribute("Condition", row.FieldAsString(0)), | 5061 | new XAttribute("Condition", row.FieldAsString(0)), |
5072 | new XAttribute("Message", row.FieldAsString(1))); | 5062 | new XAttribute("Message", row.FieldAsString(1))); |
5073 | 5063 | ||
5074 | this.RootElement.Add(condition); | 5064 | this.DecompilerHelper.AddElementToRoot(condition); |
5075 | } | 5065 | } |
5076 | } | 5066 | } |
5077 | 5067 | ||
@@ -5230,7 +5220,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
5230 | } | 5220 | } |
5231 | } | 5221 | } |
5232 | 5222 | ||
5233 | this.IndexElement(row, xPermission); | 5223 | this.DecompilerHelper.IndexElement(row, xPermission); |
5234 | } | 5224 | } |
5235 | } | 5225 | } |
5236 | 5226 | ||
@@ -5260,8 +5250,8 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
5260 | xMedia.SetAttributeValue("Cabinet", cabinet); | 5250 | xMedia.SetAttributeValue("Cabinet", cabinet); |
5261 | } | 5251 | } |
5262 | 5252 | ||
5263 | this.RootElement.Add(xMedia); | 5253 | this.DecompilerHelper.AddElementToRoot(xMedia); |
5264 | this.IndexElement(mediaRow, xMedia); | 5254 | this.DecompilerHelper.IndexElement(mediaRow, xMedia); |
5265 | } | 5255 | } |
5266 | } | 5256 | } |
5267 | 5257 | ||
@@ -5277,7 +5267,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
5277 | new XAttribute("ContentType", row.FieldAsString(0)), | 5267 | new XAttribute("ContentType", row.FieldAsString(0)), |
5278 | row.IsColumnNull(2) ? null : new XAttribute("Class", row.FieldAsString(2))); | 5268 | row.IsColumnNull(2) ? null : new XAttribute("Class", row.FieldAsString(2))); |
5279 | 5269 | ||
5280 | this.IndexElement(row, mime); | 5270 | this.DecompilerHelper.IndexElement(row, mime); |
5281 | } | 5271 | } |
5282 | } | 5272 | } |
5283 | 5273 | ||
@@ -5338,7 +5328,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
5338 | } | 5328 | } |
5339 | } | 5329 | } |
5340 | 5330 | ||
5341 | this.RootElement.Add(configuration); | 5331 | this.DecompilerHelper.AddElementToRoot(configuration); |
5342 | } | 5332 | } |
5343 | } | 5333 | } |
5344 | 5334 | ||
@@ -5355,7 +5345,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
5355 | new XAttribute("RequiredLanguage", row.FieldAsString(3)), | 5345 | new XAttribute("RequiredLanguage", row.FieldAsString(3)), |
5356 | XAttributeIfNotNull("RequiredVersion", row, 4)); | 5346 | XAttributeIfNotNull("RequiredVersion", row, 4)); |
5357 | 5347 | ||
5358 | this.RootElement.Add(xDependency); | 5348 | this.DecompilerHelper.AddElementToRoot(xDependency); |
5359 | } | 5349 | } |
5360 | } | 5350 | } |
5361 | 5351 | ||
@@ -5382,7 +5372,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
5382 | xExclusion.SetAttributeValue("ExcludeExceptLanguage", -excludedLanguage); | 5372 | xExclusion.SetAttributeValue("ExcludeExceptLanguage", -excludedLanguage); |
5383 | } | 5373 | } |
5384 | 5374 | ||
5385 | this.RootElement.Add(xExclusion); | 5375 | this.DecompilerHelper.AddElementToRoot(xExclusion); |
5386 | } | 5376 | } |
5387 | } | 5377 | } |
5388 | 5378 | ||
@@ -5402,7 +5392,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
5402 | var xIgnoreTable = new XElement(Names.IgnoreTableElement, | 5392 | var xIgnoreTable = new XElement(Names.IgnoreTableElement, |
5403 | new XAttribute("Id", tableName)); | 5393 | new XAttribute("Id", tableName)); |
5404 | 5394 | ||
5405 | this.RootElement.Add(xIgnoreTable); | 5395 | this.DecompilerHelper.AddElementToRoot(xIgnoreTable); |
5406 | } | 5396 | } |
5407 | } | 5397 | } |
5408 | } | 5398 | } |
@@ -5417,10 +5407,10 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
5417 | { | 5407 | { |
5418 | var row = table.Rows[0]; | 5408 | var row = table.Rows[0]; |
5419 | 5409 | ||
5420 | this.RootElement.SetAttributeValue("Id", row.FieldAsString(0)); | 5410 | this.DecompilerHelper.RootElement.SetAttributeValue("Id", row.FieldAsString(0)); |
5421 | // support Language columns that are treated as integers as well as strings (the WiX default, to support localizability) | 5411 | // support Language columns that are treated as integers as well as strings (the WiX default, to support localizability) |
5422 | this.RootElement.SetAttributeValue("Language", row.FieldAsString(1)); | 5412 | this.DecompilerHelper.RootElement.SetAttributeValue("Language", row.FieldAsString(1)); |
5423 | this.RootElement.SetAttributeValue("Version", row.FieldAsString(2)); | 5413 | this.DecompilerHelper.RootElement.SetAttributeValue("Version", row.FieldAsString(2)); |
5424 | } | 5414 | } |
5425 | else | 5415 | else |
5426 | { | 5416 | { |
@@ -5442,7 +5432,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
5442 | new XAttribute("Column", row.FieldAsString(2)), | 5432 | new XAttribute("Column", row.FieldAsString(2)), |
5443 | XAttributeIfNotNull("Value", row, 3)); | 5433 | XAttributeIfNotNull("Value", row, 3)); |
5444 | 5434 | ||
5445 | this.RootElement.Add(xSubstitution); | 5435 | this.DecompilerHelper.AddElementToRoot(xSubstitution); |
5446 | } | 5436 | } |
5447 | } | 5437 | } |
5448 | 5438 | ||
@@ -5487,7 +5477,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
5487 | } | 5477 | } |
5488 | 5478 | ||
5489 | this.AddChildToParent("Component", xCopyFile, row, 1); | 5479 | this.AddChildToParent("Component", xCopyFile, row, 1); |
5490 | this.IndexElement(row, xCopyFile); | 5480 | this.DecompilerHelper.IndexElement(row, xCopyFile); |
5491 | } | 5481 | } |
5492 | } | 5482 | } |
5493 | 5483 | ||
@@ -5503,7 +5493,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
5503 | new XAttribute("Id", row.FieldAsString(0)), | 5493 | new XAttribute("Id", row.FieldAsString(0)), |
5504 | new XAttribute("SourceFile", row.FieldAsString(1))); | 5494 | new XAttribute("SourceFile", row.FieldAsString(1))); |
5505 | 5495 | ||
5506 | this.IndexElement(row, xDigitalCertificate); | 5496 | this.DecompilerHelper.IndexElement(row, xDigitalCertificate); |
5507 | } | 5497 | } |
5508 | } | 5498 | } |
5509 | 5499 | ||
@@ -5520,7 +5510,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
5520 | 5510 | ||
5521 | this.AddChildToParent("MsiDigitalCertificate", xDigitalSignature, row, 2); | 5511 | this.AddChildToParent("MsiDigitalCertificate", xDigitalSignature, row, 2); |
5522 | 5512 | ||
5523 | if (this.TryGetIndexedElement(row.FieldAsString(0), out var xParentElement, row.FieldAsString(1))) | 5513 | if (this.DecompilerHelper.TryGetIndexedElement(row.FieldAsString(0), row.FieldAsString(1), out var xParentElement)) |
5524 | { | 5514 | { |
5525 | xParentElement.Add(xDigitalSignature); | 5515 | xParentElement.Add(xDigitalSignature); |
5526 | } | 5516 | } |
@@ -5560,7 +5550,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
5560 | break; | 5550 | break; |
5561 | } | 5551 | } |
5562 | 5552 | ||
5563 | this.RootElement.Add(xEmbeddedChainer); | 5553 | this.DecompilerHelper.AddElementToRoot(xEmbeddedChainer); |
5564 | } | 5554 | } |
5565 | } | 5555 | } |
5566 | 5556 | ||
@@ -5735,7 +5725,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
5735 | return; | 5725 | return; |
5736 | } | 5726 | } |
5737 | 5727 | ||
5738 | this.IndexElement(row, xPermissionEx); | 5728 | this.DecompilerHelper.IndexElement(row, xPermissionEx); |
5739 | } | 5729 | } |
5740 | } | 5730 | } |
5741 | 5731 | ||
@@ -5748,7 +5738,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
5748 | if (0 < table.Rows.Count) | 5738 | if (0 < table.Rows.Count) |
5749 | { | 5739 | { |
5750 | var xPackageCertificates = new XElement(Names.PatchCertificatesElement); | 5740 | var xPackageCertificates = new XElement(Names.PatchCertificatesElement); |
5751 | this.RootElement.Add(xPackageCertificates); | 5741 | this.DecompilerHelper.AddElementToRoot(xPackageCertificates); |
5752 | this.AddCertificates(table, xPackageCertificates); | 5742 | this.AddCertificates(table, xPackageCertificates); |
5753 | } | 5743 | } |
5754 | } | 5744 | } |
@@ -5762,7 +5752,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
5762 | if (0 < table.Rows.Count) | 5752 | if (0 < table.Rows.Count) |
5763 | { | 5753 | { |
5764 | var xPatchCertificates = new XElement(Names.PatchCertificatesElement); | 5754 | var xPatchCertificates = new XElement(Names.PatchCertificatesElement); |
5765 | this.RootElement.Add(xPatchCertificates); | 5755 | this.DecompilerHelper.AddElementToRoot(xPatchCertificates); |
5766 | this.AddCertificates(table, xPatchCertificates); | 5756 | this.AddCertificates(table, xPatchCertificates); |
5767 | } | 5757 | } |
5768 | } | 5758 | } |
@@ -5776,7 +5766,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
5776 | { | 5766 | { |
5777 | foreach (var row in table.Rows) | 5767 | foreach (var row in table.Rows) |
5778 | { | 5768 | { |
5779 | if (this.TryGetIndexedElement("MsiDigitalCertificate", out var xDigitalCertificate, row.FieldAsString(1))) | 5769 | if (this.DecompilerHelper.TryGetIndexedElement("MsiDigitalCertificate", row.FieldAsString(1), out var xDigitalCertificate)) |
5780 | { | 5770 | { |
5781 | parent.Add(xDigitalCertificate); | 5771 | parent.Add(xDigitalCertificate); |
5782 | } | 5772 | } |
@@ -5846,7 +5836,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
5846 | break; | 5836 | break; |
5847 | } | 5837 | } |
5848 | 5838 | ||
5849 | this.IndexElement(row, xOdbcDataSource); | 5839 | this.DecompilerHelper.IndexElement(row, xOdbcDataSource); |
5850 | } | 5840 | } |
5851 | } | 5841 | } |
5852 | 5842 | ||
@@ -5865,7 +5855,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
5865 | XAttributeIfNotNull("SetupFile", row, 4)); | 5855 | XAttributeIfNotNull("SetupFile", row, 4)); |
5866 | 5856 | ||
5867 | this.AddChildToParent("Component", xOdbcDriver, row, 1); | 5857 | this.AddChildToParent("Component", xOdbcDriver, row, 1); |
5868 | this.IndexElement(row, xOdbcDriver); | 5858 | this.DecompilerHelper.IndexElement(row, xOdbcDriver); |
5869 | } | 5859 | } |
5870 | } | 5860 | } |
5871 | 5861 | ||
@@ -6010,7 +6000,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
6010 | } | 6000 | } |
6011 | } | 6001 | } |
6012 | 6002 | ||
6013 | this.RootElement.Add(xPatchMetadata); | 6003 | this.DecompilerHelper.AddElementToRoot(xPatchMetadata); |
6014 | } | 6004 | } |
6015 | } | 6005 | } |
6016 | 6006 | ||
@@ -6049,7 +6039,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
6049 | patchSequence.SetAttributeValue("Supersede", "yes"); | 6039 | patchSequence.SetAttributeValue("Supersede", "yes"); |
6050 | } | 6040 | } |
6051 | 6041 | ||
6052 | this.RootElement.Add(patchSequence); | 6042 | this.DecompilerHelper.AddElementToRoot(patchSequence); |
6053 | } | 6043 | } |
6054 | } | 6044 | } |
6055 | 6045 | ||
@@ -6068,13 +6058,13 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
6068 | XAttributeIfNotNull("Icon", row, 4), | 6058 | XAttributeIfNotNull("Icon", row, 4), |
6069 | XAttributeIfNotNull("IconIndex", row, 5)); | 6059 | XAttributeIfNotNull("IconIndex", row, 5)); |
6070 | 6060 | ||
6071 | this.IndexElement(row, xProgId); | 6061 | this.DecompilerHelper.IndexElement(row, xProgId); |
6072 | } | 6062 | } |
6073 | 6063 | ||
6074 | // nest the ProgIds | 6064 | // nest the ProgIds |
6075 | foreach (var row in table.Rows) | 6065 | foreach (var row in table.Rows) |
6076 | { | 6066 | { |
6077 | var xProgId = this.GetIndexedElement(row); | 6067 | var xProgId = this.DecompilerHelper.GetIndexedElement(row); |
6078 | 6068 | ||
6079 | if (!row.IsColumnNull(1)) | 6069 | if (!row.IsColumnNull(1)) |
6080 | { | 6070 | { |
@@ -6107,13 +6097,13 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
6107 | case "AllowProductCodeMismatches": | 6097 | case "AllowProductCodeMismatches": |
6108 | if ("1" == value) | 6098 | if ("1" == value) |
6109 | { | 6099 | { |
6110 | this.RootElement.SetAttributeValue("AllowProductCodeMismatches", "yes"); | 6100 | this.DecompilerHelper.RootElement.SetAttributeValue("AllowProductCodeMismatches", "yes"); |
6111 | } | 6101 | } |
6112 | break; | 6102 | break; |
6113 | case "AllowProductVersionMajorMismatches": | 6103 | case "AllowProductVersionMajorMismatches": |
6114 | if ("1" == value) | 6104 | if ("1" == value) |
6115 | { | 6105 | { |
6116 | this.RootElement.SetAttributeValue("AllowMajorVersionMismatches", "yes"); | 6106 | this.DecompilerHelper.RootElement.SetAttributeValue("AllowMajorVersionMismatches", "yes"); |
6117 | } | 6107 | } |
6118 | break; | 6108 | break; |
6119 | case "ApiPatchingSymbolFlags": | 6109 | case "ApiPatchingSymbolFlags": |
@@ -6127,7 +6117,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
6127 | value = value.Substring(2); | 6117 | value = value.Substring(2); |
6128 | } | 6118 | } |
6129 | 6119 | ||
6130 | this.RootElement.SetAttributeValue("SymbolFlags", Convert.ToInt32(value, 16)); | 6120 | this.DecompilerHelper.RootElement.SetAttributeValue("SymbolFlags", Convert.ToInt32(value, 16)); |
6131 | } | 6121 | } |
6132 | catch | 6122 | catch |
6133 | { | 6123 | { |
@@ -6138,13 +6128,13 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
6138 | case "DontRemoveTempFolderWhenFinished": | 6128 | case "DontRemoveTempFolderWhenFinished": |
6139 | if ("1" == value) | 6129 | if ("1" == value) |
6140 | { | 6130 | { |
6141 | this.RootElement.SetAttributeValue("CleanWorkingFolder", "no"); | 6131 | this.DecompilerHelper.RootElement.SetAttributeValue("CleanWorkingFolder", "no"); |
6142 | } | 6132 | } |
6143 | break; | 6133 | break; |
6144 | case "IncludeWholeFilesOnly": | 6134 | case "IncludeWholeFilesOnly": |
6145 | if ("1" == value) | 6135 | if ("1" == value) |
6146 | { | 6136 | { |
6147 | this.RootElement.SetAttributeValue("WholeFilesOnly", "yes"); | 6137 | this.DecompilerHelper.RootElement.SetAttributeValue("WholeFilesOnly", "yes"); |
6148 | } | 6138 | } |
6149 | break; | 6139 | break; |
6150 | case "ListOfPatchGUIDsToReplace": | 6140 | case "ListOfPatchGUIDsToReplace": |
@@ -6158,7 +6148,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
6158 | var xReplacePatch = new XElement(Names.ReplacePatchElement, | 6148 | var xReplacePatch = new XElement(Names.ReplacePatchElement, |
6159 | new XAttribute("Id", guidMatch.Value)); | 6149 | new XAttribute("Id", guidMatch.Value)); |
6160 | 6150 | ||
6161 | this.RootElement.Add(xReplacePatch); | 6151 | this.DecompilerHelper.AddElementToRoot(xReplacePatch); |
6162 | } | 6152 | } |
6163 | } | 6153 | } |
6164 | break; | 6154 | break; |
@@ -6172,25 +6162,25 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
6172 | var xTargetProductCode = new XElement(Names.TargetProductCodeElement, | 6162 | var xTargetProductCode = new XElement(Names.TargetProductCodeElement, |
6173 | new XAttribute("Id", targetProductCodeString)); | 6163 | new XAttribute("Id", targetProductCodeString)); |
6174 | 6164 | ||
6175 | this.RootElement.Add(xTargetProductCode); | 6165 | this.DecompilerHelper.AddElementToRoot(xTargetProductCode); |
6176 | } | 6166 | } |
6177 | } | 6167 | } |
6178 | break; | 6168 | break; |
6179 | case "PatchGUID": | 6169 | case "PatchGUID": |
6180 | this.RootElement.SetAttributeValue("Id", value); | 6170 | this.DecompilerHelper.RootElement.SetAttributeValue("Id", value); |
6181 | break; | 6171 | break; |
6182 | case "PatchSourceList": | 6172 | case "PatchSourceList": |
6183 | this.RootElement.SetAttributeValue("SourceList", value); | 6173 | this.DecompilerHelper.RootElement.SetAttributeValue("SourceList", value); |
6184 | break; | 6174 | break; |
6185 | case "PatchOutputPath": | 6175 | case "PatchOutputPath": |
6186 | this.RootElement.SetAttributeValue("OutputPath", value); | 6176 | this.DecompilerHelper.RootElement.SetAttributeValue("OutputPath", value); |
6187 | break; | 6177 | break; |
6188 | default: | 6178 | default: |
6189 | var patchProperty = new XElement(Names.PatchPropertyElement, | 6179 | var patchProperty = new XElement(Names.PatchPropertyElement, |
6190 | new XAttribute("Name", name), | 6180 | new XAttribute("Name", name), |
6191 | new XAttribute("Value", value)); | 6181 | new XAttribute("Value", value)); |
6192 | 6182 | ||
6193 | this.RootElement.Add(patchProperty); | 6183 | this.DecompilerHelper.AddElementToRoot(patchProperty); |
6194 | break; | 6184 | break; |
6195 | } | 6185 | } |
6196 | } | 6186 | } |
@@ -6260,22 +6250,22 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
6260 | switch (id) | 6250 | switch (id) |
6261 | { | 6251 | { |
6262 | case "Manufacturer": | 6252 | case "Manufacturer": |
6263 | this.RootElement.SetAttributeValue("Manufacturer", value); | 6253 | this.DecompilerHelper.RootElement.SetAttributeValue("Manufacturer", value); |
6264 | continue; | 6254 | continue; |
6265 | case "ProductCode": | 6255 | case "ProductCode": |
6266 | this.RootElement.SetAttributeValue("ProductCode", value.ToUpper(CultureInfo.InvariantCulture)); | 6256 | this.DecompilerHelper.RootElement.SetAttributeValue("ProductCode", value.ToUpper(CultureInfo.InvariantCulture)); |
6267 | continue; | 6257 | continue; |
6268 | case "ProductLanguage": | 6258 | case "ProductLanguage": |
6269 | this.RootElement.SetAttributeValue("Language", value); | 6259 | this.DecompilerHelper.RootElement.SetAttributeValue("Language", value); |
6270 | continue; | 6260 | continue; |
6271 | case "ProductName": | 6261 | case "ProductName": |
6272 | this.RootElement.SetAttributeValue("Name", value); | 6262 | this.DecompilerHelper.RootElement.SetAttributeValue("Name", value); |
6273 | continue; | 6263 | continue; |
6274 | case "ProductVersion": | 6264 | case "ProductVersion": |
6275 | this.RootElement.SetAttributeValue("Version", value); | 6265 | this.DecompilerHelper.RootElement.SetAttributeValue("Version", value); |
6276 | continue; | 6266 | continue; |
6277 | case "UpgradeCode": | 6267 | case "UpgradeCode": |
6278 | this.RootElement.SetAttributeValue("UpgradeCode", value); | 6268 | this.DecompilerHelper.RootElement.SetAttributeValue("UpgradeCode", value); |
6279 | continue; | 6269 | continue; |
6280 | } | 6270 | } |
6281 | } | 6271 | } |
@@ -6340,14 +6330,14 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
6340 | } | 6330 | } |
6341 | } | 6331 | } |
6342 | 6332 | ||
6343 | this.IndexElement(row, radioButton); | 6333 | this.DecompilerHelper.IndexElement(row, radioButton); |
6344 | } | 6334 | } |
6345 | 6335 | ||
6346 | // nest the radio buttons | 6336 | // nest the radio buttons |
6347 | var xRadioButtonGroups = new Dictionary<string, XElement>(); | 6337 | var xRadioButtonGroups = new Dictionary<string, XElement>(); |
6348 | foreach (var row in table.Rows.OrderBy(row => row.FieldAsString(0)).ThenBy(row => row.FieldAsInteger(1))) | 6338 | foreach (var row in table.Rows.OrderBy(row => row.FieldAsString(0)).ThenBy(row => row.FieldAsInteger(1))) |
6349 | { | 6339 | { |
6350 | var xRadioButton = this.GetIndexedElement(row); | 6340 | var xRadioButton = this.DecompilerHelper.GetIndexedElement(row); |
6351 | 6341 | ||
6352 | if (!xRadioButtonGroups.TryGetValue(row.FieldAsString(0), out var xRadioButtonGroup)) | 6342 | if (!xRadioButtonGroups.TryGetValue(row.FieldAsString(0), out var xRadioButtonGroup)) |
6353 | { | 6343 | { |
@@ -6395,7 +6385,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
6395 | break; | 6385 | break; |
6396 | } | 6386 | } |
6397 | 6387 | ||
6398 | this.IndexElement(row, xRegistryKey); | 6388 | this.DecompilerHelper.IndexElement(row, xRegistryKey); |
6399 | } | 6389 | } |
6400 | else | 6390 | else |
6401 | { | 6391 | { |
@@ -6480,7 +6470,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
6480 | xRegistryValue.SetAttributeValue("Value", String.Empty); | 6470 | xRegistryValue.SetAttributeValue("Value", String.Empty); |
6481 | } | 6471 | } |
6482 | 6472 | ||
6483 | this.IndexElement(row, xRegistryValue); | 6473 | this.DecompilerHelper.IndexElement(row, xRegistryValue); |
6484 | } | 6474 | } |
6485 | } | 6475 | } |
6486 | } | 6476 | } |
@@ -6552,7 +6542,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
6552 | } | 6542 | } |
6553 | } | 6543 | } |
6554 | 6544 | ||
6555 | this.IndexElement(row, xRegistrySearch); | 6545 | this.DecompilerHelper.IndexElement(row, xRegistrySearch); |
6556 | } | 6546 | } |
6557 | } | 6547 | } |
6558 | 6548 | ||
@@ -6588,7 +6578,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
6588 | } | 6578 | } |
6589 | 6579 | ||
6590 | this.AddChildToParent("Component", xRemoveFolder, row, 1); | 6580 | this.AddChildToParent("Component", xRemoveFolder, row, 1); |
6591 | this.IndexElement(row, xRemoveFolder); | 6581 | this.DecompilerHelper.IndexElement(row, xRemoveFolder); |
6592 | } | 6582 | } |
6593 | else | 6583 | else |
6594 | { | 6584 | { |
@@ -6625,7 +6615,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
6625 | } | 6615 | } |
6626 | 6616 | ||
6627 | this.AddChildToParent("Component", xRemoveFile, row, 1); | 6617 | this.AddChildToParent("Component", xRemoveFile, row, 1); |
6628 | this.IndexElement(row, xRemoveFile); | 6618 | this.DecompilerHelper.IndexElement(row, xRemoveFile); |
6629 | } | 6619 | } |
6630 | } | 6620 | } |
6631 | } | 6621 | } |
@@ -6738,7 +6728,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
6738 | { | 6728 | { |
6739 | foreach (var row in table.Rows) | 6729 | foreach (var row in table.Rows) |
6740 | { | 6730 | { |
6741 | if (this.TryGetIndexedElement("File", out var xFile, row.FieldAsString(0))) | 6731 | if (this.DecompilerHelper.TryGetIndexedElement("File", row.FieldAsString(0), out var xFile)) |
6742 | { | 6732 | { |
6743 | xFile.SetAttributeValue("SelfRegCost", row.IsColumnNull(1) ? 0 : row.FieldAsInteger(1)); | 6733 | xFile.SetAttributeValue("SelfRegCost", row.IsColumnNull(1) ? 0 : row.FieldAsInteger(1)); |
6744 | } | 6734 | } |
@@ -6927,7 +6917,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
6927 | } | 6917 | } |
6928 | 6918 | ||
6929 | this.AddChildToParent("Component", xServiceInstall, row, 11); | 6919 | this.AddChildToParent("Component", xServiceInstall, row, 11); |
6930 | this.IndexElement(row, xServiceInstall); | 6920 | this.DecompilerHelper.IndexElement(row, xServiceInstall); |
6931 | } | 6921 | } |
6932 | } | 6922 | } |
6933 | 6923 | ||
@@ -6943,17 +6933,17 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
6943 | new XAttribute("Name", row.FieldAsString(0)), | 6933 | new XAttribute("Name", row.FieldAsString(0)), |
6944 | new XAttribute("SourceFile", row.FieldAsString(1))); | 6934 | new XAttribute("SourceFile", row.FieldAsString(1))); |
6945 | 6935 | ||
6946 | this.IndexElement(row, xSfpCatalog); | 6936 | this.DecompilerHelper.IndexElement(row, xSfpCatalog); |
6947 | } | 6937 | } |
6948 | 6938 | ||
6949 | // nest the SFPCatalog elements | 6939 | // nest the SFPCatalog elements |
6950 | foreach (var row in table.Rows) | 6940 | foreach (var row in table.Rows) |
6951 | { | 6941 | { |
6952 | var xSfpCatalog = this.GetIndexedElement(row); | 6942 | var xSfpCatalog = this.DecompilerHelper.GetIndexedElement(row); |
6953 | 6943 | ||
6954 | if (!row.IsColumnNull(2)) | 6944 | if (!row.IsColumnNull(2)) |
6955 | { | 6945 | { |
6956 | if (this.TryGetIndexedElement("SFPCatalog", out var xParentSFPCatalog, row.FieldAsString(2))) | 6946 | if (this.DecompilerHelper.TryGetIndexedElement("SFPCatalog", row.FieldAsString(2), out var xParentSFPCatalog)) |
6957 | { | 6947 | { |
6958 | xParentSFPCatalog.Add(xSfpCatalog); | 6948 | xParentSFPCatalog.Add(xSfpCatalog); |
6959 | } | 6949 | } |
@@ -6961,12 +6951,12 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
6961 | { | 6951 | { |
6962 | xSfpCatalog.SetAttributeValue("Dependency", row.FieldAsString(2)); | 6952 | xSfpCatalog.SetAttributeValue("Dependency", row.FieldAsString(2)); |
6963 | 6953 | ||
6964 | this.RootElement.Add(xSfpCatalog); | 6954 | this.DecompilerHelper.AddElementToRoot(xSfpCatalog); |
6965 | } | 6955 | } |
6966 | } | 6956 | } |
6967 | else | 6957 | else |
6968 | { | 6958 | { |
6969 | this.RootElement.Add(xSfpCatalog); | 6959 | this.DecompilerHelper.AddElementToRoot(xSfpCatalog); |
6970 | } | 6960 | } |
6971 | } | 6961 | } |
6972 | } | 6962 | } |
@@ -7044,7 +7034,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
7044 | } | 7034 | } |
7045 | 7035 | ||
7046 | this.AddChildToParent("Component", xShortcut, row, 3); | 7036 | this.AddChildToParent("Component", xShortcut, row, 3); |
7047 | this.IndexElement(row, xShortcut); | 7037 | this.DecompilerHelper.IndexElement(row, xShortcut); |
7048 | } | 7038 | } |
7049 | } | 7039 | } |
7050 | 7040 | ||
@@ -7093,7 +7083,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
7093 | fileSearch.SetAttributeValue("MaxDate", ConvertIntegerToDateTime(row.FieldAsInteger(7))); | 7083 | fileSearch.SetAttributeValue("MaxDate", ConvertIntegerToDateTime(row.FieldAsInteger(7))); |
7094 | } | 7084 | } |
7095 | 7085 | ||
7096 | this.IndexElement(row, fileSearch); | 7086 | this.DecompilerHelper.IndexElement(row, fileSearch); |
7097 | } | 7087 | } |
7098 | } | 7088 | } |
7099 | 7089 | ||
@@ -7110,7 +7100,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
7110 | xPatchTargetFile = new XElement(Names.TargetFileElement, | 7100 | xPatchTargetFile = new XElement(Names.TargetFileElement, |
7111 | new XAttribute("Id", row.FieldAsString(1))); | 7101 | new XAttribute("Id", row.FieldAsString(1))); |
7112 | 7102 | ||
7113 | if (this.TryGetIndexedElement("TargetImages", out var xTargetImage, row.FieldAsString(0))) | 7103 | if (this.DecompilerHelper.TryGetIndexedElement("TargetImages", row.FieldAsString(0), out var xTargetImage)) |
7114 | { | 7104 | { |
7115 | xTargetImage.Add(xPatchTargetFile); | 7105 | xTargetImage.Add(xPatchTargetFile); |
7116 | } | 7106 | } |
@@ -7192,7 +7182,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
7192 | } | 7182 | } |
7193 | 7183 | ||
7194 | this.AddChildToParent("UpgradedImages", xTargetImage, row, 3); | 7184 | this.AddChildToParent("UpgradedImages", xTargetImage, row, 3); |
7195 | this.IndexElement(row, xTargetImage); | 7185 | this.DecompilerHelper.IndexElement(row, xTargetImage); |
7196 | } | 7186 | } |
7197 | } | 7187 | } |
7198 | 7188 | ||
@@ -7282,7 +7272,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
7282 | } | 7272 | } |
7283 | 7273 | ||
7284 | // nested under the appropriate File element in FinalizeFileTable | 7274 | // nested under the appropriate File element in FinalizeFileTable |
7285 | this.IndexElement(row, xTypeLib); | 7275 | this.DecompilerHelper.IndexElement(row, xTypeLib); |
7286 | } | 7276 | } |
7287 | } | 7277 | } |
7288 | 7278 | ||
@@ -7306,7 +7296,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
7306 | xUpgrade = new XElement(Names.UpgradeElement, | 7296 | xUpgrade = new XElement(Names.UpgradeElement, |
7307 | new XAttribute("Id", upgradeRow.UpgradeCode)); | 7297 | new XAttribute("Id", upgradeRow.UpgradeCode)); |
7308 | 7298 | ||
7309 | this.RootElement.Add(xUpgrade); | 7299 | this.DecompilerHelper.AddElementToRoot(xUpgrade); |
7310 | xUpgrades.Add(upgradeRow.UpgradeCode, xUpgrade); | 7300 | xUpgrades.Add(upgradeRow.UpgradeCode, xUpgrade); |
7311 | } | 7301 | } |
7312 | 7302 | ||
@@ -7435,7 +7425,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
7435 | AddSymbolPaths(row, 3, xUpgradeImage); | 7425 | AddSymbolPaths(row, 3, xUpgradeImage); |
7436 | 7426 | ||
7437 | this.AddChildToParent("ImageFamilies", xUpgradeImage, row, 4); | 7427 | this.AddChildToParent("ImageFamilies", xUpgradeImage, row, 4); |
7438 | this.IndexElement(row, xUpgradeImage); | 7428 | this.DecompilerHelper.IndexElement(row, xUpgradeImage); |
7439 | } | 7429 | } |
7440 | } | 7430 | } |
7441 | 7431 | ||
@@ -7485,7 +7475,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
7485 | XAttributeIfNotNull("Command", row, 3), | 7475 | XAttributeIfNotNull("Command", row, 3), |
7486 | XAttributeIfNotNull("Argument", row, 4)); | 7476 | XAttributeIfNotNull("Argument", row, 4)); |
7487 | 7477 | ||
7488 | this.IndexElement(row, verb); | 7478 | this.DecompilerHelper.IndexElement(row, verb); |
7489 | } | 7479 | } |
7490 | } | 7480 | } |
7491 | 7481 | ||
@@ -7537,7 +7527,7 @@ namespace WixToolset.Core.WindowsInstaller.Decompile | |||
7537 | var featureField = row.Fields[featureColumnIndex]; | 7527 | var featureField = row.Fields[featureColumnIndex]; |
7538 | var componentField = row.Fields[componentColumnIndex]; | 7528 | var componentField = row.Fields[componentColumnIndex]; |
7539 | 7529 | ||
7540 | if (this.TryGetIndexedElement("FeatureComponents", out var xComponentRef, Convert.ToString(featureField.Data), Convert.ToString(componentField.Data))) | 7530 | if (this.DecompilerHelper.TryGetIndexedElement("FeatureComponents", featureField.AsString(), componentField.AsString(), out var xComponentRef)) |
7541 | { | 7531 | { |
7542 | xComponentRef.SetAttributeValue("Primary", "yes"); | 7532 | xComponentRef.SetAttributeValue("Primary", "yes"); |
7543 | } | 7533 | } |
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/ExtensibilityServices/WindowsInstallerDecompilerHelper.cs b/src/wix/WixToolset.Core.WindowsInstaller/ExtensibilityServices/WindowsInstallerDecompilerHelper.cs new file mode 100644 index 00000000..e09270e7 --- /dev/null +++ b/src/wix/WixToolset.Core.WindowsInstaller/ExtensibilityServices/WindowsInstallerDecompilerHelper.cs | |||
@@ -0,0 +1,133 @@ | |||
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 | |||
3 | namespace WixToolset.Core.WindowsInstaller.ExtensibilityServices | ||
4 | { | ||
5 | using System; | ||
6 | using System.Collections.Generic; | ||
7 | using System.Xml.Linq; | ||
8 | using WixToolset.Core.WindowsInstaller.Decompile; | ||
9 | using WixToolset.Data.WindowsInstaller; | ||
10 | using WixToolset.Extensibility.Services; | ||
11 | |||
12 | internal class WindowsInstallerDecompilerHelper : IWindowsInstallerDecompilerHelper | ||
13 | { | ||
14 | public WindowsInstallerDecompilerHelper(IServiceProvider _) | ||
15 | { | ||
16 | } | ||
17 | |||
18 | private Dictionary<string, XElement> IndexedElements { get; } = new Dictionary<string, XElement>(); | ||
19 | |||
20 | #region IWindowsInstallerDecompilerHelper interfaces | ||
21 | |||
22 | public XElement RootElement { get; set; } | ||
23 | |||
24 | public XElement AddElementToRoot(string name, params object[] content) | ||
25 | { | ||
26 | var element = new XElement(Names.WxsNamespace + name, content); | ||
27 | |||
28 | this.RootElement.Add(element); | ||
29 | |||
30 | return element; | ||
31 | } | ||
32 | |||
33 | public XElement AddElementToRoot(XName name, params object[] content) | ||
34 | { | ||
35 | var element = new XElement(name, content); | ||
36 | |||
37 | this.RootElement.Add(element); | ||
38 | |||
39 | return element; | ||
40 | } | ||
41 | |||
42 | public XElement AddElementToRoot(XElement element) | ||
43 | { | ||
44 | this.RootElement.Add(element); | ||
45 | |||
46 | return element; | ||
47 | } | ||
48 | |||
49 | public XElement CreateElement(string name, params object[] content) | ||
50 | { | ||
51 | return new XElement(Names.WxsNamespace + name, content); | ||
52 | } | ||
53 | |||
54 | public XElement GetIndexedElement(Row row) | ||
55 | { | ||
56 | return this.GetIndexedElement(row.TableDefinition.Name, row.GetPrimaryKey()); | ||
57 | } | ||
58 | |||
59 | public XElement GetIndexedElement(string table, string primaryKey) | ||
60 | { | ||
61 | return this.TryGetIndexedElement(table, primaryKey, out var element) ? element : null; | ||
62 | } | ||
63 | |||
64 | public XElement GetIndexedElement(string table, string primaryKey1, string primaryKey2) | ||
65 | { | ||
66 | return this.TryGetIndexedElement(table, primaryKey1, primaryKey2, out var element) ? element : null; | ||
67 | } | ||
68 | |||
69 | public XElement GetIndexedElement(string table, string primaryKey1, string primaryKey2, string primaryKey3) | ||
70 | { | ||
71 | return this.TryGetIndexedElement(table, primaryKey1, primaryKey2, primaryKey3, out var element) ? element : null; | ||
72 | } | ||
73 | |||
74 | public XElement GetIndexedElement(string table, string[] primaryKeys) | ||
75 | { | ||
76 | return this.TryGetIndexedElement(table, primaryKeys, out var element) ? element : null; | ||
77 | } | ||
78 | |||
79 | public void IndexElement(Row row, XElement element) | ||
80 | { | ||
81 | this.IndexElement(row.Table.Name, row.GetPrimaryKey(), element); | ||
82 | } | ||
83 | |||
84 | public void IndexElement(string table, string primaryKey, XElement element) | ||
85 | { | ||
86 | var key = String.Concat(table, ':', primaryKey); | ||
87 | this.IndexedElements.Add(key, element); | ||
88 | } | ||
89 | |||
90 | public void IndexElement(string table, string primaryKey1, string primaryKey2, XElement element) | ||
91 | { | ||
92 | this.IndexElement(table, String.Join("/", primaryKey1, primaryKey2), element); | ||
93 | } | ||
94 | |||
95 | public void IndexElement(string table, string primaryKey1, string primaryKey2, string primaryKey3, XElement element) | ||
96 | { | ||
97 | this.IndexElement(table, String.Join("/", primaryKey1, primaryKey2, primaryKey3), element); | ||
98 | } | ||
99 | |||
100 | public void IndexElement(string table, string[] primaryKeys, XElement element) | ||
101 | { | ||
102 | this.IndexElement(table, String.Join("/", primaryKeys), element); | ||
103 | } | ||
104 | |||
105 | public bool TryGetIndexedElement(Row row, out XElement element) | ||
106 | { | ||
107 | return this.TryGetIndexedElement(row.TableDefinition.Name, row.GetPrimaryKey(), out element); | ||
108 | } | ||
109 | |||
110 | public bool TryGetIndexedElement(string table, string primaryKey, out XElement element) | ||
111 | { | ||
112 | var key = String.Concat(table, ':', primaryKey); | ||
113 | return this.IndexedElements.TryGetValue(key, out element); | ||
114 | } | ||
115 | |||
116 | public bool TryGetIndexedElement(string table, string primaryKey1, string primaryKey2, out XElement element) | ||
117 | { | ||
118 | return this.TryGetIndexedElement(table, String.Join("/", primaryKey1, primaryKey2), out element); | ||
119 | } | ||
120 | |||
121 | public bool TryGetIndexedElement(string table, string primaryKey1, string primaryKey2, string primaryKey3, out XElement element) | ||
122 | { | ||
123 | return this.TryGetIndexedElement(table, String.Join("/", primaryKey1, primaryKey2, primaryKey3), out element); | ||
124 | } | ||
125 | |||
126 | public bool TryGetIndexedElement(string table, string[] primaryKeys, out XElement element) | ||
127 | { | ||
128 | return this.TryGetIndexedElement(table, String.Join("/", primaryKeys), out element); | ||
129 | } | ||
130 | |||
131 | #endregion | ||
132 | } | ||
133 | } | ||
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs index b510690e..c1fb7f12 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs | |||
@@ -171,7 +171,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind | |||
171 | } | 171 | } |
172 | break; | 172 | break; |
173 | case ColumnType.Object: | 173 | case ColumnType.Object: |
174 | var sourceFile = "FILE NOT EXPORTED, USE THE dark.exe -x OPTION TO EXPORT BINARIES"; | 174 | var sourceFile = "FILE NOT EXPORTED"; |
175 | 175 | ||
176 | if (null != this.ExportBasePath) | 176 | if (null != this.ExportBasePath) |
177 | { | 177 | { |
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/WindowsInstallerDecompileContext.cs b/src/wix/WixToolset.Core.WindowsInstaller/WindowsInstallerDecompileContext.cs index 1428a469..22745ab0 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/WindowsInstallerDecompileContext.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/WindowsInstallerDecompileContext.cs | |||
@@ -23,6 +23,10 @@ namespace WixToolset.Core.WindowsInstaller | |||
23 | 23 | ||
24 | public IReadOnlyCollection<IWindowsInstallerDecompilerExtension> Extensions { get; set; } | 24 | public IReadOnlyCollection<IWindowsInstallerDecompilerExtension> Extensions { get; set; } |
25 | 25 | ||
26 | public IReadOnlyCollection<IExtensionData> ExtensionData { get; set; } | ||
27 | |||
28 | public ISymbolDefinitionCreator SymbolDefinitionCreator { get; set; } | ||
29 | |||
26 | public string ExtractFolder { get; set; } | 30 | public string ExtractFolder { get; set; } |
27 | 31 | ||
28 | public string CabinetExtractFolder { get; set; } | 32 | public string CabinetExtractFolder { get; set; } |
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/WindowsInstallerDecompileResult.cs b/src/wix/WixToolset.Core.WindowsInstaller/WindowsInstallerDecompileResult.cs index 69363286..272fb3c2 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/WindowsInstallerDecompileResult.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/WindowsInstallerDecompileResult.cs | |||
@@ -11,7 +11,7 @@ namespace WixToolset.Core.WindowsInstaller | |||
11 | { | 11 | { |
12 | public XDocument Document { get; set; } | 12 | public XDocument Document { get; set; } |
13 | 13 | ||
14 | public IReadOnlyCollection<string> ExtractedFilePaths { get; set; } | 14 | public IList<string> ExtractedFilePaths { get; set; } |
15 | 15 | ||
16 | public Platform? Platform { get; set; } | 16 | public Platform? Platform { get; set; } |
17 | } | 17 | } |
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/WindowsInstallerDecompiler.cs b/src/wix/WixToolset.Core.WindowsInstaller/WindowsInstallerDecompiler.cs index 10420010..b35e3587 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/WindowsInstallerDecompiler.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/WindowsInstallerDecompiler.cs | |||
@@ -3,8 +3,15 @@ | |||
3 | namespace WixToolset.Core.WindowsInstaller | 3 | namespace WixToolset.Core.WindowsInstaller |
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.Collections.Generic; | ||
7 | using System.ComponentModel; | ||
8 | using System.IO; | ||
9 | using System.Linq; | ||
10 | using WixToolset.Core.Native.Msi; | ||
6 | using WixToolset.Core.WindowsInstaller.Decompile; | 11 | using WixToolset.Core.WindowsInstaller.Decompile; |
7 | using WixToolset.Extensibility; | 12 | using WixToolset.Core.WindowsInstaller.Unbind; |
13 | using WixToolset.Data; | ||
14 | using WixToolset.Data.WindowsInstaller; | ||
8 | using WixToolset.Extensibility.Data; | 15 | using WixToolset.Extensibility.Data; |
9 | using WixToolset.Extensibility.Services; | 16 | using WixToolset.Extensibility.Services; |
10 | 17 | ||
@@ -16,12 +23,20 @@ namespace WixToolset.Core.WindowsInstaller | |||
16 | internal WindowsInstallerDecompiler(IServiceProvider serviceProvider) | 23 | internal WindowsInstallerDecompiler(IServiceProvider serviceProvider) |
17 | { | 24 | { |
18 | this.ServiceProvider = serviceProvider; | 25 | this.ServiceProvider = serviceProvider; |
26 | this.Messaging = serviceProvider.GetService<IMessaging>(); | ||
19 | } | 27 | } |
20 | 28 | ||
21 | public IServiceProvider ServiceProvider { get; } | 29 | private IServiceProvider ServiceProvider { get; } |
30 | |||
31 | private IMessaging Messaging { get; } | ||
22 | 32 | ||
23 | public IWindowsInstallerDecompileResult Decompile(IWindowsInstallerDecompileContext context) | 33 | public IWindowsInstallerDecompileResult Decompile(IWindowsInstallerDecompileContext context) |
24 | { | 34 | { |
35 | if (context.SymbolDefinitionCreator == null) | ||
36 | { | ||
37 | context.SymbolDefinitionCreator = this.ServiceProvider.GetService<ISymbolDefinitionCreator>(); | ||
38 | } | ||
39 | |||
25 | // Pre-decompile. | 40 | // Pre-decompile. |
26 | // | 41 | // |
27 | foreach (var extension in context.Extensions) | 42 | foreach (var extension in context.Extensions) |
@@ -31,8 +46,7 @@ namespace WixToolset.Core.WindowsInstaller | |||
31 | 46 | ||
32 | // Decompile. | 47 | // Decompile. |
33 | // | 48 | // |
34 | var command = new DecompileMsiOrMsmCommand(context); | 49 | var result = this.Execute(context); |
35 | var result = command.Execute(); | ||
36 | 50 | ||
37 | if (result != null) | 51 | if (result != null) |
38 | { | 52 | { |
@@ -46,5 +60,68 @@ namespace WixToolset.Core.WindowsInstaller | |||
46 | 60 | ||
47 | return result; | 61 | return result; |
48 | } | 62 | } |
63 | |||
64 | private IWindowsInstallerDecompileResult Execute(IWindowsInstallerDecompileContext context) | ||
65 | { | ||
66 | var result = context.ServiceProvider.GetService<IWindowsInstallerDecompileResult>(); | ||
67 | |||
68 | try | ||
69 | { | ||
70 | using (var database = new Database(context.DecompilePath, OpenDatabase.ReadOnly)) | ||
71 | { | ||
72 | // Delete the directory and its files to prevent cab extraction failure due to an existing file. | ||
73 | if (Directory.Exists(context.ExtractFolder)) | ||
74 | { | ||
75 | Directory.Delete(context.ExtractFolder, true); | ||
76 | } | ||
77 | |||
78 | var backendHelper = context.ServiceProvider.GetService<IWindowsInstallerBackendHelper>(); | ||
79 | var decompilerHelper = context.ServiceProvider.GetService<IWindowsInstallerDecompilerHelper>(); | ||
80 | |||
81 | var unbindCommand = new UnbindDatabaseCommand(this.Messaging, backendHelper, database, context.DecompilePath, context.DecompileType, context.ExtractFolder, context.IntermediateFolder, context.IsAdminImage, suppressDemodularization: false, skipSummaryInfo: false); | ||
82 | var output = unbindCommand.Execute(); | ||
83 | var extractedFilePaths = new List<string>(unbindCommand.ExportedFiles); | ||
84 | |||
85 | var decompiler = new Decompiler(this.Messaging, backendHelper, decompilerHelper, context.Extensions, context.ExtensionData, context.SymbolDefinitionCreator, context.BaseSourcePath, context.SuppressCustomTables, context.SuppressDroppingEmptyTables, context.SuppressRelativeActionSequencing, context.SuppressUI, context.TreatProductAsModule); | ||
86 | result.Document = decompiler.Decompile(output); | ||
87 | |||
88 | result.Platform = GetPlatformFromOutput(output); | ||
89 | |||
90 | // extract the files from the cabinets | ||
91 | if (!String.IsNullOrEmpty(context.ExtractFolder) && !context.SuppressExtractCabinets) | ||
92 | { | ||
93 | var fileDirectory = String.IsNullOrEmpty(context.CabinetExtractFolder) ? Path.Combine(context.ExtractFolder, "File") : context.CabinetExtractFolder; | ||
94 | |||
95 | var extractCommand = new ExtractCabinetsCommand(output, database, context.DecompilePath, fileDirectory, context.IntermediateFolder, context.TreatProductAsModule); | ||
96 | extractCommand.Execute(); | ||
97 | |||
98 | extractedFilePaths.AddRange(extractCommand.ExtractedFiles); | ||
99 | result.ExtractedFilePaths = extractedFilePaths; | ||
100 | } | ||
101 | else | ||
102 | { | ||
103 | result.ExtractedFilePaths = new string[0]; | ||
104 | } | ||
105 | } | ||
106 | } | ||
107 | catch (Win32Exception e) | ||
108 | { | ||
109 | if (0x6E == e.NativeErrorCode) // ERROR_OPEN_FAILED | ||
110 | { | ||
111 | throw new WixException(ErrorMessages.OpenDatabaseFailed(context.DecompilePath)); | ||
112 | } | ||
113 | |||
114 | throw; | ||
115 | } | ||
116 | |||
117 | return result; | ||
118 | } | ||
119 | |||
120 | private static Platform? GetPlatformFromOutput(WindowsInstallerData output) | ||
121 | { | ||
122 | var template = output.Tables["_SummaryInformation"]?.Rows.SingleOrDefault(row => row.FieldAsInteger(0) == 7)?.FieldAsString(1); | ||
123 | |||
124 | return Decompiler.GetPlatformFromTemplateSummaryInformation(template?.Split(';')); | ||
125 | } | ||
49 | } | 126 | } |
50 | } | 127 | } |
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/WixToolsetCoreServiceProviderExtensions.cs b/src/wix/WixToolset.Core.WindowsInstaller/WixToolsetCoreServiceProviderExtensions.cs index d064aed1..c085af9b 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/WixToolsetCoreServiceProviderExtensions.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/WixToolsetCoreServiceProviderExtensions.cs | |||
@@ -16,8 +16,8 @@ namespace WixToolset.Core.WindowsInstaller | |||
16 | /// <summary> | 16 | /// <summary> |
17 | /// Adds WindowsInstaller services. | 17 | /// Adds WindowsInstaller services. |
18 | /// </summary> | 18 | /// </summary> |
19 | /// <param name="coreProvider"></param> | 19 | /// <param name="coreProvider">Core service provider.</param> |
20 | /// <returns></returns> | 20 | /// <returns>The core service provider provided to this method.</returns> |
21 | public static IWixToolsetCoreServiceProvider AddWindowsInstallerBackend(this IWixToolsetCoreServiceProvider coreProvider) | 21 | public static IWixToolsetCoreServiceProvider AddWindowsInstallerBackend(this IWixToolsetCoreServiceProvider coreProvider) |
22 | { | 22 | { |
23 | AddServices(coreProvider); | 23 | AddServices(coreProvider); |
@@ -32,6 +32,7 @@ namespace WixToolset.Core.WindowsInstaller | |||
32 | { | 32 | { |
33 | // Singletons. | 33 | // Singletons. |
34 | coreProvider.AddService((provider, singletons) => AddSingleton<IWindowsInstallerBackendHelper>(singletons, new WindowsInstallerBackendHelper(provider))); | 34 | coreProvider.AddService((provider, singletons) => AddSingleton<IWindowsInstallerBackendHelper>(singletons, new WindowsInstallerBackendHelper(provider))); |
35 | coreProvider.AddService((provider, singletons) => AddSingleton<IWindowsInstallerDecompilerHelper>(singletons, new WindowsInstallerDecompilerHelper(provider))); | ||
35 | 36 | ||
36 | // Transients. | 37 | // Transients. |
37 | coreProvider.AddService<IWindowsInstallerDecompiler>((provider, singletons) => new WindowsInstallerDecompiler(provider)); | 38 | coreProvider.AddService<IWindowsInstallerDecompiler>((provider, singletons) => new WindowsInstallerDecompiler(provider)); |
diff --git a/src/wix/test/Example.Extension/ExampleCompilerExtension.cs b/src/wix/test/Example.Extension/ExampleCompilerExtension.cs index 5b8d4b3f..b68a87f1 100644 --- a/src/wix/test/Example.Extension/ExampleCompilerExtension.cs +++ b/src/wix/test/Example.Extension/ExampleCompilerExtension.cs | |||
@@ -10,8 +10,9 @@ namespace Example.Extension | |||
10 | 10 | ||
11 | internal class ExampleCompilerExtension : BaseCompilerExtension | 11 | internal class ExampleCompilerExtension : BaseCompilerExtension |
12 | { | 12 | { |
13 | public override XNamespace Namespace => "http://www.example.com/scheams/v1/wxs"; | 13 | private const string BundleExtensionId = "ExampleBundleExtension"; |
14 | public string BundleExtensionId => "ExampleBundleExtension"; | 14 | |
15 | public override XNamespace Namespace => ExampleConstants.Namespace; | ||
15 | 16 | ||
16 | public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context) | 17 | public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context) |
17 | { | 18 | { |
@@ -38,10 +39,12 @@ namespace Example.Extension | |||
38 | } | 39 | } |
39 | break; | 40 | break; |
40 | case "Component": | 41 | case "Component": |
42 | var componentId = context["ComponentId"]; | ||
43 | |||
41 | switch (element.Name.LocalName) | 44 | switch (element.Name.LocalName) |
42 | { | 45 | { |
43 | case "Example": | 46 | case "Example": |
44 | this.ParseExampleElement(intermediate, section, element); | 47 | this.ParseExampleElement(intermediate, section, element, componentId); |
45 | processed = true; | 48 | processed = true; |
46 | break; | 49 | break; |
47 | } | 50 | } |
@@ -54,7 +57,7 @@ namespace Example.Extension | |||
54 | } | 57 | } |
55 | } | 58 | } |
56 | 59 | ||
57 | private void ParseExampleElement(Intermediate intermediate, IntermediateSection section, XElement element) | 60 | private void ParseExampleElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId) |
58 | { | 61 | { |
59 | var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); | 62 | var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); |
60 | Identifier id = null; | 63 | Identifier id = null; |
@@ -93,7 +96,8 @@ namespace Example.Extension | |||
93 | if (!this.Messaging.EncounteredError) | 96 | if (!this.Messaging.EncounteredError) |
94 | { | 97 | { |
95 | var symbol = this.ParseHelper.CreateSymbol(section, sourceLineNumbers, "Example", id); | 98 | var symbol = this.ParseHelper.CreateSymbol(section, sourceLineNumbers, "Example", id); |
96 | symbol.Set(0, value); | 99 | symbol.Set(0, componentId); |
100 | symbol.Set(1, value); | ||
97 | } | 101 | } |
98 | } | 102 | } |
99 | 103 | ||
@@ -152,12 +156,12 @@ namespace Example.Extension | |||
152 | 156 | ||
153 | if (!this.Messaging.EncounteredError) | 157 | if (!this.Messaging.EncounteredError) |
154 | { | 158 | { |
155 | this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, this.BundleExtensionId); | 159 | this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, BundleExtensionId); |
156 | } | 160 | } |
157 | 161 | ||
158 | if (!this.Messaging.EncounteredError) | 162 | if (!this.Messaging.EncounteredError) |
159 | { | 163 | { |
160 | var symbol = section.AddSymbol(new ExampleSearchSymbol(sourceLineNumbers, id) | 164 | section.AddSymbol(new ExampleSearchSymbol(sourceLineNumbers, id) |
161 | { | 165 | { |
162 | SearchFor = searchFor, | 166 | SearchFor = searchFor, |
163 | }); | 167 | }); |
diff --git a/src/wix/test/Example.Extension/ExampleConstants.cs b/src/wix/test/Example.Extension/ExampleConstants.cs new file mode 100644 index 00000000..abed40ea --- /dev/null +++ b/src/wix/test/Example.Extension/ExampleConstants.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 | |||
3 | namespace Example.Extension | ||
4 | { | ||
5 | using System.Xml.Linq; | ||
6 | |||
7 | internal class ExampleConstants | ||
8 | { | ||
9 | public static readonly XNamespace Namespace = "http://www.example.com/scheams/v1/wxs"; | ||
10 | |||
11 | public static readonly XName ExampleName = Namespace + "Example"; | ||
12 | } | ||
13 | } | ||
diff --git a/src/wix/test/Example.Extension/ExampleExtensionFactory.cs b/src/wix/test/Example.Extension/ExampleExtensionFactory.cs index e54561ee..0b0fb836 100644 --- a/src/wix/test/Example.Extension/ExampleExtensionFactory.cs +++ b/src/wix/test/Example.Extension/ExampleExtensionFactory.cs | |||
@@ -43,6 +43,10 @@ namespace Example.Extension | |||
43 | { | 43 | { |
44 | extension = new ExampleWindowsInstallerBackendExtension(); | 44 | extension = new ExampleWindowsInstallerBackendExtension(); |
45 | } | 45 | } |
46 | else if (extensionType == typeof(IWindowsInstallerDecompilerExtension)) | ||
47 | { | ||
48 | extension = new ExampleWindowsInstallerDecompilerExtension(); | ||
49 | } | ||
46 | else | 50 | else |
47 | { | 51 | { |
48 | extension = null; | 52 | extension = null; |
diff --git a/src/wix/test/Example.Extension/ExampleRow.cs b/src/wix/test/Example.Extension/ExampleRow.cs index fc20c6c9..5c96035d 100644 --- a/src/wix/test/Example.Extension/ExampleRow.cs +++ b/src/wix/test/Example.Extension/ExampleRow.cs | |||
@@ -23,10 +23,16 @@ namespace Example.Extension | |||
23 | set { this.Fields[0].Data = value; } | 23 | set { this.Fields[0].Data = value; } |
24 | } | 24 | } |
25 | 25 | ||
26 | public string Value | 26 | public string ComponentRef |
27 | { | 27 | { |
28 | get { return (string)this.Fields[1].Data; } | 28 | get { return (string)this.Fields[1].Data; } |
29 | set { this.Fields[1].Data = value; } | 29 | set { this.Fields[1].Data = value; } |
30 | } | 30 | } |
31 | |||
32 | public string Value | ||
33 | { | ||
34 | get { return (string)this.Fields[2].Data; } | ||
35 | set { this.Fields[2].Data = value; } | ||
36 | } | ||
31 | } | 37 | } |
32 | } | 38 | } |
diff --git a/src/wix/test/Example.Extension/ExampleSymbol.cs b/src/wix/test/Example.Extension/ExampleSymbol.cs index 314087e9..f82d9604 100644 --- a/src/wix/test/Example.Extension/ExampleSymbol.cs +++ b/src/wix/test/Example.Extension/ExampleSymbol.cs | |||
@@ -6,6 +6,7 @@ namespace Example.Extension | |||
6 | 6 | ||
7 | public enum ExampleSymbolFields | 7 | public enum ExampleSymbolFields |
8 | { | 8 | { |
9 | ComponentRef, | ||
9 | Value, | 10 | Value, |
10 | } | 11 | } |
11 | 12 | ||
@@ -21,6 +22,12 @@ namespace Example.Extension | |||
21 | 22 | ||
22 | public IntermediateField this[ExampleSymbolFields index] => this.Fields[(int)index]; | 23 | public IntermediateField this[ExampleSymbolFields index] => this.Fields[(int)index]; |
23 | 24 | ||
25 | public string ComponentRef | ||
26 | { | ||
27 | get => this.Fields[(int)ExampleSymbolFields.ComponentRef]?.AsString(); | ||
28 | set => this.Set((int)ExampleSymbolFields.ComponentRef, value); | ||
29 | } | ||
30 | |||
24 | public string Value | 31 | public string Value |
25 | { | 32 | { |
26 | get => this.Fields[(int)ExampleSymbolFields.Value]?.AsString(); | 33 | get => this.Fields[(int)ExampleSymbolFields.Value]?.AsString(); |
diff --git a/src/wix/test/Example.Extension/ExampleSymbolDefinitions.cs b/src/wix/test/Example.Extension/ExampleSymbolDefinitions.cs index f13d716d..83b675c9 100644 --- a/src/wix/test/Example.Extension/ExampleSymbolDefinitions.cs +++ b/src/wix/test/Example.Extension/ExampleSymbolDefinitions.cs | |||
@@ -18,6 +18,7 @@ namespace Example.Extension | |||
18 | ExampleSymbolDefinitionType.Example.ToString(), | 18 | ExampleSymbolDefinitionType.Example.ToString(), |
19 | new[] | 19 | new[] |
20 | { | 20 | { |
21 | new IntermediateFieldDefinition(nameof(ExampleSymbolFields.ComponentRef), IntermediateFieldType.String), | ||
21 | new IntermediateFieldDefinition(nameof(ExampleSymbolFields.Value), IntermediateFieldType.String), | 22 | new IntermediateFieldDefinition(nameof(ExampleSymbolFields.Value), IntermediateFieldType.String), |
22 | }, | 23 | }, |
23 | typeof(ExampleSymbol)); | 24 | typeof(ExampleSymbol)); |
diff --git a/src/wix/test/Example.Extension/ExampleTableDefinitions.cs b/src/wix/test/Example.Extension/ExampleTableDefinitions.cs index a2b81698..3da30609 100644 --- a/src/wix/test/Example.Extension/ExampleTableDefinitions.cs +++ b/src/wix/test/Example.Extension/ExampleTableDefinitions.cs | |||
@@ -11,7 +11,8 @@ namespace Example.Extension | |||
11 | ExampleSymbolDefinitions.Example, | 11 | ExampleSymbolDefinitions.Example, |
12 | new[] | 12 | new[] |
13 | { | 13 | { |
14 | new ColumnDefinition("Example", ColumnType.String, 72, true, false, ColumnCategory.Identifier), | 14 | new ColumnDefinition("Example", ColumnType.String, 72, true, false, ColumnCategory.Identifier, modularizeType: ColumnModularizeType.Column), |
15 | new ColumnDefinition("Component_", ColumnType.String, 72, false, false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, modularizeType: ColumnModularizeType.Column), | ||
15 | new ColumnDefinition("Value", ColumnType.String, 0, false, false, ColumnCategory.Formatted), | 16 | new ColumnDefinition("Value", ColumnType.String, 0, false, false, ColumnCategory.Formatted), |
16 | }, | 17 | }, |
17 | strongRowType: typeof(ExampleRow), | 18 | strongRowType: typeof(ExampleRow), |
diff --git a/src/wix/test/Example.Extension/ExampleWindowsInstallerBackendExtension.cs b/src/wix/test/Example.Extension/ExampleWindowsInstallerBackendExtension.cs index afccc56f..95d82875 100644 --- a/src/wix/test/Example.Extension/ExampleWindowsInstallerBackendExtension.cs +++ b/src/wix/test/Example.Extension/ExampleWindowsInstallerBackendExtension.cs | |||
@@ -18,12 +18,13 @@ namespace Example.Extension | |||
18 | switch (symbolType) | 18 | switch (symbolType) |
19 | { | 19 | { |
20 | case ExampleSymbolDefinitionType.Example: | 20 | case ExampleSymbolDefinitionType.Example: |
21 | { | 21 | { |
22 | var row = (ExampleRow)this.BackendHelper.CreateRow(section, symbol, output, ExampleTableDefinitions.ExampleTable); | 22 | var row = (ExampleRow)this.BackendHelper.CreateRow(section, symbol, output, ExampleTableDefinitions.ExampleTable); |
23 | row.Example = symbol.Id.Id; | 23 | row.Example = symbol.Id.Id; |
24 | row.Value = symbol[0].AsString(); | 24 | row.ComponentRef = symbol[0].AsString(); |
25 | } | 25 | row.Value = symbol[1].AsString(); |
26 | return true; | 26 | return true; |
27 | } | ||
27 | } | 28 | } |
28 | } | 29 | } |
29 | 30 | ||
diff --git a/src/wix/test/Example.Extension/ExampleWindowsInstallerDecompilerExtension.cs b/src/wix/test/Example.Extension/ExampleWindowsInstallerDecompilerExtension.cs new file mode 100644 index 00000000..dc671e82 --- /dev/null +++ b/src/wix/test/Example.Extension/ExampleWindowsInstallerDecompilerExtension.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 | |||
3 | namespace Example.Extension | ||
4 | { | ||
5 | using System; | ||
6 | using System.Collections.Generic; | ||
7 | using System.Xml.Linq; | ||
8 | using WixToolset.Data.WindowsInstaller; | ||
9 | using WixToolset.Extensibility; | ||
10 | |||
11 | internal class ExampleWindowsInstallerDecompilerExtension : BaseWindowsInstallerDecompilerExtension | ||
12 | { | ||
13 | public override IReadOnlyCollection<TableDefinition> TableDefinitions => ExampleTableDefinitions.All; | ||
14 | |||
15 | public override bool TryDecompileTable(Table table) | ||
16 | { | ||
17 | switch (table.Name) | ||
18 | { | ||
19 | case "Wix4Example": | ||
20 | this.ProcessExampleTable(table); | ||
21 | return true; | ||
22 | } | ||
23 | |||
24 | return false; | ||
25 | } | ||
26 | |||
27 | private void ProcessExampleTable(Table table) | ||
28 | { | ||
29 | foreach (var row in table.Rows) | ||
30 | { | ||
31 | var componentId = row.FieldAsString(1); | ||
32 | if (this.DecompilerHelper.TryGetIndexedElement("Component", componentId, out var component)) | ||
33 | { | ||
34 | component.Add(new XElement(ExampleConstants.ExampleName, | ||
35 | new XAttribute("Id", row.FieldAsString(0)), | ||
36 | new XAttribute("Value", row.FieldAsString(2)) | ||
37 | )); | ||
38 | } | ||
39 | } | ||
40 | } | ||
41 | } | ||
42 | } | ||
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/ExtensionFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/ExtensionFixture.cs index d814000c..a5155069 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/ExtensionFixture.cs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/ExtensionFixture.cs | |||
@@ -5,6 +5,7 @@ namespace WixToolsetTest.CoreIntegration | |||
5 | using System; | 5 | using System; |
6 | using System.IO; | 6 | using System.IO; |
7 | using System.Linq; | 7 | using System.Linq; |
8 | using System.Text.RegularExpressions; | ||
8 | using Example.Extension; | 9 | using Example.Extension; |
9 | using WixBuildTools.TestSupport; | 10 | using WixBuildTools.TestSupport; |
10 | using WixToolset.Core.TestPackage; | 11 | using WixToolset.Core.TestPackage; |
@@ -23,11 +24,38 @@ namespace WixToolsetTest.CoreIntegration | |||
23 | var results = build.BuildAndQuery(Build, "Wix4Example"); | 24 | var results = build.BuildAndQuery(Build, "Wix4Example"); |
24 | WixAssert.CompareLineByLine(new[] | 25 | WixAssert.CompareLineByLine(new[] |
25 | { | 26 | { |
26 | "Wix4Example:Foo\tBar" | 27 | "Wix4Example:Foo\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo\tBar" |
27 | }, results); | 28 | }, results); |
28 | } | 29 | } |
29 | 30 | ||
30 | [Fact] | 31 | [Fact] |
32 | public void CanRoundtripExampleExtension() | ||
33 | { | ||
34 | var folder = TestData.Get(@"TestData", "ExampleExtension"); | ||
35 | var expectedOutputPath = Path.Combine(folder, "Decompiled-Expected.xml"); | ||
36 | |||
37 | var build = new Builder(folder, typeof(ExampleExtensionFactory), new[] { Path.Combine(folder, "data") }); | ||
38 | using (var fs = new DisposableFileSystem()) | ||
39 | { | ||
40 | var decompileFolder = fs.GetFolder(); | ||
41 | var actualOutputPath = Path.Combine(decompileFolder, "decompiled.xml"); | ||
42 | |||
43 | build.BuildAndDecompileAndBuild(Build, Decompile, actualOutputPath); | ||
44 | |||
45 | var expected = File.ReadAllLines(expectedOutputPath); | ||
46 | var actual = File.ReadAllLines(actualOutputPath).Select(ReplaceGuids).ToArray(); ; | ||
47 | WixAssert.CompareLineByLine(expected, actual); | ||
48 | } | ||
49 | } | ||
50 | |||
51 | private static string ReplaceGuids(string value) | ||
52 | { | ||
53 | value = String.IsNullOrWhiteSpace(value) ? value : Regex.Replace(value, @" ProductCode=\""\{[a-fA-F0-9\-]+\}\""", " ProductCode=\"{GUID}\""); | ||
54 | return String.IsNullOrWhiteSpace(value) ? value : Regex.Replace(value, @" Guid=\""\{[a-fA-F0-9\-]+\}\""", " Guid=\"{GUID}\""); | ||
55 | |||
56 | } | ||
57 | |||
58 | [Fact] | ||
31 | public void CanBuildWithExampleExtension() | 59 | public void CanBuildWithExampleExtension() |
32 | { | 60 | { |
33 | var folder = TestData.Get(@"TestData\ExampleExtension"); | 61 | var folder = TestData.Get(@"TestData\ExampleExtension"); |
@@ -64,7 +92,8 @@ namespace WixToolsetTest.CoreIntegration | |||
64 | 92 | ||
65 | var example = section.Symbols.Where(t => t.Definition.Type == SymbolDefinitionType.MustBeFromAnExtension).Single(); | 93 | var example = section.Symbols.Where(t => t.Definition.Type == SymbolDefinitionType.MustBeFromAnExtension).Single(); |
66 | Assert.Equal("Foo", example.Id?.Id); | 94 | Assert.Equal("Foo", example.Id?.Id); |
67 | Assert.Equal("Bar", example[0].AsString()); | 95 | Assert.Equal("filF5_pLhBuF5b4N9XEo52g_hUM5Lo", example[0].AsString()); |
96 | Assert.Equal("Bar", example[1].AsString()); | ||
68 | } | 97 | } |
69 | } | 98 | } |
70 | 99 | ||
@@ -192,8 +221,14 @@ namespace WixToolsetTest.CoreIntegration | |||
192 | 221 | ||
193 | private static void Build(string[] args) | 222 | private static void Build(string[] args) |
194 | { | 223 | { |
195 | var result = WixRunner.Execute(args) | 224 | var result = WixRunner.Execute(args); |
196 | .AssertSuccess(); | 225 | result.AssertSuccess(); |
226 | } | ||
227 | |||
228 | private static void Decompile(string[] args) | ||
229 | { | ||
230 | var result = WixRunner.Execute(args); | ||
231 | result.AssertSuccess(); | ||
197 | } | 232 | } |
198 | } | 233 | } |
199 | } | 234 | } |
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/AppSearch/DecompiledNestedDirSearchUnderRegSearch.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/AppSearch/DecompiledNestedDirSearchUnderRegSearch.wxs index 6b9fe013..9e72390a 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/AppSearch/DecompiledNestedDirSearchUnderRegSearch.wxs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/AppSearch/DecompiledNestedDirSearchUnderRegSearch.wxs | |||
@@ -1,9 +1,9 @@ | |||
1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | 1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> |
2 | <Package Codepage="1252" Language="1033" Manufacturer="Example Corporation" Name="MsiPackage" UpgradeCode="{12E4699F-E774-4D05-8A01-5BDD41BBA127}" Version="1.0.0.0" ProductCode="{33C58183-7333-4257-AEFD-6705DA66E617}"> | 2 | <Package Codepage="1252" Language="1033" Manufacturer="Example Corporation" Name="MsiPackage" UpgradeCode="{12E4699F-E774-4D05-8A01-5BDD41BBA127}" Version="1.0.0.0" ProductCode="{33C58183-7333-4257-AEFD-6705DA66E617}" Compressed="no"> |
3 | <StandardDirectory Id="ProgramFilesFolder"> | 3 | <StandardDirectory Id="ProgramFilesFolder"> |
4 | <Directory Id="INSTALLFOLDER" Name="MsiPackage" ShortName="ykd0udtb"> | 4 | <Directory Id="INSTALLFOLDER" Name="MsiPackage" ShortName="ykd0udtb"> |
5 | <Component Id="test.txt" Guid="{E597A58A-03CB-50D8-93E3-DABA263F233A}" Bitness="always32"> | 5 | <Component Id="test.txt" Guid="{E597A58A-03CB-50D8-93E3-DABA263F233A}" Bitness="always32"> |
6 | <File Id="test.txt" Name="test.txt" KeyPath="yes" Source="MsiPackage\test.txt" /> | 6 | <File Id="test.txt" Name="test.txt" KeyPath="yes" Source="PFiles\MsiPackage\test.txt" /> |
7 | </Component> | 7 | </Component> |
8 | </Directory> | 8 | </Directory> |
9 | </StandardDirectory> | 9 | </StandardDirectory> |
@@ -39,4 +39,4 @@ | |||
39 | </RegistrySearch> | 39 | </RegistrySearch> |
40 | </Property> | 40 | </Property> |
41 | </Package> | 41 | </Package> |
42 | </Wix> \ No newline at end of file | 42 | </Wix> |
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Class/DecompiledOldClassTableDef.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Class/DecompiledOldClassTableDef.wxs index 514f9243..0f4d0678 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Class/DecompiledOldClassTableDef.wxs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Class/DecompiledOldClassTableDef.wxs | |||
@@ -1,12 +1,12 @@ | |||
1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | 1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> |
2 | <Package Codepage="1252" Language="1033" Manufacturer="Example Corporation" Name="MsiPackage" UpgradeCode="{12E4699F-E774-4D05-8A01-5BDD41BBA127}" Version="1.0.0.0" ProductCode="{FE17A505-11A9-44D2-8D94-EB6BEAB8FF93}"> | 2 | <Package Codepage="1252" Language="1033" Manufacturer="Example Corporation" Name="MsiPackage" UpgradeCode="{12E4699F-E774-4D05-8A01-5BDD41BBA127}" Version="1.0.0.0" ProductCode="{FE17A505-11A9-44D2-8D94-EB6BEAB8FF93}" Compressed="no"> |
3 | <StandardDirectory Id="ProgramFilesFolder"> | 3 | <StandardDirectory Id="ProgramFilesFolder"> |
4 | <Directory Id="INSTALLFOLDER" Name="MsiPackage" ShortName="oekcr5lq"> | 4 | <Directory Id="INSTALLFOLDER" Name="MsiPackage" ShortName="oekcr5lq"> |
5 | <Component Id="ProgIdComp" Guid="{5B3B3FC1-533D-4C29-BFB3-0E88B51E59D8}" Bitness="always32"> | 5 | <Component Id="ProgIdComp" Guid="{5B3B3FC1-533D-4C29-BFB3-0E88B51E59D8}" Bitness="always32"> |
6 | <Class Id="{F12A6F69-117F-471F-AE73-F8E74218F498}" Context="LocalServer32" Description="FakeClassF12A" Advertise="yes"> | 6 | <Class Id="{F12A6F69-117F-471F-AE73-F8E74218F498}" Context="LocalServer32" Description="FakeClassF12A" Advertise="yes"> |
7 | <ProgId Id="73E7DF7E-EFAC-4E11-90E2-6EBAEB8DE58D" Description="FakeClassF12A" Advertise="yes" /> | 7 | <ProgId Id="73E7DF7E-EFAC-4E11-90E2-6EBAEB8DE58D" Description="FakeClassF12A" Advertise="yes" /> |
8 | </Class> | 8 | </Class> |
9 | <File Id="filTki4JQ2gSapF7wK4K1vd.4mDSFQ" Name="ProgIdComp.txt" KeyPath="yes" ShortName="bnvvntsc.txt" Source="MsiPackage\ProgIdComp.txt" /> | 9 | <File Id="filTki4JQ2gSapF7wK4K1vd.4mDSFQ" Name="ProgIdComp.txt" KeyPath="yes" ShortName="bnvvntsc.txt" Source="PFiles\MsiPackage\ProgIdComp.txt" /> |
10 | <RegistryValue Id="regUIIK326nDZpkWHuexeF58EikQvA" Root="HKCR" Key="73E7DF7E-EFAC-4E11-90E2-6EBAEB8DE58D" Name="NoOpen" Value="NoOpen73E7" Type="string" /> | 10 | <RegistryValue Id="regUIIK326nDZpkWHuexeF58EikQvA" Root="HKCR" Key="73E7DF7E-EFAC-4E11-90E2-6EBAEB8DE58D" Name="NoOpen" Value="NoOpen73E7" Type="string" /> |
11 | <RegistryValue Id="regY1F4E2lvu_Up6gV6c3jeN5ukn8s" Root="HKCR" Key="CLSID\{F12A6F69-117F-471F-AE73-F8E74218F498}\LocalServer32" Name="ThreadingModel" Value="Apartment" Type="string" /> | 11 | <RegistryValue Id="regY1F4E2lvu_Up6gV6c3jeN5ukn8s" Root="HKCR" Key="CLSID\{F12A6F69-117F-471F-AE73-F8E74218F498}\LocalServer32" Name="ThreadingModel" Value="Apartment" Type="string" /> |
12 | <RegistryValue Id="regvrhMurMp98anbQJkpgA8yJCefdM" Root="HKCR" Key="CLSID\{F12A6F69-117F-471F-AE73-F8E74218F498}\Version" Value="0.0.0.1" Type="string" /> | 12 | <RegistryValue Id="regvrhMurMp98anbQJkpgA8yJCefdM" Root="HKCR" Key="CLSID\{F12A6F69-117F-471F-AE73-F8E74218F498}\Version" Value="0.0.0.1" Type="string" /> |
@@ -19,4 +19,4 @@ | |||
19 | <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." /> | 19 | <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." /> |
20 | <Media Id="1" /> | 20 | <Media Id="1" /> |
21 | </Package> | 21 | </Package> |
22 | </Wix> \ No newline at end of file | 22 | </Wix> |
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/CustomTable/CustomTable-Expected.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/CustomTable/CustomTable-Expected.wxs index d7d86008..fdcc3438 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/CustomTable/CustomTable-Expected.wxs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/CustomTable/CustomTable-Expected.wxs | |||
@@ -1,5 +1,5 @@ | |||
1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | 1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> |
2 | <Package Codepage="1252" Language="1033" Manufacturer="Example Corporation" Name="MsiPackage" UpgradeCode="{12E4699F-E774-4D05-8A01-5BDD41BBA127}" Version="1.0.0.0" ProductCode="{83F9C623-26FE-42AB-951E-170022117F54}"> | 2 | <Package Codepage="1252" Language="1033" Manufacturer="Example Corporation" Name="MsiPackage" UpgradeCode="{12E4699F-E774-4D05-8A01-5BDD41BBA127}" Version="1.0.0.0" ProductCode="{83F9C623-26FE-42AB-951E-170022117F54}" Compressed="no"> |
3 | <CustomTable Id="CustomTable1"> | 3 | <CustomTable Id="CustomTable1"> |
4 | <Column Id="Column1" PrimaryKey="yes" Type="string" Width="0" Category="text" Description="The first custom column." /> | 4 | <Column Id="Column1" PrimaryKey="yes" Type="string" Width="0" Category="text" Description="The first custom column." /> |
5 | <Column Id="Component_" Type="string" Width="72" KeyTable="Component" KeyColumn="1" Description="The custom table's Component reference" /> | 5 | <Column Id="Component_" Type="string" Width="72" KeyTable="Component" KeyColumn="1" Description="The custom table's Component reference" /> |
@@ -15,7 +15,7 @@ | |||
15 | <StandardDirectory Id="ProgramFiles6432Folder"> | 15 | <StandardDirectory Id="ProgramFiles6432Folder"> |
16 | <Directory Id="INSTALLFOLDER" Name="MsiPackage" ShortName="1egc1laj"> | 16 | <Directory Id="INSTALLFOLDER" Name="MsiPackage" ShortName="1egc1laj"> |
17 | <Component Id="filcV1yrx0x8wJWj4qMzcH21jwkPko" Guid="{E597A58A-03CB-50D8-93E3-DABA263F233A}" Bitness="always32"> | 17 | <Component Id="filcV1yrx0x8wJWj4qMzcH21jwkPko" Guid="{E597A58A-03CB-50D8-93E3-DABA263F233A}" Bitness="always32"> |
18 | <File Id="filcV1yrx0x8wJWj4qMzcH21jwkPko" Name="test.txt" KeyPath="yes" Source="MsiPackage\test.txt" /> | 18 | <File Id="filcV1yrx0x8wJWj4qMzcH21jwkPko" Name="test.txt" KeyPath="yes" Source=".\MsiPackage\test.txt" /> |
19 | </Component> | 19 | </Component> |
20 | </Directory> | 20 | </Directory> |
21 | </StandardDirectory> | 21 | </StandardDirectory> |
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/DecompileNullComponent/Expected.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/DecompileNullComponent/Expected.wxs index 71553e2a..3d15dd3e 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/DecompileNullComponent/Expected.wxs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/DecompileNullComponent/Expected.wxs | |||
@@ -1,5 +1,5 @@ | |||
1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | 1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> |
2 | <Package Codepage="65001" Language="1033" Manufacturer="Example Corporation" Name="MsiPackage" UpgradeCode="{047730A5-30FE-4A62-A520-DA9381B8226A}" Version="1.0.0.0" Compressed="yes" InstallerVersion="200" ProductCode="{6F9B5694-F0F1-437C-919B-0D2DAF2D9DEA}"> | 2 | <Package Codepage="65001" Language="1033" Manufacturer="Example Corporation" Name="MsiPackage" UpgradeCode="{047730A5-30FE-4A62-A520-DA9381B8226A}" Version="1.0.0.0" InstallerVersion="200" ProductCode="{6F9B5694-F0F1-437C-919B-0D2DAF2D9DEA}"> |
3 | <StandardDirectory Id="ProgramFilesFolder"> | 3 | <StandardDirectory Id="ProgramFilesFolder"> |
4 | <Directory Id="INSTALLFOLDER" Name="MsiPackage" ShortName="oekcr5lq"> | 4 | <Directory Id="INSTALLFOLDER" Name="MsiPackage" ShortName="oekcr5lq"> |
5 | <Component Id="filcV1yrx0x8wJWj4qMzcH21jwkPko" Guid="" Bitness="always32"> | 5 | <Component Id="filcV1yrx0x8wJWj4qMzcH21jwkPko" Guid="" Bitness="always32"> |
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/DecompileSingleFileCompressed/Expected.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/DecompileSingleFileCompressed/Expected.wxs index 246bcafc..9d0b8462 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/DecompileSingleFileCompressed/Expected.wxs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/DecompileSingleFileCompressed/Expected.wxs | |||
@@ -1,5 +1,5 @@ | |||
1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | 1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> |
2 | <Package Codepage="65001" Language="1033" Manufacturer="Example Corporation" Name="MsiPackage" UpgradeCode="{047730A5-30FE-4A62-A520-DA9381B8226A}" Version="1.0.0.0" Compressed="yes" InstallerVersion="200" ProductCode="{6F9B5694-F0F1-437C-919B-0D2DAF2D9DEA}"> | 2 | <Package Codepage="65001" Language="1033" Manufacturer="Example Corporation" Name="MsiPackage" UpgradeCode="{047730A5-30FE-4A62-A520-DA9381B8226A}" Version="1.0.0.0" InstallerVersion="200" ProductCode="{6F9B5694-F0F1-437C-919B-0D2DAF2D9DEA}"> |
3 | <StandardDirectory Id="ProgramFilesFolder"> | 3 | <StandardDirectory Id="ProgramFilesFolder"> |
4 | <Directory Id="INSTALLFOLDER" Name="MsiPackage" ShortName="oekcr5lq"> | 4 | <Directory Id="INSTALLFOLDER" Name="MsiPackage" ShortName="oekcr5lq"> |
5 | <Component Id="filcV1yrx0x8wJWj4qMzcH21jwkPko" Guid="{E597A58A-03CB-50D8-93E3-DABA263F233A}" Bitness="always32"> | 5 | <Component Id="filcV1yrx0x8wJWj4qMzcH21jwkPko" Guid="{E597A58A-03CB-50D8-93E3-DABA263F233A}" Bitness="always32"> |
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/DecompileSingleFileCompressed64/Expected.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/DecompileSingleFileCompressed64/Expected.wxs index 81915759..a30d2c91 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/DecompileSingleFileCompressed64/Expected.wxs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/DecompileSingleFileCompressed64/Expected.wxs | |||
@@ -1,5 +1,5 @@ | |||
1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | 1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> |
2 | <Package Codepage="65001" Language="1033" Manufacturer="Example Corporation" Name="MsiPackage" UpgradeCode="{047730A5-30FE-4A62-A520-DA9381B8226A}" Version="1.0.0.0" Compressed="yes" ProductCode="{C51B773A-B3BE-4F29-A8A9-549AAF7FF6EC}"> | 2 | <Package Codepage="65001" Language="1033" Manufacturer="Example Corporation" Name="MsiPackage" UpgradeCode="{047730A5-30FE-4A62-A520-DA9381B8226A}" Version="1.0.0.0" ProductCode="{C51B773A-B3BE-4F29-A8A9-549AAF7FF6EC}"> |
3 | <StandardDirectory Id="ProgramFiles64Folder"> | 3 | <StandardDirectory Id="ProgramFiles64Folder"> |
4 | <Directory Id="INSTALLFOLDER" Name="MsiPackage" ShortName="oekcr5lq"> | 4 | <Directory Id="INSTALLFOLDER" Name="MsiPackage" ShortName="oekcr5lq"> |
5 | <Component Id="filcV1yrx0x8wJWj4qMzcH21jwkPko" Guid="{E597A58A-03CB-50D8-93E3-DABA263F233A}" Bitness="always64"> | 5 | <Component Id="filcV1yrx0x8wJWj4qMzcH21jwkPko" Guid="{E597A58A-03CB-50D8-93E3-DABA263F233A}" Bitness="always64"> |
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExampleExtension/Decompiled-Expected.xml b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExampleExtension/Decompiled-Expected.xml new file mode 100644 index 00000000..42ececb1 --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExampleExtension/Decompiled-Expected.xml | |||
@@ -0,0 +1,19 @@ | |||
1 | <?xml version="1.0" encoding="utf-8"?> | ||
2 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | ||
3 | <Package Codepage="1252" Manufacturer="Example Corporation" ProductCode="{GUID}" Language="1033" Name="MsiPackage" Version="1.0.0.0" UpgradeCode="{047730A5-30FE-4A62-A520-DA9381B8226A}" InstallerVersion="200" Compressed="no"> | ||
4 | <Property Id="ExampleProperty" Value="(null)" /> | ||
5 | <StandardDirectory Id="ProgramFilesFolder"> | ||
6 | <Directory Id="INSTALLFOLDER" ShortName="oekcr5lq" Name="MsiPackage"> | ||
7 | <Component Id="filF5_pLhBuF5b4N9XEo52g_hUM5Lo" Guid="{GUID}" Bitness="always32"> | ||
8 | <Example Id="Foo" Value="Bar" xmlns="http://www.example.com/scheams/v1/wxs" /> | ||
9 | <File Id="filF5_pLhBuF5b4N9XEo52g_hUM5Lo" Name="example.txt" KeyPath="yes" Source="PFiles\MsiPackage\example.txt" /> | ||
10 | </Component> | ||
11 | </Directory> | ||
12 | </StandardDirectory> | ||
13 | <Feature Id="ProductFeature" Title="MsiPackage" Level="1"> | ||
14 | <ComponentRef Id="filF5_pLhBuF5b4N9XEo52g_hUM5Lo" /> | ||
15 | </Feature> | ||
16 | <Media Id="1" /> | ||
17 | <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." /> | ||
18 | </Package> | ||
19 | </Wix> | ||
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/SequenceTables/DecompiledSequenceTables.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/SequenceTables/DecompiledSequenceTables.wxs index d5379e7b..096b56e8 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/SequenceTables/DecompiledSequenceTables.wxs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/SequenceTables/DecompiledSequenceTables.wxs | |||
@@ -1,10 +1,10 @@ | |||
1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | 1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> |
2 | <Package Codepage="1252" Language="1033" Manufacturer="Example Corporation" Name="MsiPackage" UpgradeCode="{12E4699F-E774-4D05-8A01-5BDD41BBA127}" Version="1.0.0.0" ProductCode="{74C29381-1915-4948-B8B4-5646806A0BD4}"> | 2 | <Package Codepage="1252" Language="1033" Manufacturer="Example Corporation" Name="MsiPackage" UpgradeCode="{12E4699F-E774-4D05-8A01-5BDD41BBA127}" Version="1.0.0.0" ProductCode="{74C29381-1915-4948-B8B4-5646806A0BD4}" Compressed="no"> |
3 | <CustomAction Id="CustomAction2" Property="TestAdvtExecuteSequenceProperty" Value="1" /> | 3 | <CustomAction Id="CustomAction2" Property="TestAdvtExecuteSequenceProperty" Value="1" /> |
4 | <StandardDirectory Id="ProgramFilesFolder"> | 4 | <StandardDirectory Id="ProgramFilesFolder"> |
5 | <Directory Id="INSTALLFOLDER" Name="MsiPackage" ShortName="ykd0udtb"> | 5 | <Directory Id="INSTALLFOLDER" Name="MsiPackage" ShortName="ykd0udtb"> |
6 | <Component Id="test.txt" Guid="{E597A58A-03CB-50D8-93E3-DABA263F233A}" Bitness="always32"> | 6 | <Component Id="test.txt" Guid="{E597A58A-03CB-50D8-93E3-DABA263F233A}" Bitness="always32"> |
7 | <File Id="test.txt" Name="test.txt" KeyPath="yes" Source="MsiPackage\test.txt" /> | 7 | <File Id="test.txt" Name="test.txt" KeyPath="yes" Source="PFiles\MsiPackage\test.txt" /> |
8 | </Component> | 8 | </Component> |
9 | </Directory> | 9 | </Directory> |
10 | </StandardDirectory> | 10 | </StandardDirectory> |
@@ -29,4 +29,4 @@ | |||
29 | <Custom Action="CustomAction2" After="CostInitialize" /> | 29 | <Custom Action="CustomAction2" After="CostInitialize" /> |
30 | </AdvertiseExecuteSequence> | 30 | </AdvertiseExecuteSequence> |
31 | </Package> | 31 | </Package> |
32 | </Wix> \ No newline at end of file | 32 | </Wix> |
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Shortcut/DecompiledShortcuts.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Shortcut/DecompiledShortcuts.wxs index da1e4f38..b04c635e 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Shortcut/DecompiledShortcuts.wxs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Shortcut/DecompiledShortcuts.wxs | |||
@@ -1,9 +1,9 @@ | |||
1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | 1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> |
2 | <Package Codepage="1252" Language="1033" Manufacturer="Example Corporation" Name="MsiPackage" UpgradeCode="{12E4699F-E774-4D05-8A01-5BDD41BBA127}" Version="1.0.0.0" ProductCode="{6CA94D1D-B568-4ED6-9EBC-3534C85970BB}"> | 2 | <Package Codepage="1252" Language="1033" Manufacturer="Example Corporation" Name="MsiPackage" UpgradeCode="{12E4699F-E774-4D05-8A01-5BDD41BBA127}" Version="1.0.0.0" ProductCode="{6CA94D1D-B568-4ED6-9EBC-3534C85970BB}" Compressed="no"> |
3 | <StandardDirectory Id="ProgramFilesFolder"> | 3 | <StandardDirectory Id="ProgramFilesFolder"> |
4 | <Directory Id="INSTALLFOLDER" Name="MsiPackage" ShortName="ykd0udtb"> | 4 | <Directory Id="INSTALLFOLDER" Name="MsiPackage" ShortName="ykd0udtb"> |
5 | <Component Id="ShortcutComp" Guid="{5B3B3FC1-533D-4C29-BFB3-0E88B51E59D8}" Bitness="always32"> | 5 | <Component Id="ShortcutComp" Guid="{5B3B3FC1-533D-4C29-BFB3-0E88B51E59D8}" Bitness="always32"> |
6 | <File Id="test.txt" Name="test.txt" KeyPath="yes" Source="MsiPackage\test.txt" /> | 6 | <File Id="test.txt" Name="test.txt" KeyPath="yes" Source="PFiles\MsiPackage\test.txt" /> |
7 | <Shortcut Id="FileTargetShortcut" Directory="INSTALLFOLDER" Name="FileTargetShortcut" ShortName="lm2tdtqp" Target="[#test.txt]" /> | 7 | <Shortcut Id="FileTargetShortcut" Directory="INSTALLFOLDER" Name="FileTargetShortcut" ShortName="lm2tdtqp" Target="[#test.txt]" /> |
8 | <Shortcut Id="CustomTargetShortcut" Directory="INSTALLFOLDER" Name="Planner" ShortName="PLANNER" Target="[INSTALLFOLDER]custom.target" /> | 8 | <Shortcut Id="CustomTargetShortcut" Directory="INSTALLFOLDER" Name="Planner" ShortName="PLANNER" Target="[INSTALLFOLDER]custom.target" /> |
9 | <Shortcut Id="AdvtShortcut" Directory="INSTALLFOLDER" Name="AdvtShortcut" ShortName="mdbqel9r" Advertise="yes" /> | 9 | <Shortcut Id="AdvtShortcut" Directory="INSTALLFOLDER" Name="AdvtShortcut" ShortName="mdbqel9r" Advertise="yes" /> |
@@ -16,4 +16,4 @@ | |||
16 | <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." /> | 16 | <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." /> |
17 | <Media Id="1" /> | 17 | <Media Id="1" /> |
18 | </Package> | 18 | </Package> |
19 | </Wix> \ No newline at end of file | 19 | </Wix> |
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/WixlibFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/WixlibFixture.cs index 01b82eb3..184b291b 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/WixlibFixture.cs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/WixlibFixture.cs | |||
@@ -289,7 +289,7 @@ namespace WixToolsetTest.CoreIntegration | |||
289 | 289 | ||
290 | var example = section.Symbols.Where(t => t.Definition.Type == SymbolDefinitionType.MustBeFromAnExtension).Single(); | 290 | var example = section.Symbols.Where(t => t.Definition.Type == SymbolDefinitionType.MustBeFromAnExtension).Single(); |
291 | Assert.Equal("Foo", example.Id?.Id); | 291 | Assert.Equal("Foo", example.Id?.Id); |
292 | Assert.Equal("Bar", example[0].AsString()); | 292 | Assert.Equal("Bar", example[1].AsString()); |
293 | } | 293 | } |
294 | } | 294 | } |
295 | 295 | ||
@@ -352,7 +352,8 @@ namespace WixToolsetTest.CoreIntegration | |||
352 | 352 | ||
353 | var examples = section.Symbols.Where(t => t.Definition.Type == SymbolDefinitionType.MustBeFromAnExtension).ToArray(); | 353 | var examples = section.Symbols.Where(t => t.Definition.Type == SymbolDefinitionType.MustBeFromAnExtension).ToArray(); |
354 | WixAssert.CompareLineByLine(new string[] { "Foo", "Other" }, examples.Select(t => t.Id?.Id).ToArray()); | 354 | WixAssert.CompareLineByLine(new string[] { "Foo", "Other" }, examples.Select(t => t.Id?.Id).ToArray()); |
355 | WixAssert.CompareLineByLine(new[] { "Bar", "Value" }, examples.Select(t => t[0].AsString()).ToArray()); | 355 | WixAssert.CompareLineByLine(new[] { "filF5_pLhBuF5b4N9XEo52g_hUM5Lo", "filvxdStJhRE_M5kbpLsTZJXbs34Sg" }, examples.Select(t => t[0].AsString()).ToArray()); |
356 | WixAssert.CompareLineByLine(new[] { "Bar", "Value" }, examples.Select(t => t[1].AsString()).ToArray()); | ||
356 | } | 357 | } |
357 | } | 358 | } |
358 | } | 359 | } |