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 /src | |
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
Diffstat (limited to 'src')
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 | } |