aboutsummaryrefslogtreecommitdiff
path: root/src/burn/test/BurnUnitTest/SearchTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/burn/test/BurnUnitTest/SearchTest.cpp')
-rw-r--r--src/burn/test/BurnUnitTest/SearchTest.cpp815
1 files changed, 815 insertions, 0 deletions
diff --git a/src/burn/test/BurnUnitTest/SearchTest.cpp b/src/burn/test/BurnUnitTest/SearchTest.cpp
new file mode 100644
index 00000000..eca01f5f
--- /dev/null
+++ b/src/burn/test/BurnUnitTest/SearchTest.cpp
@@ -0,0 +1,815 @@
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
6static INSTALLSTATE WINAPI MsiComponentSearchTest_MsiGetComponentPathW(
7 __in LPCWSTR szProduct,
8 __in LPCWSTR szComponent,
9 __out_ecount_opt(*pcchBuf) LPWSTR lpPathBuf,
10 __inout_opt LPDWORD pcchBuf
11 );
12static INSTALLSTATE WINAPI MsiComponentSearchTest_MsiLocateComponentW(
13 __in LPCWSTR szComponent,
14 __out_ecount_opt(*pcchBuf) LPWSTR lpPathBuf,
15 __inout_opt LPDWORD pcchBuf
16 );
17static UINT WINAPI MsiProductSearchTest_MsiGetProductInfoW(
18 __in LPCWSTR szProductCode,
19 __in LPCWSTR szProperty,
20 __out_ecount_opt(*pcchValue) LPWSTR szValue,
21 __inout_opt LPDWORD pcchValue
22 );
23static UINT WINAPI MsiProductSearchTest_MsiGetProductInfoExW(
24 __in LPCWSTR szProductCode,
25 __in_opt LPCWSTR szUserSid,
26 __in MSIINSTALLCONTEXT dwContext,
27 __in LPCWSTR szProperty,
28 __out_ecount_opt(*pcchValue) LPWSTR szValue,
29 __inout_opt LPDWORD pcchValue
30 );
31
32using namespace System;
33using namespace Xunit;
34using namespace Microsoft::Win32;
35
36namespace Microsoft
37{
38namespace Tools
39{
40namespace WindowsInstallerXml
41{
42namespace Test
43{
44namespace Bootstrapper
45{
46 public ref class SearchTest : BurnUnitTest
47 {
48 public:
49 SearchTest(BurnTestFixture^ fixture) : BurnUnitTest(fixture)
50 {
51 }
52
53 [Fact]
54 void DirectorySearchTest()
55 {
56 HRESULT hr = S_OK;
57 IXMLDOMElement* pixeBundle = NULL;
58 BURN_VARIABLES variables = { };
59 BURN_SEARCHES searches = { };
60 BURN_EXTENSIONS burnExtensions = { };
61 try
62 {
63 hr = VariableInitialize(&variables);
64 TestThrowOnFailure(hr, L"Failed to initialize variables.");
65
66 pin_ptr<const WCHAR> wzDirectory1 = PtrToStringChars(this->TestContext->TestDirectory);
67 pin_ptr<const WCHAR> wzDirectory2 = PtrToStringChars(System::IO::Path::Combine(this->TestContext->TestDirectory, gcnew String(L"none")));
68
69 VariableSetStringHelper(&variables, L"Directory1", wzDirectory1, FALSE);
70 VariableSetStringHelper(&variables, L"Directory2", wzDirectory2, FALSE);
71
72 LPCWSTR wzDocument =
73 L"<Bundle>"
74 L" <DirectorySearch Id='Search1' Type='exists' Path='[Directory1]' Variable='Variable1' />"
75 L" <DirectorySearch Id='Search2' Type='exists' Path='[Directory2]' Variable='Variable2' />"
76 L"</Bundle>";
77
78 // load XML document
79 LoadBundleXmlHelper(wzDocument, &pixeBundle);
80
81 hr = SearchesParseFromXml(&searches, &burnExtensions, pixeBundle);
82 TestThrowOnFailure(hr, L"Failed to parse searches from XML.");
83
84 // execute searches
85 hr = SearchesExecute(&searches, &variables);
86 TestThrowOnFailure(hr, L"Failed to execute searches.");
87
88 // check variable values
89 Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable1"));
90 Assert::Equal(0ll, VariableGetNumericHelper(&variables, L"Variable2"));
91 }
92 finally
93 {
94 ReleaseObject(pixeBundle);
95 VariablesUninitialize(&variables);
96 SearchesUninitialize(&searches);
97 }
98 }
99
100 [Fact(Skip = "Currently fails")]
101 void FileSearchTest()
102 {
103 HRESULT hr = S_OK;
104 IXMLDOMElement* pixeBundle = NULL;
105 BURN_VARIABLES variables = { };
106 BURN_SEARCHES searches = { };
107 BURN_EXTENSIONS burnExtensions = { };
108 ULARGE_INTEGER uliVersion = { };
109 VERUTIL_VERSION* pVersion = NULL;
110 try
111 {
112 hr = VariableInitialize(&variables);
113 TestThrowOnFailure(hr, L"Failed to initialize variables.");
114
115 pin_ptr<const WCHAR> wzFile1 = PtrToStringChars(System::IO::Path::Combine(this->TestContext->TestDirectory, gcnew String(L"none.txt")));
116 pin_ptr<const WCHAR> wzFile2 = PtrToStringChars(System::Reflection::Assembly::GetExecutingAssembly()->Location);
117
118 hr = FileVersion(wzFile2, &uliVersion.HighPart, &uliVersion.LowPart);
119 TestThrowOnFailure(hr, L"Failed to get DLL version.");
120
121 hr = VerVersionFromQword(uliVersion.QuadPart, &pVersion);
122 NativeAssert::Succeeded(hr, "Failed to create version.");
123
124 VariableSetStringHelper(&variables, L"File1", wzFile1, FALSE);
125 VariableSetStringHelper(&variables, L"File2", wzFile2, FALSE);
126
127 LPCWSTR wzDocument =
128 L"<Bundle>"
129 L" <FileSearch Id='Search1' Type='exists' Path='[File1]' Variable='Variable1' />"
130 L" <FileSearch Id='Search2' Type='exists' Path='[File2]' Variable='Variable2' />"
131 L" <FileSearch Id='Search3' Type='version' Path='[File2]' Variable='Variable3' />"
132 L"</Bundle>";
133
134 // load XML document
135 LoadBundleXmlHelper(wzDocument, &pixeBundle);
136
137 hr = SearchesParseFromXml(&searches, &burnExtensions, pixeBundle);
138 TestThrowOnFailure(hr, L"Failed to parse searches from XML.");
139
140 // execute searches
141 hr = SearchesExecute(&searches, &variables);
142 TestThrowOnFailure(hr, L"Failed to execute searches.");
143
144 // check variable values
145 Assert::Equal(0ll, VariableGetNumericHelper(&variables, L"Variable1"));
146 Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable2"));
147 Assert::Equal<String^>(gcnew String(pVersion->sczVersion), VariableGetVersionHelper(&variables, L"Variable3"));
148 }
149 finally
150 {
151 ReleaseVerutilVersion(pVersion);
152 ReleaseObject(pixeBundle);
153 VariablesUninitialize(&variables);
154 SearchesUninitialize(&searches);
155 }
156 }
157
158 [Fact]
159 void RegistrySearchTest()
160 {
161 HRESULT hr = S_OK;
162 IXMLDOMElement* pixeBundle = NULL;
163 BURN_VARIABLES variables = { };
164 BURN_SEARCHES searches = { };
165 BURN_EXTENSIONS burnExtensions = { };
166 HKEY hkey32 = NULL;
167 HKEY hkey64 = NULL;
168 BOOL f64bitMachine = (nullptr != Environment::GetEnvironmentVariable("ProgramFiles(x86)"));
169
170 try
171 {
172 hr = VariableInitialize(&variables);
173 TestThrowOnFailure(hr, L"Failed to initialize variables.");
174
175 Registry::SetValue(gcnew String(L"HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Value"), gcnew String(L"String"), gcnew String(L"String1 %TEMP%"), RegistryValueKind::String);
176 Registry::SetValue(gcnew String(L"HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Value"), gcnew String(L"StringExpand"), gcnew String(L"String1 %TEMP%"), RegistryValueKind::ExpandString);
177 Registry::SetValue(gcnew String(L"HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Value"), gcnew String(L"DWord"), 1, RegistryValueKind::DWord);
178 Registry::SetValue(gcnew String(L"HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Value"), gcnew String(L"QWord"), 1ll, RegistryValueKind::QWord);
179 Registry::SetValue(gcnew String(L"HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Value"), gcnew String(L"VersionString"), gcnew String(L"1.1.1.1"), RegistryValueKind::String);
180 Registry::SetValue(gcnew String(L"HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Value"), gcnew String(L"VersionQWord"), MAKEQWORDVERSION(1,1,1,1), RegistryValueKind::QWord);
181 Registry::SetValue(gcnew String(L"HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\String"), nullptr, gcnew String(L"String1"), RegistryValueKind::String);
182 Registry::SetValue(gcnew String(L"HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Numeric"), nullptr, 1ll, RegistryValueKind::DWord);
183
184 if (f64bitMachine)
185 {
186 hr = RegCreate(HKEY_CURRENT_USER, L"SOFTWARE\\Classes\\CLSID\\WiX_Burn_UnitTest\\Bitness\\", KEY_WRITE | KEY_WOW64_32KEY, &hkey32);
187 Assert::True(SUCCEEDED(hr));
188
189 hr = RegCreate(HKEY_CURRENT_USER, L"SOFTWARE\\Classes\\CLSID\\WiX_Burn_UnitTest\\Bitness\\", KEY_WRITE | KEY_WOW64_64KEY, &hkey64);
190 Assert::True(SUCCEEDED(hr));
191
192 hr = RegWriteString(hkey64, L"TestStringSpecificToBitness", L"64-bit");
193 Assert::True(SUCCEEDED(hr));
194
195 hr = RegWriteString(hkey32, L"TestStringSpecificToBitness", L"32-bit");
196 Assert::True(SUCCEEDED(hr));
197 }
198
199 VariableSetStringHelper(&variables, L"MyKey", L"SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Value", FALSE);
200 VariableSetStringHelper(&variables, L"MyValue", L"String", FALSE);
201 VariableSetStringHelper(&variables, L"Variable27", L"Default27", FALSE);
202 VariableSetStringHelper(&variables, L"Variable28", L"Default28", FALSE);
203
204 LPCWSTR wzDocument =
205 L"<Bundle>"
206 L" <RegistrySearch Id='Search1' Type='exists' Root='HKLM' Key='SOFTWARE\\Microsoft' Variable='Variable1' />"
207 L" <RegistrySearch Id='Search2' Type='exists' Root='HKCU' Key='SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\None' Variable='Variable2' />"
208 L" <RegistrySearch Id='Search3' Type='exists' Root='HKCU' Key='SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Value' Value='None' Variable='Variable3' />"
209 L" <RegistrySearch Id='Search4' Type='exists' Root='HKCU' Key='SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Value' Value='String' Variable='Variable4' />"
210 L" <RegistrySearch Id='Search5' Type='value' Root='HKCU' Key='SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Value' Value='String' Variable='Variable5' VariableType='string' />"
211 L" <RegistrySearch Id='Search6' Type='value' Root='HKCU' Key='SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Value' Value='String' Variable='Variable6' VariableType='string' ExpandEnvironment='no' />"
212 L" <RegistrySearch Id='Search7' Type='value' Root='HKCU' Key='SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Value' Value='String' Variable='Variable7' VariableType='string' ExpandEnvironment='yes' />"
213 L" <RegistrySearch Id='Search8' Type='value' Root='HKCU' Key='SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Value' Value='StringExpand' Variable='Variable8' VariableType='string' />"
214 L" <RegistrySearch Id='Search9' Type='value' Root='HKCU' Key='SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Value' Value='StringExpand' Variable='Variable9' VariableType='string' ExpandEnvironment='no' />"
215 L" <RegistrySearch Id='Search10' Type='value' Root='HKCU' Key='SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Value' Value='StringExpand' Variable='Variable10' VariableType='string' ExpandEnvironment='yes' />"
216 L" <RegistrySearch Id='Search11' Type='value' Root='HKCU' Key='SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Value' Value='DWord' Variable='Variable11' VariableType='numeric' />"
217 L" <RegistrySearch Id='Search12' Type='value' Root='HKCU' Key='SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Value' Value='QWord' Variable='Variable12' VariableType='numeric' />"
218 L" <RegistrySearch Id='Search13' Type='value' Root='HKCU' Key='SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Value' Value='VersionString' Variable='Variable13' VariableType='version' />"
219 L" <RegistrySearch Id='Search14' Type='value' Root='HKCU' Key='SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Value' Value='VersionQWord' Variable='Variable14' VariableType='version' />"
220 L" <RegistrySearch Id='Search15' Type='value' Root='HKCU' Key='SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\String' Variable='Variable15' VariableType='string' />"
221 L" <RegistrySearch Id='Search16' Type='value' Root='HKCU' Key='SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Numeric' Variable='Variable16' VariableType='numeric' />"
222 L" <RegistrySearch Id='Search17' Type='value' Root='HKCU' Key='SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\None' Variable='Variable17' VariableType='numeric' />"
223 L" <RegistrySearch Id='Search18' Type='value' Root='HKCU' Key='SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Numeric' Value='None' Variable='Variable18' VariableType='numeric' />"
224 L" <RegistrySearch Id='Search19' Type='exists' Root='HKCU' Key='[MyKey]' Value='[MyValue]' Variable='Variable19' />"
225 L" <RegistrySearch Id='Search20' Type='value' Root='HKCU' Key='[MyKey]' Value='[MyValue]' Variable='Variable20' VariableType='string' />"
226 L" <RegistrySearch Id='Search21' Type='value' Root='HKCU' Key='SOFTWARE\\Classes\\CLSID\\WiX_Burn_UnitTest\\Bitness' Value='TestStringSpecificToBitness' Variable='Variable21' VariableType='string' Win64='no' />"
227 L" <RegistrySearch Id='Search22' Type='value' Root='HKCU' Key='SOFTWARE\\Classes\\CLSID\\WiX_Burn_UnitTest\\Bitness' Value='TestStringSpecificToBitness' Variable='Variable22' VariableType='string' Win64='yes' />"
228 L" <RegistrySearch Id='Search23' Type='exists' Root='HKU' Key='.DEFAULT\\Environment' Variable='Variable23' />"
229 L" <RegistrySearch Id='Search24' Type='exists' Root='HKU' Key='.DEFAULT\\System\\NetworkServiceSidSubkeyDoesNotExist' Variable='Variable24' />"
230 L" <RegistrySearch Id='Search25' Type='value' Root='HKCR' Key='.msi' Variable='Variable25' VariableType='string' />"
231 L" <RegistrySearch Id='Search26' Type='value' Root='HKCR' Key='.msi' Variable='Variable26' VariableType='formatted' />"
232 L" <RegistrySearch Id='Search27' Type='value' Root='HKCU' Key='SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\StringDoesNotExist' Value='String' Variable='Variable27' VariableType='string' />"
233 L" <RegistrySearch Id='Search28' Type='value' Root='HKCU' Key='SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\String' Value='DoesNotExist' Variable='Variable28' VariableType='string' />"
234 L"</Bundle>";
235
236 // load XML document
237 LoadBundleXmlHelper(wzDocument, &pixeBundle);
238
239 hr = SearchesParseFromXml(&searches, &burnExtensions, pixeBundle);
240 TestThrowOnFailure(hr, L"Failed to parse searches from XML.");
241
242 // execute searches
243 hr = SearchesExecute(&searches, &variables);
244 TestThrowOnFailure(hr, L"Failed to execute searches.");
245
246 // check variable values
247 Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable1"));
248 Assert::Equal(0ll, VariableGetNumericHelper(&variables, L"Variable2"));
249 Assert::Equal(0ll, VariableGetNumericHelper(&variables, L"Variable3"));
250 Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable4"));
251 Assert::Equal<String^>(gcnew String(L"String1 %TEMP%"), VariableGetStringHelper(&variables, L"Variable5"));
252 Assert::Equal<String^>(gcnew String(L"String1 %TEMP%"), VariableGetStringHelper(&variables, L"Variable6"));
253 Assert::Equal<String^>(gcnew String(L"String1 %TEMP%"), VariableGetStringHelper(&variables, L"Variable7"));
254 Assert::Equal<String^>(gcnew String(L"String1 %TEMP%"), VariableGetStringHelper(&variables, L"Variable8"));
255 Assert::Equal<String^>(gcnew String(L"String1 %TEMP%"), VariableGetStringHelper(&variables, L"Variable9"));
256 Assert::NotEqual(gcnew String(L"String1 %TEMP%"), VariableGetStringHelper(&variables, L"Variable10"));
257 Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable11"));
258 Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable12"));
259 Assert::Equal<String^>(gcnew String(L"1.1.1.1"), VariableGetVersionHelper(&variables, L"Variable13"));
260 Assert::Equal<String^>(gcnew String(L"1.1.1.1"), VariableGetVersionHelper(&variables, L"Variable14"));
261 Assert::Equal<String^>(gcnew String(L"String1"), VariableGetStringHelper(&variables, L"Variable15"));
262 Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable16"));
263 Assert::False(VariableExistsHelper(&variables, L"Variable17"));
264 Assert::False(VariableExistsHelper(&variables, L"Variable18"));
265 Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable19"));
266 Assert::Equal<String^>(gcnew String(L"String1 %TEMP%"), VariableGetStringHelper(&variables, L"Variable20"));
267 if (f64bitMachine)
268 {
269 Assert::Equal<String^>(gcnew String(L"32-bit"), VariableGetStringHelper(&variables, L"Variable21"));
270 Assert::Equal<String^>(gcnew String(L"64-bit"), VariableGetStringHelper(&variables, L"Variable22"));
271 }
272
273 Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable23"));
274 Assert::Equal(0ll, VariableGetNumericHelper(&variables, L"Variable24"));
275 Assert::Equal<String^>(gcnew String(L"Msi.Package"), VariableGetStringHelper(&variables, L"Variable25"));
276 Assert::Equal<String^>(gcnew String(L"Msi.Package"), VariableGetStringHelper(&variables, L"Variable26"));
277 Assert::Equal<String^>(gcnew String(L"Default27"), VariableGetStringHelper(&variables, L"Variable27"));
278 Assert::Equal<String^>(gcnew String(L"Default28"), VariableGetStringHelper(&variables, L"Variable28"));
279 }
280 finally
281 {
282 ReleaseRegKey(hkey32);
283 ReleaseRegKey(hkey64);
284 ReleaseObject(pixeBundle);
285 VariablesUninitialize(&variables);
286 SearchesUninitialize(&searches);
287
288 Registry::CurrentUser->DeleteSubKeyTree(gcnew String(L"SOFTWARE\\Microsoft\\WiX_Burn_UnitTest"));
289 if (f64bitMachine)
290 {
291 RegDelete(HKEY_CURRENT_USER, L"SOFTWARE\\Classes\\CLSID\\WiX_Burn_UnitTest\\Bitness", REG_KEY_32BIT, FALSE);
292 RegDelete(HKEY_CURRENT_USER, L"SOFTWARE\\Classes\\CLSID\\WiX_Burn_UnitTest", REG_KEY_32BIT, FALSE);
293 RegDelete(HKEY_CURRENT_USER, L"SOFTWARE\\Classes\\CLSID\\WiX_Burn_UnitTest\\Bitness", REG_KEY_64BIT, FALSE);
294 RegDelete(HKEY_CURRENT_USER, L"SOFTWARE\\Classes\\CLSID\\WiX_Burn_UnitTest", REG_KEY_64BIT, FALSE);
295 }
296 }
297 }
298
299 [Fact]
300 void MsiComponentSearchTest()
301 {
302 HRESULT hr = S_OK;
303 IXMLDOMElement* pixeBundle = NULL;
304 BURN_VARIABLES variables = { };
305 BURN_SEARCHES searches = { };
306 BURN_EXTENSIONS burnExtensions = { };
307 try
308 {
309 hr = VariableInitialize(&variables);
310 TestThrowOnFailure(hr, L"Failed to initialize variables.");
311
312 // set mock API's
313 WiuFunctionOverride(NULL, MsiComponentSearchTest_MsiGetComponentPathW, MsiComponentSearchTest_MsiLocateComponentW, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
314
315 LPCWSTR wzDocument =
316 L"<Bundle>"
317 L" <MsiComponentSearch Id='Search1' Type='state' ComponentId='{BAD00000-1000-0000-0000-000000000000}' Variable='Variable1' />"
318 L" <MsiComponentSearch Id='Search2' Type='state' ProductCode='{BAD00000-0000-0000-0000-000000000000}' ComponentId='{BAD00000-1000-0000-0000-000000000000}' Variable='Variable2' />"
319 L" <MsiComponentSearch Id='Search3' Type='state' ProductCode='{600D0000-0000-0000-0000-000000000000}' ComponentId='{BAD00000-1000-0000-0000-000000000000}' Variable='Variable3' />"
320 L" <MsiComponentSearch Id='Search4' Type='keyPath' ProductCode='{600D0000-0000-0000-0000-000000000000}' ComponentId='{600D0000-1000-1000-0000-000000000000}' Variable='Variable4' />"
321 L" <MsiComponentSearch Id='Search5' Type='keyPath' ProductCode='{600D0000-0000-0000-0000-000000000000}' ComponentId='{600D0000-1000-2000-0000-000000000000}' Variable='Variable5' />"
322 L" <MsiComponentSearch Id='Search6' Type='keyPath' ProductCode='{600D0000-0000-0000-0000-000000000000}' ComponentId='{600D0000-1000-3000-0000-000000000000}' Variable='Variable6' />"
323 L" <MsiComponentSearch Id='Search7' Type='keyPath' ProductCode='{600D0000-0000-0000-0000-000000000000}' ComponentId='{600D0000-1000-4000-0000-000000000000}' Variable='Variable7' />"
324 L" <MsiComponentSearch Id='Search8' Type='keyPath' ProductCode='{600D0000-0000-0000-0000-000000000000}' ComponentId='{600D0000-1000-5000-0000-000000000000}' Variable='Variable8' />"
325 L" <MsiComponentSearch Id='Search9' Type='keyPath' ProductCode='{600D0000-0000-0000-0000-000000000000}' ComponentId='{600D0000-1000-6000-0000-000000000000}' Variable='Variable9' />" // todo: value key path
326 L" <MsiComponentSearch Id='Search10' Type='state' ComponentId='{600D0000-1000-1000-0000-000000000000}' Variable='Variable10' />"
327 L" <MsiComponentSearch Id='Search11' Type='state' ProductCode='{600D0000-0000-0000-0000-000000000000}' ComponentId='{600D0000-1000-1000-0000-000000000000}' Variable='Variable11' />"
328 L" <MsiComponentSearch Id='Search12' Type='state' ProductCode='{600D0000-0000-0000-0000-000000000000}' ComponentId='{600D0000-1000-2000-0000-000000000000}' Variable='Variable12' />"
329 L" <MsiComponentSearch Id='Search13' Type='state' ProductCode='{600D0000-0000-0000-0000-000000000000}' ComponentId='{600D0000-1000-3000-0000-000000000000}' Variable='Variable13' />"
330 L" <MsiComponentSearch Id='Search14' Type='state' ProductCode='{600D0000-0000-0000-0000-000000000000}' ComponentId='{600D0000-1000-4000-0000-000000000000}' Variable='Variable14' />"
331 L" <MsiComponentSearch Id='Search15' Type='directory' ProductCode='{600D0000-0000-0000-0000-000000000000}' ComponentId='{600D0000-1000-1000-0000-000000000000}' Variable='Variable15' />"
332 L" <MsiComponentSearch Id='Search16' Type='directory' ProductCode='{600D0000-0000-0000-0000-000000000000}' ComponentId='{600D0000-1000-2000-0000-000000000000}' Variable='Variable16' />"
333 L" <MsiComponentSearch Id='Search17' Type='directory' ProductCode='{600D0000-0000-0000-0000-000000000000}' ComponentId='{600D0000-1000-3000-0000-000000000000}' Variable='Variable17' />"
334 L" <MsiComponentSearch Id='Search18' Type='directory' ProductCode='{600D0000-0000-0000-0000-000000000000}' ComponentId='{600D0000-1000-4000-0000-000000000000}' Variable='Variable18' />"
335 L" <MsiComponentSearch Id='Search19' Type='keyPath' ProductCode='{600D0000-0000-0000-0000-000000000000}' ComponentId='{600D0000-1000-7000-0000-000000000000}' Variable='Variable19' />"
336 L"</Bundle>";
337
338 // load XML document
339 LoadBundleXmlHelper(wzDocument, &pixeBundle);
340
341 hr = SearchesParseFromXml(&searches, &burnExtensions, pixeBundle);
342 TestThrowOnFailure(hr, L"Failed to parse searches from XML.");
343
344 // execute searches
345 hr = SearchesExecute(&searches, &variables);
346 TestThrowOnFailure(hr, L"Failed to execute searches.");
347
348 // check variable values
349 Assert::Equal(2ll, VariableGetNumericHelper(&variables, L"Variable1"));
350 Assert::Equal(2ll, VariableGetNumericHelper(&variables, L"Variable2"));
351 Assert::Equal(2ll, VariableGetNumericHelper(&variables, L"Variable3"));
352 Assert::Equal<String^>(gcnew String(L"C:\\directory\\file1.txt"), VariableGetStringHelper(&variables, L"Variable4"));
353 Assert::Equal<String^>(gcnew String(L"C:\\directory\\file2.txt"), VariableGetStringHelper(&variables, L"Variable5"));
354 Assert::Equal<String^>(gcnew String(L"C:\\directory\\file3.txt"), VariableGetStringHelper(&variables, L"Variable6"));
355 Assert::Equal<String^>(gcnew String(L"C:\\directory\\file4.txt"), VariableGetStringHelper(&variables, L"Variable7"));
356 Assert::Equal<String^>(gcnew String(L"02:\\SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\"), VariableGetStringHelper(&variables, L"Variable8"));
357 Assert::Equal<String^>(gcnew String(L"02:\\SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Value"), VariableGetStringHelper(&variables, L"Variable9"));
358 Assert::Equal(3ll, VariableGetNumericHelper(&variables, L"Variable10"));
359 Assert::Equal(3ll, VariableGetNumericHelper(&variables, L"Variable11"));
360 Assert::Equal(4ll, VariableGetNumericHelper(&variables, L"Variable12"));
361 Assert::Equal(4ll, VariableGetNumericHelper(&variables, L"Variable13"));
362 Assert::Equal(2ll, VariableGetNumericHelper(&variables, L"Variable14"));
363 Assert::Equal<String^>(gcnew String(L"C:\\directory\\"), VariableGetStringHelper(&variables, L"Variable15"));
364 Assert::Equal<String^>(gcnew String(L"C:\\directory\\"), VariableGetStringHelper(&variables, L"Variable16"));
365 Assert::Equal<String^>(gcnew String(L"C:\\directory\\"), VariableGetStringHelper(&variables, L"Variable17"));
366 Assert::Equal<String^>(gcnew String(L"C:\\directory\\"), VariableGetStringHelper(&variables, L"Variable18"));
367 Assert::Equal<String^>(gcnew String(L"C:\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\file5.txt"), VariableGetStringHelper(&variables, L"Variable19"));
368 }
369 finally
370 {
371 ReleaseObject(pixeBundle);
372 VariablesUninitialize(&variables);
373 SearchesUninitialize(&searches);
374 }
375 }
376
377 [Fact]
378 void MsiProductSearchTest()
379 {
380 HRESULT hr = S_OK;
381 IXMLDOMElement* pixeBundle = NULL;
382 BURN_VARIABLES variables = { };
383 BURN_SEARCHES searches = { };
384 BURN_EXTENSIONS burnExtensions = { };
385 try
386 {
387 hr = VariableInitialize(&variables);
388 TestThrowOnFailure(hr, L"Failed to initialize variables.");
389
390 // set mock API's
391 WiuFunctionOverride(NULL, NULL, NULL, NULL, MsiProductSearchTest_MsiGetProductInfoW, MsiProductSearchTest_MsiGetProductInfoExW, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
392
393 LPCWSTR wzDocument =
394 L"<Bundle>"
395 L" <MsiProductSearch Id='Search1' Type='state' ProductCode='{BAD00000-0000-0000-0000-000000000000}' Variable='Variable1' />"
396 L" <MsiProductSearch Id='Search2' Type='version' ProductCode='{600D0000-0000-0000-0000-000000000000}' Variable='Variable2' />"
397 L" <MsiProductSearch Id='Search3' Type='language' ProductCode='{600D0000-0000-0000-0000-000000000000}' Variable='Variable3' />"
398 L" <MsiProductSearch Id='Search4' Type='state' ProductCode='{600D0000-0000-0000-0000-000000000000}' Variable='Variable4' />"
399 L" <MsiProductSearch Id='Search5' Type='assignment' ProductCode='{600D0000-0000-0000-0000-000000000000}' Variable='Variable5' />"
400 L" <MsiProductSearch Id='Search6' Type='version' ProductCode='{600D0000-1000-0000-0000-000000000000}' Variable='Variable6' />"
401 L"</Bundle>";
402
403 // load XML document
404 LoadBundleXmlHelper(wzDocument, &pixeBundle);
405
406 hr = SearchesParseFromXml(&searches, &burnExtensions, pixeBundle);
407 TestThrowOnFailure(hr, L"Failed to parse searches from XML.");
408
409 // execute searches
410 hr = SearchesExecute(&searches, &variables);
411 TestThrowOnFailure(hr, L"Failed to execute searches.");
412
413 // check variable values
414 Assert::Equal(2ll, VariableGetNumericHelper(&variables, L"Variable1"));
415 Assert::Equal<String^>(gcnew String(L"1.0.0.0"), VariableGetVersionHelper(&variables, L"Variable2"));
416 Assert::Equal(1033ll, VariableGetNumericHelper(&variables, L"Variable3"));
417 Assert::Equal(5ll, VariableGetNumericHelper(&variables, L"Variable4"));
418 Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable5"));
419 Assert::Equal<String^>(gcnew String(L"1.0.0.0"), VariableGetVersionHelper(&variables, L"Variable6"));
420 }
421 finally
422 {
423 ReleaseObject(pixeBundle);
424 VariablesUninitialize(&variables);
425 SearchesUninitialize(&searches);
426 }
427 }
428
429 [Fact]
430 void MsiFeatureSearchTest()
431 {
432 HRESULT hr = S_OK;
433 IXMLDOMElement* pixeBundle = NULL;
434 BURN_VARIABLES variables = { };
435 BURN_SEARCHES searches = { };
436 BURN_EXTENSIONS burnExtensions = { };
437 try
438 {
439 LPCWSTR wzDocument =
440 L"<Bundle>"
441 L" <MsiFeatureSearch Id='Search1' Type='state' ProductCode='{BAD00000-0000-0000-0000-000000000000}' FeatureId='' Variable='Variable1' />"
442 L"</Bundle>";
443
444 hr = VariableInitialize(&variables);
445 TestThrowOnFailure(hr, L"Failed to initialize variables.");
446
447 // load XML document
448 LoadBundleXmlHelper(wzDocument, &pixeBundle);
449
450 hr = SearchesParseFromXml(&searches, &burnExtensions, pixeBundle);
451 TestThrowOnFailure(hr, L"Failed to parse searches from XML.");
452
453 // execute searches
454 hr = SearchesExecute(&searches, &variables);
455 TestThrowOnFailure(hr, L"Failed to execute searches.");
456 }
457 finally
458 {
459 ReleaseObject(pixeBundle);
460 VariablesUninitialize(&variables);
461 SearchesUninitialize(&searches);
462 }
463 }
464
465 [Fact]
466 void ConditionalSearchTest()
467 {
468 HRESULT hr = S_OK;
469 IXMLDOMElement* pixeBundle = NULL;
470 BURN_VARIABLES variables = { };
471 BURN_SEARCHES searches = { };
472 BURN_EXTENSIONS burnExtensions = { };
473 try
474 {
475 LPCWSTR wzDocument =
476 L"<Bundle>"
477 L" <RegistrySearch Id='Search1' Type='exists' Root='HKLM' Key='SOFTWARE\\Microsoft' Variable='Variable1' Condition='0' />"
478 L" <RegistrySearch Id='Search2' Type='exists' Root='HKLM' Key='SOFTWARE\\Microsoft' Variable='Variable2' Condition='1' />"
479 L" <RegistrySearch Id='Search3' Type='exists' Root='HKLM' Key='SOFTWARE\\Microsoft' Variable='Variable3' Condition='=' />"
480 L"</Bundle>";
481
482 hr = VariableInitialize(&variables);
483 TestThrowOnFailure(hr, L"Failed to initialize variables.");
484
485 // load XML document
486 LoadBundleXmlHelper(wzDocument, &pixeBundle);
487
488 hr = SearchesParseFromXml(&searches, &burnExtensions, pixeBundle);
489 TestThrowOnFailure(hr, L"Failed to parse searches from XML.");
490
491 // execute searches
492 hr = SearchesExecute(&searches, &variables);
493 TestThrowOnFailure(hr, L"Failed to execute searches.");
494
495 // check variable values
496 Assert::False(VariableExistsHelper(&variables, L"Variable1"));
497 Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable2"));
498 Assert::False(VariableExistsHelper(&variables, L"Variable3"));
499 }
500 finally
501 {
502 ReleaseObject(pixeBundle);
503 VariablesUninitialize(&variables);
504 SearchesUninitialize(&searches);
505 }
506 }
507 [Fact]
508 void NoSearchesTest()
509 {
510 HRESULT hr = S_OK;
511 IXMLDOMElement* pixeBundle = NULL;
512 BURN_VARIABLES variables = { };
513 BURN_SEARCHES searches = { };
514 BURN_EXTENSIONS burnExtensions = { };
515 try
516 {
517 LPCWSTR wzDocument =
518 L"<Bundle>"
519 L"</Bundle>";
520
521 hr = VariableInitialize(&variables);
522 TestThrowOnFailure(hr, L"Failed to initialize variables.");
523
524 // load XML document
525 LoadBundleXmlHelper(wzDocument, &pixeBundle);
526
527 hr = SearchesParseFromXml(&searches, &burnExtensions, pixeBundle);
528 TestThrowOnFailure(hr, L"Failed to parse searches from XML.");
529
530 // execute searches
531 hr = SearchesExecute(&searches, &variables);
532 TestThrowOnFailure(hr, L"Failed to execute searches.");
533 }
534 finally
535 {
536 ReleaseObject(pixeBundle);
537 VariablesUninitialize(&variables);
538 SearchesUninitialize(&searches);
539 }
540 }
541
542 [Fact]
543 void SetVariableSearchTest()
544 {
545 HRESULT hr = S_OK;
546 IXMLDOMElement* pixeBundle = NULL;
547 BURN_VARIABLES variables = { };
548 BURN_SEARCHES searches = { };
549 BURN_EXTENSIONS burnExtensions = { };
550 try
551 {
552 LPCWSTR wzDocument =
553 L"<Bundle>"
554 L" <SetVariable Id='Search1' Type='string' Value='VAL1' Variable='PROP1' />"
555 L" <SetVariable Id='Search2' Type='numeric' Value='2' Variable='PROP2' />"
556 L" <SetVariable Id='Search3' Type='string' Value='VAL3' Variable='PROP3' />"
557 L" <SetVariable Id='Search4' Type='string' Value='VAL4' Variable='PROP4' />"
558 L" <SetVariable Id='Search5' Type='string' Value='VAL5' Variable='PROP5' />"
559 L" <SetVariable Id='Search6' Type='string' Value='VAL6' Variable='PROP6' />"
560 L" <SetVariable Id='Search7' Type='string' Value='7' Variable='PROP7' />"
561 L" <SetVariable Id='Search8' Type='version' Value='1.1.0.0' Variable='PROP8' />"
562 L" <SetVariable Id='Search9' Type='formatted' Value='[VAL9]' Variable='PROP9' />"
563 L" <SetVariable Id='Search10' Type='numeric' Value='42' Variable='OVERWRITTEN_STRING' />"
564 L" <SetVariable Id='Search11' Type='string' Value='NEW' Variable='OVERWRITTEN_NUMBER' />"
565 L" <SetVariable Id='Search12' Variable='REMOVED_NUMBER' />"
566 L"</Bundle>";
567
568 hr = VariableInitialize(&variables);
569 TestThrowOnFailure(hr, L"Failed to initialize variables.");
570
571 // set variables
572 VariableSetStringHelper(&variables, L"OVERWRITTEN_STRING", L"ORIGINAL", FALSE);
573 VariableSetNumericHelper(&variables, L"OVERWRITTEN_NUMBER", 5);
574 VariableSetNumericHelper(&variables, L"REMOVED_NUMBER", 22);
575
576 // load XML document
577 LoadBundleXmlHelper(wzDocument, &pixeBundle);
578
579 hr = SearchesParseFromXml(&searches, &burnExtensions, pixeBundle);
580 TestThrowOnFailure(hr, L"Failed to parse searches from XML.");
581
582 // execute searches
583 hr = SearchesExecute(&searches, &variables);
584 TestThrowOnFailure(hr, L"Failed to execute searches.");
585
586 // check variable values
587 Assert::Equal<String^>(gcnew String(L"VAL1"), VariableGetStringHelper(&variables, L"PROP1"));
588 Assert::Equal(2ll, VariableGetNumericHelper(&variables, L"PROP2"));
589 Assert::Equal<String^>(gcnew String(L"2"), VariableGetStringHelper(&variables, L"PROP2"));
590 Assert::Equal<String^>(gcnew String(L"VAL3"), VariableGetStringHelper(&variables, L"PROP3"));
591 Assert::Equal<String^>(gcnew String(L"VAL4"), VariableGetStringHelper(&variables, L"PROP4"));
592 Assert::Equal<String^>(gcnew String(L"VAL5"), VariableGetStringHelper(&variables, L"PROP5"));
593 Assert::Equal<String^>(gcnew String(L"VAL6"), VariableGetStringHelper(&variables, L"PROP6"));
594 Assert::Equal(7ll, VariableGetNumericHelper(&variables, L"PROP7"));
595 Assert::Equal<String^>(gcnew String(L"1.1.0.0"), VariableGetVersionHelper(&variables, L"PROP8"));
596 Assert::Equal<String^>(gcnew String(L"1.1.0.0"), VariableGetStringHelper(&variables, L"PROP8"));
597 Assert::Equal<String^>(gcnew String(L"[VAL9]"), VariableGetStringHelper(&variables, L"PROP9"));
598
599 Assert::Equal(42ll, VariableGetNumericHelper(&variables, L"OVERWRITTEN_STRING"));
600 Assert::Equal<String^>(gcnew String(L"NEW"), VariableGetStringHelper(&variables, L"OVERWRITTEN_NUMBER"));
601 Assert::Equal((int)BURN_VARIANT_TYPE_NONE, VariableGetTypeHelper(&variables, L"REMOVED_NUMBER"));
602 }
603 finally
604 {
605 ReleaseObject(pixeBundle);
606 VariablesUninitialize(&variables);
607 SearchesUninitialize(&searches);
608 }
609 }
610 };
611}
612}
613}
614}
615}
616
617
618static INSTALLSTATE WINAPI MsiComponentSearchTest_MsiGetComponentPathW(
619 __in LPCWSTR szProduct,
620 __in LPCWSTR szComponent,
621 __out_ecount_opt(*pcchBuf) LPWSTR lpPathBuf,
622 __inout_opt LPDWORD pcchBuf
623 )
624{
625 INSTALLSTATE is = INSTALLSTATE_INVALIDARG;
626 String^ product = gcnew String(szProduct);
627
628 if (String::Equals(product, gcnew String(L"{BAD00000-0000-0000-0000-000000000000}")))
629 {
630 is = INSTALLSTATE_UNKNOWN;
631 }
632 else if (String::Equals(product, gcnew String(L"{600D0000-0000-0000-0000-000000000000}")))
633 {
634 is = MsiComponentSearchTest_MsiLocateComponentW(szComponent, lpPathBuf, pcchBuf);
635 }
636
637 return is;
638}
639
640static INSTALLSTATE WINAPI MsiComponentSearchTest_MsiLocateComponentW(
641 __in LPCWSTR szComponent,
642 __out_ecount_opt(*pcchBuf) LPWSTR lpPathBuf,
643 __inout_opt LPDWORD pcchBuf
644 )
645{
646 HRESULT hr = S_OK;
647 INSTALLSTATE is = INSTALLSTATE_INVALIDARG;
648 String^ component = gcnew String(szComponent);
649 LPCWSTR wzValue = NULL;
650
651 if (String::Equals(component, gcnew String(L"{BAD00000-1000-0000-0000-000000000000}")))
652 {
653 is = INSTALLSTATE_UNKNOWN;
654 }
655 else if (String::Equals(component, gcnew String(L"{600D0000-1000-1000-0000-000000000000}")))
656 {
657 wzValue = L"C:\\directory\\file1.txt";
658 is = INSTALLSTATE_LOCAL;
659 }
660 else if (String::Equals(component, gcnew String(L"{600D0000-1000-2000-0000-000000000000}")))
661 {
662 wzValue = L"C:\\directory\\file2.txt";
663 is = INSTALLSTATE_SOURCE;
664 }
665 else if (String::Equals(component, gcnew String(L"{600D0000-1000-3000-0000-000000000000}")))
666 {
667 wzValue = L"C:\\directory\\file3.txt";
668 is = INSTALLSTATE_SOURCEABSENT;
669 }
670 else if (String::Equals(component, gcnew String(L"{600D0000-1000-4000-0000-000000000000}")))
671 {
672 wzValue = L"C:\\directory\\file4.txt";
673 is = INSTALLSTATE_ABSENT;
674 }
675 else if (String::Equals(component, gcnew String(L"{600D0000-1000-5000-0000-000000000000}")))
676 {
677 wzValue = L"02:\\SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\";
678 is = INSTALLSTATE_LOCAL;
679 }
680 else if (String::Equals(component, gcnew String(L"{600D0000-1000-6000-0000-000000000000}")))
681 {
682 wzValue = L"02:\\SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Value";
683 is = INSTALLSTATE_LOCAL;
684 }
685 else if (String::Equals(component, gcnew String(L"{600D0000-1000-7000-0000-000000000000}")))
686 {
687 wzValue = L"C:\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\directory\\file5.txt";
688 is = INSTALLSTATE_ABSENT;
689 }
690
691 if (wzValue && lpPathBuf)
692 {
693 hr = ::StringCchCopyW(lpPathBuf, *pcchBuf, wzValue);
694 if (STRSAFE_E_INSUFFICIENT_BUFFER == hr)
695 {
696 *pcchBuf = lstrlenW(wzValue);
697 is = INSTALLSTATE_MOREDATA;
698 }
699 else if (FAILED(hr))
700 {
701 is = INSTALLSTATE_INVALIDARG;
702 }
703 }
704
705 return is;
706}
707
708static UINT WINAPI MsiProductSearchTest_MsiGetProductInfoW(
709 __in LPCWSTR szProductCode,
710 __in LPCWSTR szProperty,
711 __out_ecount_opt(*pcchValue) LPWSTR szValue,
712 __inout_opt LPDWORD pcchValue
713 )
714{
715 if (String::Equals(gcnew String(szProductCode), gcnew String(L"{600D0000-0000-0000-0000-000000000000}")) &&
716 String::Equals(gcnew String(szProperty), gcnew String(INSTALLPROPERTY_PRODUCTSTATE)))
717 {
718 // force call to WiuGetProductInfoEx
719 return ERROR_UNKNOWN_PROPERTY;
720 }
721
722 UINT er = MsiProductSearchTest_MsiGetProductInfoExW(szProductCode, NULL, MSIINSTALLCONTEXT_MACHINE, szProperty, szValue, pcchValue);
723 return er;
724}
725
726static UINT WINAPI MsiProductSearchTest_MsiGetProductInfoExW(
727 __in LPCWSTR szProductCode,
728 __in_opt LPCWSTR /*szUserSid*/,
729 __in MSIINSTALLCONTEXT dwContext,
730 __in LPCWSTR szProperty,
731 __out_ecount_opt(*pcchValue) LPWSTR szValue,
732 __inout_opt LPDWORD pcchValue
733 )
734{
735 HRESULT hr = S_OK;
736 DWORD er = ERROR_FUNCTION_FAILED;
737 LPCWSTR wzValue = NULL;
738
739 String^ productCode = gcnew String(szProductCode);
740 String^ _property = gcnew String(szProperty);
741 switch (dwContext)
742 {
743 case MSIINSTALLCONTEXT_USERMANAGED:
744 er = ERROR_UNKNOWN_PRODUCT;
745 break;
746 case MSIINSTALLCONTEXT_USERUNMANAGED:
747 if (String::Equals(productCode, gcnew String(L"{600D0000-0000-0000-0000-000000000000}")))
748 {
749 if (String::Equals(_property, gcnew String(INSTALLPROPERTY_PRODUCTSTATE)))
750 {
751 wzValue = L"5";
752 }
753 }
754 break;
755 case MSIINSTALLCONTEXT_MACHINE:
756 if (String::Equals(productCode, gcnew String(L"{BAD00000-0000-0000-0000-000000000000}")))
757 {
758 er = ERROR_UNKNOWN_PRODUCT;
759 }
760 else if (String::Equals(productCode, gcnew String(L"{600D0000-0000-0000-0000-000000000000}")))
761 {
762 if (String::Equals(_property, gcnew String(INSTALLPROPERTY_VERSIONSTRING)))
763 {
764 wzValue = L"1.0.0.0";
765 }
766 else if (String::Equals(_property, gcnew String(INSTALLPROPERTY_LANGUAGE)))
767 {
768 wzValue = L"1033";
769 }
770 else if (String::Equals(_property, gcnew String(INSTALLPROPERTY_ASSIGNMENTTYPE)))
771 {
772 wzValue = L"1";
773 }
774 else if (String::Equals(_property, gcnew String(INSTALLPROPERTY_PRODUCTSTATE)))
775 {
776 // try again in per-user context
777 er = ERROR_UNKNOWN_PRODUCT;
778 }
779 }
780 else if (String::Equals(productCode, gcnew String(L"{600D0000-1000-0000-0000-000000000000}")))
781 {
782 static BOOL fFlipp = FALSE;
783 if (fFlipp)
784 {
785 if (String::Equals(_property, gcnew String(INSTALLPROPERTY_VERSIONSTRING)))
786 {
787 wzValue = L"1.0.0.0";
788 }
789 }
790 else
791 {
792 *pcchValue = MAX_PATH * 2;
793 er = ERROR_MORE_DATA;
794 }
795 fFlipp = !fFlipp;
796 }
797 break;
798 }
799
800 if (wzValue)
801 {
802 hr = ::StringCchCopyW(szValue, *pcchValue, wzValue);
803 if (STRSAFE_E_INSUFFICIENT_BUFFER == hr)
804 {
805 *pcchValue = lstrlenW(wzValue);
806 er = ERROR_MORE_DATA;
807 }
808 else if (SUCCEEDED(hr))
809 {
810 er = ERROR_SUCCESS;
811 }
812 }
813
814 return er;
815}