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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
// 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.
namespace WixToolset.Mba.Core
{
using System;
using System.Runtime.InteropServices;
using System.Text;
/// <summary>
/// Managed wrapper for verutil.
/// </summary>
public static class VerUtil
{
[DllImport("mbanative.dll", ExactSpelling = true, PreserveSig = false)]
internal static extern int VerCompareParsedVersions(
VersionHandle pVersion1,
VersionHandle pVersion2
);
[DllImport("mbanative.dll", ExactSpelling = true, PreserveSig = false)]
internal static extern int VerCompareStringVersions(
[MarshalAs(UnmanagedType.LPWStr)] string wzVersion1,
[MarshalAs(UnmanagedType.LPWStr)] string wzVersion2,
[MarshalAs(UnmanagedType.Bool)] bool fStrict
);
[DllImport("mbanative.dll", ExactSpelling = true, PreserveSig = false)]
internal static extern VersionHandle VerCopyVersion(
VersionHandle pSource
);
[DllImport("mbanative.dll", ExactSpelling = true)]
internal static extern void VerFreeVersion(
IntPtr pVersion
);
[DllImport("mbanative.dll", ExactSpelling = true, PreserveSig = false)]
internal static extern VersionHandle VerParseVersion(
[MarshalAs(UnmanagedType.LPWStr)] string wzVersion,
[MarshalAs(UnmanagedType.U4)] uint cchValue,
[MarshalAs(UnmanagedType.Bool)] bool fStrict
);
[DllImport("mbanative.dll", ExactSpelling = true, PreserveSig = false)]
internal static extern VersionHandle VerVersionFromQword(
[MarshalAs(UnmanagedType.I8)] long qwVersion
);
[StructLayout(LayoutKind.Sequential)]
internal struct VersionReleaseLabelStruct
{
public bool fNumeric;
public uint dwValue;
public IntPtr cchLabelOffset;
public int cchLabel;
}
[StructLayout(LayoutKind.Sequential)]
internal struct VersionStruct
{
public IntPtr sczVersion;
public char chPrefix;
public uint dwMajor;
public uint dwMinor;
public uint dwPatch;
public uint dwRevision;
public int cReleaseLabels;
public IntPtr rgReleaseLabels;
public IntPtr cchMetadataOffset;
public bool fInvalid;
public bool fHasMajor;
public bool fHasMinor;
public bool fHasPatch;
public bool fHasRevision;
}
internal static string VersionStringFromOffset(IntPtr wzVersion, IntPtr cchOffset, int? cchLength = null)
{
var offset = cchOffset.ToInt64() * UnicodeEncoding.CharSize;
var wz = new IntPtr(wzVersion.ToInt64() + offset);
if (cchLength.HasValue)
{
return Marshal.PtrToStringUni(wz, (int)cchLength);
}
else
{
return Marshal.PtrToStringUni(wz);
}
}
internal sealed class VersionHandle : SafeHandleZeroIsDefaultAndInvalid
{
protected override bool ReleaseHandle()
{
VerFreeVersion(this.handle);
return true;
}
}
/// <returns>0 if equal, 1 if version1 > version2, -1 if version1 < version2</returns>
public static int CompareParsedVersions(VerUtilVersion version1, VerUtilVersion version2)
{
return VerCompareParsedVersions(version1.GetHandle(), version2.GetHandle());
}
/// <returns>0 if equal, 1 if version1 > version2, -1 if version1 < version2</returns>
public static int CompareStringVersions(string version1, string version2, bool strict)
{
return VerCompareStringVersions(version1, version2, strict);
}
/// <summary>
/// Clone the version.
/// </summary>
/// <param name="version">Source version</param>
/// <returns>Cloned version</returns>
public static VerUtilVersion CopyVersion(VerUtilVersion version)
{
var handle = VerCopyVersion(version.GetHandle());
return new VerUtilVersion(handle);
}
/// <summary>
/// Parse a version.
/// </summary>
/// <param name="version">Source version</param>
/// <param name="strict">Whether to throw exception on invalid version.</param>
/// <returns>Parsed version</returns>
public static VerUtilVersion ParseVersion(string version, bool strict)
{
var handle = VerParseVersion(version, 0, strict);
return new VerUtilVersion(handle);
}
/// <summary>
/// Parse version from qword.
/// </summary>
/// <param name="version">Source version</param>
/// <returns>Parsed version</returns>
public static VerUtilVersion VersionFromQword(long version)
{
var handle = VerVersionFromQword(version);
return new VerUtilVersion(handle);
}
}
}
|