diff options
Diffstat (limited to 'src/WixToolset.Core.WindowsInstaller/MspBackend.cs')
-rw-r--r-- | src/WixToolset.Core.WindowsInstaller/MspBackend.cs | 111 |
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 | |||
3 | namespace 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 | ||