summaryrefslogtreecommitdiff
path: root/src/burn/engine/variant.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/burn/engine/variant.cpp')
-rw-r--r--src/burn/engine/variant.cpp321
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
7static 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
16extern "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
28extern "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
63extern "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
90LExit:
91 return hr;
92}
93
94extern "C" HRESULT BVariantGetVersion(
95 __in BURN_VARIANT* pVariant,
96 __out VERUTIL_VERSION** ppValue
97 )
98{
99 return GetVersionInternal(pVariant, FALSE, FALSE, ppValue);
100}
101
102extern "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
111extern "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
120static 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
160extern "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
179extern "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
206LExit:
207 return hr;
208}
209
210extern "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
236extern "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
263LExit:
264 return hr;
265}
266
267extern "C" HRESULT BVariantCopy(
268 __in BURN_VARIANT* pSource,
269 __out BURN_VARIANT* pTarget
270 )
271{
272 return BVariantSetValue(pTarget, pSource);
273}
274
275extern "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
319LExit:
320 return hr;
321}