diff options
Diffstat (limited to 'src/api/burn/WixToolset.Mba.Core/VerUtil.cs')
-rw-r--r-- | src/api/burn/WixToolset.Mba.Core/VerUtil.cs | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/src/api/burn/WixToolset.Mba.Core/VerUtil.cs b/src/api/burn/WixToolset.Mba.Core/VerUtil.cs new file mode 100644 index 00000000..81c5b716 --- /dev/null +++ b/src/api/burn/WixToolset.Mba.Core/VerUtil.cs | |||
@@ -0,0 +1,145 @@ | |||
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.Mba.Core | ||
4 | { | ||
5 | using System; | ||
6 | using System.Runtime.InteropServices; | ||
7 | using System.Text; | ||
8 | |||
9 | /// <summary> | ||
10 | /// Managed wrapper for verutil. | ||
11 | /// </summary> | ||
12 | public static class VerUtil | ||
13 | { | ||
14 | [DllImport("mbanative.dll", ExactSpelling = true, PreserveSig = false)] | ||
15 | internal static extern int VerCompareParsedVersions( | ||
16 | VersionHandle pVersion1, | ||
17 | VersionHandle pVersion2 | ||
18 | ); | ||
19 | |||
20 | [DllImport("mbanative.dll", ExactSpelling = true, PreserveSig = false)] | ||
21 | internal static extern int VerCompareStringVersions( | ||
22 | [MarshalAs(UnmanagedType.LPWStr)] string wzVersion1, | ||
23 | [MarshalAs(UnmanagedType.LPWStr)] string wzVersion2, | ||
24 | [MarshalAs(UnmanagedType.Bool)] bool fStrict | ||
25 | ); | ||
26 | |||
27 | [DllImport("mbanative.dll", ExactSpelling = true, PreserveSig = false)] | ||
28 | internal static extern VersionHandle VerCopyVersion( | ||
29 | VersionHandle pSource | ||
30 | ); | ||
31 | |||
32 | [DllImport("mbanative.dll", ExactSpelling = true)] | ||
33 | internal static extern void VerFreeVersion( | ||
34 | IntPtr pVersion | ||
35 | ); | ||
36 | |||
37 | [DllImport("mbanative.dll", ExactSpelling = true, PreserveSig = false)] | ||
38 | internal static extern VersionHandle VerParseVersion( | ||
39 | [MarshalAs(UnmanagedType.LPWStr)] string wzVersion, | ||
40 | [MarshalAs(UnmanagedType.U4)] uint cchValue, | ||
41 | [MarshalAs(UnmanagedType.Bool)] bool fStrict | ||
42 | ); | ||
43 | |||
44 | [DllImport("mbanative.dll", ExactSpelling = true, PreserveSig = false)] | ||
45 | internal static extern VersionHandle VerVersionFromQword( | ||
46 | [MarshalAs(UnmanagedType.I8)] long qwVersion | ||
47 | ); | ||
48 | |||
49 | [StructLayout(LayoutKind.Sequential)] | ||
50 | internal struct VersionReleaseLabelStruct | ||
51 | { | ||
52 | public bool fNumeric; | ||
53 | public uint dwValue; | ||
54 | public IntPtr cchLabelOffset; | ||
55 | public int cchLabel; | ||
56 | } | ||
57 | |||
58 | [StructLayout(LayoutKind.Sequential)] | ||
59 | internal struct VersionStruct | ||
60 | { | ||
61 | public IntPtr sczVersion; | ||
62 | public uint dwMajor; | ||
63 | public uint dwMinor; | ||
64 | public uint dwPatch; | ||
65 | public uint dwRevision; | ||
66 | public int cReleaseLabels; | ||
67 | public IntPtr rgReleaseLabels; | ||
68 | public IntPtr cchMetadataOffset; | ||
69 | public bool fInvalid; | ||
70 | } | ||
71 | |||
72 | internal static string VersionStringFromOffset(IntPtr wzVersion, IntPtr cchOffset, int? cchLength = null) | ||
73 | { | ||
74 | var offset = cchOffset.ToInt64() * UnicodeEncoding.CharSize; | ||
75 | var wz = new IntPtr(wzVersion.ToInt64() + offset); | ||
76 | if (cchLength.HasValue) | ||
77 | { | ||
78 | return Marshal.PtrToStringUni(wz, (int)cchLength); | ||
79 | } | ||
80 | else | ||
81 | { | ||
82 | return Marshal.PtrToStringUni(wz); | ||
83 | } | ||
84 | } | ||
85 | |||
86 | internal sealed class VersionHandle : SafeHandle | ||
87 | { | ||
88 | public VersionHandle() : base(IntPtr.Zero, true) { } | ||
89 | |||
90 | public override bool IsInvalid => false; | ||
91 | |||
92 | protected override bool ReleaseHandle() | ||
93 | { | ||
94 | VerFreeVersion(this.handle); | ||
95 | return true; | ||
96 | } | ||
97 | } | ||
98 | |||
99 | /// <returns>0 if equal, 1 if version1 > version2, -1 if version1 < version2</returns> | ||
100 | public static int CompareParsedVersions(VerUtilVersion version1, VerUtilVersion version2) | ||
101 | { | ||
102 | return VerCompareParsedVersions(version1.GetHandle(), version2.GetHandle()); | ||
103 | } | ||
104 | |||
105 | /// <returns>0 if equal, 1 if version1 > version2, -1 if version1 < version2</returns> | ||
106 | public static int CompareStringVersions(string version1, string version2, bool strict) | ||
107 | { | ||
108 | return VerCompareStringVersions(version1, version2, strict); | ||
109 | } | ||
110 | |||
111 | /// <summary> | ||
112 | /// | ||
113 | /// </summary> | ||
114 | /// <param name="version"></param> | ||
115 | /// <returns></returns> | ||
116 | public static VerUtilVersion CopyVersion(VerUtilVersion version) | ||
117 | { | ||
118 | var handle = VerCopyVersion(version.GetHandle()); | ||
119 | return new VerUtilVersion(handle); | ||
120 | } | ||
121 | |||
122 | /// <summary> | ||
123 | /// | ||
124 | /// </summary> | ||
125 | /// <param name="version"></param> | ||
126 | /// <param name="strict">Whether to throw exception on invalid version.</param> | ||
127 | /// <returns></returns> | ||
128 | public static VerUtilVersion ParseVersion(string version, bool strict) | ||
129 | { | ||
130 | var handle = VerParseVersion(version, 0, strict); | ||
131 | return new VerUtilVersion(handle); | ||
132 | } | ||
133 | |||
134 | /// <summary> | ||
135 | /// | ||
136 | /// </summary> | ||
137 | /// <param name="version"></param> | ||
138 | /// <returns></returns> | ||
139 | public static VerUtilVersion VersionFromQword(long version) | ||
140 | { | ||
141 | var handle = VerVersionFromQword(version); | ||
142 | return new VerUtilVersion(handle); | ||
143 | } | ||
144 | } | ||
145 | } | ||