1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
// 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.
using System;
using System.IO;
using WixToolset.Dtf.WindowsInstaller;
using WixToolset.Dtf.WindowsInstaller.Package;
namespace WixToolset.Dtf.Tools.DDiff
{
public class MspDiffEngine : MsiDiffEngine
{
public MspDiffEngine()
{
}
private string GetPatchTargetOption(string[] options)
{
for(int i = 0; i < options.Length - 1; i++)
{
switch(options[i].ToLower())
{
case "/p": goto case "-patchtarget";
case "-p": goto case "-patchtarget";
case "/patchtarget": goto case "-patchtarget";
case "-patchtarget": return options[i+1];
}
}
return null;
}
public override float GetDiffQuality(string diffInput1, string diffInput2, string[] options, IDiffEngineFactory diffFactory)
{
if(diffInput1 != null && File.Exists(diffInput1) &&
diffInput2 != null && File.Exists(diffInput2) &&
GetPatchTargetOption(options) != null &&
(IsMspPatch(diffInput1) && IsMspPatch(diffInput2)))
{
return .80f;
}
else if(diffInput1 != null && File.Exists(diffInput1) &&
diffInput2 != null && File.Exists(diffInput2) &&
GetPatchTargetOption(options) == null &&
(IsMspPatch(diffInput1) && IsMsiDatabase(diffInput2)) ||
(IsMsiDatabase(diffInput1) && IsMspPatch(diffInput2)))
{
return .75f;
}
else
{
return 0;
}
}
public override bool GetDiff(string diffInput1, string diffInput2, string[] options, TextWriter diffOutput, string linePrefix, IDiffEngineFactory diffFactory)
{
bool difference = false;
InstallPackage db1, db2;
if(IsMspPatch(diffInput1))
{
string patchTargetDbFile = GetPatchTargetOption(options);
if(patchTargetDbFile == null) patchTargetDbFile = diffInput2;
string tempPatchedDbFile = Path.GetTempFileName();
File.Copy(patchTargetDbFile, tempPatchedDbFile, true);
File.SetAttributes(tempPatchedDbFile, File.GetAttributes(tempPatchedDbFile) & ~System.IO.FileAttributes.ReadOnly);
db1 = new InstallPackage(tempPatchedDbFile, DatabaseOpenMode.Direct);
db1.ApplyPatch(new PatchPackage(diffInput1), null);
db1.Commit();
}
else
{
db1 = new InstallPackage(diffInput1, DatabaseOpenMode.ReadOnly);
}
if(IsMspPatch(diffInput2))
{
string patchTargetDbFile = GetPatchTargetOption(options);
if(patchTargetDbFile == null) patchTargetDbFile = diffInput1;
string tempPatchedDbFile = Path.GetTempFileName();
File.Copy(patchTargetDbFile, tempPatchedDbFile, true);
File.SetAttributes(tempPatchedDbFile, File.GetAttributes(tempPatchedDbFile) & ~System.IO.FileAttributes.ReadOnly);
db2 = new InstallPackage(tempPatchedDbFile, DatabaseOpenMode.Direct);
db2.ApplyPatch(new PatchPackage(diffInput2), null);
db2.Commit();
}
else
{
db2 = new InstallPackage(diffInput2, DatabaseOpenMode.ReadOnly);
}
if(GetSummaryInfoDiff(db1, db2, options, diffOutput, linePrefix, diffFactory)) difference = true;
if(GetDatabaseDiff(db1, db2, options, diffOutput, linePrefix, diffFactory)) difference = true;
if(GetStreamsDiff(db1, db2, options, diffOutput, linePrefix, diffFactory)) difference = true;
db1.Close();
db2.Close();
try
{
if(IsMspPatch(diffInput1)) File.Delete(db1.FilePath);
if(IsMspPatch(diffInput1)) File.Delete(db2.FilePath);
}
catch(IOException)
{
#if DEBUG
Console.WriteLine("Could not delete temporary files {0} and {1}", db1.FilePath, db2.FilePath);
#endif
}
if(IsMspPatch(diffInput1) && IsMspPatch(diffInput2))
{
Database dbp1 = new Database(diffInput1, DatabaseOpenMode.ReadOnly);
Database dbp2 = new Database(diffInput2, DatabaseOpenMode.ReadOnly);
if(GetStreamsDiff(dbp1, dbp2, options, diffOutput, linePrefix, diffFactory)) difference = true;
dbp1.Close();
dbp2.Close();
}
return difference;
}
public override IDiffEngine Clone()
{
return new MspDiffEngine();
}
}
}
|