aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core.WindowsInstaller/MspBackend.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core.WindowsInstaller/MspBackend.cs')
-rw-r--r--src/WixToolset.Core.WindowsInstaller/MspBackend.cs111
1 files changed, 111 insertions, 0 deletions
diff --git a/src/WixToolset.Core.WindowsInstaller/MspBackend.cs b/src/WixToolset.Core.WindowsInstaller/MspBackend.cs
new file mode 100644
index 00000000..4b13258b
--- /dev/null
+++ b/src/WixToolset.Core.WindowsInstaller/MspBackend.cs
@@ -0,0 +1,111 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Core.WindowsInstaller
4{
5 using System;
6 using System.ComponentModel;
7 using System.IO;
8 using WixToolset.Core.Native;
9 using WixToolset.Core.WindowsInstaller.Unbind;
10 using WixToolset.Data;
11 using WixToolset.Data.Bind;
12 using WixToolset.Extensibility;
13 using WixToolset.Msi;
14 using WixToolset.Ole32;
15
16 internal class MspBackend : IBackend
17 {
18 public BindResult Bind(IBindContext context)
19 {
20 throw new NotImplementedException();
21 }
22
23 public bool Inscribe(IInscribeContext context)
24 {
25 throw new NotImplementedException();
26 }
27
28 public Output Unbind(IUnbindContext context)
29 {
30 Output patch;
31
32 // patch files are essentially database files (use a special flag to let the API know its a patch file)
33 try
34 {
35 using (Database database = new Database(context.InputFilePath, OpenDatabase.ReadOnly | OpenDatabase.OpenPatchFile))
36 {
37 var unbindCommand = new UnbindDatabaseCommand(context.Messaging, database, context.InputFilePath, OutputType.Patch, context.ExportBasePath, context.IntermediateFolder, context.IsAdminImage, context.SuppressDemodularization, skipSummaryInfo: false);
38 patch = unbindCommand.Execute();
39 }
40 }
41 catch (Win32Exception e)
42 {
43 if (0x6E == e.NativeErrorCode) // ERROR_OPEN_FAILED
44 {
45 throw new WixException(WixErrors.OpenDatabaseFailed(context.InputFilePath));
46 }
47
48 throw;
49 }
50
51 // retrieve the transforms (they are in substorages)
52 using (Storage storage = Storage.Open(context.InputFilePath, StorageMode.Read | StorageMode.ShareDenyWrite))
53 {
54 Table summaryInformationTable = patch.Tables["_SummaryInformation"];
55 foreach (Row row in summaryInformationTable.Rows)
56 {
57 if (8 == (int)row[0]) // PID_LASTAUTHOR
58 {
59 string value = (string)row[1];
60
61 foreach (string decoratedSubStorageName in value.Split(';'))
62 {
63 string subStorageName = decoratedSubStorageName.Substring(1);
64 string transformFile = Path.Combine(context.IntermediateFolder, String.Concat("Transform", Path.DirectorySeparatorChar, subStorageName, ".mst"));
65
66 // ensure the parent directory exists
67 System.IO.Directory.CreateDirectory(Path.GetDirectoryName(transformFile));
68
69 // copy the substorage to a new storage for the transform file
70 using (Storage subStorage = storage.OpenStorage(subStorageName))
71 {
72 using (Storage transformStorage = Storage.CreateDocFile(transformFile, StorageMode.ReadWrite | StorageMode.ShareExclusive | StorageMode.Create))
73 {
74 subStorage.CopyTo(transformStorage);
75 }
76 }
77
78 // unbind the transform
79 var unbindCommand= new UnbindTransformCommand(context.Messaging, transformFile, (null == context.ExportBasePath ? null : Path.Combine(context.ExportBasePath, subStorageName)), context.IntermediateFolder);
80 var transform = unbindCommand.Execute();
81
82 patch.SubStorages.Add(new SubStorage(subStorageName, transform));
83 }
84
85 break;
86 }
87 }
88 }
89
90 // extract the files from the cabinets
91 // TODO: use per-transform export paths for support of multi-product patches
92 if (null != context.ExportBasePath && !context.SuppressExtractCabinets)
93 {
94 using (Database database = new Database(context.InputFilePath, OpenDatabase.ReadOnly | OpenDatabase.OpenPatchFile))
95 {
96 foreach (SubStorage subStorage in patch.SubStorages)
97 {
98 // only patch transforms should carry files
99 if (subStorage.Name.StartsWith("#", StringComparison.Ordinal))
100 {
101 var extractCommand = new ExtractCabinetsCommand(subStorage.Data, database, context.InputFilePath, context.ExportBasePath, context.IntermediateFolder);
102 extractCommand.Execute();
103 }
104 }
105 }
106 }
107
108 return patch;
109 }
110 }
111} \ No newline at end of file