aboutsummaryrefslogtreecommitdiff
path: root/src/libs/dutil
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/dutil')
-rw-r--r--src/libs/dutil/WixToolset.DUtil/acl2util.cpp2
-rw-r--r--src/libs/dutil/WixToolset.DUtil/apuputil.cpp42
-rw-r--r--src/libs/dutil/WixToolset.DUtil/atomutil.cpp66
-rw-r--r--src/libs/dutil/WixToolset.DUtil/build/WixToolset.DUtil.props2
-rw-r--r--src/libs/dutil/WixToolset.DUtil/dictutil.cpp11
-rw-r--r--src/libs/dutil/WixToolset.DUtil/dutil.nuspec2
-rw-r--r--src/libs/dutil/WixToolset.DUtil/dutil.vcxproj2
-rw-r--r--src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters4
-rw-r--r--src/libs/dutil/WixToolset.DUtil/iis7util.cpp6
-rw-r--r--src/libs/dutil/WixToolset.DUtil/inc/thmutil.h13
-rw-r--r--src/libs/dutil/WixToolset.DUtil/iniutil.cpp10
-rw-r--r--src/libs/dutil/WixToolset.DUtil/locutil.cpp6
-rw-r--r--src/libs/dutil/WixToolset.DUtil/monutil.cpp4
-rw-r--r--src/libs/dutil/WixToolset.DUtil/path2utl.cpp4
-rw-r--r--src/libs/dutil/WixToolset.DUtil/sceutil.cpp16
-rw-r--r--src/libs/dutil/WixToolset.DUtil/strutil.cpp31
-rw-r--r--src/libs/dutil/WixToolset.DUtil/thmutil.cpp92
-rw-r--r--src/libs/dutil/WixToolset.DUtil/xmlutil.cpp4
-rw-r--r--src/libs/dutil/dutil.sln49
-rw-r--r--src/libs/dutil/dutil.slnx12
-rw-r--r--src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj2
-rw-r--r--src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj.filters4
-rw-r--r--src/libs/dutil/test/DUtilUnitTest/FileUtilTest.cpp74
-rw-r--r--src/libs/dutil/test/DUtilUnitTest/LocControlsUtilTests.cpp11
-rw-r--r--src/libs/dutil/test/DUtilUnitTest/LocStringsUtilTests.cpp11
-rw-r--r--src/libs/dutil/test/DUtilUnitTest/MonUtilTest.cpp896
-rw-r--r--src/libs/dutil/test/DUtilUnitTest/PathUtilTest.cpp76
-rw-r--r--src/libs/dutil/test/DUtilUnitTest/StrUtilTest.cpp210
28 files changed, 948 insertions, 714 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/acl2util.cpp b/src/libs/dutil/WixToolset.DUtil/acl2util.cpp
index 598f12e7..e62a03d4 100644
--- a/src/libs/dutil/WixToolset.DUtil/acl2util.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/acl2util.cpp
@@ -106,7 +106,7 @@ extern "C" HRESULT DAPI AclGetAccountSidStringEx(
106 HRESULT hrLength = ::StringCchLengthW(wzAccount, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cchAccount)); 106 HRESULT hrLength = ::StringCchLengthW(wzAccount, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cchAccount));
107 AclExitOnFailure(hrLength, "Failed to get the length of the account name."); 107 AclExitOnFailure(hrLength, "Failed to get the length of the account name.");
108 108
109 if (11 < cchAccount && CSTR_EQUAL == CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, L"NT SERVICE\\", 11, wzAccount, 11)) 109 if (11 < cchAccount && CSTR_EQUAL == CompareStringOrdinal(L"NT SERVICE\\", 11, wzAccount, 11, TRUE))
110 { 110 {
111 // If the service is not installed then LookupAccountName doesn't resolve the SID, but we can calculate it. 111 // If the service is not installed then LookupAccountName doesn't resolve the SID, but we can calculate it.
112 LPCWSTR wzServiceName = &wzAccount[11]; 112 LPCWSTR wzServiceName = &wzAccount[11];
diff --git a/src/libs/dutil/WixToolset.DUtil/apuputil.cpp b/src/libs/dutil/WixToolset.DUtil/apuputil.cpp
index eb96d515..848aac15 100644
--- a/src/libs/dutil/WixToolset.DUtil/apuputil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/apuputil.cpp
@@ -70,16 +70,16 @@ extern "C" HRESULT DAPI ApupAllocChainFromAtom(
70 // First search the ATOM feed's custom elements to try and find the default application identity. 70 // First search the ATOM feed's custom elements to try and find the default application identity.
71 for (ATOM_UNKNOWN_ELEMENT* pElement = pFeed->pUnknownElements; pElement; pElement = pElement->pNext) 71 for (ATOM_UNKNOWN_ELEMENT* pElement = pFeed->pUnknownElements; pElement; pElement = pElement->pNext)
72 { 72 {
73 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pElement->wzNamespace, -1, APPLICATION_SYNDICATION_NAMESPACE, -1)) 73 if (CSTR_EQUAL == ::CompareStringOrdinal(pElement->wzNamespace, -1, APPLICATION_SYNDICATION_NAMESPACE, -1, FALSE))
74 { 74 {
75 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pElement->wzElement, -1, L"application", -1)) 75 if (CSTR_EQUAL == ::CompareStringOrdinal(pElement->wzElement, -1, L"application", -1, FALSE))
76 { 76 {
77 hr = StrAllocString(&pChain->wzDefaultApplicationId, pElement->wzValue, 0); 77 hr = StrAllocString(&pChain->wzDefaultApplicationId, pElement->wzValue, 0);
78 ApupExitOnFailure(hr, "Failed to allocate default application id."); 78 ApupExitOnFailure(hr, "Failed to allocate default application id.");
79 79
80 for (ATOM_UNKNOWN_ATTRIBUTE* pAttribute = pElement->pAttributes; pAttribute; pAttribute = pAttribute->pNext) 80 for (ATOM_UNKNOWN_ATTRIBUTE* pAttribute = pElement->pAttributes; pAttribute; pAttribute = pAttribute->pNext)
81 { 81 {
82 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pAttribute->wzAttribute, -1, L"type", -1)) 82 if (CSTR_EQUAL == ::CompareStringOrdinal(pAttribute->wzAttribute, -1, L"type", -1, FALSE))
83 { 83 {
84 hr = StrAllocString(&pChain->wzDefaultApplicationType, pAttribute->wzValue, 0); 84 hr = StrAllocString(&pChain->wzDefaultApplicationType, pAttribute->wzValue, 0);
85 ApupExitOnFailure(hr, "Failed to allocate default application type."); 85 ApupExitOnFailure(hr, "Failed to allocate default application type.");
@@ -112,7 +112,7 @@ extern "C" HRESULT DAPI ApupAllocChainFromAtom(
112 } 112 }
113 113
114 // Trim the unused entries from the end, if any of the entries failed to parse or validate 114 // Trim the unused entries from the end, if any of the entries failed to parse or validate
115 if (pChain->cEntries != pFeed->cEntries) 115 if (pChain->cEntries != pFeed->cEntries)
116 { 116 {
117 if (pChain->cEntries > 0) 117 if (pChain->cEntries > 0)
118 { 118 {
@@ -213,44 +213,44 @@ static HRESULT ProcessEntry(
213 // First search the ATOM entry's custom elements to try and find the application update information. 213 // First search the ATOM entry's custom elements to try and find the application update information.
214 for (ATOM_UNKNOWN_ELEMENT* pElement = pAtomEntry->pUnknownElements; pElement; pElement = pElement->pNext) 214 for (ATOM_UNKNOWN_ELEMENT* pElement = pAtomEntry->pUnknownElements; pElement; pElement = pElement->pNext)
215 { 215 {
216 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pElement->wzNamespace, -1, APPLICATION_SYNDICATION_NAMESPACE, -1)) 216 if (CSTR_EQUAL == ::CompareStringOrdinal(pElement->wzNamespace, -1, APPLICATION_SYNDICATION_NAMESPACE, -1, FALSE))
217 { 217 {
218 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pElement->wzElement, -1, L"application", -1)) 218 if (CSTR_EQUAL == ::CompareStringOrdinal(pElement->wzElement, -1, L"application", -1, FALSE))
219 { 219 {
220 hr = StrAllocString(&pApupEntry->wzApplicationId, pElement->wzValue, 0); 220 hr = StrAllocString(&pApupEntry->wzApplicationId, pElement->wzValue, 0);
221 ApupExitOnFailure(hr, "Failed to allocate application identity."); 221 ApupExitOnFailure(hr, "Failed to allocate application identity.");
222 222
223 for (ATOM_UNKNOWN_ATTRIBUTE* pAttribute = pElement->pAttributes; pAttribute; pAttribute = pAttribute->pNext) 223 for (ATOM_UNKNOWN_ATTRIBUTE* pAttribute = pElement->pAttributes; pAttribute; pAttribute = pAttribute->pNext)
224 { 224 {
225 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pAttribute->wzAttribute, -1, L"type", -1)) 225 if (CSTR_EQUAL == ::CompareStringOrdinal(pAttribute->wzAttribute, -1, L"type", -1, FALSE))
226 { 226 {
227 hr = StrAllocString(&pApupEntry->wzApplicationType, pAttribute->wzValue, 0); 227 hr = StrAllocString(&pApupEntry->wzApplicationType, pAttribute->wzValue, 0);
228 ApupExitOnFailure(hr, "Failed to allocate application type."); 228 ApupExitOnFailure(hr, "Failed to allocate application type.");
229 } 229 }
230 } 230 }
231 } 231 }
232 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pElement->wzElement, -1, L"upgrade", -1)) 232 else if (CSTR_EQUAL == ::CompareStringOrdinal(pElement->wzElement, -1, L"upgrade", -1, FALSE))
233 { 233 {
234 hr = StrAllocString(&pApupEntry->wzUpgradeId, pElement->wzValue, 0); 234 hr = StrAllocString(&pApupEntry->wzUpgradeId, pElement->wzValue, 0);
235 ApupExitOnFailure(hr, "Failed to allocate upgrade id."); 235 ApupExitOnFailure(hr, "Failed to allocate upgrade id.");
236 236
237 for (ATOM_UNKNOWN_ATTRIBUTE* pAttribute = pElement->pAttributes; pAttribute; pAttribute = pAttribute->pNext) 237 for (ATOM_UNKNOWN_ATTRIBUTE* pAttribute = pElement->pAttributes; pAttribute; pAttribute = pAttribute->pNext)
238 { 238 {
239 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pAttribute->wzAttribute, -1, L"version", -1)) 239 if (CSTR_EQUAL == ::CompareStringOrdinal(pAttribute->wzAttribute, -1, L"version", -1, FALSE))
240 { 240 {
241 hr = VerParseVersion(pAttribute->wzValue, 0, FALSE, &pApupEntry->pUpgradeVersion); 241 hr = VerParseVersion(pAttribute->wzValue, 0, FALSE, &pApupEntry->pUpgradeVersion);
242 ApupExitOnFailure(hr, "Failed to parse upgrade version string '%ls' from ATOM entry.", pAttribute->wzValue); 242 ApupExitOnFailure(hr, "Failed to parse upgrade version string '%ls' from ATOM entry.", pAttribute->wzValue);
243 } 243 }
244 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pAttribute->wzAttribute, -1, L"exclusive", -1)) 244 else if (CSTR_EQUAL == ::CompareStringOrdinal(pAttribute->wzAttribute, -1, L"exclusive", -1, FALSE))
245 { 245 {
246 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pAttribute->wzValue, -1, L"true", -1)) 246 if (CSTR_EQUAL == ::CompareStringOrdinal(pAttribute->wzValue, -1, L"true", -1, FALSE))
247 { 247 {
248 pApupEntry->fUpgradeExclusive = TRUE; 248 pApupEntry->fUpgradeExclusive = TRUE;
249 } 249 }
250 } 250 }
251 } 251 }
252 } 252 }
253 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pElement->wzElement, -1, L"version", -1)) 253 else if (CSTR_EQUAL == ::CompareStringOrdinal(pElement->wzElement, -1, L"version", -1, FALSE))
254 { 254 {
255 hr = VerParseVersion(pElement->wzValue, 0, FALSE, &pApupEntry->pVersion); 255 hr = VerParseVersion(pElement->wzValue, 0, FALSE, &pApupEntry->pVersion);
256 ApupExitOnFailure(hr, "Failed to parse version string '%ls' from ATOM entry.", pElement->wzValue); 256 ApupExitOnFailure(hr, "Failed to parse version string '%ls' from ATOM entry.", pElement->wzValue);
@@ -309,7 +309,7 @@ static HRESULT ProcessEntry(
309 for (DWORD i = 0; i < pAtomEntry->cLinks; ++i) 309 for (DWORD i = 0; i < pAtomEntry->cLinks; ++i)
310 { 310 {
311 ATOM_LINK* pLink = pAtomEntry->rgLinks + i; 311 ATOM_LINK* pLink = pAtomEntry->rgLinks + i;
312 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pLink->wzRel, -1, L"enclosure", -1)) 312 if (CSTR_EQUAL == ::CompareStringOrdinal(pLink->wzRel, -1, L"enclosure", -1, FALSE))
313 { 313 {
314 hr = ParseEnclosure(pLink, pApupEntry->rgEnclosures + pApupEntry->cEnclosures); 314 hr = ParseEnclosure(pLink, pApupEntry->rgEnclosures + pApupEntry->cEnclosures);
315 ApupExitOnFailure(hr, "Failed to parse enclosure."); 315 ApupExitOnFailure(hr, "Failed to parse enclosure.");
@@ -344,32 +344,32 @@ static HRESULT ParseEnclosure(
344 // First search the ATOM link's custom elements to try and find the application update enclosure information. 344 // First search the ATOM link's custom elements to try and find the application update enclosure information.
345 for (ATOM_UNKNOWN_ELEMENT* pElement = pLink->pUnknownElements; pElement; pElement = pElement->pNext) 345 for (ATOM_UNKNOWN_ELEMENT* pElement = pLink->pUnknownElements; pElement; pElement = pElement->pNext)
346 { 346 {
347 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pElement->wzNamespace, -1, APPLICATION_SYNDICATION_NAMESPACE, -1)) 347 if (CSTR_EQUAL == ::CompareStringOrdinal(pElement->wzNamespace, -1, APPLICATION_SYNDICATION_NAMESPACE, -1, FALSE))
348 { 348 {
349 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, L"digest", -1, pElement->wzElement, -1)) 349 if (CSTR_EQUAL == ::CompareStringOrdinal(L"digest", -1, pElement->wzElement, -1, FALSE))
350 { 350 {
351 // Find the digest[@algorithm] which is required. Everything else is ignored. 351 // Find the digest[@algorithm] which is required. Everything else is ignored.
352 for (ATOM_UNKNOWN_ATTRIBUTE* pAttribute = pElement->pAttributes; pAttribute; pAttribute = pAttribute->pNext) 352 for (ATOM_UNKNOWN_ATTRIBUTE* pAttribute = pElement->pAttributes; pAttribute; pAttribute = pAttribute->pNext)
353 { 353 {
354 dwDigestLength = 0; 354 dwDigestLength = 0;
355 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, L"algorithm", -1, pAttribute->wzAttribute, -1)) 355 if (CSTR_EQUAL == ::CompareStringOrdinal(L"algorithm", -1, pAttribute->wzAttribute, -1, FALSE))
356 { 356 {
357 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, L"md5", -1, pAttribute->wzValue, -1)) 357 if (CSTR_EQUAL == ::CompareStringOrdinal(L"md5", -1, pAttribute->wzValue, -1, TRUE))
358 { 358 {
359 pEnclosure->digestAlgorithm = APUP_HASH_ALGORITHM_MD5; 359 pEnclosure->digestAlgorithm = APUP_HASH_ALGORITHM_MD5;
360 dwDigestLength = MD5_HASH_LEN; 360 dwDigestLength = MD5_HASH_LEN;
361 } 361 }
362 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, L"sha1", -1, pAttribute->wzValue, -1)) 362 else if (CSTR_EQUAL == ::CompareStringOrdinal(L"sha1", -1, pAttribute->wzValue, -1, TRUE))
363 { 363 {
364 pEnclosure->digestAlgorithm = APUP_HASH_ALGORITHM_SHA1; 364 pEnclosure->digestAlgorithm = APUP_HASH_ALGORITHM_SHA1;
365 dwDigestLength = SHA1_HASH_LEN; 365 dwDigestLength = SHA1_HASH_LEN;
366 } 366 }
367 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, L"sha256", -1, pAttribute->wzValue, -1)) 367 else if (CSTR_EQUAL == ::CompareStringOrdinal(L"sha256", -1, pAttribute->wzValue, -1, TRUE))
368 { 368 {
369 pEnclosure->digestAlgorithm = APUP_HASH_ALGORITHM_SHA256; 369 pEnclosure->digestAlgorithm = APUP_HASH_ALGORITHM_SHA256;
370 dwDigestLength = SHA256_HASH_LEN; 370 dwDigestLength = SHA256_HASH_LEN;
371 } 371 }
372 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, L"sha512", -1, pAttribute->wzValue, -1)) 372 else if (CSTR_EQUAL == ::CompareStringOrdinal(L"sha512", -1, pAttribute->wzValue, -1, TRUE))
373 { 373 {
374 pEnclosure->digestAlgorithm = APUP_HASH_ALGORITHM_SHA512; 374 pEnclosure->digestAlgorithm = APUP_HASH_ALGORITHM_SHA512;
375 dwDigestLength = SHA512_HASH_LEN; 375 dwDigestLength = SHA512_HASH_LEN;
@@ -406,7 +406,7 @@ static HRESULT ParseEnclosure(
406 406
407 break; 407 break;
408 } 408 }
409 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, L"name", -1, pElement->wzElement, -1)) 409 else if (CSTR_EQUAL == ::CompareStringOrdinal(L"name", -1, pElement->wzElement, -1, FALSE))
410 { 410 {
411 hr = StrAllocString(&pEnclosure->wzLocalName, pElement->wzValue, 0); 411 hr = StrAllocString(&pEnclosure->wzLocalName, pElement->wzValue, 0);
412 ApupExitOnFailure(hr, "Failed to copy local name."); 412 ApupExitOnFailure(hr, "Failed to copy local name.");
diff --git a/src/libs/dutil/WixToolset.DUtil/atomutil.cpp b/src/libs/dutil/WixToolset.DUtil/atomutil.cpp
index d6fd3890..df5bb424 100644
--- a/src/libs/dutil/WixToolset.DUtil/atomutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/atomutil.cpp
@@ -341,63 +341,63 @@ static HRESULT ParseAtomFeed(
341 341
342 while (S_OK == (hr = XmlNextElement(pNodeList, &pNode, &bstrNodeName))) 342 while (S_OK == (hr = XmlNextElement(pNodeList, &pNode, &bstrNodeName)))
343 { 343 {
344 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"generator", -1)) 344 if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"generator", -1, FALSE))
345 { 345 {
346 hr = AssignString(&pNewFeed->wzGenerator, pNode); 346 hr = AssignString(&pNewFeed->wzGenerator, pNode);
347 AtomExitOnFailure(hr, "Failed to allocate ATOM feed generator."); 347 AtomExitOnFailure(hr, "Failed to allocate ATOM feed generator.");
348 } 348 }
349 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"icon", -1)) 349 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"icon", -1, FALSE))
350 { 350 {
351 hr = AssignString(&pNewFeed->wzIcon, pNode); 351 hr = AssignString(&pNewFeed->wzIcon, pNode);
352 AtomExitOnFailure(hr, "Failed to allocate ATOM feed icon."); 352 AtomExitOnFailure(hr, "Failed to allocate ATOM feed icon.");
353 } 353 }
354 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"id", -1)) 354 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"id", -1, FALSE))
355 { 355 {
356 hr = AssignString(&pNewFeed->wzId, pNode); 356 hr = AssignString(&pNewFeed->wzId, pNode);
357 AtomExitOnFailure(hr, "Failed to allocate ATOM feed id."); 357 AtomExitOnFailure(hr, "Failed to allocate ATOM feed id.");
358 } 358 }
359 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"logo", -1)) 359 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"logo", -1, FALSE))
360 { 360 {
361 hr = AssignString(&pNewFeed->wzLogo, pNode); 361 hr = AssignString(&pNewFeed->wzLogo, pNode);
362 AtomExitOnFailure(hr, "Failed to allocate ATOM feed logo."); 362 AtomExitOnFailure(hr, "Failed to allocate ATOM feed logo.");
363 } 363 }
364 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"subtitle", -1)) 364 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"subtitle", -1, FALSE))
365 { 365 {
366 hr = AssignString(&pNewFeed->wzSubtitle, pNode); 366 hr = AssignString(&pNewFeed->wzSubtitle, pNode);
367 AtomExitOnFailure(hr, "Failed to allocate ATOM feed subtitle."); 367 AtomExitOnFailure(hr, "Failed to allocate ATOM feed subtitle.");
368 } 368 }
369 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"title", -1)) 369 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"title", -1, FALSE))
370 { 370 {
371 hr = AssignString(&pNewFeed->wzTitle, pNode); 371 hr = AssignString(&pNewFeed->wzTitle, pNode);
372 AtomExitOnFailure(hr, "Failed to allocate ATOM feed title."); 372 AtomExitOnFailure(hr, "Failed to allocate ATOM feed title.");
373 } 373 }
374 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"updated", -1)) 374 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"updated", -1, FALSE))
375 { 375 {
376 hr = AssignDateTime(&pNewFeed->ftUpdated, pNode); 376 hr = AssignDateTime(&pNewFeed->ftUpdated, pNode);
377 AtomExitOnFailure(hr, "Failed to allocate ATOM feed updated."); 377 AtomExitOnFailure(hr, "Failed to allocate ATOM feed updated.");
378 } 378 }
379 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"author", -1)) 379 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"author", -1, FALSE))
380 { 380 {
381 hr = ParseAtomAuthor(pNode, &pNewFeed->rgAuthors[cAuthors]); 381 hr = ParseAtomAuthor(pNode, &pNewFeed->rgAuthors[cAuthors]);
382 AtomExitOnFailure(hr, "Failed to parse ATOM author."); 382 AtomExitOnFailure(hr, "Failed to parse ATOM author.");
383 383
384 ++cAuthors; 384 ++cAuthors;
385 } 385 }
386 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"category", -1)) 386 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"category", -1, FALSE))
387 { 387 {
388 hr = ParseAtomCategory(pNode, &pNewFeed->rgCategories[cCategories]); 388 hr = ParseAtomCategory(pNode, &pNewFeed->rgCategories[cCategories]);
389 AtomExitOnFailure(hr, "Failed to parse ATOM category."); 389 AtomExitOnFailure(hr, "Failed to parse ATOM category.");
390 390
391 ++cCategories; 391 ++cCategories;
392 } 392 }
393 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"entry", -1)) 393 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"entry", -1, FALSE))
394 { 394 {
395 hr = ParseAtomEntry(pNode, &pNewFeed->rgEntries[cEntries]); 395 hr = ParseAtomEntry(pNode, &pNewFeed->rgEntries[cEntries]);
396 AtomExitOnFailure(hr, "Failed to parse ATOM entry."); 396 AtomExitOnFailure(hr, "Failed to parse ATOM entry.");
397 397
398 ++cEntries; 398 ++cEntries;
399 } 399 }
400 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"link", -1)) 400 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"link", -1, FALSE))
401 { 401 {
402 hr = ParseAtomLink(pNode, &pNewFeed->rgLinks[cLinks]); 402 hr = ParseAtomLink(pNode, &pNewFeed->rgLinks[cLinks]);
403 AtomExitOnFailure(hr, "Failed to parse ATOM link."); 403 AtomExitOnFailure(hr, "Failed to parse ATOM link.");
@@ -516,17 +516,17 @@ static HRESULT ParseAtomAuthor(
516 516
517 while (S_OK == (hr = XmlNextElement(pNodeList, &pNode, &bstrNodeName))) 517 while (S_OK == (hr = XmlNextElement(pNodeList, &pNode, &bstrNodeName)))
518 { 518 {
519 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"name", -1)) 519 if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"name", -1, FALSE))
520 { 520 {
521 hr = AssignString(&pAuthor->wzName, pNode); 521 hr = AssignString(&pAuthor->wzName, pNode);
522 AtomExitOnFailure(hr, "Failed to allocate ATOM author name."); 522 AtomExitOnFailure(hr, "Failed to allocate ATOM author name.");
523 } 523 }
524 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"email", -1)) 524 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"email", -1, FALSE))
525 { 525 {
526 hr = AssignString(&pAuthor->wzEmail, pNode); 526 hr = AssignString(&pAuthor->wzEmail, pNode);
527 AtomExitOnFailure(hr, "Failed to allocate ATOM author email."); 527 AtomExitOnFailure(hr, "Failed to allocate ATOM author email.");
528 } 528 }
529 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"uri", -1)) 529 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"uri", -1, FALSE))
530 { 530 {
531 hr = AssignString(&pAuthor->wzUrl, pNode); 531 hr = AssignString(&pAuthor->wzUrl, pNode);
532 AtomExitOnFailure(hr, "Failed to allocate ATOM author uri."); 532 AtomExitOnFailure(hr, "Failed to allocate ATOM author uri.");
@@ -570,17 +570,17 @@ static HRESULT ParseAtomCategory(
570 570
571 while (S_OK == (hr = XmlNextAttribute(pixnnmAttributes, &pNode, &bstrNodeName))) 571 while (S_OK == (hr = XmlNextAttribute(pixnnmAttributes, &pNode, &bstrNodeName)))
572 { 572 {
573 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"label", -1)) 573 if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"label", -1, FALSE))
574 { 574 {
575 hr = AssignString(&pCategory->wzLabel, pNode); 575 hr = AssignString(&pCategory->wzLabel, pNode);
576 AtomExitOnFailure(hr, "Failed to allocate ATOM category label."); 576 AtomExitOnFailure(hr, "Failed to allocate ATOM category label.");
577 } 577 }
578 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"scheme", -1)) 578 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"scheme", -1, FALSE))
579 { 579 {
580 hr = AssignString(&pCategory->wzScheme, pNode); 580 hr = AssignString(&pCategory->wzScheme, pNode);
581 AtomExitOnFailure(hr, "Failed to allocate ATOM category scheme."); 581 AtomExitOnFailure(hr, "Failed to allocate ATOM category scheme.");
582 } 582 }
583 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"term", -1)) 583 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"term", -1, FALSE))
584 { 584 {
585 hr = AssignString(&pCategory->wzTerm, pNode); 585 hr = AssignString(&pCategory->wzTerm, pNode);
586 AtomExitOnFailure(hr, "Failed to allocate ATOM category term."); 586 AtomExitOnFailure(hr, "Failed to allocate ATOM category term.");
@@ -639,12 +639,12 @@ static HRESULT ParseAtomContent(
639 639
640 while (S_OK == (hr = XmlNextAttribute(pixnnmAttributes, &pNode, &bstrNodeName))) 640 while (S_OK == (hr = XmlNextAttribute(pixnnmAttributes, &pNode, &bstrNodeName)))
641 { 641 {
642 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"type", -1)) 642 if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"type", -1, FALSE))
643 { 643 {
644 hr = AssignString(&pContent->wzType, pNode); 644 hr = AssignString(&pContent->wzType, pNode);
645 AtomExitOnFailure(hr, "Failed to allocate ATOM content type."); 645 AtomExitOnFailure(hr, "Failed to allocate ATOM content type.");
646 } 646 }
647 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"url", -1)) 647 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"url", -1, FALSE))
648 { 648 {
649 hr = AssignString(&pContent->wzUrl, pNode); 649 hr = AssignString(&pContent->wzUrl, pNode);
650 AtomExitOnFailure(hr, "Failed to allocate ATOM content scheme."); 650 AtomExitOnFailure(hr, "Failed to allocate ATOM content scheme.");
@@ -721,46 +721,46 @@ static HRESULT ParseAtomEntry(
721 721
722 while (S_OK == (hr = XmlNextElement(pNodeList, &pNode, &bstrNodeName))) 722 while (S_OK == (hr = XmlNextElement(pNodeList, &pNode, &bstrNodeName)))
723 { 723 {
724 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"id", -1)) 724 if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"id", -1, FALSE))
725 { 725 {
726 hr = AssignString(&pEntry->wzId, pNode); 726 hr = AssignString(&pEntry->wzId, pNode);
727 AtomExitOnFailure(hr, "Failed to allocate ATOM entry id."); 727 AtomExitOnFailure(hr, "Failed to allocate ATOM entry id.");
728 } 728 }
729 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"summary", -1)) 729 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"summary", -1, FALSE))
730 { 730 {
731 hr = AssignString(&pEntry->wzSummary, pNode); 731 hr = AssignString(&pEntry->wzSummary, pNode);
732 AtomExitOnFailure(hr, "Failed to allocate ATOM entry summary."); 732 AtomExitOnFailure(hr, "Failed to allocate ATOM entry summary.");
733 } 733 }
734 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"title", -1)) 734 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"title", -1, FALSE))
735 { 735 {
736 hr = AssignString(&pEntry->wzTitle, pNode); 736 hr = AssignString(&pEntry->wzTitle, pNode);
737 AtomExitOnFailure(hr, "Failed to allocate ATOM entry title."); 737 AtomExitOnFailure(hr, "Failed to allocate ATOM entry title.");
738 } 738 }
739 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"published", -1)) 739 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"published", -1, FALSE))
740 { 740 {
741 hr = AssignDateTime(&pEntry->ftPublished, pNode); 741 hr = AssignDateTime(&pEntry->ftPublished, pNode);
742 AtomExitOnFailure(hr, "Failed to allocate ATOM entry published."); 742 AtomExitOnFailure(hr, "Failed to allocate ATOM entry published.");
743 } 743 }
744 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"updated", -1)) 744 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"updated", -1, FALSE))
745 { 745 {
746 hr = AssignDateTime(&pEntry->ftUpdated, pNode); 746 hr = AssignDateTime(&pEntry->ftUpdated, pNode);
747 AtomExitOnFailure(hr, "Failed to allocate ATOM entry updated."); 747 AtomExitOnFailure(hr, "Failed to allocate ATOM entry updated.");
748 } 748 }
749 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"author", -1)) 749 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"author", -1, FALSE))
750 { 750 {
751 hr = ParseAtomAuthor(pNode, &pEntry->rgAuthors[cAuthors]); 751 hr = ParseAtomAuthor(pNode, &pEntry->rgAuthors[cAuthors]);
752 AtomExitOnFailure(hr, "Failed to parse ATOM entry author."); 752 AtomExitOnFailure(hr, "Failed to parse ATOM entry author.");
753 753
754 ++cAuthors; 754 ++cAuthors;
755 } 755 }
756 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"category", -1)) 756 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"category", -1, FALSE))
757 { 757 {
758 hr = ParseAtomCategory(pNode, &pEntry->rgCategories[cCategories]); 758 hr = ParseAtomCategory(pNode, &pEntry->rgCategories[cCategories]);
759 AtomExitOnFailure(hr, "Failed to parse ATOM entry category."); 759 AtomExitOnFailure(hr, "Failed to parse ATOM entry category.");
760 760
761 ++cCategories; 761 ++cCategories;
762 } 762 }
763 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"content", -1)) 763 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"content", -1, FALSE))
764 { 764 {
765 if (NULL != pEntry->pContent) 765 if (NULL != pEntry->pContent)
766 { 766 {
@@ -774,7 +774,7 @@ static HRESULT ParseAtomEntry(
774 hr = ParseAtomContent(pNode, pEntry->pContent); 774 hr = ParseAtomContent(pNode, pEntry->pContent);
775 AtomExitOnFailure(hr, "Failed to parse ATOM entry content."); 775 AtomExitOnFailure(hr, "Failed to parse ATOM entry content.");
776 } 776 }
777 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"link", -1)) 777 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"link", -1, FALSE))
778 { 778 {
779 hr = ParseAtomLink(pNode, &pEntry->rgLinks[cLinks]); 779 hr = ParseAtomLink(pNode, &pEntry->rgLinks[cLinks]);
780 AtomExitOnFailure(hr, "Failed to parse ATOM entry link."); 780 AtomExitOnFailure(hr, "Failed to parse ATOM entry link.");
@@ -842,17 +842,17 @@ static HRESULT ParseAtomLink(
842 842
843 while (S_OK == (hr = XmlNextAttribute(pixnnmAttributes, &pNode, &bstrNodeName))) 843 while (S_OK == (hr = XmlNextAttribute(pixnnmAttributes, &pNode, &bstrNodeName)))
844 { 844 {
845 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"rel", -1)) 845 if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"rel", -1, FALSE))
846 { 846 {
847 hr = AssignString(&pLink->wzRel, pNode); 847 hr = AssignString(&pLink->wzRel, pNode);
848 AtomExitOnFailure(hr, "Failed to allocate ATOM link rel."); 848 AtomExitOnFailure(hr, "Failed to allocate ATOM link rel.");
849 } 849 }
850 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"href", -1)) 850 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"href", -1, FALSE))
851 { 851 {
852 hr = AssignString(&pLink->wzUrl, pNode); 852 hr = AssignString(&pLink->wzUrl, pNode);
853 AtomExitOnFailure(hr, "Failed to allocate ATOM link href."); 853 AtomExitOnFailure(hr, "Failed to allocate ATOM link href.");
854 } 854 }
855 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"length", -1)) 855 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"length", -1, FALSE))
856 { 856 {
857 hr = XmlGetAttributeUInt64(pixnLink, bstrNodeName, &pLink->dw64Length); 857 hr = XmlGetAttributeUInt64(pixnLink, bstrNodeName, &pLink->dw64Length);
858 if (E_INVALIDARG == hr) 858 if (E_INVALIDARG == hr)
@@ -861,12 +861,12 @@ static HRESULT ParseAtomLink(
861 } 861 }
862 AtomExitOnFailure(hr, "Failed to parse ATOM link length."); 862 AtomExitOnFailure(hr, "Failed to parse ATOM link length.");
863 } 863 }
864 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"title", -1)) 864 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"title", -1, FALSE))
865 { 865 {
866 hr = AssignString(&pLink->wzTitle, pNode); 866 hr = AssignString(&pLink->wzTitle, pNode);
867 AtomExitOnFailure(hr, "Failed to allocate ATOM link title."); 867 AtomExitOnFailure(hr, "Failed to allocate ATOM link title.");
868 } 868 }
869 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"type", -1)) 869 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"type", -1, FALSE))
870 { 870 {
871 hr = AssignString(&pLink->wzType, pNode); 871 hr = AssignString(&pLink->wzType, pNode);
872 AtomExitOnFailure(hr, "Failed to allocate ATOM link type."); 872 AtomExitOnFailure(hr, "Failed to allocate ATOM link type.");
diff --git a/src/libs/dutil/WixToolset.DUtil/build/WixToolset.DUtil.props b/src/libs/dutil/WixToolset.DUtil/build/WixToolset.DUtil.props
index 4e773137..66c19206 100644
--- a/src/libs/dutil/WixToolset.DUtil/build/WixToolset.DUtil.props
+++ b/src/libs/dutil/WixToolset.DUtil/build/WixToolset.DUtil.props
@@ -1,7 +1,7 @@
1<?xml version="1.0" encoding="utf-8"?> 1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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<!-- 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. -->
3 3
4<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 4<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
5 <ItemDefinitionGroup> 5 <ItemDefinitionGroup>
6 <ClCompile> 6 <ClCompile>
7 <AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)native\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> 7 <AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)native\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
diff --git a/src/libs/dutil/WixToolset.DUtil/dictutil.cpp b/src/libs/dutil/WixToolset.DUtil/dictutil.cpp
index 09b150df..247b7b43 100644
--- a/src/libs/dutil/WixToolset.DUtil/dictutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/dictutil.cpp
@@ -499,14 +499,9 @@ static BOOL IsMatchExact(
499 ) 499 )
500{ 500{
501 LPCWSTR wzMatchString = GetKey(psd, TranslateOffsetToValue(psd, psd->ppvBuckets[dwMatchIndex])); 501 LPCWSTR wzMatchString = GetKey(psd, TranslateOffsetToValue(psd, psd->ppvBuckets[dwMatchIndex]));
502 DWORD dwFlags = 0; 502 BOOL fIgnoreCase = (DICT_FLAG_CASEINSENSITIVE & psd->dfFlags) ? TRUE : FALSE;
503 503
504 if (DICT_FLAG_CASEINSENSITIVE & psd->dfFlags) 504 if (CSTR_EQUAL == ::CompareStringOrdinal(wzOriginalString, -1, wzMatchString, -1, fIgnoreCase))
505 {
506 dwFlags |= NORM_IGNORECASE;
507 }
508
509 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, dwFlags, wzOriginalString, -1, wzMatchString, -1))
510 { 505 {
511 return TRUE; 506 return TRUE;
512 } 507 }
@@ -605,7 +600,7 @@ static HRESULT GetInsertIndex(
605 // If we wrapped all the way back around to our original index, the dict is full - throw an error 600 // If we wrapped all the way back around to our original index, the dict is full - throw an error
606 if (dwIndexCandidate == dwOriginalIndexCandidate) 601 if (dwIndexCandidate == dwOriginalIndexCandidate)
607 { 602 {
608 // The dict table is full - this error seems to be a reasonably close match 603 // The dict table is full - this error seems to be a reasonably close match
609 hr = HRESULT_FROM_WIN32(ERROR_DATABASE_FULL); 604 hr = HRESULT_FROM_WIN32(ERROR_DATABASE_FULL);
610 DictExitOnRootFailure(hr, "Failed to add item '%ls' to dict table because dict table is full of items", pszString); 605 DictExitOnRootFailure(hr, "Failed to add item '%ls' to dict table because dict table is full of items", pszString);
611 } 606 }
diff --git a/src/libs/dutil/WixToolset.DUtil/dutil.nuspec b/src/libs/dutil/WixToolset.DUtil/dutil.nuspec
index 5c4634e4..534ccd69 100644
--- a/src/libs/dutil/WixToolset.DUtil/dutil.nuspec
+++ b/src/libs/dutil/WixToolset.DUtil/dutil.nuspec
@@ -7,6 +7,7 @@
7 <description>$description$</description> 7 <description>$description$</description>
8 <authors>$authors$</authors> 8 <authors>$authors$</authors>
9 <icon>icon.png</icon> 9 <icon>icon.png</icon>
10 <readme>README.md</readme>
10 <license type="file">OSMFEULA.txt</license> 11 <license type="file">OSMFEULA.txt</license>
11 <requireLicenseAcceptance>true</requireLicenseAcceptance> 12 <requireLicenseAcceptance>true</requireLicenseAcceptance>
12 <tags>$packageTags$</tags> 13 <tags>$packageTags$</tags>
@@ -18,6 +19,7 @@
18 <files> 19 <files>
19 <file src="$eulaTxt$" /> 20 <file src="$eulaTxt$" />
20 <file src="$iconPng$" /> 21 <file src="$iconPng$" />
22 <file src="$projectFolder$\..\README.md" />
21 <file src="$projectFolder$\build\$id$.props" target="build\" /> 23 <file src="$projectFolder$\build\$id$.props" target="build\" />
22 <file src="$projectFolder$\inc\*" target="build\native\include" /> 24 <file src="$projectFolder$\inc\*" target="build\native\include" />
23 <file src="..\..\v143\x64\dutil.lib" target="build\native\v14\x64" /> 25 <file src="..\..\v143\x64\dutil.lib" target="build\native\v14\x64" />
diff --git a/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj b/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj
index c973b141..f60ef19d 100644
--- a/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj
+++ b/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj
@@ -1,7 +1,7 @@
1<?xml version="1.0" encoding="utf-8"?> 1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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<!-- 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. -->
3 3
4<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 4<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
5 <ItemGroup Label="ProjectConfigurations"> 5 <ItemGroup Label="ProjectConfigurations">
6 <ProjectConfiguration Include="Debug|ARM64"> 6 <ProjectConfiguration Include="Debug|ARM64">
7 <Configuration>Debug</Configuration> 7 <Configuration>Debug</Configuration>
diff --git a/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters b/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters
index 470fd3d0..d8877f25 100644
--- a/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters
+++ b/src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters
@@ -1,5 +1,5 @@
1<?xml version="1.0" encoding="utf-8"?> 1<?xml version="1.0" encoding="utf-8"?>
2<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 2<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 <ItemGroup> 3 <ItemGroup>
4 <Filter Include="Source Files"> 4 <Filter Include="Source Files">
5 <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> 5 <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
@@ -410,4 +410,4 @@
410 <Filter>Header Files</Filter> 410 <Filter>Header Files</Filter>
411 </None> 411 </None>
412 </ItemGroup> 412 </ItemGroup>
413</Project> \ No newline at end of file 413</Project>
diff --git a/src/libs/dutil/WixToolset.DUtil/iis7util.cpp b/src/libs/dutil/WixToolset.DUtil/iis7util.cpp
index d0a0b000..b0dc1444 100644
--- a/src/libs/dutil/WixToolset.DUtil/iis7util.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/iis7util.cpp
@@ -222,7 +222,7 @@ BOOL DAPI CompareVariantPath(
222 IisExitOnFailure(hr, "Failed to expand path %ls", pVariant2->bstrVal); 222 IisExitOnFailure(hr, "Failed to expand path %ls", pVariant2->bstrVal);
223 } 223 }
224 224
225 fEqual = CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, wzValue1, -1, wzValue2, -1); 225 fEqual = CSTR_EQUAL == ::CompareStringOrdinal(wzValue1, -1, wzValue2, -1, TRUE);
226 226
227LExit: 227LExit:
228 ReleaseNullStr(wzValue1); 228 ReleaseNullStr(wzValue1);
@@ -258,7 +258,7 @@ extern "C" BOOL DAPI Iis7IsMatchingAppHostElement(
258 258
259 hr = pElement->get_Name(&bstrElementName); 259 hr = pElement->get_Name(&bstrElementName);
260 IisExitOnFailure(hr, "Failed to get name of element"); 260 IisExitOnFailure(hr, "Failed to get name of element");
261 if (CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pComparison->sczElementName, -1, bstrElementName, -1)) 261 if (CSTR_EQUAL != ::CompareStringOrdinal(pComparison->sczElementName, -1, bstrElementName, -1, TRUE))
262 { 262 {
263 ExitFunction(); 263 ExitFunction();
264 } 264 }
@@ -293,7 +293,7 @@ BOOL DAPI IsMatchingAppHostMethod(
293 293
294 Assert(bstrName); 294 Assert(bstrName);
295 295
296 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, wzMethodName, -1, bstrName, -1)) 296 if (CSTR_EQUAL == ::CompareStringOrdinal(wzMethodName, -1, bstrName, -1, TRUE))
297 { 297 {
298 fResult = TRUE; 298 fResult = TRUE;
299 } 299 }
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h b/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h
index 45e4fc51..14e20c0d 100644
--- a/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h
+++ b/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h
@@ -567,6 +567,19 @@ void DAPI ThemeInitializeWindowClass(
567 ); 567 );
568 568
569/******************************************************************** 569/********************************************************************
570 ThemeInitializeWindowClassEx - sets defaults for the window class
571 from the given theme.
572
573*******************************************************************/
574void DAPI ThemeInitializeWindowClassEx(
575 __in THEME* pTheme,
576 __in WNDCLASSEXW* pWndClass,
577 __in WNDPROC pfnWndProc,
578 __in HINSTANCE hInstance,
579 __in LPCWSTR wzClassName
580 );
581
582/********************************************************************
570 ThemeCreateParentWindow - creates a parent window for the theme. 583 ThemeCreateParentWindow - creates a parent window for the theme.
571 584
572*******************************************************************/ 585*******************************************************************/
diff --git a/src/libs/dutil/WixToolset.DUtil/iniutil.cpp b/src/libs/dutil/WixToolset.DUtil/iniutil.cpp
index 46f6e380..12af6fb2 100644
--- a/src/libs/dutil/WixToolset.DUtil/iniutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/iniutil.cpp
@@ -441,7 +441,7 @@ extern "C" HRESULT DAPI IniGetValue(
441 441
442 for (DWORD i = 0; i < pi->cValues; ++i) 442 for (DWORD i = 0; i < pi->cValues; ++i)
443 { 443 {
444 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pi->rgivValues[i].wzName, -1, wzValueName, -1)) 444 if (CSTR_EQUAL == ::CompareStringOrdinal(pi->rgivValues[i].wzName, -1, wzValueName, -1, FALSE))
445 { 445 {
446 pValue = pi->rgivValues + i; 446 pValue = pi->rgivValues + i;
447 break; 447 break;
@@ -483,7 +483,7 @@ extern "C" HRESULT DAPI IniSetValue(
483 483
484 for (DWORD i = 0; i < pi->cValues; ++i) 484 for (DWORD i = 0; i < pi->cValues; ++i)
485 { 485 {
486 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pi->rgivValues[i].wzName, -1, wzValueName, -1)) 486 if (CSTR_EQUAL == ::CompareStringOrdinal(pi->rgivValues[i].wzName, -1, wzValueName, -1, FALSE))
487 { 487 {
488 pValue = pi->rgivValues + i; 488 pValue = pi->rgivValues + i;
489 break; 489 break;
@@ -507,7 +507,7 @@ extern "C" HRESULT DAPI IniSetValue(
507 { 507 {
508 if (pValue) 508 if (pValue)
509 { 509 {
510 if (CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, 0, pValue->wzValue, -1, wzValue, -1)) 510 if (CSTR_EQUAL != ::CompareStringOrdinal(pValue->wzValue, -1, wzValue, -1, FALSE))
511 { 511 {
512 pi->fModified = TRUE; 512 pi->fModified = TRUE;
513 hr = StrAllocString(const_cast<LPWSTR *>(&pValue->wzValue), wzValue, 0); 513 hr = StrAllocString(const_cast<LPWSTR *>(&pValue->wzValue), wzValue, 0);
@@ -660,7 +660,7 @@ extern "C" HRESULT DAPI IniWriteFile(
660 IniExitOnFailure(hr, "Failed to get section prefix from name: %ls", pi->rgivValues[i].wzName); 660 IniExitOnFailure(hr, "Failed to get section prefix from name: %ls", pi->rgivValues[i].wzName);
661 661
662 // If the new section prefix is different, write a section out for it 662 // If the new section prefix is different, write a section out for it
663 if (fSections && sczNewSectionPrefix && (NULL == sczCurrentSectionPrefix || CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, 0, sczNewSectionPrefix, -1, sczCurrentSectionPrefix, -1))) 663 if (fSections && sczNewSectionPrefix && (NULL == sczCurrentSectionPrefix || CSTR_EQUAL != ::CompareStringOrdinal(sczNewSectionPrefix, -1, sczCurrentSectionPrefix, -1, FALSE)))
664 { 664 {
665 hr = StrAllocConcat(&sczContents, pi->sczOpenTagPrefix, 0); 665 hr = StrAllocConcat(&sczContents, pi->sczOpenTagPrefix, 0);
666 IniExitOnFailure(hr, "Failed to concat open tag prefix to string"); 666 IniExitOnFailure(hr, "Failed to concat open tag prefix to string");
@@ -674,7 +674,7 @@ extern "C" HRESULT DAPI IniWriteFile(
674 674
675 hr = StrAllocConcat(&sczContents, L"\r\n", 2); 675 hr = StrAllocConcat(&sczContents, L"\r\n", 2);
676 IniExitOnFailure(hr, "Failed to add endline to ini output buffer in-memory"); 676 IniExitOnFailure(hr, "Failed to add endline to ini output buffer in-memory");
677 677
678 ReleaseNullStr(sczCurrentSectionPrefix); 678 ReleaseNullStr(sczCurrentSectionPrefix);
679 sczCurrentSectionPrefix = sczNewSectionPrefix; 679 sczCurrentSectionPrefix = sczNewSectionPrefix;
680 sczNewSectionPrefix = NULL; 680 sczNewSectionPrefix = NULL;
diff --git a/src/libs/dutil/WixToolset.DUtil/locutil.cpp b/src/libs/dutil/WixToolset.DUtil/locutil.cpp
index 008d0367..0e897186 100644
--- a/src/libs/dutil/WixToolset.DUtil/locutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/locutil.cpp
@@ -315,7 +315,7 @@ extern "C" HRESULT DAPI LocGetControl(
315 { 315 {
316 pLocControl = &pWixLoc->rgLocControls[i]; 316 pLocControl = &pWixLoc->rgLocControls[i];
317 317
318 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pLocControl->wzControl, -1, wzId, -1)) 318 if (CSTR_EQUAL == ::CompareStringOrdinal(pLocControl->wzControl, -1, wzId, -1, FALSE))
319 { 319 {
320 *ppLocControl = pLocControl; 320 *ppLocControl = pLocControl;
321 ExitFunction1(hr = S_OK); 321 ExitFunction1(hr = S_OK);
@@ -341,7 +341,7 @@ extern "C" HRESULT DAPI LocGetString(
341 { 341 {
342 pLocString = pWixLoc->rgLocStrings + i; 342 pLocString = pWixLoc->rgLocStrings + i;
343 343
344 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pLocString->wzId, -1, wzId, -1)) 344 if (CSTR_EQUAL == ::CompareStringOrdinal(pLocString->wzId, -1, wzId, -1, FALSE))
345 { 345 {
346 *ppLocString = pLocString; 346 *ppLocString = pLocString;
347 hr = S_OK; 347 hr = S_OK;
@@ -555,7 +555,7 @@ static HRESULT ParseWxlString(
555 555
556 if (S_OK == hr) 556 if (S_OK == hr)
557 { 557 {
558 pLocString->bOverridable = CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrText, -1, L"yes", -1); 558 pLocString->bOverridable = CSTR_EQUAL == ::CompareStringOrdinal(bstrText, -1, L"yes", -1, FALSE);
559 } 559 }
560 560
561 ReleaseNullBSTR(bstrText); 561 ReleaseNullBSTR(bstrText);
diff --git a/src/libs/dutil/WixToolset.DUtil/monutil.cpp b/src/libs/dutil/WixToolset.DUtil/monutil.cpp
index b42332ef..d6437b39 100644
--- a/src/libs/dutil/WixToolset.DUtil/monutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/monutil.cpp
@@ -1598,14 +1598,14 @@ static HRESULT FindRequestIndex(
1598 switch (pWaiterContext->rgRequests[i].type) 1598 switch (pWaiterContext->rgRequests[i].type)
1599 { 1599 {
1600 case MON_DIRECTORY: 1600 case MON_DIRECTORY:
1601 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pWaiterContext->rgRequests[i].rgsczPathHierarchy[pWaiterContext->rgRequests[i].cPathHierarchy - 1], -1, pMessage->directory.sczDirectory, -1) && pWaiterContext->rgRequests[i].fRecursive == pMessage->fRecursive) 1601 if (CSTR_EQUAL == ::CompareStringOrdinal(pWaiterContext->rgRequests[i].rgsczPathHierarchy[pWaiterContext->rgRequests[i].cPathHierarchy - 1], -1, pMessage->directory.sczDirectory, -1, FALSE) && pWaiterContext->rgRequests[i].fRecursive == pMessage->fRecursive)
1602 { 1602 {
1603 *pdwIndex = i; 1603 *pdwIndex = i;
1604 ExitFunction1(hr = S_OK); 1604 ExitFunction1(hr = S_OK);
1605 } 1605 }
1606 break; 1606 break;
1607 case MON_REGKEY: 1607 case MON_REGKEY:
1608 if (reinterpret_cast<DWORD_PTR>(pMessage->regkey.hkRoot) == reinterpret_cast<DWORD_PTR>(pWaiterContext->rgRequests[i].regkey.hkRoot) && CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pWaiterContext->rgRequests[i].rgsczPathHierarchy[pWaiterContext->rgRequests[i].cPathHierarchy - 1], -1, pMessage->regkey.sczSubKey, -1) && pWaiterContext->rgRequests[i].fRecursive == pMessage->fRecursive && pWaiterContext->rgRequests[i].regkey.kbKeyBitness == pMessage->regkey.kbKeyBitness) 1608 if (reinterpret_cast<DWORD_PTR>(pMessage->regkey.hkRoot) == reinterpret_cast<DWORD_PTR>(pWaiterContext->rgRequests[i].regkey.hkRoot) && CSTR_EQUAL == ::CompareStringOrdinal(pWaiterContext->rgRequests[i].rgsczPathHierarchy[pWaiterContext->rgRequests[i].cPathHierarchy - 1], -1, pMessage->regkey.sczSubKey, -1, FALSE) && pWaiterContext->rgRequests[i].fRecursive == pMessage->fRecursive && pWaiterContext->rgRequests[i].regkey.kbKeyBitness == pMessage->regkey.kbKeyBitness)
1609 { 1609 {
1610 *pdwIndex = i; 1610 *pdwIndex = i;
1611 ExitFunction1(hr = S_OK); 1611 ExitFunction1(hr = S_OK);
diff --git a/src/libs/dutil/WixToolset.DUtil/path2utl.cpp b/src/libs/dutil/WixToolset.DUtil/path2utl.cpp
index d83a4578..06df8617 100644
--- a/src/libs/dutil/WixToolset.DUtil/path2utl.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/path2utl.cpp
@@ -306,7 +306,7 @@ DAPI_(HRESULT) PathCompareCanonicalized(
306 hr = PathCanonicalizeForComparison(wzPath2, dwDefaultFlags, &sczCanonicalized2); 306 hr = PathCanonicalizeForComparison(wzPath2, dwDefaultFlags, &sczCanonicalized2);
307 PathExitOnFailure(hr, "Failed to canonicalize wzPath2."); 307 PathExitOnFailure(hr, "Failed to canonicalize wzPath2.");
308 308
309 nResult = ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, sczCanonicalized1, -1, sczCanonicalized2, -1); 309 nResult = ::CompareStringOrdinal(sczCanonicalized1, -1, sczCanonicalized2, -1, TRUE);
310 PathExitOnNullWithLastError(nResult, hr, "Failed to compare canonicalized paths."); 310 PathExitOnNullWithLastError(nResult, hr, "Failed to compare canonicalized paths.");
311 311
312 *pfEqual = CSTR_EQUAL == nResult; 312 *pfEqual = CSTR_EQUAL == nResult;
@@ -364,7 +364,7 @@ DAPI_(HRESULT) PathDirectoryContainsPath(
364 ExitFunction1(hr = S_FALSE); 364 ExitFunction1(hr = S_FALSE);
365 } 365 }
366 366
367 if (CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, sczCanonicalizedDirectory, (DWORD)cchDirectory, sczCanonicalizedPath, (DWORD)cchDirectory)) 367 if (CSTR_EQUAL != ::CompareStringOrdinal(sczCanonicalizedDirectory, (DWORD)cchDirectory, sczCanonicalizedPath, (DWORD)cchDirectory, TRUE))
368 { 368 {
369 ExitFunction1(hr = S_FALSE); 369 ExitFunction1(hr = S_FALSE);
370 } 370 }
diff --git a/src/libs/dutil/WixToolset.DUtil/sceutil.cpp b/src/libs/dutil/WixToolset.DUtil/sceutil.cpp
index 590c937a..98b5e2d8 100644
--- a/src/libs/dutil/WixToolset.DUtil/sceutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/sceutil.cpp
@@ -224,7 +224,7 @@ extern "C" HRESULT DAPI SceCreateDatabase(
224 LPWSTR sczDirectory = NULL; 224 LPWSTR sczDirectory = NULL;
225 SCE_DATABASE *pNewSceDatabase = NULL; 225 SCE_DATABASE *pNewSceDatabase = NULL;
226 SCE_DATABASE_INTERNAL *pNewSceDatabaseInternal = NULL; 226 SCE_DATABASE_INTERNAL *pNewSceDatabaseInternal = NULL;
227 IDBDataSourceAdmin *pIDBDataSourceAdmin = NULL; 227 IDBDataSourceAdmin *pIDBDataSourceAdmin = NULL;
228 DBPROPSET rgdbpDataSourcePropSet[2] = { }; 228 DBPROPSET rgdbpDataSourcePropSet[2] = { };
229 DBPROP rgdbpDataSourceProp[2] = { }; 229 DBPROP rgdbpDataSourceProp[2] = { };
230 DBPROP rgdbpDataSourceSsceProp[1] = { }; 230 DBPROP rgdbpDataSourceSsceProp[1] = { };
@@ -239,7 +239,7 @@ extern "C" HRESULT DAPI SceCreateDatabase(
239 239
240 hr = CreateSqlCe(wzSqlCeDllPath, &pNewSceDatabaseInternal->pIDBInitialize, &pNewSceDatabaseInternal->hSqlCeDll); 240 hr = CreateSqlCe(wzSqlCeDllPath, &pNewSceDatabaseInternal->pIDBInitialize, &pNewSceDatabaseInternal->hSqlCeDll);
241 ExitOnFailure(hr, "Failed to get IDBInitialize interface"); 241 ExitOnFailure(hr, "Failed to get IDBInitialize interface");
242 242
243 hr = pNewSceDatabaseInternal->pIDBInitialize->QueryInterface(IID_IDBDataSourceAdmin, reinterpret_cast<void **>(&pIDBDataSourceAdmin)); 243 hr = pNewSceDatabaseInternal->pIDBInitialize->QueryInterface(IID_IDBDataSourceAdmin, reinterpret_cast<void **>(&pIDBDataSourceAdmin));
244 ExitOnFailure(hr, "Failed to get IDBDataSourceAdmin interface"); 244 ExitOnFailure(hr, "Failed to get IDBDataSourceAdmin interface");
245 245
@@ -259,7 +259,7 @@ extern "C" HRESULT DAPI SceCreateDatabase(
259 rgdbpDataSourceProp[1].vValue.vt = VT_I4; 259 rgdbpDataSourceProp[1].vValue.vt = VT_I4;
260 rgdbpDataSourceProp[1].vValue.lVal = DB_MODE_SHARE_DENY_NONE; 260 rgdbpDataSourceProp[1].vValue.lVal = DB_MODE_SHARE_DENY_NONE;
261 261
262 // SQL CE doesn't seem to allow us to specify DBPROP_INIT_PROMPT if we include any properties from DBPROPSET_SSCE_DBINIT 262 // SQL CE doesn't seem to allow us to specify DBPROP_INIT_PROMPT if we include any properties from DBPROPSET_SSCE_DBINIT
263 rgdbpDataSourcePropSet[0].guidPropertySet = DBPROPSET_DBINIT; 263 rgdbpDataSourcePropSet[0].guidPropertySet = DBPROPSET_DBINIT;
264 rgdbpDataSourcePropSet[0].rgProperties = rgdbpDataSourceProp; 264 rgdbpDataSourcePropSet[0].rgProperties = rgdbpDataSourceProp;
265 rgdbpDataSourcePropSet[0].cProperties = _countof(rgdbpDataSourceProp); 265 rgdbpDataSourcePropSet[0].cProperties = _countof(rgdbpDataSourceProp);
@@ -336,7 +336,7 @@ extern "C" HRESULT DAPI SceOpenDatabase(
336 336
337 hr = CreateSqlCe(wzSqlCeDllPath, &pNewSceDatabaseInternal->pIDBInitialize, &pNewSceDatabaseInternal->hSqlCeDll); 337 hr = CreateSqlCe(wzSqlCeDllPath, &pNewSceDatabaseInternal->pIDBInitialize, &pNewSceDatabaseInternal->hSqlCeDll);
338 ExitOnFailure(hr, "Failed to get IDBInitialize interface"); 338 ExitOnFailure(hr, "Failed to get IDBInitialize interface");
339 339
340 hr = pNewSceDatabaseInternal->pIDBInitialize->QueryInterface(IID_IDBProperties, reinterpret_cast<void **>(&pNewSceDatabaseInternal->pIDBProperties)); 340 hr = pNewSceDatabaseInternal->pIDBInitialize->QueryInterface(IID_IDBProperties, reinterpret_cast<void **>(&pNewSceDatabaseInternal->pIDBProperties));
341 ExitOnFailure(hr, "Failed to get IDBProperties interface"); 341 ExitOnFailure(hr, "Failed to get IDBProperties interface");
342 342
@@ -369,7 +369,7 @@ extern "C" HRESULT DAPI SceOpenDatabase(
369 rgdbpDataSourceProp[1].vValue.vt = VT_I4; 369 rgdbpDataSourceProp[1].vValue.vt = VT_I4;
370 rgdbpDataSourceProp[1].vValue.lVal = DB_MODE_SHARE_DENY_NONE; 370 rgdbpDataSourceProp[1].vValue.lVal = DB_MODE_SHARE_DENY_NONE;
371 371
372 // SQL CE doesn't seem to allow us to specify DBPROP_INIT_PROMPT if we include any properties from DBPROPSET_SSCE_DBINIT 372 // SQL CE doesn't seem to allow us to specify DBPROP_INIT_PROMPT if we include any properties from DBPROPSET_SSCE_DBINIT
373 rgdbpDataSourcePropSet[0].guidPropertySet = DBPROPSET_DBINIT; 373 rgdbpDataSourcePropSet[0].guidPropertySet = DBPROPSET_DBINIT;
374 rgdbpDataSourcePropSet[0].rgProperties = rgdbpDataSourceProp; 374 rgdbpDataSourcePropSet[0].rgProperties = rgdbpDataSourceProp;
375 rgdbpDataSourcePropSet[0].cProperties = _countof(rgdbpDataSourceProp); 375 rgdbpDataSourcePropSet[0].cProperties = _countof(rgdbpDataSourceProp);
@@ -407,7 +407,7 @@ extern "C" HRESULT DAPI SceOpenDatabase(
407 hr = GetDatabaseSchemaInfo(pNewSceDatabase, &sczSchemaType, &dwVersionFound); 407 hr = GetDatabaseSchemaInfo(pNewSceDatabase, &sczSchemaType, &dwVersionFound);
408 ExitOnFailure(hr, "Failed to find schema version of database"); 408 ExitOnFailure(hr, "Failed to find schema version of database");
409 409
410 if (CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, 0, sczSchemaType, -1, wzExpectedSchemaType, -1)) 410 if (CSTR_EQUAL != ::CompareStringOrdinal(sczSchemaType, -1, wzExpectedSchemaType, -1, FALSE))
411 { 411 {
412 hr = HRESULT_FROM_WIN32(ERROR_BAD_FILE_TYPE); 412 hr = HRESULT_FROM_WIN32(ERROR_BAD_FILE_TYPE);
413 ExitOnRootFailure(hr, "Tried to open wrong database type - expected type %ls, found type %ls", wzExpectedSchemaType, sczSchemaType); 413 ExitOnRootFailure(hr, "Tried to open wrong database type - expected type %ls, found type %ls", wzExpectedSchemaType, sczSchemaType);
@@ -2306,8 +2306,8 @@ static HRESULT SetSessionProperties(
2306 rgdbpDataSourceProp[0].dwPropertyID = DBPROP_SSCE_TRANSACTION_COMMIT_MODE; 2306 rgdbpDataSourceProp[0].dwPropertyID = DBPROP_SSCE_TRANSACTION_COMMIT_MODE;
2307 rgdbpDataSourceProp[0].dwOptions = DBPROPOPTIONS_REQUIRED; 2307 rgdbpDataSourceProp[0].dwOptions = DBPROPOPTIONS_REQUIRED;
2308 rgdbpDataSourceProp[0].vValue.vt = VT_I4; 2308 rgdbpDataSourceProp[0].vValue.vt = VT_I4;
2309 rgdbpDataSourceProp[0].vValue.lVal = DBPROPVAL_SSCE_TCM_FLUSH; 2309 rgdbpDataSourceProp[0].vValue.lVal = DBPROPVAL_SSCE_TCM_FLUSH;
2310 2310
2311 rgdbpDataSourcePropSet[0].guidPropertySet = DBPROPSET_SSCE_SESSION; 2311 rgdbpDataSourcePropSet[0].guidPropertySet = DBPROPSET_SSCE_SESSION;
2312 rgdbpDataSourcePropSet[0].rgProperties = rgdbpDataSourceProp; 2312 rgdbpDataSourcePropSet[0].rgProperties = rgdbpDataSourceProp;
2313 rgdbpDataSourcePropSet[0].cProperties = 1; 2313 rgdbpDataSourcePropSet[0].cProperties = 1;
diff --git a/src/libs/dutil/WixToolset.DUtil/strutil.cpp b/src/libs/dutil/WixToolset.DUtil/strutil.cpp
index 0a00c690..013c1b12 100644
--- a/src/libs/dutil/WixToolset.DUtil/strutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/strutil.cpp
@@ -1872,9 +1872,14 @@ NOTE: returns 0 if the multisz in not properly terminated with two nulls
1872extern "C" HRESULT DAPI MultiSzLen( 1872extern "C" HRESULT DAPI MultiSzLen(
1873 __in_ecount(*pcch) __nullnullterminated LPCWSTR pwzMultiSz, 1873 __in_ecount(*pcch) __nullnullterminated LPCWSTR pwzMultiSz,
1874 __out SIZE_T* pcch 1874 __out SIZE_T* pcch
1875) 1875 )
1876{ 1876{
1877 Assert(pcch); 1877 Assert(pcch);
1878 if (!pwzMultiSz)
1879 {
1880 *pcch = 0;
1881 return S_OK;
1882 }
1878 1883
1879 HRESULT hr = S_OK; 1884 HRESULT hr = S_OK;
1880 LPCWSTR wz = pwzMultiSz; 1885 LPCWSTR wz = pwzMultiSz;
@@ -1941,10 +1946,10 @@ extern "C" HRESULT DAPI MultiSzPrepend(
1941 hr = ::StringCchLengthW(pwzInsert, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cchInsert)); 1946 hr = ::StringCchLengthW(pwzInsert, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cchInsert));
1942 StrExitOnRootFailure(hr, "failed to get length of insert string"); 1947 StrExitOnRootFailure(hr, "failed to get length of insert string");
1943 1948
1944 cchResult = cchInsert + cchMultiSz + 1; 1949 cchResult = cchInsert + (cchMultiSz ? cchMultiSz : 1) + 1;
1945 1950
1946 // Allocate the result buffer 1951 // Allocate the result buffer
1947 hr = StrAlloc(&pwzResult, cchResult + 1); 1952 hr = StrAlloc(&pwzResult, cchResult);
1948 StrExitOnFailure(hr, "failed to allocate result string"); 1953 StrExitOnFailure(hr, "failed to allocate result string");
1949 1954
1950 // Prepend 1955 // Prepend
@@ -1954,8 +1959,7 @@ extern "C" HRESULT DAPI MultiSzPrepend(
1954 // If there was no MULTISZ, double null terminate our result, otherwise, copy the MULTISZ in 1959 // If there was no MULTISZ, double null terminate our result, otherwise, copy the MULTISZ in
1955 if (0 == cchMultiSz) 1960 if (0 == cchMultiSz)
1956 { 1961 {
1957 pwzResult[cchResult] = L'\0'; 1962 pwzResult[cchResult - 2] = L'\0';
1958 ++cchResult;
1959 } 1963 }
1960 else 1964 else
1961 { 1965 {
@@ -1967,6 +1971,7 @@ extern "C" HRESULT DAPI MultiSzPrepend(
1967 } 1971 }
1968 1972
1969 // Set the result 1973 // Set the result
1974 pwzResult[cchResult - 1] = L'\0';
1970 *ppwzMultiSz = pwzResult; 1975 *ppwzMultiSz = pwzResult;
1971 1976
1972 if (pcchMultiSz) 1977 if (pcchMultiSz)
@@ -2257,19 +2262,29 @@ extern "C" HRESULT DAPI MultiSzInsertString(
2257 // 2262 //
2258 // Insert the string 2263 // Insert the string
2259 // 2264 //
2260 cchResult = cchMultiSz + cchString + 1; 2265 cchResult = (cchMultiSz ? cchMultiSz : 1) + cchString + 1;
2261 2266
2262 hr = StrAlloc(&pwzResult, cchResult); 2267 hr = StrAlloc(&pwzResult, cchResult);
2263 StrExitOnFailure(hr, "failed to allocate result string for MULTISZ insert"); 2268 StrExitOnFailure(hr, "failed to allocate result string for MULTISZ insert");
2264 2269
2265 // Copy the part before the insert 2270 // Copy the part before the insert
2266 ::CopyMemory(pwzResult, *ppwzMultiSz, cchProgress * sizeof(WCHAR)); 2271 if (cchProgress)
2272 {
2273 ::CopyMemory(pwzResult, *ppwzMultiSz, cchProgress * sizeof(WCHAR));
2274 }
2267 2275
2268 // Copy the insert part 2276 // Copy the insert part
2269 ::CopyMemory(pwzResult + cchProgress, pwzInsert, (cchString + 1) * sizeof(WCHAR)); 2277 ::CopyMemory(pwzResult + cchProgress, pwzInsert, (cchString + 1) * sizeof(WCHAR));
2270 2278
2271 // Copy the part after the insert 2279 // Copy the part after the insert
2272 ::CopyMemory(pwzResult + cchProgress + cchString + 1, wz, (cchMultiSz - cchProgress) * sizeof(WCHAR)); 2280 if (cchMultiSz > cchProgress)
2281 {
2282 ::CopyMemory(pwzResult + cchProgress + cchString + 1, wz, (cchMultiSz - cchProgress) * sizeof(WCHAR));
2283 }
2284
2285 // Ensure double-null termination
2286 pwzResult[cchResult - 1] = L'\0';
2287 pwzResult[cchResult - 2] = L'\0';
2273 2288
2274 // Free the old buffer 2289 // Free the old buffer
2275 ReleaseNullStr(*ppwzMultiSz); 2290 ReleaseNullStr(*ppwzMultiSz);
diff --git a/src/libs/dutil/WixToolset.DUtil/thmutil.cpp b/src/libs/dutil/WixToolset.DUtil/thmutil.cpp
index 36b187a7..4482c96e 100644
--- a/src/libs/dutil/WixToolset.DUtil/thmutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/thmutil.cpp
@@ -856,6 +856,28 @@ DAPI_(void) ThemeInitializeWindowClass(
856} 856}
857 857
858 858
859DAPI_(void) ThemeInitializeWindowClassEx(
860 __in THEME* pTheme,
861 __in WNDCLASSEXW* pWndClass,
862 __in WNDPROC pfnWndProc,
863 __in HINSTANCE hInstance,
864 __in LPCWSTR wzClassName
865 )
866{
867 pWndClass->cbSize = sizeof(WNDCLASSEXW);
868 pWndClass->style = CS_HREDRAW | CS_VREDRAW;
869 pWndClass->cbWndExtra = DLGWINDOWEXTRA;
870 pWndClass->hCursor = ::LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
871
872 pWndClass->lpfnWndProc = pfnWndProc;
873 pWndClass->hInstance = hInstance;
874 pWndClass->lpszClassName = wzClassName;
875
876 pWndClass->hIcon = reinterpret_cast<HICON>(pTheme->hIcon);
877 pWndClass->hbrBackground = pTheme->rgFonts[pTheme->dwFontId].hBackground;
878}
879
880
859DAPI_(HRESULT) ThemeCreateParentWindow( 881DAPI_(HRESULT) ThemeCreateParentWindow(
860 __in THEME* pTheme, 882 __in THEME* pTheme,
861 __in DWORD dwExStyle, 883 __in DWORD dwExStyle,
@@ -1145,7 +1167,7 @@ DAPI_(void) ThemeGetPageIds(
1145 for (DWORD j = 0; j < pTheme->cPages; ++j) 1167 for (DWORD j = 0; j < pTheme->cPages; ++j)
1146 { 1168 {
1147 LPCWSTR wzPageName = pTheme->rgPages[j].sczName; 1169 LPCWSTR wzPageName = pTheme->rgPages[j].sczName;
1148 if (wzPageName && CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzPageName, -1, wzFindName, -1)) 1170 if (wzPageName && CSTR_EQUAL == ::CompareStringOrdinal(wzPageName, -1, wzFindName, -1, FALSE))
1149 { 1171 {
1150 rgdwPageIds[i] = j + 1; // add one to make the page ids 1-based (so zero is invalid). 1172 rgdwPageIds[i] = j + 1; // add one to make the page ids 1-based (so zero is invalid).
1151 break; 1173 break;
@@ -2082,7 +2104,7 @@ static HRESULT ParseButtonImages(
2082 ThmExitOnFailure(hr, "Null element encountered!"); 2104 ThmExitOnFailure(hr, "Null element encountered!");
2083 } 2105 }
2084 2106
2085 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"ButtonFocusImage", -1)) 2107 if (CSTR_EQUAL == ::CompareStringOrdinal(bstrType, -1, L"ButtonFocusImage", -1, FALSE))
2086 { 2108 {
2087 if (pFocusImageRef) 2109 if (pFocusImageRef)
2088 { 2110 {
@@ -2091,7 +2113,7 @@ static HRESULT ParseButtonImages(
2091 2113
2092 pImageRef = pFocusImageRef = pControl->Button.rgImageRef + 3; 2114 pImageRef = pFocusImageRef = pControl->Button.rgImageRef + 3;
2093 } 2115 }
2094 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"ButtonHoverImage", -1)) 2116 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrType, -1, L"ButtonHoverImage", -1, FALSE))
2095 { 2117 {
2096 if (pHoverImageRef) 2118 if (pHoverImageRef)
2097 { 2119 {
@@ -2100,7 +2122,7 @@ static HRESULT ParseButtonImages(
2100 2122
2101 pImageRef = pHoverImageRef = pControl->Button.rgImageRef + 1; 2123 pImageRef = pHoverImageRef = pControl->Button.rgImageRef + 1;
2102 } 2124 }
2103 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"ButtonSelectedImage", -1)) 2125 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrType, -1, L"ButtonSelectedImage", -1, FALSE))
2104 { 2126 {
2105 if (pSelectedImageRef) 2127 if (pSelectedImageRef)
2106 { 2128 {
@@ -2776,35 +2798,35 @@ static HRESULT GetFontColor(
2776 2798
2777 if (pdwSystemColor) 2799 if (pdwSystemColor)
2778 { 2800 {
2779 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstr, -1, L"btnface", -1)) 2801 if (CSTR_EQUAL == ::CompareStringOrdinal(bstr, -1, L"btnface", -1, FALSE))
2780 { 2802 {
2781 *pdwSystemColor = COLOR_BTNFACE; 2803 *pdwSystemColor = COLOR_BTNFACE;
2782 } 2804 }
2783 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstr, -1, L"btntext", -1)) 2805 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstr, -1, L"btntext", -1, FALSE))
2784 { 2806 {
2785 *pdwSystemColor = COLOR_BTNTEXT; 2807 *pdwSystemColor = COLOR_BTNTEXT;
2786 } 2808 }
2787 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstr, -1, L"graytext", -1)) 2809 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstr, -1, L"graytext", -1, FALSE))
2788 { 2810 {
2789 *pdwSystemColor = COLOR_GRAYTEXT; 2811 *pdwSystemColor = COLOR_GRAYTEXT;
2790 } 2812 }
2791 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstr, -1, L"highlight", -1)) 2813 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstr, -1, L"highlight", -1, FALSE))
2792 { 2814 {
2793 *pdwSystemColor = COLOR_HIGHLIGHT; 2815 *pdwSystemColor = COLOR_HIGHLIGHT;
2794 } 2816 }
2795 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstr, -1, L"highlighttext", -1)) 2817 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstr, -1, L"highlighttext", -1, FALSE))
2796 { 2818 {
2797 *pdwSystemColor = COLOR_HIGHLIGHTTEXT; 2819 *pdwSystemColor = COLOR_HIGHLIGHTTEXT;
2798 } 2820 }
2799 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstr, -1, L"hotlight", -1)) 2821 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstr, -1, L"hotlight", -1, FALSE))
2800 { 2822 {
2801 *pdwSystemColor = COLOR_HOTLIGHT; 2823 *pdwSystemColor = COLOR_HOTLIGHT;
2802 } 2824 }
2803 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstr, -1, L"window", -1)) 2825 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstr, -1, L"window", -1, FALSE))
2804 { 2826 {
2805 *pdwSystemColor = COLOR_WINDOW; 2827 *pdwSystemColor = COLOR_WINDOW;
2806 } 2828 }
2807 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstr, -1, L"windowtext", -1)) 2829 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstr, -1, L"windowtext", -1, FALSE))
2808 { 2830 {
2809 *pdwSystemColor = COLOR_WINDOWTEXT; 2831 *pdwSystemColor = COLOR_WINDOWTEXT;
2810 } 2832 }
@@ -3229,71 +3251,71 @@ static HRESULT ParseControls(
3229 ThmExitOnFailure(hr, "Null element encountered!"); 3251 ThmExitOnFailure(hr, "Null element encountered!");
3230 } 3252 }
3231 3253
3232 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"Billboard", -1)) 3254 if (CSTR_EQUAL == ::CompareStringOrdinal(bstrType, -1, L"Billboard", -1, FALSE))
3233 { 3255 {
3234 type = THEME_CONTROL_TYPE_BILLBOARD; 3256 type = THEME_CONTROL_TYPE_BILLBOARD;
3235 } 3257 }
3236 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"Button", -1)) 3258 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrType, -1, L"Button", -1, FALSE))
3237 { 3259 {
3238 type = THEME_CONTROL_TYPE_BUTTON; 3260 type = THEME_CONTROL_TYPE_BUTTON;
3239 } 3261 }
3240 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"Checkbox", -1)) 3262 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrType, -1, L"Checkbox", -1, FALSE))
3241 { 3263 {
3242 type = THEME_CONTROL_TYPE_CHECKBOX; 3264 type = THEME_CONTROL_TYPE_CHECKBOX;
3243 } 3265 }
3244 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"Combobox", -1)) 3266 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrType, -1, L"Combobox", -1, FALSE))
3245 { 3267 {
3246 type = THEME_CONTROL_TYPE_COMBOBOX; 3268 type = THEME_CONTROL_TYPE_COMBOBOX;
3247 } 3269 }
3248 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"CommandLink", -1)) 3270 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrType, -1, L"CommandLink", -1, FALSE))
3249 { 3271 {
3250 type = THEME_CONTROL_TYPE_COMMANDLINK; 3272 type = THEME_CONTROL_TYPE_COMMANDLINK;
3251 } 3273 }
3252 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"Editbox", -1)) 3274 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrType, -1, L"Editbox", -1, FALSE))
3253 { 3275 {
3254 type = THEME_CONTROL_TYPE_EDITBOX; 3276 type = THEME_CONTROL_TYPE_EDITBOX;
3255 } 3277 }
3256 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"Hyperlink", -1)) 3278 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrType, -1, L"Hyperlink", -1, FALSE))
3257 { 3279 {
3258 type = THEME_CONTROL_TYPE_HYPERLINK; 3280 type = THEME_CONTROL_TYPE_HYPERLINK;
3259 } 3281 }
3260 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"Hypertext", -1)) 3282 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrType, -1, L"Hypertext", -1, FALSE))
3261 { 3283 {
3262 type = THEME_CONTROL_TYPE_HYPERTEXT; 3284 type = THEME_CONTROL_TYPE_HYPERTEXT;
3263 } 3285 }
3264 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"ImageControl", -1)) 3286 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrType, -1, L"ImageControl", -1, FALSE))
3265 { 3287 {
3266 type = THEME_CONTROL_TYPE_IMAGE; 3288 type = THEME_CONTROL_TYPE_IMAGE;
3267 } 3289 }
3268 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"Label", -1)) 3290 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrType, -1, L"Label", -1, FALSE))
3269 { 3291 {
3270 type = THEME_CONTROL_TYPE_LABEL; 3292 type = THEME_CONTROL_TYPE_LABEL;
3271 } 3293 }
3272 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"ListView", -1)) 3294 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrType, -1, L"ListView", -1, FALSE))
3273 { 3295 {
3274 type = THEME_CONTROL_TYPE_LISTVIEW; 3296 type = THEME_CONTROL_TYPE_LISTVIEW;
3275 } 3297 }
3276 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"Panel", -1)) 3298 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrType, -1, L"Panel", -1, FALSE))
3277 { 3299 {
3278 type = THEME_CONTROL_TYPE_PANEL; 3300 type = THEME_CONTROL_TYPE_PANEL;
3279 } 3301 }
3280 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"Progressbar", -1)) 3302 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrType, -1, L"Progressbar", -1, FALSE))
3281 { 3303 {
3282 type = THEME_CONTROL_TYPE_PROGRESSBAR; 3304 type = THEME_CONTROL_TYPE_PROGRESSBAR;
3283 } 3305 }
3284 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"Richedit", -1)) 3306 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrType, -1, L"Richedit", -1, FALSE))
3285 { 3307 {
3286 type = THEME_CONTROL_TYPE_RICHEDIT; 3308 type = THEME_CONTROL_TYPE_RICHEDIT;
3287 } 3309 }
3288 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"Static", -1)) 3310 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrType, -1, L"Static", -1, FALSE))
3289 { 3311 {
3290 type = THEME_CONTROL_TYPE_STATIC; 3312 type = THEME_CONTROL_TYPE_STATIC;
3291 } 3313 }
3292 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"Tabs", -1)) 3314 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrType, -1, L"Tabs", -1, FALSE))
3293 { 3315 {
3294 type = THEME_CONTROL_TYPE_TAB; 3316 type = THEME_CONTROL_TYPE_TAB;
3295 } 3317 }
3296 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"TreeView", -1)) 3318 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrType, -1, L"TreeView", -1, FALSE))
3297 { 3319 {
3298 type = THEME_CONTROL_TYPE_TREEVIEW; 3320 type = THEME_CONTROL_TYPE_TREEVIEW;
3299 } 3321 }
@@ -3705,14 +3727,14 @@ static HRESULT ParseActions(
3705 3727
3706 THEME_ACTION* pAction = pControl->rgActions + i; 3728 THEME_ACTION* pAction = pControl->rgActions + i;
3707 3729
3708 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"BrowseDirectoryAction", -1)) 3730 if (CSTR_EQUAL == ::CompareStringOrdinal(bstrType, -1, L"BrowseDirectoryAction", -1, FALSE))
3709 { 3731 {
3710 pAction->type = THEME_ACTION_TYPE_BROWSE_DIRECTORY; 3732 pAction->type = THEME_ACTION_TYPE_BROWSE_DIRECTORY;
3711 3733
3712 hr = XmlGetAttributeEx(pixnChild, L"VariableName", &pAction->BrowseDirectory.sczVariableName); 3734 hr = XmlGetAttributeEx(pixnChild, L"VariableName", &pAction->BrowseDirectory.sczVariableName);
3713 ThmExitOnFailure(hr, "Failed when querying BrowseDirectoryAction/@VariableName attribute."); 3735 ThmExitOnFailure(hr, "Failed when querying BrowseDirectoryAction/@VariableName attribute.");
3714 } 3736 }
3715 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"ChangePageAction", -1)) 3737 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrType, -1, L"ChangePageAction", -1, FALSE))
3716 { 3738 {
3717 pAction->type = THEME_ACTION_TYPE_CHANGE_PAGE; 3739 pAction->type = THEME_ACTION_TYPE_CHANGE_PAGE;
3718 3740
@@ -3725,7 +3747,7 @@ static HRESULT ParseActions(
3725 ThmExitOnFailure(hr, "Failed when querying ChangePageAction/@Cancel attribute."); 3747 ThmExitOnFailure(hr, "Failed when querying ChangePageAction/@Cancel attribute.");
3726 } 3748 }
3727 } 3749 }
3728 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrType, -1, L"CloseWindowAction", -1)) 3750 else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrType, -1, L"CloseWindowAction", -1, FALSE))
3729 { 3751 {
3730 pAction->type = THEME_ACTION_TYPE_CLOSE_WINDOW; 3752 pAction->type = THEME_ACTION_TYPE_CLOSE_WINDOW;
3731 } 3753 }
@@ -4367,7 +4389,7 @@ static HRESULT FindImageList(
4367 4389
4368 for (DWORD i = 0; i < pTheme->cImageLists; ++i) 4390 for (DWORD i = 0; i < pTheme->cImageLists; ++i)
4369 { 4391 {
4370 if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pTheme->rgImageLists[i].sczName, -1, wzImageListName, -1)) 4392 if (CSTR_EQUAL == ::CompareStringOrdinal(pTheme->rgImageLists[i].sczName, -1, wzImageListName, -1, FALSE))
4371 { 4393 {
4372 *phImageList = pTheme->rgImageLists[i].hImageList; 4394 *phImageList = pTheme->rgImageLists[i].hImageList;
4373 ExitFunction1(hr = S_OK); 4395 ExitFunction1(hr = S_OK);
@@ -5027,7 +5049,7 @@ static void OnBrowseDirectory(
5027 THEME_CONTROL* pControl = pTheme->rgControls + i; 5049 THEME_CONTROL* pControl = pTheme->rgControls + i;
5028 5050
5029 if ((!pControl->wPageId || pControl->wPageId == pTheme->dwCurrentPageId) && 5051 if ((!pControl->wPageId || pControl->wPageId == pTheme->dwCurrentPageId) &&
5030 CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pControl->sczName, -1, pAction->BrowseDirectory.sczVariableName, -1)) 5052 CSTR_EQUAL == ::CompareStringOrdinal(pControl->sczName, -1, pAction->BrowseDirectory.sczVariableName, -1, FALSE))
5031 { 5053 {
5032 pTargetControl = pControl; 5054 pTargetControl = pControl;
5033 break; 5055 break;
@@ -5790,7 +5812,7 @@ static HRESULT ShowControl(
5790 5812
5791 hr = S_OK; 5813 hr = S_OK;
5792 5814
5793 Button_SetCheck(hWnd, (!sczText && !pControl->sczValue) || (sczText && CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, sczText, -1, pControl->sczValue, -1))); 5815 Button_SetCheck(hWnd, (!sczText && !pControl->sczValue) || (sczText && CSTR_EQUAL == ::CompareStringOrdinal(sczText, -1, pControl->sczValue, -1, FALSE)));
5794 } 5816 }
5795 } 5817 }
5796 5818
diff --git a/src/libs/dutil/WixToolset.DUtil/xmlutil.cpp b/src/libs/dutil/WixToolset.DUtil/xmlutil.cpp
index 2e1a2200..c4273c2e 100644
--- a/src/libs/dutil/WixToolset.DUtil/xmlutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/xmlutil.cpp
@@ -98,7 +98,7 @@ extern "C" void DAPI XmlUninitialize(
98 { 98 {
99 ::CoUninitialize(); 99 ::CoUninitialize();
100 } 100 }
101 } 101 }
102} 102}
103 103
104extern "C" HRESULT DAPI XmlCreateElement( 104extern "C" HRESULT DAPI XmlCreateElement(
@@ -738,7 +738,7 @@ HRESULT DAPI XmlGetYesNoAttribute(
738 { 738 {
739 XmlExitOnFailure(hr, "Failed to get attribute."); 739 XmlExitOnFailure(hr, "Failed to get attribute.");
740 740
741 *pfYes = CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, sczValue, -1, L"yes", -1); 741 *pfYes = CSTR_EQUAL == ::CompareStringOrdinal(sczValue, -1, L"yes", -1, FALSE);
742 } 742 }
743 743
744LExit: 744LExit:
diff --git a/src/libs/dutil/dutil.sln b/src/libs/dutil/dutil.sln
deleted file mode 100644
index 9dd7d62b..00000000
--- a/src/libs/dutil/dutil.sln
+++ /dev/null
@@ -1,49 +0,0 @@
1
2Microsoft Visual Studio Solution File, Format Version 12.00
3# Visual Studio Version 16
4VisualStudioVersion = 16.0.30711.63
5MinimumVisualStudioVersion = 15.0.26124.0
6Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dutil", "WixToolset.DUtil\dutil.vcxproj", "{1244E671-F108-4334-BA52-8A7517F26ECD}"
7EndProject
8Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DUtilUnitTest", "test\DUtilUnitTest\DUtilUnitTest.vcxproj", "{AB7EE608-E5FB-42A5-831F-0DEEEA141223}"
9EndProject
10Global
11 GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 Debug|ARM64 = Debug|ARM64
13 Debug|x64 = Debug|x64
14 Debug|x86 = Debug|x86
15 Release|ARM64 = Release|ARM64
16 Release|x64 = Release|x64
17 Release|x86 = Release|x86
18 EndGlobalSection
19 GlobalSection(ProjectConfigurationPlatforms) = postSolution
20 {1244E671-F108-4334-BA52-8A7517F26ECD}.Debug|ARM64.ActiveCfg = Debug|ARM64
21 {1244E671-F108-4334-BA52-8A7517F26ECD}.Debug|ARM64.Build.0 = Debug|ARM64
22 {1244E671-F108-4334-BA52-8A7517F26ECD}.Debug|x64.ActiveCfg = Debug|x64
23 {1244E671-F108-4334-BA52-8A7517F26ECD}.Debug|x64.Build.0 = Debug|x64
24 {1244E671-F108-4334-BA52-8A7517F26ECD}.Debug|x86.ActiveCfg = Debug|Win32
25 {1244E671-F108-4334-BA52-8A7517F26ECD}.Debug|x86.Build.0 = Debug|Win32
26 {1244E671-F108-4334-BA52-8A7517F26ECD}.Release|ARM64.ActiveCfg = Release|ARM64
27 {1244E671-F108-4334-BA52-8A7517F26ECD}.Release|ARM64.Build.0 = Release|ARM64
28 {1244E671-F108-4334-BA52-8A7517F26ECD}.Release|x64.ActiveCfg = Release|x64
29 {1244E671-F108-4334-BA52-8A7517F26ECD}.Release|x64.Build.0 = Release|x64
30 {1244E671-F108-4334-BA52-8A7517F26ECD}.Release|x86.ActiveCfg = Release|Win32
31 {1244E671-F108-4334-BA52-8A7517F26ECD}.Release|x86.Build.0 = Release|Win32
32 {AB7EE608-E5FB-42A5-831F-0DEEEA141223}.Debug|ARM64.ActiveCfg = Debug|x64
33 {AB7EE608-E5FB-42A5-831F-0DEEEA141223}.Debug|x64.ActiveCfg = Debug|x64
34 {AB7EE608-E5FB-42A5-831F-0DEEEA141223}.Debug|x64.Build.0 = Debug|x64
35 {AB7EE608-E5FB-42A5-831F-0DEEEA141223}.Debug|x86.ActiveCfg = Debug|Win32
36 {AB7EE608-E5FB-42A5-831F-0DEEEA141223}.Debug|x86.Build.0 = Debug|Win32
37 {AB7EE608-E5FB-42A5-831F-0DEEEA141223}.Release|ARM64.ActiveCfg = Release|x64
38 {AB7EE608-E5FB-42A5-831F-0DEEEA141223}.Release|x64.ActiveCfg = Release|x64
39 {AB7EE608-E5FB-42A5-831F-0DEEEA141223}.Release|x64.Build.0 = Release|x64
40 {AB7EE608-E5FB-42A5-831F-0DEEEA141223}.Release|x86.ActiveCfg = Release|Win32
41 {AB7EE608-E5FB-42A5-831F-0DEEEA141223}.Release|x86.Build.0 = Release|Win32
42 EndGlobalSection
43 GlobalSection(SolutionProperties) = preSolution
44 HideSolutionNode = FALSE
45 EndGlobalSection
46 GlobalSection(ExtensibilityGlobals) = postSolution
47 SolutionGuid = {DD209744-C40E-4C34-8CB4-BC6B71F9A133}
48 EndGlobalSection
49EndGlobal
diff --git a/src/libs/dutil/dutil.slnx b/src/libs/dutil/dutil.slnx
new file mode 100644
index 00000000..e4a94156
--- /dev/null
+++ b/src/libs/dutil/dutil.slnx
@@ -0,0 +1,12 @@
1<Solution>
2 <Configurations>
3 <Platform Name="ARM64" />
4 <Platform Name="x64" />
5 <Platform Name="x86" />
6 </Configurations>
7 <Project Path="test/DUtilUnitTest/DUtilUnitTest.vcxproj" Id="ab7ee608-e5fb-42a5-831f-0deeea141223">
8 <Platform Solution="*|ARM64" Project="x64" />
9 <Build Solution="*|ARM64" Project="false" />
10 </Project>
11 <Project Path="WixToolset.DUtil/dutil.vcxproj" Id="1244e671-f108-4334-ba52-8a7517f26ecd" />
12</Solution>
diff --git a/src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj b/src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj
index fccb73c4..e12eac00 100644
--- a/src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj
+++ b/src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj
@@ -1,7 +1,7 @@
1<?xml version="1.0" encoding="utf-8"?> 1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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<!-- 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. -->
3 3
4<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 4<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
5 <Import Project="..\..\..\..\internal\WixInternal.TestSupport.Native\build\WixInternal.TestSupport.Native.props" /> 5 <Import Project="..\..\..\..\internal\WixInternal.TestSupport.Native\build\WixInternal.TestSupport.Native.props" />
6 6
7 <ItemGroup Label="ProjectConfigurations"> 7 <ItemGroup Label="ProjectConfigurations">
diff --git a/src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj.filters b/src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj.filters
index e4972c1a..b236ed80 100644
--- a/src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj.filters
+++ b/src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj.filters
@@ -1,5 +1,5 @@
1<?xml version="1.0" encoding="utf-8"?> 1<?xml version="1.0" encoding="utf-8"?>
2<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 2<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 <ItemGroup> 3 <ItemGroup>
4 <Filter Include="Source Files"> 4 <Filter Include="Source Files">
5 <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> 5 <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
@@ -102,4 +102,4 @@
102 <None Include="TestData\LocUtilTests\strings.wxl" /> 102 <None Include="TestData\LocUtilTests\strings.wxl" />
103 <None Include="TestData\LocUtilTests\controls.wxl" /> 103 <None Include="TestData\LocUtilTests\controls.wxl" />
104 </ItemGroup> 104 </ItemGroup>
105</Project> \ No newline at end of file 105</Project>
diff --git a/src/libs/dutil/test/DUtilUnitTest/FileUtilTest.cpp b/src/libs/dutil/test/DUtilUnitTest/FileUtilTest.cpp
index 8ea045f5..80fe2f1a 100644
--- a/src/libs/dutil/test/DUtilUnitTest/FileUtilTest.cpp
+++ b/src/libs/dutil/test/DUtilUnitTest/FileUtilTest.cpp
@@ -11,43 +11,43 @@ namespace DutilTests
11 public ref class FileUtil 11 public ref class FileUtil
12 { 12 {
13 public: 13 public:
14 [Fact(Skip="Skipped until we have a good way to reference ANSI.txt.")] 14 // [Fact(Skip="Skipped until we have a good way to reference ANSI.txt.")]
15 void FileUtilTest() 15 // void FileUtilTest()
16 { 16 // {
17 HRESULT hr = S_OK; 17 // HRESULT hr = S_OK;
18 LPWSTR sczTempDir = NULL; 18 // LPWSTR sczTempDir = NULL;
19 LPWSTR sczFileDir = NULL; 19 // LPWSTR sczFileDir = NULL;
20 20
21 DutilInitialize(&DutilTestTraceError); 21 // DutilInitialize(&DutilTestTraceError);
22 22
23 try 23 // try
24 { 24 // {
25 hr = PathExpand(&sczTempDir, L"%TEMP%\\FileUtilTest\\", PATH_EXPAND_ENVIRONMENT); 25 // hr = PathExpand(&sczTempDir, L"%TEMP%\\FileUtilTest\\", PATH_EXPAND_ENVIRONMENT);
26 NativeAssert::Succeeded(hr, "Failed to get temp dir"); 26 // NativeAssert::Succeeded(hr, "Failed to get temp dir");
27 27
28 hr = PathExpand(&sczFileDir, L"%WIX_ROOT%\\examples\\data\\TextEncodings\\", PATH_EXPAND_ENVIRONMENT); 28 // hr = PathExpand(&sczFileDir, L"%WIX_ROOT%\\examples\\data\\TextEncodings\\", PATH_EXPAND_ENVIRONMENT);
29 NativeAssert::Succeeded(hr, "Failed to get path to encodings file dir"); 29 // NativeAssert::Succeeded(hr, "Failed to get path to encodings file dir");
30 30
31 hr = DirEnsureExists(sczTempDir, NULL); 31 // hr = DirEnsureExists(sczTempDir, NULL);
32 NativeAssert::Succeeded(hr, "Failed to ensure directory exists: {0}", sczTempDir); 32 // NativeAssert::Succeeded(hr, "Failed to ensure directory exists: {0}", sczTempDir);
33 33
34 TestFile(sczFileDir, sczTempDir, L"ANSI.txt", 32, FILE_ENCODING_UTF8); 34 // TestFile(sczFileDir, sczTempDir, L"ANSI.txt", 32, FILE_ENCODING_UTF8);
35 // Big endian not supported today! 35 // // Big endian not supported today!
36 //TestFile(sczFileDir, L"UnicodeBENoBOM.txt", 34); 36 // //TestFile(sczFileDir, L"UnicodeBENoBOM.txt", 34);
37 //TestFile(sczFileDir, L"UnicodeBEWithBOM.txt", 34); 37 // //TestFile(sczFileDir, L"UnicodeBEWithBOM.txt", 34);
38 TestFile(sczFileDir, sczTempDir, L"UnicodeLENoBOM.txt", 34, FILE_ENCODING_UTF16); 38 // TestFile(sczFileDir, sczTempDir, L"UnicodeLENoBOM.txt", 34, FILE_ENCODING_UTF16);
39 TestFile(sczFileDir, sczTempDir, L"UnicodeLEWithBOM.txt", 34, FILE_ENCODING_UTF16_WITH_BOM); 39 // TestFile(sczFileDir, sczTempDir, L"UnicodeLEWithBOM.txt", 34, FILE_ENCODING_UTF16_WITH_BOM);
40 TestFile(sczFileDir, sczTempDir, L"UTF8WithSignature.txt", 34, FILE_ENCODING_UTF8_WITH_BOM); 40 // TestFile(sczFileDir, sczTempDir, L"UTF8WithSignature.txt", 34, FILE_ENCODING_UTF8_WITH_BOM);
41 41
42 hr = DirEnsureDelete(sczTempDir, TRUE, TRUE); 42 // hr = DirEnsureDelete(sczTempDir, TRUE, TRUE);
43 } 43 // }
44 finally 44 // finally
45 { 45 // {
46 ReleaseStr(sczTempDir); 46 // ReleaseStr(sczTempDir);
47 ReleaseStr(sczFileDir); 47 // ReleaseStr(sczFileDir);
48 DutilUninitialize(); 48 // DutilUninitialize();
49 } 49 // }
50 } 50 // }
51 51
52 private: 52 private:
53 void TestFile(LPWSTR wzDir, LPCWSTR wzTempDir, LPWSTR wzFileName, size_t cbExpectedStringLength, FILE_ENCODING feExpectedEncoding) 53 void TestFile(LPWSTR wzDir, LPCWSTR wzTempDir, LPWSTR wzFileName, size_t cbExpectedStringLength, FILE_ENCODING feExpectedEncoding)
diff --git a/src/libs/dutil/test/DUtilUnitTest/LocControlsUtilTests.cpp b/src/libs/dutil/test/DUtilUnitTest/LocControlsUtilTests.cpp
index a558c0c5..fd8679cb 100644
--- a/src/libs/dutil/test/DUtilUnitTest/LocControlsUtilTests.cpp
+++ b/src/libs/dutil/test/DUtilUnitTest/LocControlsUtilTests.cpp
@@ -15,6 +15,7 @@ namespace DutilTests
15 void CanLoadControlsWxl() 15 void CanLoadControlsWxl()
16 { 16 {
17 HRESULT hr = S_OK; 17 HRESULT hr = S_OK;
18 DWORD dwRetry = 0;
18 WIX_LOCALIZATION* pLoc = NULL; 19 WIX_LOCALIZATION* pLoc = NULL;
19 LOC_CONTROL* pLocControl = NULL; 20 LOC_CONTROL* pLocControl = NULL;
20 21
@@ -26,7 +27,15 @@ namespace DutilTests
26 NativeAssert::Succeeded(hr, "Failed to initialize Xml."); 27 NativeAssert::Succeeded(hr, "Failed to initialize Xml.");
27 28
28 pin_ptr<const wchar_t> wxlFilePath = PtrToStringChars(TestData::Get("TestData", "LocUtilTests", "controls.wxl")); 29 pin_ptr<const wchar_t> wxlFilePath = PtrToStringChars(TestData::Get("TestData", "LocUtilTests", "controls.wxl"));
29 hr = LocLoadFromFile(wxlFilePath, &pLoc); 30 do
31 {
32 if (FAILED(hr))
33 {
34 ::Sleep(500);
35 }
36
37 hr = LocLoadFromFile(wxlFilePath, &pLoc);
38 } while (FAILED(hr) && ++dwRetry < 5);
30 NativeAssert::Succeeded(hr, "Failed to parse controls.wxl: {0}", wxlFilePath); 39 NativeAssert::Succeeded(hr, "Failed to parse controls.wxl: {0}", wxlFilePath);
31 40
32 Assert::Equal(3ul, pLoc->cLocControls); 41 Assert::Equal(3ul, pLoc->cLocControls);
diff --git a/src/libs/dutil/test/DUtilUnitTest/LocStringsUtilTests.cpp b/src/libs/dutil/test/DUtilUnitTest/LocStringsUtilTests.cpp
index 1bfc4bb4..04130098 100644
--- a/src/libs/dutil/test/DUtilUnitTest/LocStringsUtilTests.cpp
+++ b/src/libs/dutil/test/DUtilUnitTest/LocStringsUtilTests.cpp
@@ -15,6 +15,7 @@ namespace DutilTests
15 void CanLoadStringsWxl() 15 void CanLoadStringsWxl()
16 { 16 {
17 HRESULT hr = S_OK; 17 HRESULT hr = S_OK;
18 DWORD dwRetry = 0;
18 WIX_LOCALIZATION* pLoc = NULL; 19 WIX_LOCALIZATION* pLoc = NULL;
19 LOC_STRING* pLocString = NULL; 20 LOC_STRING* pLocString = NULL;
20 LPWSTR sczValue = NULL; 21 LPWSTR sczValue = NULL;
@@ -27,7 +28,15 @@ namespace DutilTests
27 NativeAssert::Succeeded(hr, "Failed to initialize Xml."); 28 NativeAssert::Succeeded(hr, "Failed to initialize Xml.");
28 29
29 pin_ptr<const wchar_t> wxlFilePath = PtrToStringChars(TestData::Get("TestData", "LocUtilTests", "strings.wxl")); 30 pin_ptr<const wchar_t> wxlFilePath = PtrToStringChars(TestData::Get("TestData", "LocUtilTests", "strings.wxl"));
30 hr = LocLoadFromFile(wxlFilePath, &pLoc); 31 do
32 {
33 if (FAILED(hr))
34 {
35 ::Sleep(500);
36 }
37
38 hr = LocLoadFromFile(wxlFilePath, &pLoc);
39 } while (FAILED(hr) && ++dwRetry < 5);
31 NativeAssert::Succeeded(hr, "Failed to parse strings.wxl: {0}", wxlFilePath); 40 NativeAssert::Succeeded(hr, "Failed to parse strings.wxl: {0}", wxlFilePath);
32 41
33 Assert::Equal(4ul, pLoc->cLocStrings); 42 Assert::Equal(4ul, pLoc->cLocStrings);
diff --git a/src/libs/dutil/test/DUtilUnitTest/MonUtilTest.cpp b/src/libs/dutil/test/DUtilUnitTest/MonUtilTest.cpp
index d9c75bf6..f10673fa 100644
--- a/src/libs/dutil/test/DUtilUnitTest/MonUtilTest.cpp
+++ b/src/libs/dutil/test/DUtilUnitTest/MonUtilTest.cpp
@@ -38,452 +38,452 @@ namespace DutilTests
38 DWORD cDirectories; 38 DWORD cDirectories;
39 }; 39 };
40 40
41 public delegate void MonGeneralDelegate(HRESULT, LPVOID); 41 // public delegate void MonGeneralDelegate(HRESULT, LPVOID);
42 42
43 public delegate void MonDriveStatusDelegate(WCHAR, BOOL, LPVOID); 43 // public delegate void MonDriveStatusDelegate(WCHAR, BOOL, LPVOID);
44 44
45 public delegate void MonDirectoryDelegate(HRESULT, LPCWSTR, BOOL, LPVOID, LPVOID); 45 // public delegate void MonDirectoryDelegate(HRESULT, LPCWSTR, BOOL, LPVOID, LPVOID);
46 46
47 public delegate void MonRegKeyDelegate(HRESULT, HKEY, LPCWSTR, REG_KEY_BITNESS, BOOL, LPVOID, LPVOID); 47 // public delegate void MonRegKeyDelegate(HRESULT, HKEY, LPCWSTR, REG_KEY_BITNESS, BOOL, LPVOID, LPVOID);
48 48
49 static void MonGeneral( 49 // static void MonGeneral(
50 __in HRESULT /*hrResult*/, 50 // __in HRESULT /*hrResult*/,
51 __in_opt LPVOID /*pvContext*/ 51 // __in_opt LPVOID /*pvContext*/
52 ) 52 // )
53 { 53 // {
54 Assert::True(false); 54 // Assert::True(false);
55 } 55 // }
56 56
57 static void MonDriveStatus( 57 // static void MonDriveStatus(
58 __in WCHAR /*chDrive*/, 58 // __in WCHAR /*chDrive*/,
59 __in BOOL /*fArriving*/, 59 // __in BOOL /*fArriving*/,
60 __in_opt LPVOID /*pvContext*/ 60 // __in_opt LPVOID /*pvContext*/
61 ) 61 // )
62 { 62 // {
63 } 63 // }
64 64
65 static void MonDirectory( 65 // static void MonDirectory(
66 __in HRESULT hrResult, 66 // __in HRESULT hrResult,
67 __in_z LPCWSTR wzPath, 67 // __in_z LPCWSTR wzPath,
68 __in_z BOOL fRecursive, 68 // __in_z BOOL fRecursive,
69 __in_opt LPVOID pvContext, 69 // __in_opt LPVOID pvContext,
70 __in_opt LPVOID pvDirectoryContext 70 // __in_opt LPVOID pvDirectoryContext
71 ) 71 // )
72 { 72 // {
73 Assert::Equal(S_OK, hrResult); 73 // Assert::Equal(S_OK, hrResult);
74 Assert::Equal<DWORD_PTR>(0, reinterpret_cast<DWORD_PTR>(pvDirectoryContext)); 74 // Assert::Equal<DWORD_PTR>(0, reinterpret_cast<DWORD_PTR>(pvDirectoryContext));
75 75
76 HRESULT hr = S_OK; 76 // HRESULT hr = S_OK;
77 Results *pResults = reinterpret_cast<Results *>(pvContext); 77 // Results *pResults = reinterpret_cast<Results *>(pvContext);
78 78
79 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pResults->rgDirectories), pResults->cDirectories + 1, sizeof(Directory), 5); 79 // hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pResults->rgDirectories), pResults->cDirectories + 1, sizeof(Directory), 5);
80 NativeAssert::ValidReturnCode(hr, S_OK); 80 // NativeAssert::ValidReturnCode(hr, S_OK);
81 ++pResults->cDirectories; 81 // ++pResults->cDirectories;
82 82
83 pResults->rgDirectories[pResults->cDirectories - 1].hr = hrResult; 83 // pResults->rgDirectories[pResults->cDirectories - 1].hr = hrResult;
84 pResults->rgDirectories[pResults->cDirectories - 1].wzPath = wzPath; 84 // pResults->rgDirectories[pResults->cDirectories - 1].wzPath = wzPath;
85 pResults->rgDirectories[pResults->cDirectories - 1].fRecursive = fRecursive; 85 // pResults->rgDirectories[pResults->cDirectories - 1].fRecursive = fRecursive;
86 } 86 // }
87 87
88 static void MonRegKey( 88 // static void MonRegKey(
89 __in HRESULT hrResult, 89 // __in HRESULT hrResult,
90 __in HKEY hkRoot, 90 // __in HKEY hkRoot,
91 __in_z LPCWSTR wzSubKey, 91 // __in_z LPCWSTR wzSubKey,
92 __in REG_KEY_BITNESS kbKeyBitness, 92 // __in REG_KEY_BITNESS kbKeyBitness,
93 __in_z BOOL fRecursive, 93 // __in_z BOOL fRecursive,
94 __in_opt LPVOID pvContext, 94 // __in_opt LPVOID pvContext,
95 __in_opt LPVOID pvRegKeyContext 95 // __in_opt LPVOID pvRegKeyContext
96 ) 96 // )
97 { 97 // {
98 Assert::Equal<HRESULT>(S_OK, hrResult); 98 // Assert::Equal<HRESULT>(S_OK, hrResult);
99 Assert::Equal<DWORD_PTR>(0, reinterpret_cast<DWORD_PTR>(pvRegKeyContext)); 99 // Assert::Equal<DWORD_PTR>(0, reinterpret_cast<DWORD_PTR>(pvRegKeyContext));
100 100
101 HRESULT hr = S_OK; 101 // HRESULT hr = S_OK;
102 Results *pResults = reinterpret_cast<Results *>(pvContext); 102 // Results *pResults = reinterpret_cast<Results *>(pvContext);
103 103
104 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pResults->rgRegKeys), pResults->cRegKeys + 1, sizeof(RegKey), 5); 104 // hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pResults->rgRegKeys), pResults->cRegKeys + 1, sizeof(RegKey), 5);
105 NativeAssert::ValidReturnCode(hr, S_OK); 105 // NativeAssert::ValidReturnCode(hr, S_OK);
106 ++pResults->cRegKeys; 106 // ++pResults->cRegKeys;
107 107
108 pResults->rgRegKeys[pResults->cRegKeys - 1].hr = hrResult; 108 // pResults->rgRegKeys[pResults->cRegKeys - 1].hr = hrResult;
109 pResults->rgRegKeys[pResults->cRegKeys - 1].hkRoot = hkRoot; 109 // pResults->rgRegKeys[pResults->cRegKeys - 1].hkRoot = hkRoot;
110 pResults->rgRegKeys[pResults->cRegKeys - 1].wzSubKey = wzSubKey; 110 // pResults->rgRegKeys[pResults->cRegKeys - 1].wzSubKey = wzSubKey;
111 pResults->rgRegKeys[pResults->cRegKeys - 1].kbKeyBitness = kbKeyBitness; 111 // pResults->rgRegKeys[pResults->cRegKeys - 1].kbKeyBitness = kbKeyBitness;
112 pResults->rgRegKeys[pResults->cRegKeys - 1].fRecursive = fRecursive; 112 // pResults->rgRegKeys[pResults->cRegKeys - 1].fRecursive = fRecursive;
113 } 113 // }
114 114
115 public ref class MonUtil 115 // public ref class MonUtil
116 { 116 // {
117 public: 117 // public:
118 void ClearResults(Results *pResults) 118 // void ClearResults(Results *pResults)
119 { 119 // {
120 ReleaseNullMem(pResults->rgDirectories); 120 // ReleaseNullMem(pResults->rgDirectories);
121 pResults->cDirectories = 0; 121 // pResults->cDirectories = 0;
122 ReleaseNullMem(pResults->rgRegKeys); 122 // ReleaseNullMem(pResults->rgRegKeys);
123 pResults->cRegKeys = 0; 123 // pResults->cRegKeys = 0;
124 } 124 // }
125 125
126 void RemoveDirectory(LPCWSTR wzPath) 126 // void RemoveDirectory(LPCWSTR wzPath)
127 { 127 // {
128 DWORD dwRetryCount = 0; 128 // DWORD dwRetryCount = 0;
129 const DWORD c_dwMaxRetryCount = 100; 129 // const DWORD c_dwMaxRetryCount = 100;
130 const DWORD c_dwRetryInterval = 50; 130 // const DWORD c_dwRetryInterval = 50;
131 131
132 HRESULT hr = DirEnsureDelete(wzPath, TRUE, TRUE); 132 // HRESULT hr = DirEnsureDelete(wzPath, TRUE, TRUE);
133 133
134 // Monitoring a directory opens a handle to that directory, which means delete requests for that directory will succeed 134 // // Monitoring a directory opens a handle to that directory, which means delete requests for that directory will succeed
135 // (and deletion will be "pending" until our monitor handle is closed) 135 // // (and deletion will be "pending" until our monitor handle is closed)
136 // but deletion of the directory containing that directory cannot complete until the handle is closed. This means DirEnsureDelete() 136 // // but deletion of the directory containing that directory cannot complete until the handle is closed. This means DirEnsureDelete()
137 // can sometimes encounter HRESULT_FROM_WIN32(ERROR_DIR_NOT_EMPTY) failures, which just means it needs to retry a bit later 137 // // can sometimes encounter HRESULT_FROM_WIN32(ERROR_DIR_NOT_EMPTY) failures, which just means it needs to retry a bit later
138 // (after the waiter thread wakes up, it will release the handle) 138 // // (after the waiter thread wakes up, it will release the handle)
139 while (HRESULT_FROM_WIN32(ERROR_DIR_NOT_EMPTY) == hr && c_dwMaxRetryCount > dwRetryCount) 139 // while (HRESULT_FROM_WIN32(ERROR_DIR_NOT_EMPTY) == hr && c_dwMaxRetryCount > dwRetryCount)
140 { 140 // {
141 ::Sleep(c_dwRetryInterval); 141 // ::Sleep(c_dwRetryInterval);
142 ++dwRetryCount; 142 // ++dwRetryCount;
143 hr = DirEnsureDelete(wzPath, TRUE, TRUE); 143 // hr = DirEnsureDelete(wzPath, TRUE, TRUE);
144 } 144 // }
145 145
146 NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE, E_PATHNOTFOUND); 146 // NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE, E_PATHNOTFOUND);
147 } 147 // }
148 148
149 void TestDirectory(MON_HANDLE handle, Results *pResults) 149 // void TestDirectory(MON_HANDLE handle, Results *pResults)
150 { 150 // {
151 HRESULT hr = S_OK; 151 // HRESULT hr = S_OK;
152 LPWSTR sczShallowPath = NULL; 152 // LPWSTR sczShallowPath = NULL;
153 LPWSTR sczParentPath = NULL; 153 // LPWSTR sczParentPath = NULL;
154 LPWSTR sczDeepPath = NULL; 154 // LPWSTR sczDeepPath = NULL;
155 LPWSTR sczChildPath = NULL; 155 // LPWSTR sczChildPath = NULL;
156 LPWSTR sczChildFilePath = NULL; 156 // LPWSTR sczChildFilePath = NULL;
157 157
158 try 158 // try
159 { 159 // {
160 hr = PathExpand(&sczShallowPath, L"%TEMP%\\MonUtilTest\\", PATH_EXPAND_ENVIRONMENT); 160 // hr = PathExpand(&sczShallowPath, L"%TEMP%\\MonUtilTest\\", PATH_EXPAND_ENVIRONMENT);
161 NativeAssert::ValidReturnCode(hr, S_OK); 161 // NativeAssert::ValidReturnCode(hr, S_OK);
162 162
163 hr = PathExpand(&sczParentPath, L"%TEMP%\\MonUtilTest\\sub\\folder\\that\\might\\not\\", PATH_EXPAND_ENVIRONMENT); 163 // hr = PathExpand(&sczParentPath, L"%TEMP%\\MonUtilTest\\sub\\folder\\that\\might\\not\\", PATH_EXPAND_ENVIRONMENT);
164 NativeAssert::ValidReturnCode(hr, S_OK); 164 // NativeAssert::ValidReturnCode(hr, S_OK);
165 165
166 hr = PathExpand(&sczDeepPath, L"%TEMP%\\MonUtilTest\\sub\\folder\\that\\might\\not\\exist\\", PATH_EXPAND_ENVIRONMENT); 166 // hr = PathExpand(&sczDeepPath, L"%TEMP%\\MonUtilTest\\sub\\folder\\that\\might\\not\\exist\\", PATH_EXPAND_ENVIRONMENT);
167 NativeAssert::ValidReturnCode(hr, S_OK); 167 // NativeAssert::ValidReturnCode(hr, S_OK);
168 168
169 hr = PathExpand(&sczChildPath, L"%TEMP%\\MonUtilTest\\sub\\folder\\that\\might\\not\\exist\\some\\sub\\folder\\", PATH_EXPAND_ENVIRONMENT); 169 // hr = PathExpand(&sczChildPath, L"%TEMP%\\MonUtilTest\\sub\\folder\\that\\might\\not\\exist\\some\\sub\\folder\\", PATH_EXPAND_ENVIRONMENT);
170 NativeAssert::ValidReturnCode(hr, S_OK); 170 // NativeAssert::ValidReturnCode(hr, S_OK);
171 171
172 hr = PathExpand(&sczChildFilePath, L"%TEMP%\\MonUtilTest\\sub\\folder\\that\\might\\not\\exist\\some\\sub\\folder\\file.txt", PATH_EXPAND_ENVIRONMENT); 172 // hr = PathExpand(&sczChildFilePath, L"%TEMP%\\MonUtilTest\\sub\\folder\\that\\might\\not\\exist\\some\\sub\\folder\\file.txt", PATH_EXPAND_ENVIRONMENT);
173 NativeAssert::ValidReturnCode(hr, S_OK); 173 // NativeAssert::ValidReturnCode(hr, S_OK);
174 174
175 RemoveDirectory(sczShallowPath); 175 // RemoveDirectory(sczShallowPath);
176 176
177 hr = MonAddDirectory(handle, sczDeepPath, TRUE, SILENCEPERIOD, NULL); 177 // hr = MonAddDirectory(handle, sczDeepPath, TRUE, SILENCEPERIOD, NULL);
178 NativeAssert::ValidReturnCode(hr, S_OK); 178 // NativeAssert::ValidReturnCode(hr, S_OK);
179 179
180 hr = DirEnsureExists(sczParentPath, NULL); 180 // hr = DirEnsureExists(sczParentPath, NULL);
181 NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE); 181 // NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE);
182 // Make sure creating the parent directory does nothing, even after silence period 182 // // Make sure creating the parent directory does nothing, even after silence period
183 ::Sleep(FULLWAIT); 183 // ::Sleep(FULLWAIT);
184 Assert::Equal<DWORD>(0, pResults->cDirectories); 184 // Assert::Equal<DWORD>(0, pResults->cDirectories);
185 185
186 // Now create the target path, no notification until after the silence period 186 // // Now create the target path, no notification until after the silence period
187 hr = DirEnsureExists(sczDeepPath, NULL); 187 // hr = DirEnsureExists(sczDeepPath, NULL);
188 NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE); 188 // NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE);
189 ::Sleep(PREWAIT); 189 // ::Sleep(PREWAIT);
190 Assert::Equal<DWORD>(0, pResults->cDirectories); 190 // Assert::Equal<DWORD>(0, pResults->cDirectories);
191 191
192 // Now after the full silence period, it should have triggered 192 // // Now after the full silence period, it should have triggered
193 ::Sleep(POSTWAIT); 193 // ::Sleep(POSTWAIT);
194 Assert::Equal<DWORD>(1, pResults->cDirectories); 194 // Assert::Equal<DWORD>(1, pResults->cDirectories);
195 NativeAssert::ValidReturnCode(pResults->rgDirectories[0].hr, S_OK); 195 // NativeAssert::ValidReturnCode(pResults->rgDirectories[0].hr, S_OK);
196 196
197 // Now delete the directory, along with a ton of parents. This verifies MonUtil will keep watching the closest parent that still exists. 197 // // Now delete the directory, along with a ton of parents. This verifies MonUtil will keep watching the closest parent that still exists.
198 RemoveDirectory(sczShallowPath); 198 // RemoveDirectory(sczShallowPath);
199 199
200 ::Sleep(FULLWAIT); 200 // ::Sleep(FULLWAIT);
201 Assert::Equal<DWORD>(2, pResults->cDirectories); 201 // Assert::Equal<DWORD>(2, pResults->cDirectories);
202 NativeAssert::ValidReturnCode(pResults->rgDirectories[1].hr, S_OK); 202 // NativeAssert::ValidReturnCode(pResults->rgDirectories[1].hr, S_OK);
203 203
204 // Create the parent directory again, still should be nothing even after full silence period 204 // // Create the parent directory again, still should be nothing even after full silence period
205 hr = DirEnsureExists(sczParentPath, NULL); 205 // hr = DirEnsureExists(sczParentPath, NULL);
206 NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE); 206 // NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE);
207 ::Sleep(FULLWAIT); 207 // ::Sleep(FULLWAIT);
208 Assert::Equal<DWORD>(2, pResults->cDirectories); 208 // Assert::Equal<DWORD>(2, pResults->cDirectories);
209 209
210 hr = DirEnsureExists(sczChildPath, NULL); 210 // hr = DirEnsureExists(sczChildPath, NULL);
211 NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE); 211 // NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE);
212 ::Sleep(PREWAIT); 212 // ::Sleep(PREWAIT);
213 Assert::Equal<DWORD>(2, pResults->cDirectories); 213 // Assert::Equal<DWORD>(2, pResults->cDirectories);
214 214
215 ::Sleep(POSTWAIT); 215 // ::Sleep(POSTWAIT);
216 Assert::Equal<DWORD>(3, pResults->cDirectories); 216 // Assert::Equal<DWORD>(3, pResults->cDirectories);
217 NativeAssert::ValidReturnCode(pResults->rgDirectories[2].hr, S_OK); 217 // NativeAssert::ValidReturnCode(pResults->rgDirectories[2].hr, S_OK);
218 218
219 // Write a file to a deep child subfolder, and make sure it's detected 219 // // Write a file to a deep child subfolder, and make sure it's detected
220 hr = FileFromString(sczChildFilePath, 0, L"contents", FILE_ENCODING_UTF16_WITH_BOM); 220 // hr = FileFromString(sczChildFilePath, 0, L"contents", FILE_ENCODING_UTF16_WITH_BOM);
221 NativeAssert::ValidReturnCode(hr, S_OK); 221 // NativeAssert::ValidReturnCode(hr, S_OK);
222 ::Sleep(PREWAIT); 222 // ::Sleep(PREWAIT);
223 Assert::Equal<DWORD>(3, pResults->cDirectories); 223 // Assert::Equal<DWORD>(3, pResults->cDirectories);
224 224
225 ::Sleep(POSTWAIT); 225 // ::Sleep(POSTWAIT);
226 Assert::Equal<DWORD>(4, pResults->cDirectories); 226 // Assert::Equal<DWORD>(4, pResults->cDirectories);
227 NativeAssert::ValidReturnCode(pResults->rgDirectories[2].hr, S_OK); 227 // NativeAssert::ValidReturnCode(pResults->rgDirectories[2].hr, S_OK);
228 228
229 RemoveDirectory(sczParentPath); 229 // RemoveDirectory(sczParentPath);
230 230
231 ::Sleep(FULLWAIT); 231 // ::Sleep(FULLWAIT);
232 Assert::Equal<DWORD>(5, pResults->cDirectories); 232 // Assert::Equal<DWORD>(5, pResults->cDirectories);
233 NativeAssert::ValidReturnCode(pResults->rgDirectories[3].hr, S_OK); 233 // NativeAssert::ValidReturnCode(pResults->rgDirectories[3].hr, S_OK);
234 234
235 // Now remove the directory from the list of things to monitor, and confirm changes are no longer tracked 235 // // Now remove the directory from the list of things to monitor, and confirm changes are no longer tracked
236 hr = MonRemoveDirectory(handle, sczDeepPath, TRUE); 236 // hr = MonRemoveDirectory(handle, sczDeepPath, TRUE);
237 NativeAssert::ValidReturnCode(hr, S_OK); 237 // NativeAssert::ValidReturnCode(hr, S_OK);
238 ::Sleep(PREWAIT); 238 // ::Sleep(PREWAIT);
239 239
240 hr = DirEnsureExists(sczDeepPath, NULL); 240 // hr = DirEnsureExists(sczDeepPath, NULL);
241 NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE); 241 // NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE);
242 ::Sleep(FULLWAIT); 242 // ::Sleep(FULLWAIT);
243 Assert::Equal<DWORD>(5, pResults->cDirectories); 243 // Assert::Equal<DWORD>(5, pResults->cDirectories);
244 NativeAssert::ValidReturnCode(pResults->rgDirectories[3].hr, S_OK); 244 // NativeAssert::ValidReturnCode(pResults->rgDirectories[3].hr, S_OK);
245 245
246 // Finally, add it back so we can test multiple things to monitor at once 246 // // Finally, add it back so we can test multiple things to monitor at once
247 hr = MonAddDirectory(handle, sczDeepPath, TRUE, SILENCEPERIOD, NULL); 247 // hr = MonAddDirectory(handle, sczDeepPath, TRUE, SILENCEPERIOD, NULL);
248 NativeAssert::ValidReturnCode(hr, S_OK); 248 // NativeAssert::ValidReturnCode(hr, S_OK);
249 } 249 // }
250 finally 250 // finally
251 { 251 // {
252 ReleaseStr(sczShallowPath); 252 // ReleaseStr(sczShallowPath);
253 ReleaseStr(sczDeepPath); 253 // ReleaseStr(sczDeepPath);
254 ReleaseStr(sczParentPath); 254 // ReleaseStr(sczParentPath);
255 } 255 // }
256 } 256 // }
257 257
258 void TestRegKey(MON_HANDLE handle, Results *pResults) 258 // void TestRegKey(MON_HANDLE handle, Results *pResults)
259 { 259 // {
260 HRESULT hr = S_OK; 260 // HRESULT hr = S_OK;
261 LPCWSTR wzShallowRegKey = L"Software\\MonUtilTest\\"; 261 // LPCWSTR wzShallowRegKey = L"Software\\MonUtilTest\\";
262 LPCWSTR wzParentRegKey = L"Software\\MonUtilTest\\sub\\folder\\that\\might\\not\\"; 262 // LPCWSTR wzParentRegKey = L"Software\\MonUtilTest\\sub\\folder\\that\\might\\not\\";
263 LPCWSTR wzDeepRegKey = L"Software\\MonUtilTest\\sub\\folder\\that\\might\\not\\exist\\"; 263 // LPCWSTR wzDeepRegKey = L"Software\\MonUtilTest\\sub\\folder\\that\\might\\not\\exist\\";
264 LPCWSTR wzChildRegKey = L"Software\\MonUtilTest\\sub\\folder\\that\\might\\not\\exist\\some\\sub\\folder\\"; 264 // LPCWSTR wzChildRegKey = L"Software\\MonUtilTest\\sub\\folder\\that\\might\\not\\exist\\some\\sub\\folder\\";
265 HKEY hk = NULL; 265 // HKEY hk = NULL;
266 266
267 try 267 // try
268 { 268 // {
269 hr = RegDelete(HKEY_CURRENT_USER, wzShallowRegKey, REG_KEY_32BIT, TRUE); 269 // hr = RegDelete(HKEY_CURRENT_USER, wzShallowRegKey, REG_KEY_32BIT, TRUE);
270 NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE, E_PATHNOTFOUND); 270 // NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE, E_PATHNOTFOUND);
271 271
272 hr = MonAddRegKey(handle, HKEY_CURRENT_USER, wzDeepRegKey, REG_KEY_DEFAULT, TRUE, SILENCEPERIOD, NULL); 272 // hr = MonAddRegKey(handle, HKEY_CURRENT_USER, wzDeepRegKey, REG_KEY_DEFAULT, TRUE, SILENCEPERIOD, NULL);
273 NativeAssert::ValidReturnCode(hr, S_OK); 273 // NativeAssert::ValidReturnCode(hr, S_OK);
274 274
275 hr = RegCreate(HKEY_CURRENT_USER, wzParentRegKey, KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hk); 275 // hr = RegCreate(HKEY_CURRENT_USER, wzParentRegKey, KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hk);
276 ReleaseRegKey(hk); 276 // ReleaseRegKey(hk);
277 // Make sure creating the parent key does nothing, even after silence period 277 // // Make sure creating the parent key does nothing, even after silence period
278 ::Sleep(FULLWAIT); 278 // ::Sleep(FULLWAIT);
279 NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE); 279 // NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE);
280 Assert::Equal<DWORD>(0, pResults->cRegKeys); 280 // Assert::Equal<DWORD>(0, pResults->cRegKeys);
281 281
282 // Now create the target path, no notification until after the silence period 282 // // Now create the target path, no notification until after the silence period
283 hr = RegCreate(HKEY_CURRENT_USER, wzDeepRegKey, KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hk); 283 // hr = RegCreate(HKEY_CURRENT_USER, wzDeepRegKey, KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hk);
284 NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE); 284 // NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE);
285 ReleaseRegKey(hk); 285 // ReleaseRegKey(hk);
286 ::Sleep(PREWAIT); 286 // ::Sleep(PREWAIT);
287 Assert::Equal<DWORD>(0, pResults->cRegKeys); 287 // Assert::Equal<DWORD>(0, pResults->cRegKeys);
288 288
289 // Now after the full silence period, it should have triggered 289 // // Now after the full silence period, it should have triggered
290 ::Sleep(POSTWAIT); 290 // ::Sleep(POSTWAIT);
291 Assert::Equal<DWORD>(1, pResults->cRegKeys); 291 // Assert::Equal<DWORD>(1, pResults->cRegKeys);
292 NativeAssert::ValidReturnCode(pResults->rgRegKeys[0].hr, S_OK); 292 // NativeAssert::ValidReturnCode(pResults->rgRegKeys[0].hr, S_OK);
293 293
294 // Now delete the directory, along with a ton of parents. This verifies MonUtil will keep watching the closest parent that still exists. 294 // // Now delete the directory, along with a ton of parents. This verifies MonUtil will keep watching the closest parent that still exists.
295 hr = RegDelete(HKEY_CURRENT_USER, wzShallowRegKey, REG_KEY_32BIT, TRUE); 295 // hr = RegDelete(HKEY_CURRENT_USER, wzShallowRegKey, REG_KEY_32BIT, TRUE);
296 NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE, E_PATHNOTFOUND); 296 // NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE, E_PATHNOTFOUND);
297 ::Sleep(PREWAIT); 297 // ::Sleep(PREWAIT);
298 Assert::Equal<DWORD>(1, pResults->cRegKeys); 298 // Assert::Equal<DWORD>(1, pResults->cRegKeys);
299 299
300 ::Sleep(FULLWAIT); 300 // ::Sleep(FULLWAIT);
301 Assert::Equal<DWORD>(2, pResults->cRegKeys); 301 // Assert::Equal<DWORD>(2, pResults->cRegKeys);
302 NativeAssert::ValidReturnCode(pResults->rgRegKeys[1].hr, S_OK); 302 // NativeAssert::ValidReturnCode(pResults->rgRegKeys[1].hr, S_OK);
303 303
304 // Create the parent directory again, still should be nothing even after full silence period 304 // // Create the parent directory again, still should be nothing even after full silence period
305 hr = RegCreate(HKEY_CURRENT_USER, wzParentRegKey, KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hk); 305 // hr = RegCreate(HKEY_CURRENT_USER, wzParentRegKey, KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hk);
306 NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE); 306 // NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE);
307 ReleaseRegKey(hk); 307 // ReleaseRegKey(hk);
308 ::Sleep(FULLWAIT); 308 // ::Sleep(FULLWAIT);
309 Assert::Equal<DWORD>(2, pResults->cRegKeys); 309 // Assert::Equal<DWORD>(2, pResults->cRegKeys);
310 310
311 hr = RegCreate(HKEY_CURRENT_USER, wzChildRegKey, KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hk); 311 // hr = RegCreate(HKEY_CURRENT_USER, wzChildRegKey, KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hk);
312 NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE); 312 // NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE);
313 ::Sleep(PREWAIT); 313 // ::Sleep(PREWAIT);
314 Assert::Equal<DWORD>(2, pResults->cRegKeys); 314 // Assert::Equal<DWORD>(2, pResults->cRegKeys);
315 315
316 ::Sleep(FULLWAIT); 316 // ::Sleep(FULLWAIT);
317 Assert::Equal<DWORD>(3, pResults->cRegKeys); 317 // Assert::Equal<DWORD>(3, pResults->cRegKeys);
318 NativeAssert::ValidReturnCode(pResults->rgRegKeys[2].hr, S_OK); 318 // NativeAssert::ValidReturnCode(pResults->rgRegKeys[2].hr, S_OK);
319 319
320 // Write a registry value to some deep child subkey, and make sure it's detected 320 // // Write a registry value to some deep child subkey, and make sure it's detected
321 hr = RegWriteString(hk, L"valuename", L"testvalue"); 321 // hr = RegWriteString(hk, L"valuename", L"testvalue");
322 NativeAssert::ValidReturnCode(hr, S_OK); 322 // NativeAssert::ValidReturnCode(hr, S_OK);
323 ReleaseRegKey(hk); 323 // ReleaseRegKey(hk);
324 ::Sleep(PREWAIT); 324 // ::Sleep(PREWAIT);
325 Assert::Equal<DWORD>(3, pResults->cRegKeys); 325 // Assert::Equal<DWORD>(3, pResults->cRegKeys);
326 326
327 ::Sleep(FULLWAIT); 327 // ::Sleep(FULLWAIT);
328 Assert::Equal<DWORD>(4, pResults->cRegKeys); 328 // Assert::Equal<DWORD>(4, pResults->cRegKeys);
329 NativeAssert::ValidReturnCode(pResults->rgRegKeys[2].hr, S_OK); 329 // NativeAssert::ValidReturnCode(pResults->rgRegKeys[2].hr, S_OK);
330 330
331 hr = RegDelete(HKEY_CURRENT_USER, wzDeepRegKey, REG_KEY_32BIT, TRUE); 331 // hr = RegDelete(HKEY_CURRENT_USER, wzDeepRegKey, REG_KEY_32BIT, TRUE);
332 NativeAssert::ValidReturnCode(hr, S_OK); 332 // NativeAssert::ValidReturnCode(hr, S_OK);
333 333
334 ::Sleep(FULLWAIT); 334 // ::Sleep(FULLWAIT);
335 Assert::Equal<DWORD>(5, pResults->cRegKeys); 335 // Assert::Equal<DWORD>(5, pResults->cRegKeys);
336 336
337 // Now remove the regkey from the list of things to monitor, and confirm changes are no longer tracked 337 // // Now remove the regkey from the list of things to monitor, and confirm changes are no longer tracked
338 hr = MonRemoveRegKey(handle, HKEY_CURRENT_USER, wzDeepRegKey, REG_KEY_DEFAULT, TRUE); 338 // hr = MonRemoveRegKey(handle, HKEY_CURRENT_USER, wzDeepRegKey, REG_KEY_DEFAULT, TRUE);
339 NativeAssert::ValidReturnCode(hr, S_OK); 339 // NativeAssert::ValidReturnCode(hr, S_OK);
340 340
341 hr = RegCreate(HKEY_CURRENT_USER, wzDeepRegKey, KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hk); 341 // hr = RegCreate(HKEY_CURRENT_USER, wzDeepRegKey, KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hk);
342 NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE); 342 // NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE);
343 ReleaseRegKey(hk); 343 // ReleaseRegKey(hk);
344 ::Sleep(FULLWAIT); 344 // ::Sleep(FULLWAIT);
345 Assert::Equal<DWORD>(5, pResults->cRegKeys); 345 // Assert::Equal<DWORD>(5, pResults->cRegKeys);
346 } 346 // }
347 finally 347 // finally
348 { 348 // {
349 ReleaseRegKey(hk); 349 // ReleaseRegKey(hk);
350 } 350 // }
351 } 351 // }
352 352
353 void TestMoreThan64(MON_HANDLE handle, Results *pResults) 353 // void TestMoreThan64(MON_HANDLE handle, Results *pResults)
354 { 354 // {
355 HRESULT hr = S_OK; 355 // HRESULT hr = S_OK;
356 LPWSTR sczBaseDir = NULL; 356 // LPWSTR sczBaseDir = NULL;
357 LPWSTR sczDir = NULL; 357 // LPWSTR sczDir = NULL;
358 LPWSTR sczFile = NULL; 358 // LPWSTR sczFile = NULL;
359 359
360 try 360 // try
361 { 361 // {
362 hr = PathExpand(&sczBaseDir, L"%TEMP%\\ScalabilityTest\\", PATH_EXPAND_ENVIRONMENT); 362 // hr = PathExpand(&sczBaseDir, L"%TEMP%\\ScalabilityTest\\", PATH_EXPAND_ENVIRONMENT);
363 NativeAssert::ValidReturnCode(hr, S_OK); 363 // NativeAssert::ValidReturnCode(hr, S_OK);
364 364
365 for (DWORD i = 0; i < 200; ++i) 365 // for (DWORD i = 0; i < 200; ++i)
366 { 366 // {
367 hr = StrAllocFormatted(&sczDir, L"%ls%u\\", sczBaseDir, i); 367 // hr = StrAllocFormatted(&sczDir, L"%ls%u\\", sczBaseDir, i);
368 NativeAssert::ValidReturnCode(hr, S_OK); 368 // NativeAssert::ValidReturnCode(hr, S_OK);
369 369
370 hr = DirEnsureExists(sczDir, NULL); 370 // hr = DirEnsureExists(sczDir, NULL);
371 NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE); 371 // NativeAssert::ValidReturnCode(hr, S_OK, S_FALSE);
372 372
373 hr = MonAddDirectory(handle, sczDir, FALSE, SILENCEPERIOD, NULL); 373 // hr = MonAddDirectory(handle, sczDir, FALSE, SILENCEPERIOD, NULL);
374 NativeAssert::ValidReturnCode(hr, S_OK); 374 // NativeAssert::ValidReturnCode(hr, S_OK);
375 } 375 // }
376 376
377 hr = PathConcat(sczDir, L"file.txt", &sczFile); 377 // hr = PathConcat(sczDir, L"file.txt", &sczFile);
378 NativeAssert::ValidReturnCode(hr, S_OK); 378 // NativeAssert::ValidReturnCode(hr, S_OK);
379 379
380 hr = FileFromString(sczFile, 0, L"contents", FILE_ENCODING_UTF16_WITH_BOM); 380 // hr = FileFromString(sczFile, 0, L"contents", FILE_ENCODING_UTF16_WITH_BOM);
381 NativeAssert::ValidReturnCode(hr, S_OK); 381 // NativeAssert::ValidReturnCode(hr, S_OK);
382 382
383 ::Sleep(FULLWAIT); 383 // ::Sleep(FULLWAIT);
384 Assert::Equal<DWORD>(1, pResults->cDirectories); 384 // Assert::Equal<DWORD>(1, pResults->cDirectories);
385 385
386 for (DWORD i = 0; i < 199; ++i) 386 // for (DWORD i = 0; i < 199; ++i)
387 { 387 // {
388 hr = StrAllocFormatted(&sczDir, L"%ls%u\\", sczBaseDir, i); 388 // hr = StrAllocFormatted(&sczDir, L"%ls%u\\", sczBaseDir, i);
389 NativeAssert::ValidReturnCode(hr, S_OK); 389 // NativeAssert::ValidReturnCode(hr, S_OK);
390 390
391 hr = MonRemoveDirectory(handle, sczDir, FALSE); 391 // hr = MonRemoveDirectory(handle, sczDir, FALSE);
392 NativeAssert::ValidReturnCode(hr, S_OK); 392 // NativeAssert::ValidReturnCode(hr, S_OK);
393 } 393 // }
394 ::Sleep(FULLWAIT); 394 // ::Sleep(FULLWAIT);
395 395
396 hr = FileFromString(sczFile, 0, L"contents2", FILE_ENCODING_UTF16_WITH_BOM); 396 // hr = FileFromString(sczFile, 0, L"contents2", FILE_ENCODING_UTF16_WITH_BOM);
397 NativeAssert::ValidReturnCode(hr, S_OK); 397 // NativeAssert::ValidReturnCode(hr, S_OK);
398 398
399 ::Sleep(FULLWAIT); 399 // ::Sleep(FULLWAIT);
400 Assert::Equal<DWORD>(2, pResults->cDirectories); 400 // Assert::Equal<DWORD>(2, pResults->cDirectories);
401 401
402 for (DWORD i = 0; i < 199; ++i) 402 // for (DWORD i = 0; i < 199; ++i)
403 { 403 // {
404 hr = StrAllocFormatted(&sczDir, L"%ls%u\\", sczBaseDir, i); 404 // hr = StrAllocFormatted(&sczDir, L"%ls%u\\", sczBaseDir, i);
405 NativeAssert::ValidReturnCode(hr, S_OK); 405 // NativeAssert::ValidReturnCode(hr, S_OK);
406 406
407 hr = MonAddDirectory(handle, sczDir, FALSE, SILENCEPERIOD, NULL); 407 // hr = MonAddDirectory(handle, sczDir, FALSE, SILENCEPERIOD, NULL);
408 NativeAssert::ValidReturnCode(hr, S_OK); 408 // NativeAssert::ValidReturnCode(hr, S_OK);
409 } 409 // }
410 ::Sleep(FULLWAIT); 410 // ::Sleep(FULLWAIT);
411 411
412 hr = FileFromString(sczFile, 0, L"contents3", FILE_ENCODING_UTF16_WITH_BOM); 412 // hr = FileFromString(sczFile, 0, L"contents3", FILE_ENCODING_UTF16_WITH_BOM);
413 NativeAssert::ValidReturnCode(hr, S_OK); 413 // NativeAssert::ValidReturnCode(hr, S_OK);
414 414
415 ::Sleep(FULLWAIT); 415 // ::Sleep(FULLWAIT);
416 Assert::Equal<DWORD>(3, pResults->cDirectories); 416 // Assert::Equal<DWORD>(3, pResults->cDirectories);
417 } 417 // }
418 finally 418 // finally
419 { 419 // {
420 ReleaseStr(sczBaseDir); 420 // ReleaseStr(sczBaseDir);
421 ReleaseStr(sczDir); 421 // ReleaseStr(sczDir);
422 ReleaseStr(sczFile); 422 // ReleaseStr(sczFile);
423 } 423 // }
424 } 424 // }
425 425
426 [Fact(Skip = "Test demonstrates failure")] 426 // [Fact(Skip = "Test demonstrates failure")]
427 void MonUtilTest() 427 // void MonUtilTest()
428 { 428 // {
429 HRESULT hr = S_OK; 429 // HRESULT hr = S_OK;
430 MON_HANDLE handle = NULL; 430 // MON_HANDLE handle = NULL;
431 List<GCHandle>^ gcHandles = gcnew List<GCHandle>(); 431 // List<GCHandle>^ gcHandles = gcnew List<GCHandle>();
432 Results *pResults = (Results *)MemAlloc(sizeof(Results), TRUE); 432 // Results *pResults = (Results *)MemAlloc(sizeof(Results), TRUE);
433 Assert::True(NULL != pResults); 433 // Assert::True(NULL != pResults);
434 434
435 try 435 // try
436 { 436 // {
437 // These ensure the function pointers we send point to this thread's appdomain, which helps with assembly binding when running tests within msbuild 437 // // These ensure the function pointers we send point to this thread's appdomain, which helps with assembly binding when running tests within msbuild
438 MonGeneralDelegate^ fpMonGeneral = gcnew MonGeneralDelegate(MonGeneral); 438 // MonGeneralDelegate^ fpMonGeneral = gcnew MonGeneralDelegate(MonGeneral);
439 GCHandle gchMonGeneral = GCHandle::Alloc(fpMonGeneral); 439 // GCHandle gchMonGeneral = GCHandle::Alloc(fpMonGeneral);
440 gcHandles->Add(gchMonGeneral); 440 // gcHandles->Add(gchMonGeneral);
441 IntPtr ipMonGeneral = Marshal::GetFunctionPointerForDelegate(fpMonGeneral); 441 // IntPtr ipMonGeneral = Marshal::GetFunctionPointerForDelegate(fpMonGeneral);
442 442
443 MonDriveStatusDelegate^ fpMonDriveStatus = gcnew MonDriveStatusDelegate(MonDriveStatus); 443 // MonDriveStatusDelegate^ fpMonDriveStatus = gcnew MonDriveStatusDelegate(MonDriveStatus);
444 GCHandle gchMonDriveStatus = GCHandle::Alloc(fpMonDriveStatus); 444 // GCHandle gchMonDriveStatus = GCHandle::Alloc(fpMonDriveStatus);
445 gcHandles->Add(gchMonDriveStatus); 445 // gcHandles->Add(gchMonDriveStatus);
446 IntPtr ipMonDriveStatus = Marshal::GetFunctionPointerForDelegate(fpMonDriveStatus); 446 // IntPtr ipMonDriveStatus = Marshal::GetFunctionPointerForDelegate(fpMonDriveStatus);
447 447
448 MonDirectoryDelegate^ fpMonDirectory = gcnew MonDirectoryDelegate(MonDirectory); 448 // MonDirectoryDelegate^ fpMonDirectory = gcnew MonDirectoryDelegate(MonDirectory);
449 GCHandle gchMonDirectory = GCHandle::Alloc(fpMonDirectory); 449 // GCHandle gchMonDirectory = GCHandle::Alloc(fpMonDirectory);
450 gcHandles->Add(gchMonDirectory); 450 // gcHandles->Add(gchMonDirectory);
451 IntPtr ipMonDirectory = Marshal::GetFunctionPointerForDelegate(fpMonDirectory); 451 // IntPtr ipMonDirectory = Marshal::GetFunctionPointerForDelegate(fpMonDirectory);
452 452
453 MonRegKeyDelegate^ fpMonRegKey = gcnew MonRegKeyDelegate(MonRegKey); 453 // MonRegKeyDelegate^ fpMonRegKey = gcnew MonRegKeyDelegate(MonRegKey);
454 GCHandle gchMonRegKey = GCHandle::Alloc(fpMonRegKey); 454 // GCHandle gchMonRegKey = GCHandle::Alloc(fpMonRegKey);
455 gcHandles->Add(gchMonRegKey); 455 // gcHandles->Add(gchMonRegKey);
456 IntPtr ipMonRegKey = Marshal::GetFunctionPointerForDelegate(fpMonRegKey); 456 // IntPtr ipMonRegKey = Marshal::GetFunctionPointerForDelegate(fpMonRegKey);
457 457
458 // "Silence period" is 100 ms 458 // // "Silence period" is 100 ms
459 hr = MonCreate(&handle, static_cast<PFN_MONGENERAL>(ipMonGeneral.ToPointer()), static_cast<PFN_MONDRIVESTATUS>(ipMonDriveStatus.ToPointer()), static_cast<PFN_MONDIRECTORY>(ipMonDirectory.ToPointer()), static_cast<PFN_MONREGKEY>(ipMonRegKey.ToPointer()), pResults); 459 // hr = MonCreate(&handle, static_cast<PFN_MONGENERAL>(ipMonGeneral.ToPointer()), static_cast<PFN_MONDRIVESTATUS>(ipMonDriveStatus.ToPointer()), static_cast<PFN_MONDIRECTORY>(ipMonDirectory.ToPointer()), static_cast<PFN_MONREGKEY>(ipMonRegKey.ToPointer()), pResults);
460 NativeAssert::ValidReturnCode(hr, S_OK); 460 // NativeAssert::ValidReturnCode(hr, S_OK);
461 461
462 hr = RegInitialize(); 462 // hr = RegInitialize();
463 NativeAssert::ValidReturnCode(hr, S_OK); 463 // NativeAssert::ValidReturnCode(hr, S_OK);
464 464
465 TestDirectory(handle, pResults); 465 // TestDirectory(handle, pResults);
466 ClearResults(pResults); 466 // ClearResults(pResults);
467 TestRegKey(handle, pResults); 467 // TestRegKey(handle, pResults);
468 ClearResults(pResults); 468 // ClearResults(pResults);
469 TestMoreThan64(handle, pResults); 469 // TestMoreThan64(handle, pResults);
470 ClearResults(pResults); 470 // ClearResults(pResults);
471 } 471 // }
472 finally 472 // finally
473 { 473 // {
474 ReleaseMon(handle); 474 // ReleaseMon(handle);
475 475
476 for each (GCHandle gcHandle in gcHandles) 476 // for each (GCHandle gcHandle in gcHandles)
477 { 477 // {
478 gcHandle.Free(); 478 // gcHandle.Free();
479 } 479 // }
480 480
481 ReleaseMem(pResults->rgDirectories); 481 // ReleaseMem(pResults->rgDirectories);
482 ReleaseMem(pResults->rgRegKeys); 482 // ReleaseMem(pResults->rgRegKeys);
483 ReleaseMem(pResults); 483 // ReleaseMem(pResults);
484 484
485 RegUninitialize(); 485 // RegUninitialize();
486 } 486 // }
487 } 487 // }
488 }; 488 // };
489} 489}
diff --git a/src/libs/dutil/test/DUtilUnitTest/PathUtilTest.cpp b/src/libs/dutil/test/DUtilUnitTest/PathUtilTest.cpp
index 381ea39a..12a2aaf1 100644
--- a/src/libs/dutil/test/DUtilUnitTest/PathUtilTest.cpp
+++ b/src/libs/dutil/test/DUtilUnitTest/PathUtilTest.cpp
@@ -142,7 +142,15 @@ namespace DutilTests
142 else 142 else
143 { 143 {
144 NativeAssert::Succeeded(hr, "Failed to canonicalize path"); 144 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
145 NativeAssert::StringEqual(L"\\\\?\\C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", sczCanonicalized); 145
146 if ('\\' == *sczCanonicalized)
147 {
148 NativeAssert::StringEqual(L"\\\\?\\C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", sczCanonicalized);
149 }
150 else
151 {
152 NativeAssert::StringEqual(L"C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", sczCanonicalized);
153 }
146 } 154 }
147 155
148 hr = PathCanonicalizeForComparison(L"\\\\?\\C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", 0, &sczCanonicalized); 156 hr = PathCanonicalizeForComparison(L"\\\\?\\C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", 0, &sczCanonicalized);
@@ -153,7 +161,15 @@ namespace DutilTests
153 else 161 else
154 { 162 {
155 NativeAssert::Succeeded(hr, "Failed to canonicalize path"); 163 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
156 NativeAssert::StringEqual(L"\\\\?\\C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", sczCanonicalized); 164
165 if ('\\' == *sczCanonicalized)
166 {
167 NativeAssert::StringEqual(L"\\\\?\\C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", sczCanonicalized);
168 }
169 else
170 {
171 NativeAssert::StringEqual(L"C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", sczCanonicalized);
172 }
157 } 173 }
158 174
159 hr = PathCanonicalizeForComparison(L"\\\\server", PATH_CANONICALIZE_KEEP_UNC_ROOT, &sczCanonicalized); 175 hr = PathCanonicalizeForComparison(L"\\\\server", PATH_CANONICALIZE_KEEP_UNC_ROOT, &sczCanonicalized);
@@ -288,7 +304,15 @@ namespace DutilTests
288 { 304 {
289 hr = PathAllocCanonicalizePath(L"C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", PATHCCH_ALLOW_LONG_PATHS, &sczCanonicalized); 305 hr = PathAllocCanonicalizePath(L"C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", PATHCCH_ALLOW_LONG_PATHS, &sczCanonicalized);
290 NativeAssert::Succeeded(hr, "Failed to canonicalize path"); 306 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
291 NativeAssert::StringEqual(L"\\\\?\\C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", sczCanonicalized); 307
308 if ('\\' == *sczCanonicalized)
309 {
310 NativeAssert::StringEqual(L"\\\\?\\C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", sczCanonicalized);
311 }
312 else
313 {
314 NativeAssert::StringEqual(L"C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", sczCanonicalized);
315 }
292 316
293 hr = PathAllocCanonicalizePath(L"abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", PATHCCH_ALLOW_LONG_PATHS, &sczCanonicalized); 317 hr = PathAllocCanonicalizePath(L"abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789", PATHCCH_ALLOW_LONG_PATHS, &sczCanonicalized);
294 NativeAssert::Succeeded(hr, "Failed to canonicalize path"); 318 NativeAssert::Succeeded(hr, "Failed to canonicalize path");
@@ -937,50 +961,22 @@ namespace DutilTests
937 void PathGetTempPathTest() 961 void PathGetTempPathTest()
938 { 962 {
939 HRESULT hr = S_OK; 963 HRESULT hr = S_OK;
940 LPCWSTR wzEnvName = L"TMP";
941 LPCWSTR wzEnvName2 = L"TEMP";
942 LPCWSTR wzLongTempPath = L"C:\\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\\cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\\";
943 LPWSTR sczTempPath = NULL; 964 LPWSTR sczTempPath = NULL;
944 WCHAR wzOriginalTemp[MAX_PATH + 1] = { };
945 WCHAR wzOriginalTemp2[MAX_PATH + 1] = { };
946 DWORD cch = 0; 965 DWORD cch = 0;
947 DWORD cch2 = 0;
948 SIZE_T cchTemp = 0; 966 SIZE_T cchTemp = 0;
949 size_t cchTemp2 = 0; 967 WCHAR wzPath[MAX_PATH + 1];
950
951 try
952 {
953 cch = ::GetEnvironmentVariableW(wzEnvName, wzOriginalTemp, countof(wzOriginalTemp));
954 Assert::NotEqual<DWORD>(0, cch);
955
956 if (!::SetEnvironmentVariableW(wzEnvName, wzLongTempPath))
957 {
958 Assert::Equal<DWORD>(0xFFFFFFFF, ::GetLastError());
959 }
960 968
961 cch2 = ::GetEnvironmentVariableW(wzEnvName2, wzOriginalTemp2, countof(wzOriginalTemp2)); 969 hr = PathGetTempPath(&sczTempPath, &cchTemp);
962 Assert::NotEqual<DWORD>(0, cch2); 970 NativeAssert::Succeeded(hr, "Failed to get temp path.");
963 971
964 hr = PathGetTempPath(&sczTempPath, &cchTemp); 972 cch = countof(wzPath);
965 NativeAssert::Succeeded(hr, "Failed to get temp path."); 973 cch = ::GetTempPathW(cch, wzPath);
974 Assert::NotEqual((DWORD)0, cch);
966 975
967 PathFixedBackslashTerminate(wzOriginalTemp2, countof(wzOriginalTemp2)); 976 // normalize trailing backslash
977 PathFixedBackslashTerminate(wzPath, cch);
968 978
969 hr = ::StringCchLengthW(wzOriginalTemp2, countof(wzOriginalTemp2), &cchTemp2); 979 NativeAssert::StringEqual(wzPath, sczTempPath);
970 NativeAssert::Succeeded(hr, "Failed to get temp path length.");
971
972 NativeAssert::StringEqual(wzOriginalTemp2, sczTempPath);
973 Assert::Equal<SIZE_T>(cchTemp2, cchTemp);
974 }
975 finally
976 {
977 if (cch)
978 {
979 ::SetEnvironmentVariableW(wzEnvName, wzOriginalTemp);
980 }
981
982 ReleaseStr(sczTempPath);
983 }
984 } 980 }
985 981
986 [Fact] 982 [Fact]
diff --git a/src/libs/dutil/test/DUtilUnitTest/StrUtilTest.cpp b/src/libs/dutil/test/DUtilUnitTest/StrUtilTest.cpp
index 89ed3dbb..7ad1ebdf 100644
--- a/src/libs/dutil/test/DUtilUnitTest/StrUtilTest.cpp
+++ b/src/libs/dutil/test/DUtilUnitTest/StrUtilTest.cpp
@@ -80,7 +80,217 @@ namespace DutilTests
80 TestStrAnsiAllocString(b, 0, "abCd"); 80 TestStrAnsiAllocString(b, 0, "abCd");
81 } 81 }
82 82
83 [Fact]
84 void StrUtilMultiSzLenNullTest()
85 {
86 HRESULT hr = S_OK;
87 SIZE_T cchMultiSz = 7;
88
89 DutilInitialize(&DutilTestTraceError);
90
91 try
92 {
93 hr = MultiSzLen(NULL, &cchMultiSz);
94 NativeAssert::Succeeded(hr, "Failed to get MULTISZ length for null.");
95 NativeAssert::Equal<SIZE_T>(0, cchMultiSz);
96 }
97 finally
98 {
99 DutilUninitialize();
100 }
101 }
102
103 [Fact]
104 void StrUtilMultiSzPrependEmptyTest()
105 {
106 HRESULT hr = S_OK;
107 LPWSTR sczMultiSz = NULL;
108 SIZE_T cchMultiSz = 0;
109 const WCHAR expected[] = { L'f', L'i', L'r', L's', L't', L'\0', L'\0' };
110
111 DutilInitialize(&DutilTestTraceError);
112
113 try
114 {
115 hr = MultiSzPrepend(&sczMultiSz, &cchMultiSz, L"first");
116 NativeAssert::Succeeded(hr, "Failed to prepend into empty MULTISZ.");
117 VerifyMultiSz(sczMultiSz, expected, sizeof(expected) / sizeof(expected[0]));
118 NativeAssert::Equal<SIZE_T>(sizeof(expected) / sizeof(expected[0]), cchMultiSz);
119 }
120 finally
121 {
122 ReleaseNullStr(sczMultiSz);
123 DutilUninitialize();
124 }
125 }
126
127 [Fact]
128 void StrUtilMultiSzInsertEmptyTest()
129 {
130 HRESULT hr = S_OK;
131 LPWSTR sczMultiSz = NULL;
132 SIZE_T cchMultiSz = 0;
133 const WCHAR expected[] = { L'i', L'n', L's', L'e', L'r', L't', L'\0', L'\0' };
134
135 DutilInitialize(&DutilTestTraceError);
136
137 try
138 {
139 hr = MultiSzInsertString(&sczMultiSz, &cchMultiSz, 0, L"insert");
140 NativeAssert::Succeeded(hr, "Failed to insert into empty MULTISZ.");
141 VerifyMultiSz(sczMultiSz, expected, sizeof(expected) / sizeof(expected[0]));
142 NativeAssert::Equal<SIZE_T>(sizeof(expected) / sizeof(expected[0]), cchMultiSz);
143 }
144 finally
145 {
146 ReleaseNullStr(sczMultiSz);
147 DutilUninitialize();
148 }
149 }
150
151 [Fact]
152 void StrUtilMultiSzFindTest()
153 {
154 HRESULT hr = S_OK;
155 LPWSTR sczMultiSz = NULL;
156 DWORD_PTR dwIndex = 0;
157 LPCWSTR wzFound = NULL;
158 const WCHAR source[] = { L'o', L'n', L'e', L'\0', L't', L'w', L'o', L'\0', L't', L'h', L'r', L'e', L'e', L'\0', L'\0' };
159
160 DutilInitialize(&DutilTestTraceError);
161
162 try
163 {
164 CreateMultiSz(&sczMultiSz, source, sizeof(source) / sizeof(source[0]));
165
166 hr = MultiSzFindString(sczMultiSz, L"two", &dwIndex, &wzFound);
167 NativeAssert::Succeeded(hr, "Failed to find string in MULTISZ.");
168 NativeAssert::Equal<DWORD_PTR>(1, dwIndex);
169 NativeAssert::StringEqual(L"two", wzFound);
170
171 hr = MultiSzFindSubstring(sczMultiSz, L"re", &dwIndex, &wzFound);
172 NativeAssert::Succeeded(hr, "Failed to find substring in MULTISZ.");
173 NativeAssert::Equal<DWORD_PTR>(2, dwIndex);
174 NativeAssert::StringEqual(L"three", wzFound);
175
176 hr = MultiSzFindString(sczMultiSz, L"missing", &dwIndex, &wzFound);
177 NativeAssert::SpecificReturnCode(S_FALSE, hr, "Expected not found for missing string.");
178
179 hr = MultiSzFindSubstring(sczMultiSz, L"zzz", &dwIndex, &wzFound);
180 NativeAssert::SpecificReturnCode(S_FALSE, hr, "Expected not found for missing substring.");
181 }
182 finally
183 {
184 ReleaseNullStr(sczMultiSz);
185 DutilUninitialize();
186 }
187 }
188
189 [Fact]
190 void StrUtilMultiSzRemoveTest()
191 {
192 HRESULT hr = S_OK;
193 LPWSTR sczMultiSz = NULL;
194 const WCHAR source[] = { L'o', L'n', L'e', L'\0', L't', L'w', L'o', L'\0', L't', L'h', L'r', L'e', L'e', L'\0', L'\0' };
195 const WCHAR expected[] = { L'o', L'n', L'e', L'\0', L't', L'h', L'r', L'e', L'e', L'\0', L'\0' };
196
197 DutilInitialize(&DutilTestTraceError);
198
199 try
200 {
201 CreateMultiSz(&sczMultiSz, source, sizeof(source) / sizeof(source[0]));
202
203 hr = MultiSzRemoveString(&sczMultiSz, 1);
204 NativeAssert::Succeeded(hr, "Failed to remove string from MULTISZ.");
205 VerifyMultiSz(sczMultiSz, expected, sizeof(expected) / sizeof(expected[0]));
206
207 hr = MultiSzRemoveString(&sczMultiSz, 10);
208 NativeAssert::SpecificReturnCode(S_FALSE, hr, "Expected S_FALSE when removing out of range.");
209 }
210 finally
211 {
212 ReleaseNullStr(sczMultiSz);
213 DutilUninitialize();
214 }
215 }
216
217 [Fact]
218 void StrUtilMultiSzInsertTest()
219 {
220 HRESULT hr = S_OK;
221 LPWSTR sczMultiSz = NULL;
222 SIZE_T cchMultiSz = 0;
223 const WCHAR source[] = { L'o', L'n', L'e', L'\0', L't', L'w', L'o', L'\0', L'\0' };
224 const WCHAR expected[] = { L'o', L'n', L'e', L'\0', L't', L'h', L'r', L'e', L'e', L'\0', L't', L'w', L'o', L'\0', L'\0' };
225
226 DutilInitialize(&DutilTestTraceError);
227
228 try
229 {
230 CreateMultiSz(&sczMultiSz, source, sizeof(source) / sizeof(source[0]));
231 cchMultiSz = sizeof(source) / sizeof(source[0]);
232
233 hr = MultiSzInsertString(&sczMultiSz, &cchMultiSz, 1, L"three");
234 NativeAssert::Succeeded(hr, "Failed to insert string into MULTISZ.");
235 VerifyMultiSz(sczMultiSz, expected, sizeof(expected) / sizeof(expected[0]));
236 NativeAssert::Equal<SIZE_T>(sizeof(expected) / sizeof(expected[0]), cchMultiSz);
237
238 hr = MultiSzInsertString(&sczMultiSz, &cchMultiSz, 10, L"bad");
239 NativeAssert::SpecificReturnCode(HRESULT_FROM_WIN32(ERROR_OBJECT_NOT_FOUND), hr, "Expected insert to fail for invalid index.");
240 }
241 finally
242 {
243 ReleaseNullStr(sczMultiSz);
244 DutilUninitialize();
245 }
246 }
247
248 [Fact]
249 void StrUtilMultiSzReplaceTest()
250 {
251 HRESULT hr = S_OK;
252 LPWSTR sczMultiSz = NULL;
253 const WCHAR source[] = { L'o', L'n', L'e', L'\0', L't', L'w', L'o', L'\0', L't', L'h', L'r', L'e', L'e', L'\0', L'\0' };
254 const WCHAR expected[] = { L'o', L'n', L'e', L'\0', L't', L'w', L'o', L'\0', L'f', L'o', L'u', L'r', L'\0', L'\0' };
255
256 DutilInitialize(&DutilTestTraceError);
257
258 try
259 {
260 CreateMultiSz(&sczMultiSz, source, sizeof(source) / sizeof(source[0]));
261
262 hr = MultiSzReplaceString(&sczMultiSz, 2, L"four");
263 NativeAssert::Succeeded(hr, "Failed to replace string in MULTISZ.");
264 VerifyMultiSz(sczMultiSz, expected, sizeof(expected) / sizeof(expected[0]));
265 }
266 finally
267 {
268 ReleaseNullStr(sczMultiSz);
269 DutilUninitialize();
270 }
271 }
272
83 private: 273 private:
274 void CreateMultiSz(LPWSTR* ppwzMultiSz, const WCHAR* pwzSource, SIZE_T cchSource)
275 {
276 HRESULT hr = S_OK;
277
278 hr = StrAlloc(ppwzMultiSz, cchSource);
279 NativeAssert::Succeeded(hr, "Failed to allocate MULTISZ.");
280 ::CopyMemory(*ppwzMultiSz, pwzSource, cchSource * sizeof(WCHAR));
281 }
282
283 void VerifyMultiSz(LPCWSTR wzMultiSz, const WCHAR* pwzExpected, SIZE_T cchExpected)
284 {
285 HRESULT hr = S_OK;
286 SIZE_T cchMultiSz = 0;
287
288 hr = MultiSzLen(wzMultiSz, &cchMultiSz);
289 NativeAssert::Succeeded(hr, "Failed to get MULTISZ length.");
290 NativeAssert::Equal<SIZE_T>(cchExpected, cchMultiSz);
291 NativeAssert::True(0 == ::memcmp(wzMultiSz, pwzExpected, cchExpected * sizeof(WCHAR)));
292 }
293
84 void TestTrim(LPCWSTR wzInput, LPCWSTR wzExpectedResult) 294 void TestTrim(LPCWSTR wzInput, LPCWSTR wzExpectedResult)
85 { 295 {
86 HRESULT hr = S_OK; 296 HRESULT hr = S_OK;