diff options
Diffstat (limited to 'src/burn/engine/variant.cpp')
-rw-r--r-- | src/burn/engine/variant.cpp | 321 |
1 files changed, 321 insertions, 0 deletions
diff --git a/src/burn/engine/variant.cpp b/src/burn/engine/variant.cpp new file mode 100644 index 00000000..2267ee7b --- /dev/null +++ b/src/burn/engine/variant.cpp | |||
@@ -0,0 +1,321 @@ | |||
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 | #include "precomp.h" | ||
4 | |||
5 | // internal function declarations | ||
6 | |||
7 | static HRESULT GetVersionInternal( | ||
8 | __in BURN_VARIANT* pVariant, | ||
9 | __in BOOL fHidden, | ||
10 | __in BOOL fSilent, | ||
11 | __out VERUTIL_VERSION** ppValue | ||
12 | ); | ||
13 | |||
14 | // function definitions | ||
15 | |||
16 | extern "C" void BVariantUninitialize( | ||
17 | __in BURN_VARIANT* pVariant | ||
18 | ) | ||
19 | { | ||
20 | if (BURN_VARIANT_TYPE_FORMATTED == pVariant->Type || | ||
21 | BURN_VARIANT_TYPE_STRING == pVariant->Type) | ||
22 | { | ||
23 | StrSecureZeroFreeString(pVariant->sczValue); | ||
24 | } | ||
25 | SecureZeroMemory(pVariant, sizeof(BURN_VARIANT)); | ||
26 | } | ||
27 | |||
28 | extern "C" HRESULT BVariantGetNumeric( | ||
29 | __in BURN_VARIANT* pVariant, | ||
30 | __out LONGLONG* pllValue | ||
31 | ) | ||
32 | { | ||
33 | HRESULT hr = S_OK; | ||
34 | |||
35 | switch (pVariant->Type) | ||
36 | { | ||
37 | case BURN_VARIANT_TYPE_NUMERIC: | ||
38 | *pllValue = pVariant->llValue; | ||
39 | break; | ||
40 | case BURN_VARIANT_TYPE_FORMATTED: __fallthrough; | ||
41 | case BURN_VARIANT_TYPE_STRING: | ||
42 | hr = StrStringToInt64(pVariant->sczValue, 0, pllValue); | ||
43 | if (FAILED(hr)) | ||
44 | { | ||
45 | hr = DISP_E_TYPEMISMATCH; | ||
46 | } | ||
47 | break; | ||
48 | case BURN_VARIANT_TYPE_VERSION: | ||
49 | hr = StrStringToInt64(pVariant->pValue ? pVariant->pValue->sczVersion : NULL, 0, pllValue); | ||
50 | if (FAILED(hr)) | ||
51 | { | ||
52 | hr = DISP_E_TYPEMISMATCH; | ||
53 | } | ||
54 | break; | ||
55 | default: | ||
56 | hr = E_INVALIDARG; | ||
57 | break; | ||
58 | } | ||
59 | |||
60 | return hr; | ||
61 | } | ||
62 | |||
63 | extern "C" HRESULT BVariantGetString( | ||
64 | __in BURN_VARIANT* pVariant, | ||
65 | __out_z LPWSTR* psczValue | ||
66 | ) | ||
67 | { | ||
68 | HRESULT hr = S_OK; | ||
69 | |||
70 | switch (pVariant->Type) | ||
71 | { | ||
72 | case BURN_VARIANT_TYPE_NUMERIC: | ||
73 | hr = StrAllocFormattedSecure(psczValue, L"%I64d", pVariant->llValue); | ||
74 | ExitOnFailure(hr, "Failed to convert int64 to string."); | ||
75 | break; | ||
76 | case BURN_VARIANT_TYPE_FORMATTED: __fallthrough; | ||
77 | case BURN_VARIANT_TYPE_STRING: | ||
78 | hr = StrAllocStringSecure(psczValue, pVariant->sczValue, 0); | ||
79 | ExitOnFailure(hr, "Failed to copy string value."); | ||
80 | break; | ||
81 | case BURN_VARIANT_TYPE_VERSION: | ||
82 | hr = StrAllocStringSecure(psczValue, pVariant->pValue ? pVariant->pValue->sczVersion : NULL, 0); | ||
83 | ExitOnFailure(hr, "Failed to copy version value."); | ||
84 | break; | ||
85 | default: | ||
86 | hr = E_INVALIDARG; | ||
87 | break; | ||
88 | } | ||
89 | |||
90 | LExit: | ||
91 | return hr; | ||
92 | } | ||
93 | |||
94 | extern "C" HRESULT BVariantGetVersion( | ||
95 | __in BURN_VARIANT* pVariant, | ||
96 | __out VERUTIL_VERSION** ppValue | ||
97 | ) | ||
98 | { | ||
99 | return GetVersionInternal(pVariant, FALSE, FALSE, ppValue); | ||
100 | } | ||
101 | |||
102 | extern "C" HRESULT BVariantGetVersionHidden( | ||
103 | __in BURN_VARIANT* pVariant, | ||
104 | __in BOOL fHidden, | ||
105 | __out VERUTIL_VERSION** ppValue | ||
106 | ) | ||
107 | { | ||
108 | return GetVersionInternal(pVariant, fHidden, FALSE, ppValue); | ||
109 | } | ||
110 | |||
111 | extern "C" HRESULT BVariantGetVersionSilent( | ||
112 | __in BURN_VARIANT* pVariant, | ||
113 | __in BOOL fSilent, | ||
114 | __out VERUTIL_VERSION** ppValue | ||
115 | ) | ||
116 | { | ||
117 | return GetVersionInternal(pVariant, FALSE, fSilent, ppValue); | ||
118 | } | ||
119 | |||
120 | static HRESULT GetVersionInternal( | ||
121 | __in BURN_VARIANT* pVariant, | ||
122 | __in BOOL fHidden, | ||
123 | __in BOOL fSilent, | ||
124 | __out VERUTIL_VERSION** ppValue | ||
125 | ) | ||
126 | { | ||
127 | HRESULT hr = S_OK; | ||
128 | |||
129 | switch (pVariant->Type) | ||
130 | { | ||
131 | case BURN_VARIANT_TYPE_NUMERIC: | ||
132 | hr = VerVersionFromQword(pVariant->llValue, ppValue); | ||
133 | break; | ||
134 | case BURN_VARIANT_TYPE_FORMATTED: __fallthrough; | ||
135 | case BURN_VARIANT_TYPE_STRING: | ||
136 | hr = VerParseVersion(pVariant->sczValue, 0, FALSE, ppValue); | ||
137 | if (SUCCEEDED(hr) && !fSilent && (*ppValue)->fInvalid) | ||
138 | { | ||
139 | LogId(REPORT_WARNING, MSG_INVALID_VERSION_COERSION, fHidden ? L"*****" : pVariant->sczValue); | ||
140 | } | ||
141 | break; | ||
142 | case BURN_VARIANT_TYPE_VERSION: | ||
143 | if (!pVariant->pValue) | ||
144 | { | ||
145 | *ppValue = NULL; | ||
146 | } | ||
147 | else | ||
148 | { | ||
149 | hr = VerCopyVersion(pVariant->pValue, ppValue); | ||
150 | } | ||
151 | break; | ||
152 | default: | ||
153 | hr = E_INVALIDARG; | ||
154 | break; | ||
155 | } | ||
156 | |||
157 | return hr; | ||
158 | } | ||
159 | |||
160 | extern "C" HRESULT BVariantSetNumeric( | ||
161 | __in BURN_VARIANT* pVariant, | ||
162 | __in LONGLONG llValue | ||
163 | ) | ||
164 | { | ||
165 | HRESULT hr = S_OK; | ||
166 | |||
167 | if (BURN_VARIANT_TYPE_FORMATTED == pVariant->Type || | ||
168 | BURN_VARIANT_TYPE_STRING == pVariant->Type) | ||
169 | { | ||
170 | StrSecureZeroFreeString(pVariant->sczValue); | ||
171 | } | ||
172 | memset(pVariant, 0, sizeof(BURN_VARIANT)); | ||
173 | pVariant->llValue = llValue; | ||
174 | pVariant->Type = BURN_VARIANT_TYPE_NUMERIC; | ||
175 | |||
176 | return hr; | ||
177 | } | ||
178 | |||
179 | extern "C" HRESULT BVariantSetString( | ||
180 | __in BURN_VARIANT* pVariant, | ||
181 | __in_z_opt LPCWSTR wzValue, | ||
182 | __in DWORD_PTR cchValue, | ||
183 | __in BOOL fFormatted | ||
184 | ) | ||
185 | { | ||
186 | HRESULT hr = S_OK; | ||
187 | |||
188 | if (!wzValue) // if we're nulling out the string, make the variable NONE. | ||
189 | { | ||
190 | BVariantUninitialize(pVariant); | ||
191 | } | ||
192 | else // assign the value. | ||
193 | { | ||
194 | if (BURN_VARIANT_TYPE_FORMATTED != pVariant->Type && | ||
195 | BURN_VARIANT_TYPE_STRING != pVariant->Type) | ||
196 | { | ||
197 | memset(pVariant, 0, sizeof(BURN_VARIANT)); | ||
198 | } | ||
199 | |||
200 | hr = StrAllocStringSecure(&pVariant->sczValue, wzValue, cchValue); | ||
201 | ExitOnFailure(hr, "Failed to copy string."); | ||
202 | |||
203 | pVariant->Type = fFormatted ? BURN_VARIANT_TYPE_FORMATTED : BURN_VARIANT_TYPE_STRING; | ||
204 | } | ||
205 | |||
206 | LExit: | ||
207 | return hr; | ||
208 | } | ||
209 | |||
210 | extern "C" HRESULT BVariantSetVersion( | ||
211 | __in BURN_VARIANT* pVariant, | ||
212 | __in VERUTIL_VERSION* pValue | ||
213 | ) | ||
214 | { | ||
215 | HRESULT hr = S_OK; | ||
216 | |||
217 | if (!pValue) // if we're nulling out the version, make the variable NONE. | ||
218 | { | ||
219 | BVariantUninitialize(pVariant); | ||
220 | } | ||
221 | else // assign the value. | ||
222 | { | ||
223 | if (BURN_VARIANT_TYPE_FORMATTED == pVariant->Type || | ||
224 | BURN_VARIANT_TYPE_STRING == pVariant->Type) | ||
225 | { | ||
226 | StrSecureZeroFreeString(pVariant->sczValue); | ||
227 | } | ||
228 | memset(pVariant, 0, sizeof(BURN_VARIANT)); | ||
229 | hr = VerCopyVersion(pValue, &pVariant->pValue); | ||
230 | pVariant->Type = BURN_VARIANT_TYPE_VERSION; | ||
231 | } | ||
232 | |||
233 | return hr; | ||
234 | } | ||
235 | |||
236 | extern "C" HRESULT BVariantSetValue( | ||
237 | __in BURN_VARIANT* pVariant, | ||
238 | __in BURN_VARIANT* pValue | ||
239 | ) | ||
240 | { | ||
241 | HRESULT hr = S_OK; | ||
242 | |||
243 | switch (pValue->Type) | ||
244 | { | ||
245 | case BURN_VARIANT_TYPE_NONE: | ||
246 | BVariantUninitialize(pVariant); | ||
247 | break; | ||
248 | case BURN_VARIANT_TYPE_NUMERIC: | ||
249 | hr = BVariantSetNumeric(pVariant, pValue->llValue); | ||
250 | break; | ||
251 | case BURN_VARIANT_TYPE_FORMATTED: __fallthrough; | ||
252 | case BURN_VARIANT_TYPE_STRING: | ||
253 | hr = BVariantSetString(pVariant, pValue->sczValue, 0, BURN_VARIANT_TYPE_FORMATTED == pValue->Type); | ||
254 | break; | ||
255 | case BURN_VARIANT_TYPE_VERSION: | ||
256 | hr = BVariantSetVersion(pVariant, pValue->pValue); | ||
257 | break; | ||
258 | default: | ||
259 | hr = E_INVALIDARG; | ||
260 | } | ||
261 | ExitOnFailure(hr, "Failed to copy variant value."); | ||
262 | |||
263 | LExit: | ||
264 | return hr; | ||
265 | } | ||
266 | |||
267 | extern "C" HRESULT BVariantCopy( | ||
268 | __in BURN_VARIANT* pSource, | ||
269 | __out BURN_VARIANT* pTarget | ||
270 | ) | ||
271 | { | ||
272 | return BVariantSetValue(pTarget, pSource); | ||
273 | } | ||
274 | |||
275 | extern "C" HRESULT BVariantChangeType( | ||
276 | __in BURN_VARIANT* pVariant, | ||
277 | __in BURN_VARIANT_TYPE type | ||
278 | ) | ||
279 | { | ||
280 | HRESULT hr = S_OK; | ||
281 | BURN_VARIANT variant = { }; | ||
282 | |||
283 | if (pVariant->Type == type) | ||
284 | { | ||
285 | ExitFunction(); // variant already is of the requested type | ||
286 | } | ||
287 | else if (BURN_VARIANT_TYPE_FORMATTED == pVariant->Type && BURN_VARIANT_TYPE_STRING == type || | ||
288 | BURN_VARIANT_TYPE_STRING == pVariant->Type && BURN_VARIANT_TYPE_FORMATTED == type) | ||
289 | { | ||
290 | pVariant->Type = type; | ||
291 | ExitFunction(); | ||
292 | } | ||
293 | |||
294 | switch (type) | ||
295 | { | ||
296 | case BURN_VARIANT_TYPE_NONE: | ||
297 | hr = S_OK; | ||
298 | break; | ||
299 | case BURN_VARIANT_TYPE_NUMERIC: | ||
300 | hr = BVariantGetNumeric(pVariant, &variant.llValue); | ||
301 | break; | ||
302 | case BURN_VARIANT_TYPE_FORMATTED: __fallthrough; | ||
303 | case BURN_VARIANT_TYPE_STRING: | ||
304 | hr = BVariantGetString(pVariant, &variant.sczValue); | ||
305 | break; | ||
306 | case BURN_VARIANT_TYPE_VERSION: | ||
307 | hr = BVariantGetVersionSilent(pVariant, TRUE, &variant.pValue); | ||
308 | break; | ||
309 | default: | ||
310 | ExitFunction1(hr = E_INVALIDARG); | ||
311 | } | ||
312 | variant.Type = type; | ||
313 | ExitOnFailure(hr, "Failed to copy variant value."); | ||
314 | |||
315 | BVariantUninitialize(pVariant); | ||
316 | memcpy_s(pVariant, sizeof(BURN_VARIANT), &variant, sizeof(BURN_VARIANT)); | ||
317 | SecureZeroMemory(&variant, sizeof(BURN_VARIANT)); | ||
318 | |||
319 | LExit: | ||
320 | return hr; | ||
321 | } | ||