diff options
Diffstat (limited to 'src/burn')
47 files changed, 846 insertions, 325 deletions
diff --git a/src/burn/burn.sln b/src/burn/burn.sln deleted file mode 100644 index c820a467..00000000 --- a/src/burn/burn.sln +++ /dev/null | |||
| @@ -1,63 +0,0 @@ | |||
| 1 | | ||
| 2 | Microsoft Visual Studio Solution File, Format Version 12.00 | ||
| 3 | # Visual Studio Version 17 | ||
| 4 | VisualStudioVersion = 17.0.32014.148 | ||
| 5 | MinimumVisualStudioVersion = 15.0.26124.0 | ||
| 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "engine", "engine\engine.vcxproj", "{8119537D-E1D9-6591-D51A-49768A2F9C37}" | ||
| 7 | EndProject | ||
| 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stub", "stub\stub.vcxproj", "{C38373AA-882F-4F55-B03F-2AAB4BFBE3F1}" | ||
| 9 | EndProject | ||
| 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BurnUnitTest", "test\BurnUnitTest\BurnUnitTest.vcxproj", "{9D1F1BA3-9393-4833-87A3-D5F1FC08EF67}" | ||
| 11 | EndProject | ||
| 12 | Global | ||
| 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
| 14 | Debug|ARM64 = Debug|ARM64 | ||
| 15 | Debug|x64 = Debug|x64 | ||
| 16 | Debug|x86 = Debug|x86 | ||
| 17 | Release|ARM64 = Release|ARM64 | ||
| 18 | Release|x64 = Release|x64 | ||
| 19 | Release|x86 = Release|x86 | ||
| 20 | EndGlobalSection | ||
| 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
| 22 | {8119537D-E1D9-6591-D51A-49768A2F9C37}.Debug|ARM64.ActiveCfg = Debug|ARM64 | ||
| 23 | {8119537D-E1D9-6591-D51A-49768A2F9C37}.Debug|ARM64.Build.0 = Debug|ARM64 | ||
| 24 | {8119537D-E1D9-6591-D51A-49768A2F9C37}.Debug|x64.ActiveCfg = Debug|x64 | ||
| 25 | {8119537D-E1D9-6591-D51A-49768A2F9C37}.Debug|x64.Build.0 = Debug|x64 | ||
| 26 | {8119537D-E1D9-6591-D51A-49768A2F9C37}.Debug|x86.ActiveCfg = Debug|Win32 | ||
| 27 | {8119537D-E1D9-6591-D51A-49768A2F9C37}.Debug|x86.Build.0 = Debug|Win32 | ||
| 28 | {8119537D-E1D9-6591-D51A-49768A2F9C37}.Release|ARM64.ActiveCfg = Release|ARM64 | ||
| 29 | {8119537D-E1D9-6591-D51A-49768A2F9C37}.Release|ARM64.Build.0 = Release|ARM64 | ||
| 30 | {8119537D-E1D9-6591-D51A-49768A2F9C37}.Release|x64.ActiveCfg = Release|x64 | ||
| 31 | {8119537D-E1D9-6591-D51A-49768A2F9C37}.Release|x64.Build.0 = Release|x64 | ||
| 32 | {8119537D-E1D9-6591-D51A-49768A2F9C37}.Release|x86.ActiveCfg = Release|Win32 | ||
| 33 | {8119537D-E1D9-6591-D51A-49768A2F9C37}.Release|x86.Build.0 = Release|Win32 | ||
| 34 | {C38373AA-882F-4F55-B03F-2AAB4BFBE3F1}.Debug|ARM64.ActiveCfg = Debug|ARM64 | ||
| 35 | {C38373AA-882F-4F55-B03F-2AAB4BFBE3F1}.Debug|ARM64.Build.0 = Debug|ARM64 | ||
| 36 | {C38373AA-882F-4F55-B03F-2AAB4BFBE3F1}.Debug|x64.ActiveCfg = Debug|x64 | ||
| 37 | {C38373AA-882F-4F55-B03F-2AAB4BFBE3F1}.Debug|x64.Build.0 = Debug|x64 | ||
| 38 | {C38373AA-882F-4F55-B03F-2AAB4BFBE3F1}.Debug|x86.ActiveCfg = Debug|Win32 | ||
| 39 | {C38373AA-882F-4F55-B03F-2AAB4BFBE3F1}.Debug|x86.Build.0 = Debug|Win32 | ||
| 40 | {C38373AA-882F-4F55-B03F-2AAB4BFBE3F1}.Release|ARM64.ActiveCfg = Release|ARM64 | ||
| 41 | {C38373AA-882F-4F55-B03F-2AAB4BFBE3F1}.Release|ARM64.Build.0 = Release|ARM64 | ||
| 42 | {C38373AA-882F-4F55-B03F-2AAB4BFBE3F1}.Release|x64.ActiveCfg = Release|x64 | ||
| 43 | {C38373AA-882F-4F55-B03F-2AAB4BFBE3F1}.Release|x64.Build.0 = Release|x64 | ||
| 44 | {C38373AA-882F-4F55-B03F-2AAB4BFBE3F1}.Release|x86.ActiveCfg = Release|Win32 | ||
| 45 | {C38373AA-882F-4F55-B03F-2AAB4BFBE3F1}.Release|x86.Build.0 = Release|Win32 | ||
| 46 | {9D1F1BA3-9393-4833-87A3-D5F1FC08EF67}.Debug|ARM64.ActiveCfg = Debug|x64 | ||
| 47 | {9D1F1BA3-9393-4833-87A3-D5F1FC08EF67}.Debug|x64.ActiveCfg = Debug|x64 | ||
| 48 | {9D1F1BA3-9393-4833-87A3-D5F1FC08EF67}.Debug|x64.Build.0 = Debug|x64 | ||
| 49 | {9D1F1BA3-9393-4833-87A3-D5F1FC08EF67}.Debug|x86.ActiveCfg = Debug|Win32 | ||
| 50 | {9D1F1BA3-9393-4833-87A3-D5F1FC08EF67}.Debug|x86.Build.0 = Debug|Win32 | ||
| 51 | {9D1F1BA3-9393-4833-87A3-D5F1FC08EF67}.Release|ARM64.ActiveCfg = Release|x64 | ||
| 52 | {9D1F1BA3-9393-4833-87A3-D5F1FC08EF67}.Release|x64.ActiveCfg = Release|x64 | ||
| 53 | {9D1F1BA3-9393-4833-87A3-D5F1FC08EF67}.Release|x64.Build.0 = Release|x64 | ||
| 54 | {9D1F1BA3-9393-4833-87A3-D5F1FC08EF67}.Release|x86.ActiveCfg = Release|Win32 | ||
| 55 | {9D1F1BA3-9393-4833-87A3-D5F1FC08EF67}.Release|x86.Build.0 = Release|Win32 | ||
| 56 | EndGlobalSection | ||
| 57 | GlobalSection(SolutionProperties) = preSolution | ||
| 58 | HideSolutionNode = FALSE | ||
| 59 | EndGlobalSection | ||
| 60 | GlobalSection(ExtensibilityGlobals) = postSolution | ||
| 61 | SolutionGuid = {A35910C5-8A89-473E-9578-E084172DD3C9} | ||
| 62 | EndGlobalSection | ||
| 63 | EndGlobal | ||
diff --git a/src/burn/burn.slnx b/src/burn/burn.slnx new file mode 100644 index 00000000..76a93036 --- /dev/null +++ b/src/burn/burn.slnx | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | <Solution> | ||
| 2 | <Configurations> | ||
| 3 | <Platform Name="ARM64" /> | ||
| 4 | <Platform Name="x64" /> | ||
| 5 | <Platform Name="x86" /> | ||
| 6 | </Configurations> | ||
| 7 | <Project Path="engine/engine.vcxproj" Id="8119537d-e1d9-6591-d51a-49768a2f9c37" /> | ||
| 8 | <Project Path="stub/stub.vcxproj" Id="c38373aa-882f-4f55-b03f-2aab4bfbe3f1" /> | ||
| 9 | <Project Path="test/BurnUnitTest/BurnUnitTest.vcxproj" Id="9d1f1ba3-9393-4833-87a3-d5f1fc08ef67"> | ||
| 10 | <Platform Solution="*|ARM64" Project="x64" /> | ||
| 11 | <Build Solution="*|ARM64" Project="false" /> | ||
| 12 | </Project> | ||
| 13 | </Solution> | ||
diff --git a/src/burn/engine/approvedexe.cpp b/src/burn/engine/approvedexe.cpp index 28b26d6d..27ec2adc 100644 --- a/src/burn/engine/approvedexe.cpp +++ b/src/burn/engine/approvedexe.cpp | |||
| @@ -3,6 +3,13 @@ | |||
| 3 | #include "precomp.h" | 3 | #include "precomp.h" |
| 4 | 4 | ||
| 5 | 5 | ||
| 6 | // internal function declarations | ||
| 7 | |||
| 8 | static HRESULT IsRunDll32( | ||
| 9 | __in BURN_VARIABLES* pVariables, | ||
| 10 | __in LPCWSTR wzExecutablePath | ||
| 11 | ); | ||
| 12 | |||
| 6 | // function definitions | 13 | // function definitions |
| 7 | 14 | ||
| 8 | extern "C" HRESULT ApprovedExesParseFromXml( | 15 | extern "C" HRESULT ApprovedExesParseFromXml( |
| @@ -122,7 +129,7 @@ extern "C" HRESULT ApprovedExesFindById( | |||
| 122 | { | 129 | { |
| 123 | pApprovedExe = &pApprovedExes->rgApprovedExes[i]; | 130 | pApprovedExe = &pApprovedExes->rgApprovedExes[i]; |
| 124 | 131 | ||
| 125 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pApprovedExe->sczId, -1, wzId, -1)) | 132 | if (CSTR_EQUAL == ::CompareStringOrdinal(pApprovedExe->sczId, -1, wzId, -1, FALSE)) |
| 126 | { | 133 | { |
| 127 | *ppApprovedExe = pApprovedExe; | 134 | *ppApprovedExe = pApprovedExe; |
| 128 | ExitFunction1(hr = S_OK); | 135 | ExitFunction1(hr = S_OK); |
| @@ -221,12 +228,15 @@ LExit: | |||
| 221 | extern "C" HRESULT ApprovedExesVerifySecureLocation( | 228 | extern "C" HRESULT ApprovedExesVerifySecureLocation( |
| 222 | __in BURN_CACHE* pCache, | 229 | __in BURN_CACHE* pCache, |
| 223 | __in BURN_VARIABLES* pVariables, | 230 | __in BURN_VARIABLES* pVariables, |
| 224 | __in LPCWSTR wzExecutablePath | 231 | __in LPCWSTR wzExecutablePath, |
| 232 | __in int argc, | ||
| 233 | __in LPCWSTR* argv | ||
| 225 | ) | 234 | ) |
| 226 | { | 235 | { |
| 227 | HRESULT hr = S_OK; | 236 | HRESULT hr = S_OK; |
| 228 | LPWSTR scz = NULL; | 237 | LPWSTR scz = NULL; |
| 229 | LPWSTR sczSecondary = NULL; | 238 | LPWSTR sczSecondary = NULL; |
| 239 | LPWSTR sczRunDll32Param = NULL; | ||
| 230 | 240 | ||
| 231 | const LPCWSTR vrgSecureFolderVariables[] = { | 241 | const LPCWSTR vrgSecureFolderVariables[] = { |
| 232 | L"ProgramFiles64Folder", | 242 | L"ProgramFiles64Folder", |
| @@ -273,11 +283,104 @@ extern "C" HRESULT ApprovedExesVerifySecureLocation( | |||
| 273 | ExitFunction(); | 283 | ExitFunction(); |
| 274 | } | 284 | } |
| 275 | 285 | ||
| 286 | // Test if executable is rundll32.exe, and it's target is in a secure location | ||
| 287 | // Example for CUDA UninstallString: "C:\WINDOWS\SysWOW64\RunDll32.EXE" "C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL",UninstallPackage CUDAToolkit_12.8 | ||
| 288 | if (argc && argv && argv[0] && *argv[0]) | ||
| 289 | { | ||
| 290 | hr = IsRunDll32(pVariables, wzExecutablePath); | ||
| 291 | ExitOnFailure(hr, "Failed to test whether executable is rundll32"); | ||
| 292 | |||
| 293 | if (hr == S_OK) | ||
| 294 | { | ||
| 295 | LPCWSTR szComma = wcschr(argv[0], L','); | ||
| 296 | if (szComma && *szComma) | ||
| 297 | { | ||
| 298 | hr = StrAllocString(&sczRunDll32Param, argv[0], szComma - argv[0]); | ||
| 299 | ExitOnFailure(hr, "Failed to allocate string"); | ||
| 300 | } | ||
| 301 | else | ||
| 302 | { | ||
| 303 | hr = StrAllocString(&sczRunDll32Param, argv[0], 0); | ||
| 304 | ExitOnFailure(hr, "Failed to allocate string"); | ||
| 305 | } | ||
| 306 | |||
| 307 | hr = ApprovedExesVerifySecureLocation(pCache, pVariables, sczRunDll32Param, 0, NULL); | ||
| 308 | ExitOnFailure(hr, "Failed to test whether rundll32's parameter, '%ls', is in a secure location", sczRunDll32Param); | ||
| 309 | if (hr == S_OK) | ||
| 310 | { | ||
| 311 | ExitFunction(); | ||
| 312 | } | ||
| 313 | } | ||
| 314 | } | ||
| 315 | |||
| 276 | hr = S_FALSE; | 316 | hr = S_FALSE; |
| 277 | 317 | ||
| 278 | LExit: | 318 | LExit: |
| 279 | ReleaseStr(scz); | 319 | ReleaseStr(scz); |
| 280 | ReleaseStr(sczSecondary); | 320 | ReleaseStr(sczSecondary); |
| 321 | ReleaseStr(sczRunDll32Param); | ||
| 322 | |||
| 323 | return hr; | ||
| 324 | } | ||
| 325 | |||
| 326 | static HRESULT IsRunDll32( | ||
| 327 | __in BURN_VARIABLES* pVariables, | ||
| 328 | __in LPCWSTR wzExecutablePath | ||
| 329 | ) | ||
| 330 | { | ||
| 331 | HRESULT hr = S_OK; | ||
| 332 | LPWSTR sczFolder = NULL; | ||
| 333 | LPWSTR sczFullPath = NULL; | ||
| 334 | BOOL fEqual = FALSE; | ||
| 335 | |||
| 336 | hr = VariableGetString(pVariables, L"SystemFolder", &sczFolder); | ||
| 337 | ExitOnFailure(hr, "Failed to get the variable: SystemFolder"); | ||
| 338 | |||
| 339 | hr = PathConcat(sczFolder, L"rundll32.exe", &sczFullPath); | ||
| 340 | ExitOnFailure(hr, "Failed to combine paths"); | ||
| 341 | |||
| 342 | hr = PathCompareCanonicalized(wzExecutablePath, sczFullPath, &fEqual); | ||
| 343 | ExitOnFailure(hr, "Failed to compare paths"); | ||
| 344 | if (fEqual) | ||
| 345 | { | ||
| 346 | hr = S_OK; | ||
| 347 | ExitFunction(); | ||
| 348 | } | ||
| 349 | |||
| 350 | hr = VariableGetString(pVariables, L"System64Folder", &sczFolder); | ||
| 351 | ExitOnFailure(hr, "Failed to get the variable: System64Folder"); | ||
| 352 | |||
| 353 | hr = PathConcat(sczFolder, L"rundll32.exe", &sczFullPath); | ||
| 354 | ExitOnFailure(hr, "Failed to combine paths"); | ||
| 355 | |||
| 356 | hr = PathCompareCanonicalized(wzExecutablePath, sczFullPath, &fEqual); | ||
| 357 | ExitOnFailure(hr, "Failed to compare paths"); | ||
| 358 | if (fEqual) | ||
| 359 | { | ||
| 360 | hr = S_OK; | ||
| 361 | ExitFunction(); | ||
| 362 | } | ||
| 363 | |||
| 364 | // Sysnative | ||
| 365 | hr = PathSystemWindowsSubdirectory(L"SysNative\\", &sczFolder); | ||
| 366 | ExitOnFailure(hr, "Failed to append SysNative directory."); | ||
| 367 | |||
| 368 | hr = PathConcat(sczFolder, L"rundll32.exe", &sczFullPath); | ||
| 369 | ExitOnFailure(hr, "Failed to combine paths"); | ||
| 370 | |||
| 371 | hr = PathCompareCanonicalized(wzExecutablePath, sczFullPath, &fEqual); | ||
| 372 | ExitOnFailure(hr, "Failed to compare paths"); | ||
| 373 | if (fEqual) | ||
| 374 | { | ||
| 375 | hr = S_OK; | ||
| 376 | ExitFunction(); | ||
| 377 | } | ||
| 378 | |||
| 379 | hr = S_FALSE; | ||
| 380 | |||
| 381 | LExit: | ||
| 382 | ReleaseStr(sczFolder); | ||
| 383 | ReleaseStr(sczFullPath); | ||
| 281 | 384 | ||
| 282 | return hr; | 385 | return hr; |
| 283 | } | 386 | } |
diff --git a/src/burn/engine/approvedexe.h b/src/burn/engine/approvedexe.h index 7a68c174..0f441485 100644 --- a/src/burn/engine/approvedexe.h +++ b/src/burn/engine/approvedexe.h | |||
| @@ -58,7 +58,9 @@ HRESULT ApprovedExesLaunch( | |||
| 58 | HRESULT ApprovedExesVerifySecureLocation( | 58 | HRESULT ApprovedExesVerifySecureLocation( |
| 59 | __in BURN_CACHE* pCache, | 59 | __in BURN_CACHE* pCache, |
| 60 | __in BURN_VARIABLES* pVariables, | 60 | __in BURN_VARIABLES* pVariables, |
| 61 | __in LPCWSTR wzExecutablePath | 61 | __in LPCWSTR wzExecutablePath, |
| 62 | __in int argc, | ||
| 63 | __in LPCWSTR* argv | ||
| 62 | ); | 64 | ); |
| 63 | 65 | ||
| 64 | 66 | ||
diff --git a/src/burn/engine/bootstrapperapplication.cpp b/src/burn/engine/bootstrapperapplication.cpp index dc3bd5da..346c47a5 100644 --- a/src/burn/engine/bootstrapperapplication.cpp +++ b/src/burn/engine/bootstrapperapplication.cpp | |||
| @@ -674,7 +674,7 @@ static HRESULT VerifyPipeSecret( | |||
| 674 | hr = StrAlloc(&sczVerificationSecret, cbVerificationSecret / sizeof(WCHAR) + 1); | 674 | hr = StrAlloc(&sczVerificationSecret, cbVerificationSecret / sizeof(WCHAR) + 1); |
| 675 | ExitOnFailure(hr, "Failed to allocate buffer for bootstrapper application verification secret."); | 675 | ExitOnFailure(hr, "Failed to allocate buffer for bootstrapper application verification secret."); |
| 676 | 676 | ||
| 677 | FileReadHandle(hPipe, reinterpret_cast<LPBYTE>(sczVerificationSecret), cbVerificationSecret); | 677 | hr = FileReadHandle(hPipe, reinterpret_cast<LPBYTE>(sczVerificationSecret), cbVerificationSecret); |
| 678 | ExitOnFailure(hr, "Failed to read verification secret from bootstrapper application pipe."); | 678 | ExitOnFailure(hr, "Failed to read verification secret from bootstrapper application pipe."); |
| 679 | 679 | ||
| 680 | // Verify the secrets match. | 680 | // Verify the secrets match. |
diff --git a/src/burn/engine/bundlepackageengine.cpp b/src/burn/engine/bundlepackageengine.cpp index 612da389..7ada5f6a 100644 --- a/src/burn/engine/bundlepackageengine.cpp +++ b/src/burn/engine/bundlepackageengine.cpp | |||
| @@ -146,7 +146,7 @@ extern "C" HRESULT BundlePackageEngineParseRelatedCodes( | |||
| 146 | hr = XmlGetAttributeEx(pixnElement, L"Code", &sczCode); | 146 | hr = XmlGetAttributeEx(pixnElement, L"Code", &sczCode); |
| 147 | ExitOnFailure(hr, "Failed to get @Code."); | 147 | ExitOnFailure(hr, "Failed to get @Code."); |
| 148 | 148 | ||
| 149 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, sczAction, -1, L"Detect", -1)) | 149 | if (CSTR_EQUAL == ::CompareStringOrdinal(sczAction, -1, L"Detect", -1, FALSE)) |
| 150 | { | 150 | { |
| 151 | hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(prgsczDetectCodes), *pcDetectCodes, 1, sizeof(LPWSTR), 5); | 151 | hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(prgsczDetectCodes), *pcDetectCodes, 1, sizeof(LPWSTR), 5); |
| 152 | ExitOnFailure(hr, "Failed to resize Detect code array"); | 152 | ExitOnFailure(hr, "Failed to resize Detect code array"); |
| @@ -155,7 +155,7 @@ extern "C" HRESULT BundlePackageEngineParseRelatedCodes( | |||
| 155 | sczCode = NULL; | 155 | sczCode = NULL; |
| 156 | *pcDetectCodes += 1; | 156 | *pcDetectCodes += 1; |
| 157 | } | 157 | } |
| 158 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, sczAction, -1, L"Upgrade", -1)) | 158 | else if (CSTR_EQUAL == ::CompareStringOrdinal(sczAction, -1, L"Upgrade", -1, FALSE)) |
| 159 | { | 159 | { |
| 160 | hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(prgsczUpgradeCodes), *pcUpgradeCodes, 1, sizeof(LPWSTR), 5); | 160 | hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(prgsczUpgradeCodes), *pcUpgradeCodes, 1, sizeof(LPWSTR), 5); |
| 161 | ExitOnFailure(hr, "Failed to resize Upgrade code array"); | 161 | ExitOnFailure(hr, "Failed to resize Upgrade code array"); |
| @@ -164,7 +164,7 @@ extern "C" HRESULT BundlePackageEngineParseRelatedCodes( | |||
| 164 | sczCode = NULL; | 164 | sczCode = NULL; |
| 165 | *pcUpgradeCodes += 1; | 165 | *pcUpgradeCodes += 1; |
| 166 | } | 166 | } |
| 167 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, sczAction, -1, L"Addon", -1)) | 167 | else if (CSTR_EQUAL == ::CompareStringOrdinal(sczAction, -1, L"Addon", -1, FALSE)) |
| 168 | { | 168 | { |
| 169 | hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(prgsczAddonCodes), *pcAddonCodes, 1, sizeof(LPWSTR), 5); | 169 | hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(prgsczAddonCodes), *pcAddonCodes, 1, sizeof(LPWSTR), 5); |
| 170 | ExitOnFailure(hr, "Failed to resize Addon code array"); | 170 | ExitOnFailure(hr, "Failed to resize Addon code array"); |
| @@ -173,7 +173,7 @@ extern "C" HRESULT BundlePackageEngineParseRelatedCodes( | |||
| 173 | sczCode = NULL; | 173 | sczCode = NULL; |
| 174 | *pcAddonCodes += 1; | 174 | *pcAddonCodes += 1; |
| 175 | } | 175 | } |
| 176 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, sczAction, -1, L"Patch", -1)) | 176 | else if (CSTR_EQUAL == ::CompareStringOrdinal(sczAction, -1, L"Patch", -1, FALSE)) |
| 177 | { | 177 | { |
| 178 | hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(prgsczPatchCodes), *pcPatchCodes, 1, sizeof(LPWSTR), 5); | 178 | hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(prgsczPatchCodes), *pcPatchCodes, 1, sizeof(LPWSTR), 5); |
| 179 | ExitOnFailure(hr, "Failed to resize Patch code array"); | 179 | ExitOnFailure(hr, "Failed to resize Patch code array"); |
| @@ -686,7 +686,7 @@ static BUNDLE_QUERY_CALLBACK_RESULT CALLBACK QueryRelatedBundlesCallback( | |||
| 686 | BOOTSTRAPPER_RELATION_TYPE relationType = RelatedBundleConvertRelationType(pBundle->relationType); | 686 | BOOTSTRAPPER_RELATION_TYPE relationType = RelatedBundleConvertRelationType(pBundle->relationType); |
| 687 | BOOL fPerMachine = BUNDLE_INSTALL_CONTEXT_MACHINE == pBundle->installContext; | 687 | BOOL fPerMachine = BUNDLE_INSTALL_CONTEXT_MACHINE == pBundle->installContext; |
| 688 | 688 | ||
| 689 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pBundle->wzBundleCode, -1, pPackage->Bundle.sczBundleCode, -1) && | 689 | if (CSTR_EQUAL == ::CompareStringOrdinal(pBundle->wzBundleCode, -1, pPackage->Bundle.sczBundleCode, -1, TRUE) && |
| 690 | pPackage->Bundle.fWin64 == (REG_KEY_64BIT == pBundle->regBitness)) | 690 | pPackage->Bundle.fWin64 == (REG_KEY_64BIT == pBundle->regBitness)) |
| 691 | { | 691 | { |
| 692 | Assert(BOOTSTRAPPER_RELATION_UPGRADE == relationType); | 692 | Assert(BOOTSTRAPPER_RELATION_UPGRADE == relationType); |
| @@ -817,7 +817,7 @@ static HRESULT ExecuteBundle( | |||
| 817 | 817 | ||
| 818 | if (pPackage->fPerMachine) | 818 | if (pPackage->fPerMachine) |
| 819 | { | 819 | { |
| 820 | hr = ApprovedExesVerifySecureLocation(pCache, pVariables, sczExecutablePath); | 820 | hr = ApprovedExesVerifySecureLocation(pCache, pVariables, sczExecutablePath, argcArp - 1, (argcArp > 1) ? const_cast<LPCWSTR*>(argvArp + 1) : NULL); |
| 821 | ExitOnFailure(hr, "Failed to verify the QuietUninstallString executable path is in a secure location: %ls", sczExecutablePath); | 821 | ExitOnFailure(hr, "Failed to verify the QuietUninstallString executable path is in a secure location: %ls", sczExecutablePath); |
| 822 | if (S_FALSE == hr) | 822 | if (S_FALSE == hr) |
| 823 | { | 823 | { |
| @@ -940,7 +940,7 @@ static HRESULT ExecuteBundle( | |||
| 940 | 940 | ||
| 941 | if (wzRelationTypeCommandLine) | 941 | if (wzRelationTypeCommandLine) |
| 942 | { | 942 | { |
| 943 | hr = StrAllocConcatFormatted(&sczBaseCommand, L" -%ls", wzRelationTypeCommandLine); | 943 | hr = StrAllocConcatFormatted(&sczBaseCommand, L" -quiet -%ls", wzRelationTypeCommandLine); |
| 944 | ExitOnFailure(hr, "Failed to append relation type argument."); | 944 | ExitOnFailure(hr, "Failed to append relation type argument."); |
| 945 | } | 945 | } |
| 946 | 946 | ||
diff --git a/src/burn/engine/burnextension.cpp b/src/burn/engine/burnextension.cpp index 536dbcc9..50657f32 100644 --- a/src/burn/engine/burnextension.cpp +++ b/src/burn/engine/burnextension.cpp | |||
| @@ -214,7 +214,7 @@ EXTERN_C HRESULT BurnExtensionFindById( | |||
| 214 | { | 214 | { |
| 215 | pExtension = &pBurnExtensions->rgExtensions[i]; | 215 | pExtension = &pBurnExtensions->rgExtensions[i]; |
| 216 | 216 | ||
| 217 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pExtension->sczId, -1, wzId, -1)) | 217 | if (CSTR_EQUAL == ::CompareStringOrdinal(pExtension->sczId, -1, wzId, -1, FALSE)) |
| 218 | { | 218 | { |
| 219 | *ppExtension = pExtension; | 219 | *ppExtension = pExtension; |
| 220 | ExitFunction1(hr = S_OK); | 220 | ExitFunction1(hr = S_OK); |
diff --git a/src/burn/engine/burnpipe.cpp b/src/burn/engine/burnpipe.cpp index 25d602b1..102ccb4f 100644 --- a/src/burn/engine/burnpipe.cpp +++ b/src/burn/engine/burnpipe.cpp | |||
| @@ -446,11 +446,11 @@ extern "C" HRESULT BurnPipeChildConnect( | |||
| 446 | 446 | ||
| 447 | // Try to connect to the parent. | 447 | // Try to connect to the parent. |
| 448 | hr = PipeClientConnect(pConnection->sczName, &pConnection->hPipe); | 448 | hr = PipeClientConnect(pConnection->sczName, &pConnection->hPipe); |
| 449 | ExitOnRootFailure(hr, "Failed to open parent pipe: %ls", sczPipeName) | 449 | ExitOnRootFailure(hr, "Failed to open parent pipe: %ls", pConnection->sczName) |
| 450 | 450 | ||
| 451 | // Verify the parent and notify it that the child connected. | 451 | // Verify the parent and notify it that the child connected. |
| 452 | hr = ChildPipeConnected(pConnection->hPipe, pConnection->sczSecret, &pConnection->dwProcessId); | 452 | hr = ChildPipeConnected(pConnection->hPipe, pConnection->sczSecret, &pConnection->dwProcessId); |
| 453 | ExitOnFailure(hr, "Failed to verify parent pipe: %ls", sczPipeName); | 453 | ExitOnFailure(hr, "Failed to verify parent pipe: %ls", pConnection->sczName); |
| 454 | 454 | ||
| 455 | if (fCompanion) | 455 | if (fCompanion) |
| 456 | { | 456 | { |
| @@ -511,11 +511,11 @@ static HRESULT ChildPipeConnected( | |||
| 511 | hr = StrAlloc(&sczVerificationSecret, cbVerificationSecret / sizeof(WCHAR) + 1); | 511 | hr = StrAlloc(&sczVerificationSecret, cbVerificationSecret / sizeof(WCHAR) + 1); |
| 512 | ExitOnFailure(hr, "Failed to allocate buffer for verification secret."); | 512 | ExitOnFailure(hr, "Failed to allocate buffer for verification secret."); |
| 513 | 513 | ||
| 514 | FileReadHandle(hPipe, reinterpret_cast<LPBYTE>(sczVerificationSecret), cbVerificationSecret); | 514 | hr = FileReadHandle(hPipe, reinterpret_cast<LPBYTE>(sczVerificationSecret), cbVerificationSecret); |
| 515 | ExitOnFailure(hr, "Failed to read verification secret from parent pipe."); | 515 | ExitOnFailure(hr, "Failed to read verification secret from parent pipe."); |
| 516 | 516 | ||
| 517 | // Verify the secrets match. | 517 | // Verify the secrets match. |
| 518 | if (CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, 0, sczVerificationSecret, -1, wzSecret, -1)) | 518 | if (CSTR_EQUAL != ::CompareStringOrdinal(sczVerificationSecret, -1, wzSecret, -1, FALSE)) |
| 519 | { | 519 | { |
| 520 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); | 520 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); |
| 521 | ExitOnRootFailure(hr, "Verification secret from parent does not match."); | 521 | ExitOnRootFailure(hr, "Verification secret from parent does not match."); |
diff --git a/src/burn/engine/cabextract.cpp b/src/burn/engine/cabextract.cpp index 5663c3f7..2140130d 100644 --- a/src/burn/engine/cabextract.cpp +++ b/src/burn/engine/cabextract.cpp | |||
| @@ -833,9 +833,13 @@ static UINT FAR DIAMONDAPI CabWrite( | |||
| 833 | 833 | ||
| 834 | case BURN_CAB_OPERATION_STREAM_TO_BUFFER: | 834 | case BURN_CAB_OPERATION_STREAM_TO_BUFFER: |
| 835 | // copy to target buffer | 835 | // copy to target buffer |
| 836 | memcpy_s(pContext->Cabinet.pbTargetBuffer + pContext->Cabinet.iTargetBuffer, pContext->Cabinet.cbTargetBuffer - pContext->Cabinet.iTargetBuffer, pv, cb); | 836 | if (memcpy_s(pContext->Cabinet.pbTargetBuffer + pContext->Cabinet.iTargetBuffer, pContext->Cabinet.cbTargetBuffer - pContext->Cabinet.iTargetBuffer, pv, cb)) |
| 837 | pContext->Cabinet.iTargetBuffer += cb; | 837 | { |
| 838 | hr = E_INSUFFICIENT_BUFFER; | ||
| 839 | ExitOnRootFailure(hr, "Failed to copy data to target buffer during cabinet extraction."); | ||
| 840 | } | ||
| 838 | 841 | ||
| 842 | pContext->Cabinet.iTargetBuffer += cb; | ||
| 839 | cbWrite = cb; | 843 | cbWrite = cb; |
| 840 | break; | 844 | break; |
| 841 | 845 | ||
diff --git a/src/burn/engine/cache.cpp b/src/burn/engine/cache.cpp index 16db4a81..c85a1be4 100644 --- a/src/burn/engine/cache.cpp +++ b/src/burn/engine/cache.cpp | |||
| @@ -260,6 +260,9 @@ extern "C" HRESULT CacheInitializeSources( | |||
| 260 | hr = PathForCurrentProcess(&sczCurrentPath, NULL); | 260 | hr = PathForCurrentProcess(&sczCurrentPath, NULL); |
| 261 | ExitOnFailure(hr, "Failed to get current process path."); | 261 | ExitOnFailure(hr, "Failed to get current process path."); |
| 262 | 262 | ||
| 263 | hr = VariableSetString(pVariables, BURN_BUNDLE_SOURCE_PROCESS_PATH, sczCurrentPath, FALSE, FALSE); | ||
| 264 | ExitOnFailure(hr, "Failed to set %ls variable.", BURN_BUNDLE_SOURCE_PROCESS_PATH); | ||
| 265 | |||
| 263 | // Determine if we are running from the package cache or not. | 266 | // Determine if we are running from the package cache or not. |
| 264 | hr = CacheGetCompletedPath(pCache, pRegistration->fPerMachine, pRegistration->sczCode, &sczCompletedFolder); | 267 | hr = CacheGetCompletedPath(pCache, pRegistration->fPerMachine, pRegistration->sczCode, &sczCompletedFolder); |
| 265 | ExitOnFailure(hr, "Failed to get completed path for bundle."); | 268 | ExitOnFailure(hr, "Failed to get completed path for bundle."); |
| @@ -275,6 +278,9 @@ extern "C" HRESULT CacheInitializeSources( | |||
| 275 | hr = PathGetDirectory(sczCurrentPath, &pCache->sczSourceProcessFolder); | 278 | hr = PathGetDirectory(sczCurrentPath, &pCache->sczSourceProcessFolder); |
| 276 | ExitOnFailure(hr, "Failed to initialize cache source folder."); | 279 | ExitOnFailure(hr, "Failed to initialize cache source folder."); |
| 277 | 280 | ||
| 281 | hr = VariableSetString(pVariables, BURN_BUNDLE_SOURCE_PROCESS_FOLDER, pCache->sczSourceProcessFolder, FALSE, FALSE); | ||
| 282 | ExitOnFailure(hr, "Failed to set %ls variable.", BURN_BUNDLE_SOURCE_PROCESS_FOLDER); | ||
| 283 | |||
| 278 | // If we're not running from the cache, ensure the original source is set. | 284 | // If we're not running from the cache, ensure the original source is set. |
| 279 | if (!pCache->fRunningFromCache) | 285 | if (!pCache->fRunningFromCache) |
| 280 | { | 286 | { |
| @@ -357,6 +363,8 @@ extern "C" HRESULT CacheEnsureBaseWorkingFolder( | |||
| 357 | } | 363 | } |
| 358 | 364 | ||
| 359 | pWorkingFolderAcl = reinterpret_cast<LPSECURITY_ATTRIBUTES>(MemAlloc(sizeof(SECURITY_ATTRIBUTES), TRUE)); | 365 | pWorkingFolderAcl = reinterpret_cast<LPSECURITY_ATTRIBUTES>(MemAlloc(sizeof(SECURITY_ATTRIBUTES), TRUE)); |
| 366 | ExitOnNull(pWorkingFolderAcl, hr, E_OUTOFMEMORY, "Failed to allocate security attributes."); | ||
| 367 | |||
| 360 | pWorkingFolderAcl->nLength = sizeof(SECURITY_ATTRIBUTES); | 368 | pWorkingFolderAcl->nLength = sizeof(SECURITY_ATTRIBUTES); |
| 361 | pWorkingFolderAcl->lpSecurityDescriptor = psd; | 369 | pWorkingFolderAcl->lpSecurityDescriptor = psd; |
| 362 | pWorkingFolderAcl->bInheritHandle = FALSE; | 370 | pWorkingFolderAcl->bInheritHandle = FALSE; |
| @@ -613,8 +621,8 @@ extern "C" HRESULT CacheGetLocalSourcePaths( | |||
| 613 | 621 | ||
| 614 | hr = GetLastUsedSourceFolder(pVariables, &sczLastSourceFolder); | 622 | hr = GetLastUsedSourceFolder(pVariables, &sczLastSourceFolder); |
| 615 | fPreferSourcePathLocation = !pCache->fRunningFromCache || FAILED(hr); | 623 | fPreferSourcePathLocation = !pCache->fRunningFromCache || FAILED(hr); |
| 616 | fTryLastFolder = SUCCEEDED(hr) && sczLastSourceFolder && *sczLastSourceFolder && CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pCache->sczSourceProcessFolder, -1, sczLastSourceFolder, -1); | 624 | fTryLastFolder = SUCCEEDED(hr) && sczLastSourceFolder && *sczLastSourceFolder && CSTR_EQUAL != ::CompareStringOrdinal(pCache->sczSourceProcessFolder, -1, sczLastSourceFolder, -1, TRUE); |
| 617 | fTryRelativePath = CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, wzSourcePath, -1, wzRelativePath, -1); | 625 | fTryRelativePath = CSTR_EQUAL != ::CompareStringOrdinal(wzSourcePath, -1, wzRelativePath, -1, TRUE); |
| 618 | fSourceIsAbsolute = PathIsRooted(wzSourcePath); | 626 | fSourceIsAbsolute = PathIsRooted(wzSourcePath); |
| 619 | 627 | ||
| 620 | // If the source path provided is a full path, try that first. | 628 | // If the source path provided is a full path, try that first. |
| @@ -791,7 +799,7 @@ extern "C" HRESULT CacheSetLastUsedSource( | |||
| 791 | 799 | ||
| 792 | // If the source path ends with the relative path then this source could be a new path. | 800 | // If the source path ends with the relative path then this source could be a new path. |
| 793 | iSourceRelativePath = cchSourcePath - cchRelativePath; | 801 | iSourceRelativePath = cchSourcePath - cchRelativePath; |
| 794 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, wzSourcePath + iSourceRelativePath, -1, wzRelativePath, -1)) | 802 | if (CSTR_EQUAL == ::CompareStringOrdinal(wzSourcePath + iSourceRelativePath, -1, wzRelativePath, -1, TRUE)) |
| 795 | { | 803 | { |
| 796 | hr = StrAllocString(&sczSourceFolder, wzSourcePath, iSourceRelativePath); | 804 | hr = StrAllocString(&sczSourceFolder, wzSourcePath, iSourceRelativePath); |
| 797 | ExitOnFailure(hr, "Failed to trim source folder."); | 805 | ExitOnFailure(hr, "Failed to trim source folder."); |
| @@ -799,7 +807,7 @@ extern "C" HRESULT CacheSetLastUsedSource( | |||
| 799 | hr = VariableGetString(pVariables, BURN_BUNDLE_LAST_USED_SOURCE, &sczLastSourceFolder); | 807 | hr = VariableGetString(pVariables, BURN_BUNDLE_LAST_USED_SOURCE, &sczLastSourceFolder); |
| 800 | if (SUCCEEDED(hr)) | 808 | if (SUCCEEDED(hr)) |
| 801 | { | 809 | { |
| 802 | nCompare = ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, sczSourceFolder, -1, sczLastSourceFolder, -1); | 810 | nCompare = ::CompareStringOrdinal(sczSourceFolder, -1, sczLastSourceFolder, -1, TRUE); |
| 803 | } | 811 | } |
| 804 | else if (E_NOTFOUND == hr) | 812 | else if (E_NOTFOUND == hr) |
| 805 | { | 813 | { |
| @@ -851,6 +859,7 @@ extern "C" HRESULT CacheSendProgressCallback( | |||
| 851 | case PROGRESS_STOP: | 859 | case PROGRESS_STOP: |
| 852 | hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); | 860 | hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); |
| 853 | ExitOnRootFailure(hr, "UX aborted on download progress."); | 861 | ExitOnRootFailure(hr, "UX aborted on download progress."); |
| 862 | break; | ||
| 854 | 863 | ||
| 855 | case PROGRESS_QUIET: // Not actually an error, just an indication to the caller to stop requesting progress. | 864 | case PROGRESS_QUIET: // Not actually an error, just an indication to the caller to stop requesting progress. |
| 856 | pCallback->pfnProgress = NULL; | 865 | pCallback->pfnProgress = NULL; |
| @@ -860,6 +869,7 @@ extern "C" HRESULT CacheSendProgressCallback( | |||
| 860 | default: | 869 | default: |
| 861 | hr = E_UNEXPECTED; | 870 | hr = E_UNEXPECTED; |
| 862 | ExitOnRootFailure(hr, "Invalid return code from progress routine."); | 871 | ExitOnRootFailure(hr, "Invalid return code from progress routine."); |
| 872 | break; | ||
| 863 | } | 873 | } |
| 864 | } | 874 | } |
| 865 | 875 | ||
| @@ -1025,7 +1035,7 @@ extern "C" HRESULT CacheCompleteBundle( | |||
| 1025 | ExitOnFailure(hr, "Failed to combine completed path with engine file name."); | 1035 | ExitOnFailure(hr, "Failed to combine completed path with engine file name."); |
| 1026 | 1036 | ||
| 1027 | // We can't just use wzExecutablePath because we needed to call CreateCompletedPath to ensure that the destination was secured. | 1037 | // We can't just use wzExecutablePath because we needed to call CreateCompletedPath to ensure that the destination was secured. |
| 1028 | Assert(CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, wzExecutablePath, -1, sczTargetPath, -1)); | 1038 | Assert(CSTR_EQUAL == ::CompareStringOrdinal(wzExecutablePath, -1, sczTargetPath, -1, TRUE)); |
| 1029 | 1039 | ||
| 1030 | // If the bundle is running out of the package cache then we don't need to copy it there | 1040 | // If the bundle is running out of the package cache then we don't need to copy it there |
| 1031 | // (and don't want to since it'll be in use) so bail. | 1041 | // (and don't want to since it'll be in use) so bail. |
| @@ -1429,8 +1439,8 @@ extern "C" void CacheUninitialize( | |||
| 1429 | ReleaseStr(pCache->sczBaseWorkingFolder); | 1439 | ReleaseStr(pCache->sczBaseWorkingFolder); |
| 1430 | ReleaseStr(pCache->sczAcquisitionFolder); | 1440 | ReleaseStr(pCache->sczAcquisitionFolder); |
| 1431 | ReleaseStr(pCache->sczSourceProcessFolder); | 1441 | ReleaseStr(pCache->sczSourceProcessFolder); |
| 1432 | ReleaseStr(pCache->sczBundleEngineWorkingPath) | 1442 | ReleaseStr(pCache->sczBundleEngineWorkingPath); |
| 1433 | ReleaseFileHandle(pCache->hBundleEngineWorkingFile) | 1443 | ReleaseFileHandle(pCache->hBundleEngineWorkingFile); |
| 1434 | 1444 | ||
| 1435 | memset(pCache, 0, sizeof(BURN_CACHE)); | 1445 | memset(pCache, 0, sizeof(BURN_CACHE)); |
| 1436 | } | 1446 | } |
diff --git a/src/burn/engine/condition.cpp b/src/burn/engine/condition.cpp index 8fa62f16..3719ce79 100644 --- a/src/burn/engine/condition.cpp +++ b/src/burn/engine/condition.cpp | |||
| @@ -740,17 +740,17 @@ static HRESULT NextSymbol( | |||
| 740 | ::GetStringTypeW(CT_CTYPE1, &pContext->wzRead[n], 1, &charType); | 740 | ::GetStringTypeW(CT_CTYPE1, &pContext->wzRead[n], 1, &charType); |
| 741 | } while (C1_ALPHA & charType || C1_DIGIT & charType || L'_' == pContext->wzRead[n]); | 741 | } while (C1_ALPHA & charType || C1_DIGIT & charType || L'_' == pContext->wzRead[n]); |
| 742 | 742 | ||
| 743 | if (2 == n && CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pContext->wzRead, 2, L"OR", 2)) | 743 | if (2 == n && CSTR_EQUAL == ::CompareStringOrdinal(pContext->wzRead, 2, L"OR", 2, TRUE)) |
| 744 | { | 744 | { |
| 745 | // OR | 745 | // OR |
| 746 | pContext->NextSymbol.Type = BURN_SYMBOL_TYPE_OR; | 746 | pContext->NextSymbol.Type = BURN_SYMBOL_TYPE_OR; |
| 747 | } | 747 | } |
| 748 | else if (3 == n && CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pContext->wzRead, 3, L"AND", 3)) | 748 | else if (3 == n && CSTR_EQUAL == ::CompareStringOrdinal(pContext->wzRead, 3, L"AND", 3, TRUE)) |
| 749 | { | 749 | { |
| 750 | // AND | 750 | // AND |
| 751 | pContext->NextSymbol.Type = BURN_SYMBOL_TYPE_AND; | 751 | pContext->NextSymbol.Type = BURN_SYMBOL_TYPE_AND; |
| 752 | } | 752 | } |
| 753 | else if (3 == n && CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pContext->wzRead, 3, L"NOT", 3)) | 753 | else if (3 == n && CSTR_EQUAL == ::CompareStringOrdinal(pContext->wzRead, 3, L"NOT", 3, TRUE)) |
| 754 | { | 754 | { |
| 755 | // NOT | 755 | // NOT |
| 756 | pContext->NextSymbol.Type = BURN_SYMBOL_TYPE_NOT; | 756 | pContext->NextSymbol.Type = BURN_SYMBOL_TYPE_NOT; |
| @@ -928,7 +928,7 @@ static HRESULT CompareStringValues( | |||
| 928 | ) | 928 | ) |
| 929 | { | 929 | { |
| 930 | HRESULT hr = S_OK; | 930 | HRESULT hr = S_OK; |
| 931 | DWORD dwCompareString = (comparison & INSENSITIVE) ? NORM_IGNORECASE : 0; | 931 | BOOL fIgnoreCase = (comparison & INSENSITIVE) ? TRUE : FALSE; |
| 932 | size_t cchLeftSize = 0; | 932 | size_t cchLeftSize = 0; |
| 933 | size_t cchRightSize = 0; | 933 | size_t cchRightSize = 0; |
| 934 | int cchLeft = 0; | 934 | int cchLeft = 0; |
| @@ -958,7 +958,7 @@ static HRESULT CompareStringValues( | |||
| 958 | case BURN_SYMBOL_TYPE_EQ_I: | 958 | case BURN_SYMBOL_TYPE_EQ_I: |
| 959 | case BURN_SYMBOL_TYPE_NE_I: | 959 | case BURN_SYMBOL_TYPE_NE_I: |
| 960 | { | 960 | { |
| 961 | int i = ::CompareStringW(LOCALE_INVARIANT, dwCompareString, wzLeftOperand, cchLeft, wzRightOperand, cchRight); | 961 | int i = ::CompareStringOrdinal(wzLeftOperand, cchLeft, wzRightOperand, cchRight, fIgnoreCase); |
| 962 | hr = CompareIntegerValues(comparison, i, CSTR_EQUAL, pfResult); | 962 | hr = CompareIntegerValues(comparison, i, CSTR_EQUAL, pfResult); |
| 963 | } | 963 | } |
| 964 | break; | 964 | break; |
| @@ -967,7 +967,7 @@ static HRESULT CompareStringValues( | |||
| 967 | // test if left string contains right string | 967 | // test if left string contains right string |
| 968 | for (int i = 0; (i + cchRight) <= cchLeft; ++i) | 968 | for (int i = 0; (i + cchRight) <= cchLeft; ++i) |
| 969 | { | 969 | { |
| 970 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, dwCompareString, wzLeftOperand + i, cchRight, wzRightOperand, cchRight)) | 970 | if (CSTR_EQUAL == ::CompareStringOrdinal(wzLeftOperand + i, cchRight, wzRightOperand, cchRight, fIgnoreCase)) |
| 971 | { | 971 | { |
| 972 | *pfResult = TRUE; | 972 | *pfResult = TRUE; |
| 973 | ExitFunction(); | 973 | ExitFunction(); |
| @@ -978,12 +978,12 @@ static HRESULT CompareStringValues( | |||
| 978 | case BURN_SYMBOL_TYPE_HIEQ: | 978 | case BURN_SYMBOL_TYPE_HIEQ: |
| 979 | case BURN_SYMBOL_TYPE_HIEQ_I: | 979 | case BURN_SYMBOL_TYPE_HIEQ_I: |
| 980 | // test if left string starts with right string | 980 | // test if left string starts with right string |
| 981 | *pfResult = cchLeft >= cchRight && CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, dwCompareString, wzLeftOperand, cchRight, wzRightOperand, cchRight); | 981 | *pfResult = cchLeft >= cchRight && CSTR_EQUAL == ::CompareStringOrdinal(wzLeftOperand, cchRight, wzRightOperand, cchRight, fIgnoreCase); |
| 982 | break; | 982 | break; |
| 983 | case BURN_SYMBOL_TYPE_LOEQ: | 983 | case BURN_SYMBOL_TYPE_LOEQ: |
| 984 | case BURN_SYMBOL_TYPE_LOEQ_I: | 984 | case BURN_SYMBOL_TYPE_LOEQ_I: |
| 985 | // test if left string ends with right string | 985 | // test if left string ends with right string |
| 986 | *pfResult = cchLeft >= cchRight && CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, dwCompareString, wzLeftOperand + (cchLeft - cchRight), cchRight, wzRightOperand, cchRight); | 986 | *pfResult = cchLeft >= cchRight && CSTR_EQUAL == ::CompareStringOrdinal(wzLeftOperand + (cchLeft - cchRight), cchRight, wzRightOperand, cchRight, fIgnoreCase); |
| 987 | break; | 987 | break; |
| 988 | default: | 988 | default: |
| 989 | ExitFunction1(hr = E_INVALIDARG); | 989 | ExitFunction1(hr = E_INVALIDARG); |
diff --git a/src/burn/engine/container.cpp b/src/burn/engine/container.cpp index fad010cf..41ab0919 100644 --- a/src/burn/engine/container.cpp +++ b/src/burn/engine/container.cpp | |||
| @@ -400,7 +400,7 @@ extern "C" HRESULT ContainerFindById( | |||
| 400 | { | 400 | { |
| 401 | pContainer = &pContainers->rgContainers[i]; | 401 | pContainer = &pContainers->rgContainers[i]; |
| 402 | 402 | ||
| 403 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pContainer->sczId, -1, wzId, -1)) | 403 | if (CSTR_EQUAL == ::CompareStringOrdinal(pContainer->sczId, -1, wzId, -1, FALSE)) |
| 404 | { | 404 | { |
| 405 | *ppContainer = pContainer; | 405 | *ppContainer = pContainer; |
| 406 | ExitFunction1(hr = S_OK); | 406 | ExitFunction1(hr = S_OK); |
diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp index b20f7f0c..2dfa4857 100644 --- a/src/burn/engine/core.cpp +++ b/src/burn/engine/core.cpp | |||
| @@ -1215,8 +1215,8 @@ HRESULT CoreAppendLogToCommandLine( | |||
| 1215 | if (rgszArgs[i][0] == L'-' || rgszArgs[i][0] == L'/') | 1215 | if (rgszArgs[i][0] == L'-' || rgszArgs[i][0] == L'/') |
| 1216 | { | 1216 | { |
| 1217 | // Now looking for 'log' or 'l' | 1217 | // Now looking for 'log' or 'l' |
| 1218 | if ((CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &rgszArgs[i][1], -1, L"log", -1)) | 1218 | if ((CSTR_EQUAL == ::CompareStringOrdinal(&rgszArgs[i][1], -1, L"log", -1, TRUE)) |
| 1219 | || (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &rgszArgs[i][1], -1, L"l", -1))) | 1219 | || (CSTR_EQUAL == ::CompareStringOrdinal(&rgszArgs[i][1], -1, L"l", -1, TRUE))) |
| 1220 | { | 1220 | { |
| 1221 | ExitFunction1(hr = S_FALSE); | 1221 | ExitFunction1(hr = S_FALSE); |
| 1222 | } | 1222 | } |
| @@ -1232,8 +1232,11 @@ HRESULT CoreAppendLogToCommandLine( | |||
| 1232 | hr = StrAllocConcat(psczCommandLine, szLogArgFormatted, 0); | 1232 | hr = StrAllocConcat(psczCommandLine, szLogArgFormatted, 0); |
| 1233 | ExitOnFailure(hr, "Failed concatenating '-log' to command line"); | 1233 | ExitOnFailure(hr, "Failed concatenating '-log' to command line"); |
| 1234 | 1234 | ||
| 1235 | hr = StrAllocConcat(psczObfuscatedCommandLine, szLogArgFormatted, 0); | 1235 | if (psczObfuscatedCommandLine) |
| 1236 | ExitOnFailure(hr, "Failed concatenating '-log' to obfuscated command line"); | 1236 | { |
| 1237 | hr = StrAllocConcat(psczObfuscatedCommandLine, szLogArgFormatted, 0); | ||
| 1238 | ExitOnFailure(hr, "Failed concatenating '-log' to obfuscated command line"); | ||
| 1239 | } | ||
| 1237 | 1240 | ||
| 1238 | LExit: | 1241 | LExit: |
| 1239 | if (rgszArgs) | 1242 | if (rgszArgs) |
| @@ -1360,13 +1363,13 @@ extern "C" HRESULT CoreParseCommandLine( | |||
| 1360 | 1363 | ||
| 1361 | if (argv[i][0] == L'-' || argv[i][0] == L'/') | 1364 | if (argv[i][0] == L'-' || argv[i][0] == L'/') |
| 1362 | { | 1365 | { |
| 1363 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"l", -1) || | 1366 | if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"l", -1, TRUE) || |
| 1364 | CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"log", -1) || | 1367 | CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"log", -1, TRUE) || |
| 1365 | CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"xlog", -1)) | 1368 | CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"xlog", -1, TRUE)) |
| 1366 | { | 1369 | { |
| 1367 | pInternalCommand->dwLoggingAttributes &= ~BURN_LOGGING_ATTRIBUTE_APPEND; | 1370 | pInternalCommand->dwLoggingAttributes &= ~BURN_LOGGING_ATTRIBUTE_APPEND; |
| 1368 | 1371 | ||
| 1369 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], 1, L"x", 1)) | 1372 | if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], 1, L"x", 1, TRUE)) |
| 1370 | { | 1373 | { |
| 1371 | pInternalCommand->dwLoggingAttributes |= BURN_LOGGING_ATTRIBUTE_VERBOSE | BURN_LOGGING_ATTRIBUTE_EXTRADEBUG; | 1374 | pInternalCommand->dwLoggingAttributes |= BURN_LOGGING_ATTRIBUTE_VERBOSE | BURN_LOGGING_ATTRIBUTE_EXTRADEBUG; |
| 1372 | } | 1375 | } |
| @@ -1382,24 +1385,24 @@ extern "C" HRESULT CoreParseCommandLine( | |||
| 1382 | hr = PathExpand(&pInternalCommand->sczLogFile, argv[i], PATH_EXPAND_FULLPATH); | 1385 | hr = PathExpand(&pInternalCommand->sczLogFile, argv[i], PATH_EXPAND_FULLPATH); |
| 1383 | ExitOnFailure(hr, "Failed to copy log file path."); | 1386 | ExitOnFailure(hr, "Failed to copy log file path."); |
| 1384 | } | 1387 | } |
| 1385 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"?", -1) || | 1388 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"?", -1, TRUE) || |
| 1386 | CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"h", -1) || | 1389 | CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"h", -1, TRUE) || |
| 1387 | CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"help", -1)) | 1390 | CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"help", -1, TRUE)) |
| 1388 | { | 1391 | { |
| 1389 | pCommand->action = BOOTSTRAPPER_ACTION_HELP; | 1392 | pCommand->action = BOOTSTRAPPER_ACTION_HELP; |
| 1390 | } | 1393 | } |
| 1391 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"q", -1) || | 1394 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"q", -1, TRUE) || |
| 1392 | CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"quiet", -1) || | 1395 | CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"quiet", -1, TRUE) || |
| 1393 | CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"s", -1) || | 1396 | CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"s", -1, TRUE) || |
| 1394 | CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"silent", -1)) | 1397 | CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"silent", -1, TRUE)) |
| 1395 | { | 1398 | { |
| 1396 | pCommand->display = BOOTSTRAPPER_DISPLAY_NONE; | 1399 | pCommand->display = BOOTSTRAPPER_DISPLAY_NONE; |
| 1397 | } | 1400 | } |
| 1398 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"passive", -1)) | 1401 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"passive", -1, TRUE)) |
| 1399 | { | 1402 | { |
| 1400 | pCommand->display = BOOTSTRAPPER_DISPLAY_PASSIVE; | 1403 | pCommand->display = BOOTSTRAPPER_DISPLAY_PASSIVE; |
| 1401 | } | 1404 | } |
| 1402 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"layout", -1)) | 1405 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"layout", -1, TRUE)) |
| 1403 | { | 1406 | { |
| 1404 | if (BOOTSTRAPPER_ACTION_HELP != pCommand->action) | 1407 | if (BOOTSTRAPPER_ACTION_HELP != pCommand->action) |
| 1405 | { | 1408 | { |
| @@ -1415,47 +1418,47 @@ extern "C" HRESULT CoreParseCommandLine( | |||
| 1415 | ExitOnFailure(hr, "Failed to copy path for layout directory."); | 1418 | ExitOnFailure(hr, "Failed to copy path for layout directory."); |
| 1416 | } | 1419 | } |
| 1417 | } | 1420 | } |
| 1418 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"unsafeuninstall", -1)) | 1421 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"unsafeuninstall", -1, TRUE)) |
| 1419 | { | 1422 | { |
| 1420 | if (BOOTSTRAPPER_ACTION_HELP != pCommand->action) | 1423 | if (BOOTSTRAPPER_ACTION_HELP != pCommand->action) |
| 1421 | { | 1424 | { |
| 1422 | pCommand->action = BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL; | 1425 | pCommand->action = BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL; |
| 1423 | } | 1426 | } |
| 1424 | } | 1427 | } |
| 1425 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"uninstall", -1)) | 1428 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"uninstall", -1, TRUE)) |
| 1426 | { | 1429 | { |
| 1427 | if (BOOTSTRAPPER_ACTION_HELP != pCommand->action) | 1430 | if (BOOTSTRAPPER_ACTION_HELP != pCommand->action) |
| 1428 | { | 1431 | { |
| 1429 | pCommand->action = BOOTSTRAPPER_ACTION_UNINSTALL; | 1432 | pCommand->action = BOOTSTRAPPER_ACTION_UNINSTALL; |
| 1430 | } | 1433 | } |
| 1431 | } | 1434 | } |
| 1432 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"repair", -1)) | 1435 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"repair", -1, TRUE)) |
| 1433 | { | 1436 | { |
| 1434 | if (BOOTSTRAPPER_ACTION_HELP != pCommand->action) | 1437 | if (BOOTSTRAPPER_ACTION_HELP != pCommand->action) |
| 1435 | { | 1438 | { |
| 1436 | pCommand->action = BOOTSTRAPPER_ACTION_REPAIR; | 1439 | pCommand->action = BOOTSTRAPPER_ACTION_REPAIR; |
| 1437 | } | 1440 | } |
| 1438 | } | 1441 | } |
| 1439 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"modify", -1)) | 1442 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"modify", -1, TRUE)) |
| 1440 | { | 1443 | { |
| 1441 | if (BOOTSTRAPPER_ACTION_HELP != pCommand->action) | 1444 | if (BOOTSTRAPPER_ACTION_HELP != pCommand->action) |
| 1442 | { | 1445 | { |
| 1443 | pCommand->action = BOOTSTRAPPER_ACTION_MODIFY; | 1446 | pCommand->action = BOOTSTRAPPER_ACTION_MODIFY; |
| 1444 | } | 1447 | } |
| 1445 | } | 1448 | } |
| 1446 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"package", -1) || | 1449 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"package", -1, TRUE) || |
| 1447 | CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"update", -1)) | 1450 | CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"update", -1, TRUE)) |
| 1448 | { | 1451 | { |
| 1449 | if (BOOTSTRAPPER_ACTION_UNKNOWN == pCommand->action) | 1452 | if (BOOTSTRAPPER_ACTION_UNKNOWN == pCommand->action) |
| 1450 | { | 1453 | { |
| 1451 | pCommand->action = BOOTSTRAPPER_ACTION_INSTALL; | 1454 | pCommand->action = BOOTSTRAPPER_ACTION_INSTALL; |
| 1452 | } | 1455 | } |
| 1453 | } | 1456 | } |
| 1454 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"noaupause", -1)) | 1457 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"noaupause", -1, TRUE)) |
| 1455 | { | 1458 | { |
| 1456 | pInternalCommand->automaticUpdates = BURN_AU_PAUSE_ACTION_NONE; | 1459 | pInternalCommand->automaticUpdates = BURN_AU_PAUSE_ACTION_NONE; |
| 1457 | } | 1460 | } |
| 1458 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"keepaupaused", -1)) | 1461 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"keepaupaused", -1, TRUE)) |
| 1459 | { | 1462 | { |
| 1460 | // Switch /noaupause takes precedence. | 1463 | // Switch /noaupause takes precedence. |
| 1461 | if (BURN_AU_PAUSE_ACTION_NONE != pInternalCommand->automaticUpdates) | 1464 | if (BURN_AU_PAUSE_ACTION_NONE != pInternalCommand->automaticUpdates) |
| @@ -1463,11 +1466,11 @@ extern "C" HRESULT CoreParseCommandLine( | |||
| 1463 | pInternalCommand->automaticUpdates = BURN_AU_PAUSE_ACTION_IFELEVATED_NORESUME; | 1466 | pInternalCommand->automaticUpdates = BURN_AU_PAUSE_ACTION_IFELEVATED_NORESUME; |
| 1464 | } | 1467 | } |
| 1465 | } | 1468 | } |
| 1466 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"disablesystemrestore", -1)) | 1469 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"disablesystemrestore", -1, TRUE)) |
| 1467 | { | 1470 | { |
| 1468 | pInternalCommand->fDisableSystemRestore = TRUE; | 1471 | pInternalCommand->fDisableSystemRestore = TRUE; |
| 1469 | } | 1472 | } |
| 1470 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"originalsource", -1)) | 1473 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"originalsource", -1, TRUE)) |
| 1471 | { | 1474 | { |
| 1472 | if (i + 1 >= argc) | 1475 | if (i + 1 >= argc) |
| 1473 | { | 1476 | { |
| @@ -1479,7 +1482,7 @@ extern "C" HRESULT CoreParseCommandLine( | |||
| 1479 | hr = PathExpand(&pInternalCommand->sczOriginalSource, argv[i], PATH_EXPAND_FULLPATH); | 1482 | hr = PathExpand(&pInternalCommand->sczOriginalSource, argv[i], PATH_EXPAND_FULLPATH); |
| 1480 | ExitOnFailure(hr, "Failed to copy last used source."); | 1483 | ExitOnFailure(hr, "Failed to copy last used source."); |
| 1481 | } | 1484 | } |
| 1482 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_PARENT, -1)) | 1485 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, BURN_COMMANDLINE_SWITCH_PARENT, -1, TRUE)) |
| 1483 | { | 1486 | { |
| 1484 | if (i + 1 >= argc) | 1487 | if (i + 1 >= argc) |
| 1485 | { | 1488 | { |
| @@ -1492,12 +1495,12 @@ extern "C" HRESULT CoreParseCommandLine( | |||
| 1492 | hr = StrAllocString(&pInternalCommand->sczActiveParent, argv[i], 0); | 1495 | hr = StrAllocString(&pInternalCommand->sczActiveParent, argv[i], 0); |
| 1493 | ExitOnFailure(hr, "Failed to copy parent."); | 1496 | ExitOnFailure(hr, "Failed to copy parent."); |
| 1494 | } | 1497 | } |
| 1495 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_PARENT_NONE, -1)) | 1498 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, BURN_COMMANDLINE_SWITCH_PARENT_NONE, -1, TRUE)) |
| 1496 | { | 1499 | { |
| 1497 | hr = StrAllocString(&pInternalCommand->sczActiveParent, L"", 0); | 1500 | hr = StrAllocString(&pInternalCommand->sczActiveParent, L"", 0); |
| 1498 | ExitOnFailure(hr, "Failed to initialize parent to none."); | 1501 | ExitOnFailure(hr, "Failed to initialize parent to none."); |
| 1499 | } | 1502 | } |
| 1500 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_LOG_APPEND, -1)) | 1503 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, BURN_COMMANDLINE_SWITCH_LOG_APPEND, -1, TRUE)) |
| 1501 | { | 1504 | { |
| 1502 | if (i + 1 >= argc) | 1505 | if (i + 1 >= argc) |
| 1503 | { | 1506 | { |
| @@ -1512,7 +1515,7 @@ extern "C" HRESULT CoreParseCommandLine( | |||
| 1512 | 1515 | ||
| 1513 | pInternalCommand->dwLoggingAttributes |= BURN_LOGGING_ATTRIBUTE_APPEND; | 1516 | pInternalCommand->dwLoggingAttributes |= BURN_LOGGING_ATTRIBUTE_APPEND; |
| 1514 | } | 1517 | } |
| 1515 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_LOG_MODE), BURN_COMMANDLINE_SWITCH_LOG_MODE, -1)) | 1518 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_LOG_MODE), BURN_COMMANDLINE_SWITCH_LOG_MODE, -1, TRUE)) |
| 1516 | { | 1519 | { |
| 1517 | // Get a pointer to the next character after the switch. | 1520 | // Get a pointer to the next character after the switch. |
| 1518 | LPCWSTR wzParam = &argv[i][2 + lstrlenW(BURN_COMMANDLINE_SWITCH_LOG_MODE)]; | 1521 | LPCWSTR wzParam = &argv[i][2 + lstrlenW(BURN_COMMANDLINE_SWITCH_LOG_MODE)]; |
| @@ -1541,7 +1544,7 @@ extern "C" HRESULT CoreParseCommandLine( | |||
| 1541 | } | 1544 | } |
| 1542 | } | 1545 | } |
| 1543 | } | 1546 | } |
| 1544 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_ELEVATED, -1)) | 1547 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, BURN_COMMANDLINE_SWITCH_ELEVATED, -1, TRUE)) |
| 1545 | { | 1548 | { |
| 1546 | if (i + 3 >= argc) | 1549 | if (i + 3 >= argc) |
| 1547 | { | 1550 | { |
| @@ -1579,7 +1582,7 @@ extern "C" HRESULT CoreParseCommandLine( | |||
| 1579 | 1582 | ||
| 1580 | i += 2; | 1583 | i += 2; |
| 1581 | } | 1584 | } |
| 1582 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_SYSTEM_COMPONENT), BURN_COMMANDLINE_SWITCH_SYSTEM_COMPONENT, lstrlenW(BURN_COMMANDLINE_SWITCH_SYSTEM_COMPONENT))) | 1585 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_SYSTEM_COMPONENT), BURN_COMMANDLINE_SWITCH_SYSTEM_COMPONENT, lstrlenW(BURN_COMMANDLINE_SWITCH_SYSTEM_COMPONENT), TRUE)) |
| 1583 | { | 1586 | { |
| 1584 | // Get a pointer to the next character after the switch. | 1587 | // Get a pointer to the next character after the switch. |
| 1585 | LPCWSTR wzParam = &argv[i][1 + lstrlenW(BURN_COMMANDLINE_SWITCH_SYSTEM_COMPONENT)]; | 1588 | LPCWSTR wzParam = &argv[i][1 + lstrlenW(BURN_COMMANDLINE_SWITCH_SYSTEM_COMPONENT)]; |
| @@ -1602,7 +1605,7 @@ extern "C" HRESULT CoreParseCommandLine( | |||
| 1602 | pInternalCommand->fArpSystemComponent = TRUE; | 1605 | pInternalCommand->fArpSystemComponent = TRUE; |
| 1603 | } | 1606 | } |
| 1604 | } | 1607 | } |
| 1605 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_EMBEDDED, -1)) | 1608 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, BURN_COMMANDLINE_SWITCH_EMBEDDED, -1, TRUE)) |
| 1606 | { | 1609 | { |
| 1607 | if (i + 3 >= argc) | 1610 | if (i + 3 >= argc) |
| 1608 | { | 1611 | { |
| @@ -1633,59 +1636,59 @@ extern "C" HRESULT CoreParseCommandLine( | |||
| 1633 | 1636 | ||
| 1634 | i += 2; | 1637 | i += 2; |
| 1635 | } | 1638 | } |
| 1636 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RELATED_DETECT, -1)) | 1639 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RELATED_DETECT, -1, TRUE)) |
| 1637 | { | 1640 | { |
| 1638 | pCommand->relationType = BOOTSTRAPPER_RELATION_DETECT; | 1641 | pCommand->relationType = BOOTSTRAPPER_RELATION_DETECT; |
| 1639 | 1642 | ||
| 1640 | LogId(REPORT_STANDARD, MSG_BURN_RUN_BY_RELATED_BUNDLE, LoggingRelationTypeToString(pCommand->relationType)); | 1643 | LogId(REPORT_STANDARD, MSG_BURN_RUN_BY_RELATED_BUNDLE, LoggingRelationTypeToString(pCommand->relationType)); |
| 1641 | } | 1644 | } |
| 1642 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RELATED_UPGRADE, -1)) | 1645 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RELATED_UPGRADE, -1, TRUE)) |
| 1643 | { | 1646 | { |
| 1644 | pCommand->relationType = BOOTSTRAPPER_RELATION_UPGRADE; | 1647 | pCommand->relationType = BOOTSTRAPPER_RELATION_UPGRADE; |
| 1645 | 1648 | ||
| 1646 | LogId(REPORT_STANDARD, MSG_BURN_RUN_BY_RELATED_BUNDLE, LoggingRelationTypeToString(pCommand->relationType)); | 1649 | LogId(REPORT_STANDARD, MSG_BURN_RUN_BY_RELATED_BUNDLE, LoggingRelationTypeToString(pCommand->relationType)); |
| 1647 | } | 1650 | } |
| 1648 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RELATED_ADDON, -1)) | 1651 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RELATED_ADDON, -1, TRUE)) |
| 1649 | { | 1652 | { |
| 1650 | pCommand->relationType = BOOTSTRAPPER_RELATION_ADDON; | 1653 | pCommand->relationType = BOOTSTRAPPER_RELATION_ADDON; |
| 1651 | 1654 | ||
| 1652 | LogId(REPORT_STANDARD, MSG_BURN_RUN_BY_RELATED_BUNDLE, LoggingRelationTypeToString(pCommand->relationType)); | 1655 | LogId(REPORT_STANDARD, MSG_BURN_RUN_BY_RELATED_BUNDLE, LoggingRelationTypeToString(pCommand->relationType)); |
| 1653 | } | 1656 | } |
| 1654 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RELATED_DEPENDENT_ADDON, -1)) | 1657 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RELATED_DEPENDENT_ADDON, -1, TRUE)) |
| 1655 | { | 1658 | { |
| 1656 | pCommand->relationType = BOOTSTRAPPER_RELATION_DEPENDENT_ADDON; | 1659 | pCommand->relationType = BOOTSTRAPPER_RELATION_DEPENDENT_ADDON; |
| 1657 | 1660 | ||
| 1658 | LogId(REPORT_STANDARD, MSG_BURN_RUN_BY_RELATED_BUNDLE, LoggingRelationTypeToString(pCommand->relationType)); | 1661 | LogId(REPORT_STANDARD, MSG_BURN_RUN_BY_RELATED_BUNDLE, LoggingRelationTypeToString(pCommand->relationType)); |
| 1659 | } | 1662 | } |
| 1660 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RELATED_PATCH, -1)) | 1663 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RELATED_PATCH, -1, TRUE)) |
| 1661 | { | 1664 | { |
| 1662 | pCommand->relationType = BOOTSTRAPPER_RELATION_PATCH; | 1665 | pCommand->relationType = BOOTSTRAPPER_RELATION_PATCH; |
| 1663 | 1666 | ||
| 1664 | LogId(REPORT_STANDARD, MSG_BURN_RUN_BY_RELATED_BUNDLE, LoggingRelationTypeToString(pCommand->relationType)); | 1667 | LogId(REPORT_STANDARD, MSG_BURN_RUN_BY_RELATED_BUNDLE, LoggingRelationTypeToString(pCommand->relationType)); |
| 1665 | } | 1668 | } |
| 1666 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RELATED_DEPENDENT_PATCH, -1)) | 1669 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RELATED_DEPENDENT_PATCH, -1, TRUE)) |
| 1667 | { | 1670 | { |
| 1668 | pCommand->relationType = BOOTSTRAPPER_RELATION_DEPENDENT_PATCH; | 1671 | pCommand->relationType = BOOTSTRAPPER_RELATION_DEPENDENT_PATCH; |
| 1669 | 1672 | ||
| 1670 | LogId(REPORT_STANDARD, MSG_BURN_RUN_BY_RELATED_BUNDLE, LoggingRelationTypeToString(pCommand->relationType)); | 1673 | LogId(REPORT_STANDARD, MSG_BURN_RUN_BY_RELATED_BUNDLE, LoggingRelationTypeToString(pCommand->relationType)); |
| 1671 | } | 1674 | } |
| 1672 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RELATED_UPDATE, -1)) | 1675 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RELATED_UPDATE, -1, TRUE)) |
| 1673 | { | 1676 | { |
| 1674 | pCommand->relationType = BOOTSTRAPPER_RELATION_UPDATE; | 1677 | pCommand->relationType = BOOTSTRAPPER_RELATION_UPDATE; |
| 1675 | 1678 | ||
| 1676 | LogId(REPORT_STANDARD, MSG_BURN_RUN_BY_RELATED_BUNDLE, LoggingRelationTypeToString(pCommand->relationType)); | 1679 | LogId(REPORT_STANDARD, MSG_BURN_RUN_BY_RELATED_BUNDLE, LoggingRelationTypeToString(pCommand->relationType)); |
| 1677 | } | 1680 | } |
| 1678 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RELATED_CHAIN_PACKAGE, -1)) | 1681 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RELATED_CHAIN_PACKAGE, -1, TRUE)) |
| 1679 | { | 1682 | { |
| 1680 | pCommand->relationType = BOOTSTRAPPER_RELATION_CHAIN_PACKAGE; | 1683 | pCommand->relationType = BOOTSTRAPPER_RELATION_CHAIN_PACKAGE; |
| 1681 | 1684 | ||
| 1682 | LogId(REPORT_STANDARD, MSG_BURN_RUN_BY_RELATED_BUNDLE, LoggingRelationTypeToString(pCommand->relationType)); | 1685 | LogId(REPORT_STANDARD, MSG_BURN_RUN_BY_RELATED_BUNDLE, LoggingRelationTypeToString(pCommand->relationType)); |
| 1683 | } | 1686 | } |
| 1684 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_PASSTHROUGH, -1)) | 1687 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, BURN_COMMANDLINE_SWITCH_PASSTHROUGH, -1, TRUE)) |
| 1685 | { | 1688 | { |
| 1686 | pCommand->fPassthrough = TRUE; | 1689 | pCommand->fPassthrough = TRUE; |
| 1687 | } | 1690 | } |
| 1688 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RUNONCE, -1)) | 1691 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RUNONCE, -1, TRUE)) |
| 1689 | { | 1692 | { |
| 1690 | switch (pInternalCommand->mode) | 1693 | switch (pInternalCommand->mode) |
| 1691 | { | 1694 | { |
| @@ -1698,7 +1701,7 @@ extern "C" HRESULT CoreParseCommandLine( | |||
| 1698 | TraceLog(E_INVALIDARG, "Multiple mode command-line switches were provided."); | 1701 | TraceLog(E_INVALIDARG, "Multiple mode command-line switches were provided."); |
| 1699 | } | 1702 | } |
| 1700 | } | 1703 | } |
| 1701 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES), BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES, lstrlenW(BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES))) | 1704 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES), BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES, lstrlenW(BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES), TRUE)) |
| 1702 | { | 1705 | { |
| 1703 | // Get a pointer to the next character after the switch. | 1706 | // Get a pointer to the next character after the switch. |
| 1704 | LPCWSTR wzParam = &argv[i][1 + lstrlenW(BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES)]; | 1707 | LPCWSTR wzParam = &argv[i][1 + lstrlenW(BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES)]; |
| @@ -1713,7 +1716,7 @@ extern "C" HRESULT CoreParseCommandLine( | |||
| 1713 | ExitOnFailure(hr, "Failed to allocate the list of dependencies to ignore."); | 1716 | ExitOnFailure(hr, "Failed to allocate the list of dependencies to ignore."); |
| 1714 | } | 1717 | } |
| 1715 | } | 1718 | } |
| 1716 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_ANCESTORS), BURN_COMMANDLINE_SWITCH_ANCESTORS, lstrlenW(BURN_COMMANDLINE_SWITCH_ANCESTORS))) | 1719 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_ANCESTORS), BURN_COMMANDLINE_SWITCH_ANCESTORS, lstrlenW(BURN_COMMANDLINE_SWITCH_ANCESTORS), TRUE)) |
| 1717 | { | 1720 | { |
| 1718 | // Get a pointer to the next character after the switch. | 1721 | // Get a pointer to the next character after the switch. |
| 1719 | LPCWSTR wzParam = &argv[i][1 + lstrlenW(BURN_COMMANDLINE_SWITCH_ANCESTORS)]; | 1722 | LPCWSTR wzParam = &argv[i][1 + lstrlenW(BURN_COMMANDLINE_SWITCH_ANCESTORS)]; |
| @@ -1728,7 +1731,7 @@ extern "C" HRESULT CoreParseCommandLine( | |||
| 1728 | ExitOnFailure(hr, "Failed to allocate the list of ancestors."); | 1731 | ExitOnFailure(hr, "Failed to allocate the list of ancestors."); |
| 1729 | } | 1732 | } |
| 1730 | } | 1733 | } |
| 1731 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_WORKING_DIRECTORY), BURN_COMMANDLINE_SWITCH_WORKING_DIRECTORY, lstrlenW(BURN_COMMANDLINE_SWITCH_WORKING_DIRECTORY))) | 1734 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_WORKING_DIRECTORY), BURN_COMMANDLINE_SWITCH_WORKING_DIRECTORY, lstrlenW(BURN_COMMANDLINE_SWITCH_WORKING_DIRECTORY), TRUE)) |
| 1732 | { | 1735 | { |
| 1733 | // Get a pointer to the next character after the switch. | 1736 | // Get a pointer to the next character after the switch. |
| 1734 | LPCWSTR wzParam = &argv[i][1 + lstrlenW(BURN_COMMANDLINE_SWITCH_WORKING_DIRECTORY)]; | 1737 | LPCWSTR wzParam = &argv[i][1 + lstrlenW(BURN_COMMANDLINE_SWITCH_WORKING_DIRECTORY)]; |
| @@ -1743,7 +1746,7 @@ extern "C" HRESULT CoreParseCommandLine( | |||
| 1743 | ExitOnFailure(hr, "Failed to store the custom working directory."); | 1746 | ExitOnFailure(hr, "Failed to store the custom working directory."); |
| 1744 | } | 1747 | } |
| 1745 | } | 1748 | } |
| 1746 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED), BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED, lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED))) | 1749 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED), BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED, lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED), TRUE)) |
| 1747 | { | 1750 | { |
| 1748 | LPCWSTR wzParam = &argv[i][2 + lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED)]; | 1751 | LPCWSTR wzParam = &argv[i][2 + lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED)]; |
| 1749 | if (L'=' != wzParam[-1] || L'\0' == wzParam[0]) | 1752 | if (L'=' != wzParam[-1] || L'\0' == wzParam[0]) |
| @@ -1765,7 +1768,7 @@ extern "C" HRESULT CoreParseCommandLine( | |||
| 1765 | } | 1768 | } |
| 1766 | } | 1769 | } |
| 1767 | } | 1770 | } |
| 1768 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF), BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF, lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF))) | 1771 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF), BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF, lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF), TRUE)) |
| 1769 | { | 1772 | { |
| 1770 | LPCWSTR wzParam = &argv[i][2 + lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF)]; | 1773 | LPCWSTR wzParam = &argv[i][2 + lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF)]; |
| 1771 | if (L'=' != wzParam[-1] || L'\0' == wzParam[0]) | 1774 | if (L'=' != wzParam[-1] || L'\0' == wzParam[0]) |
| @@ -1787,7 +1790,7 @@ extern "C" HRESULT CoreParseCommandLine( | |||
| 1787 | } | 1790 | } |
| 1788 | } | 1791 | } |
| 1789 | } | 1792 | } |
| 1790 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_SPLASH_SCREEN), BURN_COMMANDLINE_SWITCH_SPLASH_SCREEN, lstrlenW(BURN_COMMANDLINE_SWITCH_SPLASH_SCREEN))) | 1793 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_SPLASH_SCREEN), BURN_COMMANDLINE_SWITCH_SPLASH_SCREEN, lstrlenW(BURN_COMMANDLINE_SWITCH_SPLASH_SCREEN), TRUE)) |
| 1791 | { | 1794 | { |
| 1792 | LPCWSTR wzParam = &argv[i][2 + lstrlenW(BURN_COMMANDLINE_SWITCH_SPLASH_SCREEN)]; | 1795 | LPCWSTR wzParam = &argv[i][2 + lstrlenW(BURN_COMMANDLINE_SWITCH_SPLASH_SCREEN)]; |
| 1793 | if (L'=' != wzParam[-1] || L'\0' == wzParam[0]) | 1796 | if (L'=' != wzParam[-1] || L'\0' == wzParam[0]) |
| @@ -1809,7 +1812,7 @@ extern "C" HRESULT CoreParseCommandLine( | |||
| 1809 | } | 1812 | } |
| 1810 | } | 1813 | } |
| 1811 | } | 1814 | } |
| 1812 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_PREFIX), BURN_COMMANDLINE_SWITCH_PREFIX, lstrlenW(BURN_COMMANDLINE_SWITCH_PREFIX))) | 1815 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_PREFIX), BURN_COMMANDLINE_SWITCH_PREFIX, lstrlenW(BURN_COMMANDLINE_SWITCH_PREFIX), TRUE)) |
| 1813 | { | 1816 | { |
| 1814 | // Skip (but log) any other private burn switches we don't recognize, so that | 1817 | // Skip (but log) any other private burn switches we don't recognize, so that |
| 1815 | // adding future private variables doesn't break old bundles | 1818 | // adding future private variables doesn't break old bundles |
diff --git a/src/burn/engine/core.h b/src/burn/engine/core.h index c5d0a370..cf615e35 100644 --- a/src/burn/engine/core.h +++ b/src/burn/engine/core.h | |||
| @@ -46,6 +46,8 @@ const LPCWSTR BURN_BUNDLE_FORCED_RESTART_PACKAGE = L"WixBundleForcedRestartPacka | |||
| 46 | const LPCWSTR BURN_BUNDLE_INSTALLED = L"WixBundleInstalled"; | 46 | const LPCWSTR BURN_BUNDLE_INSTALLED = L"WixBundleInstalled"; |
| 47 | const LPCWSTR BURN_BUNDLE_ELEVATED = L"WixBundleElevated"; | 47 | const LPCWSTR BURN_BUNDLE_ELEVATED = L"WixBundleElevated"; |
| 48 | const LPCWSTR BURN_BUNDLE_PROVIDER_KEY = L"WixBundleProviderKey"; | 48 | const LPCWSTR BURN_BUNDLE_PROVIDER_KEY = L"WixBundleProviderKey"; |
| 49 | const LPCWSTR BURN_BUNDLE_SOURCE_PROCESS_PATH = L"WixBundleSourceProcessPath"; | ||
| 50 | const LPCWSTR BURN_BUNDLE_SOURCE_PROCESS_FOLDER = L"WixBundleSourceProcessFolder"; | ||
| 49 | const LPCWSTR BURN_BUNDLE_TAG = L"WixBundleTag"; | 51 | const LPCWSTR BURN_BUNDLE_TAG = L"WixBundleTag"; |
| 50 | const LPCWSTR BURN_BUNDLE_UILEVEL = L"WixBundleUILevel"; | 52 | const LPCWSTR BURN_BUNDLE_UILEVEL = L"WixBundleUILevel"; |
| 51 | const LPCWSTR BURN_BUNDLE_VERSION = L"WixBundleVersion"; | 53 | const LPCWSTR BURN_BUNDLE_VERSION = L"WixBundleVersion"; |
diff --git a/src/burn/engine/dependency.cpp b/src/burn/engine/dependency.cpp index f398a070..94a8a1e4 100644 --- a/src/burn/engine/dependency.cpp +++ b/src/burn/engine/dependency.cpp | |||
| @@ -263,7 +263,7 @@ extern "C" HRESULT DependencyDetectProviderKeyBundleCode( | |||
| 263 | hr = StrAllocString(&pRegistration->sczDetectedProviderKeyBundleCode, pRegistration->sczProviderKey, 0); | 263 | hr = StrAllocString(&pRegistration->sczDetectedProviderKeyBundleCode, pRegistration->sczProviderKey, 0); |
| 264 | ExitOnFailure(hr, "Failed to initialize provider key bundle code."); | 264 | ExitOnFailure(hr, "Failed to initialize provider key bundle code."); |
| 265 | } | 265 | } |
| 266 | else if (CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pRegistration->sczCode, -1, pRegistration->sczDetectedProviderKeyBundleCode, -1)) | 266 | else if (CSTR_EQUAL != ::CompareStringOrdinal(pRegistration->sczCode, -1, pRegistration->sczDetectedProviderKeyBundleCode, -1, TRUE)) |
| 267 | { | 267 | { |
| 268 | pRegistration->fDetectedForeignProviderKeyBundleCode = TRUE; | 268 | pRegistration->fDetectedForeignProviderKeyBundleCode = TRUE; |
| 269 | LogId(REPORT_STANDARD, MSG_DETECTED_FOREIGN_BUNDLE_PROVIDER_REGISTRATION, pRegistration->sczProviderKey, pRegistration->sczDetectedProviderKeyBundleCode); | 269 | LogId(REPORT_STANDARD, MSG_DETECTED_FOREIGN_BUNDLE_PROVIDER_REGISTRATION, pRegistration->sczProviderKey, pRegistration->sczDetectedProviderKeyBundleCode); |
| @@ -293,12 +293,12 @@ extern "C" HRESULT DependencyDetectBundle( | |||
| 293 | { | 293 | { |
| 294 | DEPENDENCY* pDependent = pRegistration->rgDependents + i; | 294 | DEPENDENCY* pDependent = pRegistration->rgDependents + i; |
| 295 | 295 | ||
| 296 | if (pDependencies->fActiveParent && CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pDependencies->wzActiveParent, -1, pDependent->sczKey, -1)) | 296 | if (pDependencies->fActiveParent && CSTR_EQUAL == ::CompareStringOrdinal(pDependencies->wzActiveParent, -1, pDependent->sczKey, -1, TRUE)) |
| 297 | { | 297 | { |
| 298 | pRegistration->fParentRegisteredAsDependent = TRUE; | 298 | pRegistration->fParentRegisteredAsDependent = TRUE; |
| 299 | } | 299 | } |
| 300 | 300 | ||
| 301 | if (pDependencies->fSelfDependent && CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pDependencies->wzSelfDependent, -1, pDependent->sczKey, -1)) | 301 | if (pDependencies->fSelfDependent && CSTR_EQUAL == ::CompareStringOrdinal(pDependencies->wzSelfDependent, -1, pDependent->sczKey, -1, TRUE)) |
| 302 | { | 302 | { |
| 303 | pRegistration->fSelfRegisteredAsDependent = TRUE; | 303 | pRegistration->fSelfRegisteredAsDependent = TRUE; |
| 304 | } | 304 | } |
| @@ -419,6 +419,7 @@ extern "C" HRESULT DependencyPlanPackageBegin( | |||
| 419 | STRINGDICT_HANDLE sdIgnoredDependents = NULL; | 419 | STRINGDICT_HANDLE sdIgnoredDependents = NULL; |
| 420 | BURN_DEPENDENCY_ACTION dependencyExecuteAction = BURN_DEPENDENCY_ACTION_NONE; | 420 | BURN_DEPENDENCY_ACTION dependencyExecuteAction = BURN_DEPENDENCY_ACTION_NONE; |
| 421 | BURN_DEPENDENCY_ACTION dependencyRollbackAction = BURN_DEPENDENCY_ACTION_NONE; | 421 | BURN_DEPENDENCY_ACTION dependencyRollbackAction = BURN_DEPENDENCY_ACTION_NONE; |
| 422 | BOOL fDependenciesForcedAbsent = FALSE; | ||
| 422 | BOOL fDependentBlocksUninstall = FALSE; | 423 | BOOL fDependentBlocksUninstall = FALSE; |
| 423 | BOOL fAttemptingUninstall = BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pPackage->execute || pPackage->compatiblePackage.fRemove; | 424 | BOOL fAttemptingUninstall = BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pPackage->execute || pPackage->compatiblePackage.fRemove; |
| 424 | 425 | ||
| @@ -467,7 +468,16 @@ extern "C" HRESULT DependencyPlanPackageBegin( | |||
| 467 | { | 468 | { |
| 468 | hr = S_OK; | 469 | hr = S_OK; |
| 469 | 470 | ||
| 470 | if (!fDependentBlocksUninstall) | 471 | if (BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT == pPackage->requested) |
| 472 | { | ||
| 473 | if (!fDependenciesForcedAbsent) | ||
| 474 | { | ||
| 475 | fDependenciesForcedAbsent = TRUE; | ||
| 476 | |||
| 477 | LogId(REPORT_STANDARD, MSG_DEPENDENCY_PACKAGE_DEPENDENTS_OVERRIDDEN, pPackage->sczId); | ||
| 478 | } | ||
| 479 | } | ||
| 480 | else if (!fDependentBlocksUninstall) | ||
| 471 | { | 481 | { |
| 472 | fDependentBlocksUninstall = TRUE; | 482 | fDependentBlocksUninstall = TRUE; |
| 473 | 483 | ||
| @@ -591,8 +601,8 @@ extern "C" HRESULT DependencyPlanPackageBegin( | |||
| 591 | pProvider->dependentExecute = BURN_DEPENDENCY_ACTION_NONE; | 601 | pProvider->dependentExecute = BURN_DEPENDENCY_ACTION_NONE; |
| 592 | } | 602 | } |
| 593 | 603 | ||
| 594 | if (BURN_DEPENDENCY_ACTION_UNREGISTER == pProvider->dependentRollback && pProvider->fBundleRegisteredAsDependent || | 604 | if ((BURN_DEPENDENCY_ACTION_UNREGISTER == pProvider->dependentRollback && pProvider->fBundleRegisteredAsDependent) || |
| 595 | BURN_DEPENDENCY_ACTION_REGISTER == pProvider->dependentRollback && !pProvider->fBundleRegisteredAsDependent) | 605 | (BURN_DEPENDENCY_ACTION_REGISTER == pProvider->dependentRollback && !pProvider->fBundleRegisteredAsDependent)) |
| 596 | { | 606 | { |
| 597 | pProvider->dependentRollback = BURN_DEPENDENCY_ACTION_NONE; | 607 | pProvider->dependentRollback = BURN_DEPENDENCY_ACTION_NONE; |
| 598 | } | 608 | } |
| @@ -905,7 +915,7 @@ extern "C" HRESULT DependencyDetectCompatibleEntry( | |||
| 905 | continue; | 915 | continue; |
| 906 | } | 916 | } |
| 907 | } | 917 | } |
| 908 | else if (sczId && CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, wzPackageProviderId, -1, sczId, -1)) | 918 | else if (sczId && CSTR_EQUAL == ::CompareStringOrdinal(wzPackageProviderId, -1, sczId, -1, TRUE)) |
| 909 | { | 919 | { |
| 910 | continue; | 920 | continue; |
| 911 | } | 921 | } |
| @@ -969,7 +979,7 @@ static HRESULT DetectPackageDependents( | |||
| 969 | { | 979 | { |
| 970 | DEPENDENCY* pDependent = pProvider->rgDependents + iDependent; | 980 | DEPENDENCY* pDependent = pProvider->rgDependents + iDependent; |
| 971 | 981 | ||
| 972 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pRegistration->sczCode, -1, pDependent->sczKey, -1)) | 982 | if (CSTR_EQUAL == ::CompareStringOrdinal(pRegistration->sczCode, -1, pDependent->sczKey, -1, TRUE)) |
| 973 | { | 983 | { |
| 974 | pProvider->fBundleRegisteredAsDependent = TRUE; | 984 | pProvider->fBundleRegisteredAsDependent = TRUE; |
| 975 | fBundleRegisteredAsDependent = TRUE; | 985 | fBundleRegisteredAsDependent = TRUE; |
| @@ -1043,7 +1053,7 @@ static HRESULT SplitIgnoreDependencies( | |||
| 1043 | hr = DictAddKey(sdIgnoreDependencies, wzToken); | 1053 | hr = DictAddKey(sdIgnoreDependencies, wzToken); |
| 1044 | ExitOnFailure(hr, "Failed to add \"%ls\" to the string dictionary.", wzToken); | 1054 | ExitOnFailure(hr, "Failed to add \"%ls\" to the string dictionary.", wzToken); |
| 1045 | 1055 | ||
| 1046 | if (!*pfIgnoreAll && CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, L"ALL", -1, wzToken, -1)) | 1056 | if (!*pfIgnoreAll && CSTR_EQUAL == ::CompareStringOrdinal(L"ALL", -1, wzToken, -1, TRUE)) |
| 1047 | { | 1057 | { |
| 1048 | *pfIgnoreAll = TRUE; | 1058 | *pfIgnoreAll = TRUE; |
| 1049 | } | 1059 | } |
diff --git a/src/burn/engine/detect.cpp b/src/burn/engine/detect.cpp index 08f6b57c..c19d382c 100644 --- a/src/burn/engine/detect.cpp +++ b/src/burn/engine/detect.cpp | |||
| @@ -130,7 +130,7 @@ extern "C" HRESULT DetectForwardCompatibleBundles( | |||
| 130 | BURN_RELATED_BUNDLE* pRelatedBundle = pRegistration->relatedBundles.rgRelatedBundles + iRelatedBundle; | 130 | BURN_RELATED_BUNDLE* pRelatedBundle = pRegistration->relatedBundles.rgRelatedBundles + iRelatedBundle; |
| 131 | 131 | ||
| 132 | if (BOOTSTRAPPER_RELATION_UPGRADE == pRelatedBundle->detectRelationType && | 132 | if (BOOTSTRAPPER_RELATION_UPGRADE == pRelatedBundle->detectRelationType && |
| 133 | CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pRegistration->sczDetectedProviderKeyBundleCode, -1, pRelatedBundle->package.sczId, -1)) | 133 | CSTR_EQUAL == ::CompareStringOrdinal(pRegistration->sczDetectedProviderKeyBundleCode, -1, pRelatedBundle->package.sczId, -1, TRUE)) |
| 134 | { | 134 | { |
| 135 | hr = VerCompareParsedVersions(pRegistration->pVersion, pRelatedBundle->pVersion, &nCompareResult); | 135 | hr = VerCompareParsedVersions(pRegistration->pVersion, pRelatedBundle->pVersion, &nCompareResult); |
| 136 | ExitOnFailure(hr, "Failed to compare bundle version '%ls' to related bundle version '%ls'", pRegistration->pVersion->sczVersion, pRelatedBundle->pVersion->sczVersion); | 136 | ExitOnFailure(hr, "Failed to compare bundle version '%ls' to related bundle version '%ls'", pRegistration->pVersion->sczVersion, pRelatedBundle->pVersion->sczVersion); |
diff --git a/src/burn/engine/elevation.cpp b/src/burn/engine/elevation.cpp index 90e9db01..ef87841f 100644 --- a/src/burn/engine/elevation.cpp +++ b/src/burn/engine/elevation.cpp | |||
| @@ -1452,9 +1452,9 @@ extern "C" HRESULT ElevationExecutePackageDependencyAction( | |||
| 1452 | ExitOnFailure(hr, "Failed to write bundle dependency key to message buffer."); | 1452 | ExitOnFailure(hr, "Failed to write bundle dependency key to message buffer."); |
| 1453 | 1453 | ||
| 1454 | // Dependent actions. | 1454 | // Dependent actions. |
| 1455 | for (DWORD i = 0; i < pExecuteAction->packageProvider.pPackage->cDependencyProviders; ++i) | 1455 | for (DWORD i = 0; i < pExecuteAction->packageDependency.pPackage->cDependencyProviders; ++i) |
| 1456 | { | 1456 | { |
| 1457 | BURN_DEPENDENCY_PROVIDER* pProvider = pExecuteAction->packageProvider.pPackage->rgDependencyProviders + i; | 1457 | BURN_DEPENDENCY_PROVIDER* pProvider = pExecuteAction->packageDependency.pPackage->rgDependencyProviders + i; |
| 1458 | BURN_DEPENDENCY_ACTION* pAction = fRollback ? &pProvider->dependentRollback : &pProvider->dependentExecute; | 1458 | BURN_DEPENDENCY_ACTION* pAction = fRollback ? &pProvider->dependentRollback : &pProvider->dependentExecute; |
| 1459 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)*pAction); | 1459 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)*pAction); |
| 1460 | ExitOnFailure(hr, "Failed to write dependent action to message buffer."); | 1460 | ExitOnFailure(hr, "Failed to write dependent action to message buffer."); |
| @@ -2824,7 +2824,7 @@ LExit: | |||
| 2824 | // TODO: do the right thing here. | 2824 | // TODO: do the right thing here. |
| 2825 | //DependencyUninitializeRegistrationAction(&action); | 2825 | //DependencyUninitializeRegistrationAction(&action); |
| 2826 | ReleaseStr(action.sczDependentProviderKey); | 2826 | ReleaseStr(action.sczDependentProviderKey); |
| 2827 | ReleaseStr(action.sczBundleCode) | 2827 | ReleaseStr(action.sczBundleCode); |
| 2828 | 2828 | ||
| 2829 | return hr; | 2829 | return hr; |
| 2830 | } | 2830 | } |
| @@ -3380,7 +3380,7 @@ static HRESULT OnUninstallMsiCompatiblePackage( | |||
| 3380 | } | 3380 | } |
| 3381 | 3381 | ||
| 3382 | if (!sczCompatiblePackageId || !*sczCompatiblePackageId || | 3382 | if (!sczCompatiblePackageId || !*sczCompatiblePackageId || |
| 3383 | CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pCompatiblePackage->compatibleEntry.sczId, -1, sczCompatiblePackageId, -1)) | 3383 | CSTR_EQUAL != ::CompareStringOrdinal(pCompatiblePackage->compatibleEntry.sczId, -1, sczCompatiblePackageId, -1, TRUE)) |
| 3384 | { | 3384 | { |
| 3385 | ExitWithRootFailure(hr, E_INVALIDARG, "Package '%ls' has no compatible package with id: %ls", sczPackageId, sczCompatiblePackageId); | 3385 | ExitWithRootFailure(hr, E_INVALIDARG, "Package '%ls' has no compatible package with id: %ls", sczPackageId, sczCompatiblePackageId); |
| 3386 | } | 3386 | } |
| @@ -3486,9 +3486,9 @@ static HRESULT OnExecutePackageDependencyAction( | |||
| 3486 | ExitOnFailure(hr, "Failed to read bundle dependency key from message buffer."); | 3486 | ExitOnFailure(hr, "Failed to read bundle dependency key from message buffer."); |
| 3487 | 3487 | ||
| 3488 | // Read dependent actions. | 3488 | // Read dependent actions. |
| 3489 | for (DWORD i = 0; i < executeAction.packageProvider.pPackage->cDependencyProviders; ++i) | 3489 | for (DWORD i = 0; i < executeAction.packageDependency.pPackage->cDependencyProviders; ++i) |
| 3490 | { | 3490 | { |
| 3491 | BURN_DEPENDENCY_PROVIDER* pProvider = executeAction.packageProvider.pPackage->rgDependencyProviders + i; | 3491 | BURN_DEPENDENCY_PROVIDER* pProvider = executeAction.packageDependency.pPackage->rgDependencyProviders + i; |
| 3492 | BURN_DEPENDENCY_ACTION* pAction = fRollback ? &pProvider->dependentRollback : &pProvider->dependentExecute; | 3492 | BURN_DEPENDENCY_ACTION* pAction = fRollback ? &pProvider->dependentRollback : &pProvider->dependentExecute; |
| 3493 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)pAction); | 3493 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)pAction); |
| 3494 | ExitOnFailure(hr, "Failed to read dependent action."); | 3494 | ExitOnFailure(hr, "Failed to read dependent action."); |
| @@ -3792,7 +3792,7 @@ static HRESULT OnCleanCompatiblePackage( | |||
| 3792 | } | 3792 | } |
| 3793 | 3793 | ||
| 3794 | if (!sczCompatiblePackageId || !*sczCompatiblePackageId || | 3794 | if (!sczCompatiblePackageId || !*sczCompatiblePackageId || |
| 3795 | CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pCompatiblePackage->compatibleEntry.sczId, -1, sczCompatiblePackageId, -1)) | 3795 | CSTR_EQUAL != ::CompareStringOrdinal(pCompatiblePackage->compatibleEntry.sczId, -1, sczCompatiblePackageId, -1, TRUE)) |
| 3796 | { | 3796 | { |
| 3797 | ExitWithRootFailure(hr, E_INVALIDARG, "Package '%ls' has no compatible package with id: %ls", sczPackageId, sczCompatiblePackageId); | 3797 | ExitWithRootFailure(hr, E_INVALIDARG, "Package '%ls' has no compatible package with id: %ls", sczPackageId, sczCompatiblePackageId); |
| 3798 | } | 3798 | } |
| @@ -3876,7 +3876,7 @@ static HRESULT OnLaunchApprovedExe( | |||
| 3876 | hr = RegReadString(hKey, pApprovedExe->sczValueName, &pLaunchApprovedExe->sczExecutablePath); | 3876 | hr = RegReadString(hKey, pApprovedExe->sczValueName, &pLaunchApprovedExe->sczExecutablePath); |
| 3877 | ExitOnFailure(hr, "Failed to read the value for the approved exe path."); | 3877 | ExitOnFailure(hr, "Failed to read the value for the approved exe path."); |
| 3878 | 3878 | ||
| 3879 | hr = ApprovedExesVerifySecureLocation(pCache, pVariables, pLaunchApprovedExe->sczExecutablePath); | 3879 | hr = ApprovedExesVerifySecureLocation(pCache, pVariables, pLaunchApprovedExe->sczExecutablePath, 0, NULL); |
| 3880 | ExitOnFailure(hr, "Failed to verify the executable path is in a secure location: %ls", pLaunchApprovedExe->sczExecutablePath); | 3880 | ExitOnFailure(hr, "Failed to verify the executable path is in a secure location: %ls", pLaunchApprovedExe->sczExecutablePath); |
| 3881 | if (S_FALSE == hr) | 3881 | if (S_FALSE == hr) |
| 3882 | { | 3882 | { |
diff --git a/src/burn/engine/engine.cpp b/src/burn/engine/engine.cpp index c372772c..d432f732 100644 --- a/src/burn/engine/engine.cpp +++ b/src/burn/engine/engine.cpp | |||
| @@ -379,7 +379,8 @@ static HRESULT InitializeEngineState( | |||
| 379 | BurnPipeConnectionInitialize(&pEngineState->embeddedConnection); | 379 | BurnPipeConnectionInitialize(&pEngineState->embeddedConnection); |
| 380 | 380 | ||
| 381 | // Retain whether bundle was initially run elevated. | 381 | // Retain whether bundle was initially run elevated. |
| 382 | ProcElevated(::GetCurrentProcess(), &pEngineState->internalCommand.fInitiallyElevated); | 382 | hr = ProcIsHighIntegrity(::GetCurrentProcess(), &pEngineState->internalCommand.fInitiallyElevated); |
| 383 | ExitOnFailure(hr, "Failed to determine if process is running elevated."); | ||
| 383 | 384 | ||
| 384 | // Parse command line. | 385 | // Parse command line. |
| 385 | hr = CoreParseCommandLine(&pEngineState->internalCommand, &pEngineState->command, &pEngineState->companionConnection, &pEngineState->embeddedConnection, &hSectionFile, &hSourceEngineFile); | 386 | hr = CoreParseCommandLine(&pEngineState->internalCommand, &pEngineState->command, &pEngineState->companionConnection, &pEngineState->embeddedConnection, &hSectionFile, &hSourceEngineFile); |
diff --git a/src/burn/engine/engine.mc b/src/burn/engine/engine.mc index c7a07385..776f7832 100644 --- a/src/burn/engine/engine.mc +++ b/src/burn/engine/engine.mc | |||
| @@ -1282,3 +1282,9 @@ Language=English | |||
| 1282 | Skipping MSI property '%1!ls!' because condition '%2!ls!' evaluates to %3!hs!. | 1282 | Skipping MSI property '%1!ls!' because condition '%2!ls!' evaluates to %3!hs!. |
| 1283 | . | 1283 | . |
| 1284 | 1284 | ||
| 1285 | MessageId=701 | ||
| 1286 | Severity=Warning | ||
| 1287 | SymbolicName=MSG_DEPENDENCY_PACKAGE_DEPENDENTS_OVERRIDDEN | ||
| 1288 | Language=English | ||
| 1289 | BA requested to uninstall package: %1!ls!, despite dependents: | ||
| 1290 | . | ||
diff --git a/src/burn/engine/engine.vcxproj b/src/burn/engine/engine.vcxproj index 249f8eef..98556ea6 100644 --- a/src/burn/engine/engine.vcxproj +++ b/src/burn/engine/engine.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|Win32"> | 6 | <ProjectConfiguration Include="Debug|Win32"> |
| 7 | <Configuration>Debug</Configuration> | 7 | <Configuration>Debug</Configuration> |
diff --git a/src/burn/engine/exeengine.cpp b/src/burn/engine/exeengine.cpp index 85168943..c001e563 100644 --- a/src/burn/engine/exeengine.cpp +++ b/src/burn/engine/exeengine.cpp | |||
| @@ -25,15 +25,15 @@ extern "C" HRESULT ExeEngineParsePackageFromXml( | |||
| 25 | hr = XmlGetAttributeEx(pixnExePackage, L"DetectionType", &scz); | 25 | hr = XmlGetAttributeEx(pixnExePackage, L"DetectionType", &scz); |
| 26 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @DetectionType."); | 26 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @DetectionType."); |
| 27 | 27 | ||
| 28 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"condition", -1)) | 28 | if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"condition", -1, FALSE)) |
| 29 | { | 29 | { |
| 30 | pPackage->Exe.detectionType = BURN_EXE_DETECTION_TYPE_CONDITION; | 30 | pPackage->Exe.detectionType = BURN_EXE_DETECTION_TYPE_CONDITION; |
| 31 | } | 31 | } |
| 32 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"arp", -1)) | 32 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"arp", -1, FALSE)) |
| 33 | { | 33 | { |
| 34 | pPackage->Exe.detectionType = BURN_EXE_DETECTION_TYPE_ARP; | 34 | pPackage->Exe.detectionType = BURN_EXE_DETECTION_TYPE_ARP; |
| 35 | } | 35 | } |
| 36 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"none", -1)) | 36 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"none", -1, FALSE)) |
| 37 | { | 37 | { |
| 38 | pPackage->Exe.detectionType = BURN_EXE_DETECTION_TYPE_NONE; | 38 | pPackage->Exe.detectionType = BURN_EXE_DETECTION_TYPE_NONE; |
| 39 | } | 39 | } |
| @@ -114,15 +114,15 @@ extern "C" HRESULT ExeEngineParsePackageFromXml( | |||
| 114 | 114 | ||
| 115 | if (fFoundXml) | 115 | if (fFoundXml) |
| 116 | { | 116 | { |
| 117 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"burn", -1)) | 117 | if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"burn", -1, FALSE)) |
| 118 | { | 118 | { |
| 119 | pPackage->Exe.protocol = BURN_EXE_PROTOCOL_TYPE_BURN; | 119 | pPackage->Exe.protocol = BURN_EXE_PROTOCOL_TYPE_BURN; |
| 120 | } | 120 | } |
| 121 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"netfx4", -1)) | 121 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"netfx4", -1, FALSE)) |
| 122 | { | 122 | { |
| 123 | pPackage->Exe.protocol = BURN_EXE_PROTOCOL_TYPE_NETFX4; | 123 | pPackage->Exe.protocol = BURN_EXE_PROTOCOL_TYPE_NETFX4; |
| 124 | } | 124 | } |
| 125 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"none", -1)) | 125 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"none", -1, FALSE)) |
| 126 | { | 126 | { |
| 127 | pPackage->Exe.protocol = BURN_EXE_PROTOCOL_TYPE_NONE; | 127 | pPackage->Exe.protocol = BURN_EXE_PROTOCOL_TYPE_NONE; |
| 128 | } | 128 | } |
| @@ -449,7 +449,7 @@ extern "C" HRESULT ExeEngineExecutePackage( | |||
| 449 | 449 | ||
| 450 | if (BURN_EXE_DETECTION_TYPE_ARP == pPackage->Exe.detectionType && | 450 | if (BURN_EXE_DETECTION_TYPE_ARP == pPackage->Exe.detectionType && |
| 451 | (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pExecuteAction->exePackage.action || | 451 | (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pExecuteAction->exePackage.action || |
| 452 | BOOTSTRAPPER_ACTION_STATE_INSTALL == pExecuteAction->exePackage.action && fRollback)) | 452 | (BOOTSTRAPPER_ACTION_STATE_INSTALL == pExecuteAction->exePackage.action && fRollback))) |
| 453 | { | 453 | { |
| 454 | hr = DetectArpEntry(pPackage, &applyState, &sczArpUninstallString); | 454 | hr = DetectArpEntry(pPackage, &applyState, &sczArpUninstallString); |
| 455 | ExitOnFailure(hr, "Failed to query ArpEntry for %hs.", BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pExecuteAction->exePackage.action ? "uninstall" : "install"); | 455 | ExitOnFailure(hr, "Failed to query ArpEntry for %hs.", BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pExecuteAction->exePackage.action ? "uninstall" : "install"); |
| @@ -489,29 +489,30 @@ extern "C" HRESULT ExeEngineExecutePackage( | |||
| 489 | } | 489 | } |
| 490 | else if (BURN_EXE_DETECTION_TYPE_ARP == pPackage->Exe.detectionType && BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pExecuteAction->exePackage.action) | 490 | else if (BURN_EXE_DETECTION_TYPE_ARP == pPackage->Exe.detectionType && BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pExecuteAction->exePackage.action) |
| 491 | { | 491 | { |
| 492 | ExitOnNull(sczArpUninstallString, hr, E_INVALIDARG, "%hs is null.", pPackage->Exe.fArpUseUninstallString ? "UninstallString" : "QuietUninstallString"); | 492 | LPCWSTR szRegName = pPackage->Exe.fArpUseUninstallString ? L"UninstallString" : L"QuietUninstallString"; |
| 493 | ExitOnNull(sczArpUninstallString, hr, E_INVALIDARG, "%ls is null.", szRegName); | ||
| 493 | 494 | ||
| 494 | hr = AppParseCommandLine(sczArpUninstallString, &argcArp, &argvArp); | 495 | hr = AppParseCommandLine(sczArpUninstallString, &argcArp, &argvArp); |
| 495 | ExitOnFailure(hr, "Failed to parse QuietUninstallString: %ls.", sczArpUninstallString); | 496 | ExitOnFailure(hr, "Failed to parse %ls: %ls.", szRegName, sczArpUninstallString); |
| 496 | 497 | ||
| 497 | ExitOnNull(argcArp, hr, E_INVALIDARG, "QuietUninstallString must contain an executable path."); | 498 | ExitOnNull(argcArp, hr, E_INVALIDARG, "%ls must contain an executable path.", szRegName); |
| 498 | 499 | ||
| 499 | hr = StrAllocString(&sczExecutablePath, argvArp[0], 0); | 500 | hr = StrAllocString(&sczExecutablePath, argvArp[0], 0); |
| 500 | ExitOnFailure(hr, "Failed to copy executable path."); | 501 | ExitOnFailure(hr, "Failed to copy executable path."); |
| 501 | 502 | ||
| 502 | if (pPackage->fPerMachine) | 503 | if (pPackage->fPerMachine) |
| 503 | { | 504 | { |
| 504 | hr = ApprovedExesVerifySecureLocation(pCache, pVariables, sczExecutablePath); | 505 | hr = ApprovedExesVerifySecureLocation(pCache, pVariables, sczExecutablePath, argcArp - 1, (argcArp > 1) ? const_cast<LPCWSTR*>(argvArp + 1) : NULL); |
| 505 | ExitOnFailure(hr, "Failed to verify the QuietUninstallString executable path is in a secure location: %ls", sczExecutablePath); | 506 | ExitOnFailure(hr, "Failed to verify the %ls executable path is in a secure location: %ls", szRegName, sczExecutablePath); |
| 506 | if (S_FALSE == hr) | 507 | if (S_FALSE == hr) |
| 507 | { | 508 | { |
| 508 | LogStringLine(REPORT_STANDARD, "The QuietUninstallString executable path is not in a secure location: %ls", sczExecutablePath); | 509 | LogStringLine(REPORT_STANDARD, "The %ls executable path is not in a secure location: %ls", szRegName, sczExecutablePath); |
| 509 | ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)); | 510 | ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)); |
| 510 | } | 511 | } |
| 511 | } | 512 | } |
| 512 | 513 | ||
| 513 | hr = PathGetDirectory(sczExecutablePath, &sczCachedDirectory); | 514 | hr = PathGetDirectory(sczExecutablePath, &sczCachedDirectory); |
| 514 | ExitOnFailure(hr, "Failed to get parent directory for QuietUninstallString executable path: %ls", sczExecutablePath); | 515 | ExitOnFailure(hr, "Failed to get parent directory for %ls executable path: %ls", szRegName, sczExecutablePath); |
| 515 | } | 516 | } |
| 516 | else | 517 | else |
| 517 | { | 518 | { |
| @@ -587,13 +588,15 @@ extern "C" HRESULT ExeEngineExecutePackage( | |||
| 587 | } | 588 | } |
| 588 | 589 | ||
| 589 | // build base command | 590 | // build base command |
| 590 | hr = StrAllocFormatted(&sczBaseCommand, L"\"%ls\"", sczExecutablePath); | 591 | if (sczArpUninstallString && *sczArpUninstallString) |
| 591 | ExitOnFailure(hr, "Failed to allocate base command."); | 592 | { |
| 592 | 593 | hr = StrAllocString(&sczBaseCommand, sczArpUninstallString, 0); | |
| 593 | for (int i = 1; i < argcArp; ++i) | 594 | ExitOnFailure(hr, "Failed to allocate base command."); |
| 595 | } | ||
| 596 | else | ||
| 594 | { | 597 | { |
| 595 | hr = AppAppendCommandLineArgument(&sczBaseCommand, argvArp[i]); | 598 | hr = StrAllocFormatted(&sczBaseCommand, L"\"%ls\"", sczExecutablePath); |
| 596 | ExitOnFailure(hr, "Failed to append argument from ARP."); | 599 | ExitOnFailure(hr, "Failed to allocate base command."); |
| 597 | } | 600 | } |
| 598 | 601 | ||
| 599 | if (pPackage->Exe.fBundle) | 602 | if (pPackage->Exe.fBundle) |
diff --git a/src/burn/engine/logging.cpp b/src/burn/engine/logging.cpp index 60c16c01..52123499 100644 --- a/src/burn/engine/logging.cpp +++ b/src/burn/engine/logging.cpp | |||
| @@ -322,15 +322,17 @@ extern "C" HRESULT LoggingSetPackageVariable( | |||
| 322 | ExitFunction(); | 322 | ExitFunction(); |
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | // For burn packages we'll add logging even it it wasn't explictly specified | 325 | // For burn packages we'll add logging even it it wasn't explictly specified. |
| 326 | if (BURN_PACKAGE_TYPE_BUNDLE == pPackage->type || (BURN_PACKAGE_TYPE_EXE == pPackage->type && BURN_EXE_PROTOCOL_TYPE_BURN == pPackage->Exe.protocol)) | 326 | if (BURN_PACKAGE_TYPE_BUNDLE == pPackage->type || (BURN_PACKAGE_TYPE_EXE == pPackage->type && BURN_EXE_PROTOCOL_TYPE_BURN == pPackage->Exe.protocol)) |
| 327 | { | 327 | { |
| 328 | if (!fRollback && (!pPackage->sczLogPathVariable || !*pPackage->sczLogPathVariable)) | 328 | if (!fRollback && (!pPackage->sczLogPathVariable || !*pPackage->sczLogPathVariable)) |
| 329 | { | 329 | { |
| 330 | // Best effort, no need to fail if we can't set the logging path. | ||
| 330 | StrAllocFormatted(&pPackage->sczLogPathVariable, L"WixBundleLog_%ls", pPackage->sczId); | 331 | StrAllocFormatted(&pPackage->sczLogPathVariable, L"WixBundleLog_%ls", pPackage->sczId); |
| 331 | } | 332 | } |
| 332 | else if (fRollback && (!pPackage->sczRollbackLogPathVariable || !*pPackage->sczRollbackLogPathVariable)) | 333 | else if (fRollback && (!pPackage->sczRollbackLogPathVariable || !*pPackage->sczRollbackLogPathVariable)) |
| 333 | { | 334 | { |
| 335 | // Best effort, no need to fail if we can't set the logging path. | ||
| 334 | StrAllocFormatted(&pPackage->sczRollbackLogPathVariable, L"WixBundleRollbackLog_%ls", pPackage->sczId); | 336 | StrAllocFormatted(&pPackage->sczRollbackLogPathVariable, L"WixBundleRollbackLog_%ls", pPackage->sczId); |
| 335 | } | 337 | } |
| 336 | } | 338 | } |
| @@ -1052,7 +1054,8 @@ static HRESULT GetNonSessionSpecificTempFolder( | |||
| 1052 | hr = ::StringCchLengthW(sczSessionId, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cchSessionId)); | 1054 | hr = ::StringCchLengthW(sczSessionId, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cchSessionId)); |
| 1053 | ExitOnFailure(hr, "Failed to get length of session id string."); | 1055 | ExitOnFailure(hr, "Failed to get length of session id string."); |
| 1054 | 1056 | ||
| 1055 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, sczTempFolder + cchTempFolder - cchSessionId, static_cast<DWORD>(cchSessionId), sczSessionId, static_cast<DWORD>(cchSessionId))) | 1057 | if (cchTempFolder >= cchSessionId && |
| 1058 | CSTR_EQUAL == ::CompareStringOrdinal(sczTempFolder + cchTempFolder - cchSessionId, static_cast<DWORD>(cchSessionId), sczSessionId, static_cast<DWORD>(cchSessionId), FALSE)) | ||
| 1056 | { | 1059 | { |
| 1057 | cchTempFolder -= cchSessionId; | 1060 | cchTempFolder -= cchSessionId; |
| 1058 | } | 1061 | } |
diff --git a/src/burn/engine/manifest.cpp b/src/burn/engine/manifest.cpp index 266d1987..b2680387 100644 --- a/src/burn/engine/manifest.cpp +++ b/src/burn/engine/manifest.cpp | |||
| @@ -177,7 +177,7 @@ static void ValidateHarvestingAttributes( | |||
| 177 | hr = XmlGetYesNoAttribute(pixeBundle, L"Win64", &fWin64); | 177 | hr = XmlGetYesNoAttribute(pixeBundle, L"Win64", &fWin64); |
| 178 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get BurnManifest/@Win64 attribute."); | 178 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get BurnManifest/@Win64 attribute."); |
| 179 | 179 | ||
| 180 | Assert(CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, sczEngineVersion, -1, wzVerMajorMinorBuild, -1)); | 180 | Assert(CSTR_EQUAL == ::CompareStringOrdinal(sczEngineVersion, -1, wzVerMajorMinorBuild, -1, FALSE)); |
| 181 | 181 | ||
| 182 | Assert(BURN_PROTOCOL_VERSION == dwProtocolVersion); | 182 | Assert(BURN_PROTOCOL_VERSION == dwProtocolVersion); |
| 183 | 183 | ||
diff --git a/src/burn/engine/msiengine.cpp b/src/burn/engine/msiengine.cpp index d5268b17..a1379054 100644 --- a/src/burn/engine/msiengine.cpp +++ b/src/burn/engine/msiengine.cpp | |||
| @@ -50,7 +50,9 @@ static void RegisterSourceDirectory( | |||
| 50 | __in BURN_PACKAGE* pPackage, | 50 | __in BURN_PACKAGE* pPackage, |
| 51 | __in_z LPCWSTR wzCacheDirectory | 51 | __in_z LPCWSTR wzCacheDirectory |
| 52 | ); | 52 | ); |
| 53 | 53 | static BOOL PackageHasAppliedPatch( | |
| 54 | __in BURN_PACKAGE* pPackage | ||
| 55 | ); | ||
| 54 | 56 | ||
| 55 | // function definitions | 57 | // function definitions |
| 56 | 58 | ||
| @@ -523,7 +525,7 @@ extern "C" HRESULT MsiEngineDetectPackage( | |||
| 523 | ExitOnFailure(hr, "Failed to enum related products."); | 525 | ExitOnFailure(hr, "Failed to enum related products."); |
| 524 | 526 | ||
| 525 | // If we found ourselves, skip because saying that a package is related to itself is nonsensical. | 527 | // If we found ourselves, skip because saying that a package is related to itself is nonsensical. |
| 526 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pPackage->Msi.sczProductCode, -1, wzProductCode, -1)) | 528 | if (CSTR_EQUAL == ::CompareStringOrdinal(pPackage->Msi.sczProductCode, -1, wzProductCode, -1, TRUE)) |
| 527 | { | 529 | { |
| 528 | continue; | 530 | continue; |
| 529 | } | 531 | } |
| @@ -631,7 +633,7 @@ extern "C" HRESULT MsiEngineDetectPackage( | |||
| 631 | } | 633 | } |
| 632 | // It can't be a downgrade if the upgrade codes aren't the same. | 634 | // It can't be a downgrade if the upgrade codes aren't the same. |
| 633 | else if (BOOTSTRAPPER_PACKAGE_STATE_ABSENT == pPackage->currentState && | 635 | else if (BOOTSTRAPPER_PACKAGE_STATE_ABSENT == pPackage->currentState && |
| 634 | pPackage->Msi.sczUpgradeCode && CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pPackage->Msi.sczUpgradeCode, -1, pRelatedMsi->sczUpgradeCode, -1)) | 636 | pPackage->Msi.sczUpgradeCode && CSTR_EQUAL == ::CompareStringOrdinal(pPackage->Msi.sczUpgradeCode, -1, pRelatedMsi->sczUpgradeCode, -1, TRUE)) |
| 635 | { | 637 | { |
| 636 | relatedMsiOperation = BOOTSTRAPPER_RELATED_OPERATION_DOWNGRADE; | 638 | relatedMsiOperation = BOOTSTRAPPER_RELATED_OPERATION_DOWNGRADE; |
| 637 | pPackage->Msi.operation = BOOTSTRAPPER_RELATED_OPERATION_DOWNGRADE; | 639 | pPackage->Msi.operation = BOOTSTRAPPER_RELATED_OPERATION_DOWNGRADE; |
| @@ -904,7 +906,22 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage( | |||
| 904 | else if ((BOOTSTRAPPER_REQUEST_STATE_ABSENT == pPackage->requested || BOOTSTRAPPER_REQUEST_STATE_CACHE == pPackage->requested) && | 906 | else if ((BOOTSTRAPPER_REQUEST_STATE_ABSENT == pPackage->requested || BOOTSTRAPPER_REQUEST_STATE_CACHE == pPackage->requested) && |
| 905 | !pPackage->fPermanent) // removing a package that should be removed. | 907 | !pPackage->fPermanent) // removing a package that should be removed. |
| 906 | { | 908 | { |
| 907 | execute = BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED == pPackage->currentState ? BOOTSTRAPPER_ACTION_STATE_NONE : BOOTSTRAPPER_ACTION_STATE_UNINSTALL; | 909 | if (BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED == pPackage->currentState) |
| 910 | { | ||
| 911 | // If the package is superseded, check to see if there's a patch installed. | ||
| 912 | // A minor upgrade patch could be (usually is) the cause of the | ||
| 913 | // supersedence. In that case, we should ignore the supersedence that would | ||
| 914 | // normally prevent the uninstall. There is a gap in this logic: If a minor | ||
| 915 | // upgrade package were installed without a bundle, then a small update patch | ||
| 916 | // (which by definition doesn't change the version number) were installed, | ||
| 917 | // this check would allow the uninstall. If the minor upgrade were installed | ||
| 918 | // by a bundle, dependencies would keep the package installed. | ||
| 919 | execute = PackageHasAppliedPatch(pPackage) ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; | ||
| 920 | } | ||
| 921 | else | ||
| 922 | { | ||
| 923 | execute = BOOTSTRAPPER_ACTION_STATE_UNINSTALL; | ||
| 924 | } | ||
| 908 | } | 925 | } |
| 909 | else if (BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT == pPackage->requested) | 926 | else if (BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT == pPackage->requested) |
| 910 | { | 927 | { |
| @@ -2141,7 +2158,7 @@ static HRESULT ConcatFeatureActionProperties( | |||
| 2141 | 2158 | ||
| 2142 | if (sczAddLocal) | 2159 | if (sczAddLocal) |
| 2143 | { | 2160 | { |
| 2144 | hr = StrAllocFormatted(&scz, L" ADDLOCAL=\"%s\"", sczAddLocal, 0); | 2161 | hr = StrAllocFormatted(&scz, L" ADDLOCAL=\"%s\"", sczAddLocal); |
| 2145 | ExitOnFailure(hr, "Failed to format ADDLOCAL string."); | 2162 | ExitOnFailure(hr, "Failed to format ADDLOCAL string."); |
| 2146 | 2163 | ||
| 2147 | hr = StrAllocConcatSecure(psczArguments, scz, 0); | 2164 | hr = StrAllocConcatSecure(psczArguments, scz, 0); |
| @@ -2150,7 +2167,7 @@ static HRESULT ConcatFeatureActionProperties( | |||
| 2150 | 2167 | ||
| 2151 | if (sczAddSource) | 2168 | if (sczAddSource) |
| 2152 | { | 2169 | { |
| 2153 | hr = StrAllocFormatted(&scz, L" ADDSOURCE=\"%s\"", sczAddSource, 0); | 2170 | hr = StrAllocFormatted(&scz, L" ADDSOURCE=\"%s\"", sczAddSource); |
| 2154 | ExitOnFailure(hr, "Failed to format ADDSOURCE string."); | 2171 | ExitOnFailure(hr, "Failed to format ADDSOURCE string."); |
| 2155 | 2172 | ||
| 2156 | hr = StrAllocConcatSecure(psczArguments, scz, 0); | 2173 | hr = StrAllocConcatSecure(psczArguments, scz, 0); |
| @@ -2159,7 +2176,7 @@ static HRESULT ConcatFeatureActionProperties( | |||
| 2159 | 2176 | ||
| 2160 | if (sczAddDefault) | 2177 | if (sczAddDefault) |
| 2161 | { | 2178 | { |
| 2162 | hr = StrAllocFormatted(&scz, L" ADDDEFAULT=\"%s\"", sczAddDefault, 0); | 2179 | hr = StrAllocFormatted(&scz, L" ADDDEFAULT=\"%s\"", sczAddDefault); |
| 2163 | ExitOnFailure(hr, "Failed to format ADDDEFAULT string."); | 2180 | ExitOnFailure(hr, "Failed to format ADDDEFAULT string."); |
| 2164 | 2181 | ||
| 2165 | hr = StrAllocConcatSecure(psczArguments, scz, 0); | 2182 | hr = StrAllocConcatSecure(psczArguments, scz, 0); |
| @@ -2168,7 +2185,7 @@ static HRESULT ConcatFeatureActionProperties( | |||
| 2168 | 2185 | ||
| 2169 | if (sczReinstall) | 2186 | if (sczReinstall) |
| 2170 | { | 2187 | { |
| 2171 | hr = StrAllocFormatted(&scz, L" REINSTALL=\"%s\"", sczReinstall, 0); | 2188 | hr = StrAllocFormatted(&scz, L" REINSTALL=\"%s\"", sczReinstall); |
| 2172 | ExitOnFailure(hr, "Failed to format REINSTALL string."); | 2189 | ExitOnFailure(hr, "Failed to format REINSTALL string."); |
| 2173 | 2190 | ||
| 2174 | hr = StrAllocConcatSecure(psczArguments, scz, 0); | 2191 | hr = StrAllocConcatSecure(psczArguments, scz, 0); |
| @@ -2177,7 +2194,7 @@ static HRESULT ConcatFeatureActionProperties( | |||
| 2177 | 2194 | ||
| 2178 | if (sczAdvertise) | 2195 | if (sczAdvertise) |
| 2179 | { | 2196 | { |
| 2180 | hr = StrAllocFormatted(&scz, L" ADVERTISE=\"%s\"", sczAdvertise, 0); | 2197 | hr = StrAllocFormatted(&scz, L" ADVERTISE=\"%s\"", sczAdvertise); |
| 2181 | ExitOnFailure(hr, "Failed to format ADVERTISE string."); | 2198 | ExitOnFailure(hr, "Failed to format ADVERTISE string."); |
| 2182 | 2199 | ||
| 2183 | hr = StrAllocConcatSecure(psczArguments, scz, 0); | 2200 | hr = StrAllocConcatSecure(psczArguments, scz, 0); |
| @@ -2186,7 +2203,7 @@ static HRESULT ConcatFeatureActionProperties( | |||
| 2186 | 2203 | ||
| 2187 | if (sczRemove) | 2204 | if (sczRemove) |
| 2188 | { | 2205 | { |
| 2189 | hr = StrAllocFormatted(&scz, L" REMOVE=\"%s\"", sczRemove, 0); | 2206 | hr = StrAllocFormatted(&scz, L" REMOVE=\"%s\"", sczRemove); |
| 2190 | ExitOnFailure(hr, "Failed to format REMOVE string."); | 2207 | ExitOnFailure(hr, "Failed to format REMOVE string."); |
| 2191 | 2208 | ||
| 2192 | hr = StrAllocConcatSecure(psczArguments, scz, 0); | 2209 | hr = StrAllocConcatSecure(psczArguments, scz, 0); |
| @@ -2265,6 +2282,7 @@ LExit: | |||
| 2265 | ReleaseStr(sczMspPath); | 2282 | ReleaseStr(sczMspPath); |
| 2266 | ReleaseStr(sczCachedDirectory); | 2283 | ReleaseStr(sczCachedDirectory); |
| 2267 | ReleaseStr(sczPatches); | 2284 | ReleaseStr(sczPatches); |
| 2285 | |||
| 2268 | return hr; | 2286 | return hr; |
| 2269 | } | 2287 | } |
| 2270 | 2288 | ||
| @@ -2289,6 +2307,47 @@ static void RegisterSourceDirectory( | |||
| 2289 | 2307 | ||
| 2290 | LExit: | 2308 | LExit: |
| 2291 | ReleaseStr(sczMsiDirectory); | 2309 | ReleaseStr(sczMsiDirectory); |
| 2310 | } | ||
| 2311 | |||
| 2312 | static BOOL PackageHasAppliedPatch( | ||
| 2313 | __in BURN_PACKAGE* pPackage | ||
| 2314 | ) | ||
| 2315 | { | ||
| 2316 | HRESULT hr = S_OK; | ||
| 2317 | BOOL fPatched = FALSE; | ||
| 2318 | UINT er = ERROR_SUCCESS; | ||
| 2319 | DWORD iPatch = 0; | ||
| 2320 | WCHAR wzPatchCode[MAX_GUID_CHARS + 1] = {}; | ||
| 2321 | WCHAR wzTransforms[MAX_PATH] = {}; | ||
| 2322 | DWORD cchTransforms = countof(wzTransforms); | ||
| 2323 | WCHAR wzPatchState[2] = {}; | ||
| 2324 | DWORD cchPatchState = countof(wzPatchState); | ||
| 2325 | |||
| 2326 | for (;;) | ||
| 2327 | { | ||
| 2328 | er = ::MsiEnumPatchesW(pPackage->Msi.sczProductCode, iPatch, wzPatchCode, wzTransforms, &cchTransforms); | ||
| 2329 | |||
| 2330 | if (ERROR_NO_MORE_ITEMS == er) | ||
| 2331 | { | ||
| 2332 | ExitFunction(); | ||
| 2333 | } | ||
| 2334 | ExitOnWin32Error(er, hr, "Failed to enumerate patches for package %ls, product code %ls.", pPackage->sczId, pPackage->Msi.sczProductCode); | ||
| 2335 | |||
| 2336 | er = ::MsiGetPatchInfoExW(wzPatchCode, pPackage->Msi.sczProductCode, NULL, pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED | ||
| 2337 | , INSTALLPROPERTY_PATCHSTATE, wzPatchState, &cchPatchState); | ||
| 2338 | ExitOnWin32Error(er, hr, "Failed to get patch info for patch %ls.", wzPatchCode); | ||
| 2339 | |||
| 2340 | if ('1' == wzPatchState[0]) | ||
| 2341 | { | ||
| 2342 | fPatched = TRUE; | ||
| 2343 | |||
| 2344 | ExitFunction(); | ||
| 2345 | } | ||
| 2346 | |||
| 2347 | ++iPatch; | ||
| 2348 | } | ||
| 2349 | |||
| 2350 | LExit: | ||
| 2351 | return fPatched; | ||
| 2292 | 2352 | ||
| 2293 | return; | ||
| 2294 | } | 2353 | } |
diff --git a/src/burn/engine/mspengine.cpp b/src/burn/engine/mspengine.cpp index c057c06d..e8ef7fcb 100644 --- a/src/burn/engine/mspengine.cpp +++ b/src/burn/engine/mspengine.cpp | |||
| @@ -771,7 +771,7 @@ extern "C" void MspEngineUpdateInstallRegistrationState( | |||
| 771 | { | 771 | { |
| 772 | pTargetProduct = pPackage->Msp.rgTargetProducts + j; | 772 | pTargetProduct = pPackage->Msp.rgTargetProducts + j; |
| 773 | if (pAction->mspTarget.fPerMachineTarget == (MSIINSTALLCONTEXT_MACHINE == pTargetProduct->context) && | 773 | if (pAction->mspTarget.fPerMachineTarget == (MSIINSTALLCONTEXT_MACHINE == pTargetProduct->context) && |
| 774 | CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pAction->mspTarget.sczTargetProductCode, -1, pTargetProduct->wzTargetProductCode, -1)) | 774 | CSTR_EQUAL == ::CompareStringOrdinal(pAction->mspTarget.sczTargetProductCode, -1, pTargetProduct->wzTargetProductCode, -1, FALSE)) |
| 775 | { | 775 | { |
| 776 | break; | 776 | break; |
| 777 | } | 777 | } |
| @@ -1069,7 +1069,7 @@ static HRESULT DeterminePatchChainedTarget( | |||
| 1069 | { | 1069 | { |
| 1070 | BURN_PACKAGE* pPackage = pPackages->rgPackages + iPackage; | 1070 | BURN_PACKAGE* pPackage = pPackages->rgPackages + iPackage; |
| 1071 | 1071 | ||
| 1072 | if (BURN_PACKAGE_TYPE_MSI == pPackage->type && CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzTargetProductCode, -1, pPackage->Msi.sczProductCode, -1)) | 1072 | if (BURN_PACKAGE_TYPE_MSI == pPackage->type && CSTR_EQUAL == ::CompareStringOrdinal(wzTargetProductCode, -1, pPackage->Msi.sczProductCode, -1, FALSE)) |
| 1073 | { | 1073 | { |
| 1074 | pTargetProduct->pChainedTargetPackage = pPackage; | 1074 | pTargetProduct->pChainedTargetPackage = pPackage; |
| 1075 | 1075 | ||
| @@ -1123,7 +1123,7 @@ static HRESULT PlanTargetProduct( | |||
| 1123 | if (BURN_EXECUTE_ACTION_TYPE_MSP_TARGET == pAction->type && | 1123 | if (BURN_EXECUTE_ACTION_TYPE_MSP_TARGET == pAction->type && |
| 1124 | pAction->mspTarget.action == actionState && | 1124 | pAction->mspTarget.action == actionState && |
| 1125 | pAction->mspTarget.fPerMachineTarget == (MSIINSTALLCONTEXT_MACHINE == pTargetProduct->context) && | 1125 | pAction->mspTarget.fPerMachineTarget == (MSIINSTALLCONTEXT_MACHINE == pTargetProduct->context) && |
| 1126 | CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pAction->mspTarget.sczTargetProductCode, -1, pTargetProduct->wzTargetProductCode, -1)) | 1126 | CSTR_EQUAL == ::CompareStringOrdinal(pAction->mspTarget.sczTargetProductCode, -1, pTargetProduct->wzTargetProductCode, -1, FALSE)) |
| 1127 | { | 1127 | { |
| 1128 | dwInsertSequence = i; | 1128 | dwInsertSequence = i; |
| 1129 | break; | 1129 | break; |
diff --git a/src/burn/engine/msuengine.cpp b/src/burn/engine/msuengine.cpp index 43f5f76c..d31691a5 100644 --- a/src/burn/engine/msuengine.cpp +++ b/src/burn/engine/msuengine.cpp | |||
| @@ -313,6 +313,8 @@ LExit: | |||
| 313 | SetServiceStartType(schWu, SERVICE_DISABLED); | 313 | SetServiceStartType(schWu, SERVICE_DISABLED); |
| 314 | } | 314 | } |
| 315 | 315 | ||
| 316 | ReleaseServiceHandle(schWu); | ||
| 317 | |||
| 316 | // Best effort to clear the execute package cache folder variable. | 318 | // Best effort to clear the execute package cache folder variable. |
| 317 | VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, NULL, TRUE, FALSE); | 319 | VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, NULL, TRUE, FALSE); |
| 318 | 320 | ||
diff --git a/src/burn/engine/package.cpp b/src/burn/engine/package.cpp index fe8af497..3bf676ba 100644 --- a/src/burn/engine/package.cpp +++ b/src/burn/engine/package.cpp | |||
| @@ -123,15 +123,15 @@ extern "C" HRESULT PackagesParseFromXml( | |||
| 123 | 123 | ||
| 124 | if (fFoundXml) | 124 | if (fFoundXml) |
| 125 | { | 125 | { |
| 126 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"remove", -1)) | 126 | if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"remove", -1, FALSE)) |
| 127 | { | 127 | { |
| 128 | pPackage->authoredCacheType = BOOTSTRAPPER_CACHE_TYPE_REMOVE; | 128 | pPackage->authoredCacheType = BOOTSTRAPPER_CACHE_TYPE_REMOVE; |
| 129 | } | 129 | } |
| 130 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"keep", -1)) | 130 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"keep", -1, FALSE)) |
| 131 | { | 131 | { |
| 132 | pPackage->authoredCacheType = BOOTSTRAPPER_CACHE_TYPE_KEEP; | 132 | pPackage->authoredCacheType = BOOTSTRAPPER_CACHE_TYPE_KEEP; |
| 133 | } | 133 | } |
| 134 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"force", -1)) | 134 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"force", -1, FALSE)) |
| 135 | { | 135 | { |
| 136 | pPackage->authoredCacheType = BOOTSTRAPPER_CACHE_TYPE_FORCE; | 136 | pPackage->authoredCacheType = BOOTSTRAPPER_CACHE_TYPE_FORCE; |
| 137 | } | 137 | } |
| @@ -210,28 +210,28 @@ extern "C" HRESULT PackagesParseFromXml( | |||
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | // read type specific attributes | 212 | // read type specific attributes |
| 213 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"BundlePackage", -1)) | 213 | if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"BundlePackage", -1, FALSE)) |
| 214 | { | 214 | { |
| 215 | pPackage->type = BURN_PACKAGE_TYPE_BUNDLE; | 215 | pPackage->type = BURN_PACKAGE_TYPE_BUNDLE; |
| 216 | 216 | ||
| 217 | hr = BundlePackageEngineParsePackageFromXml(pixnNode, pPackage); // TODO: Modularization | 217 | hr = BundlePackageEngineParsePackageFromXml(pixnNode, pPackage); // TODO: Modularization |
| 218 | ExitOnFailure(hr, "Failed to parse BUNDLE package."); | 218 | ExitOnFailure(hr, "Failed to parse BUNDLE package."); |
| 219 | } | 219 | } |
| 220 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"ExePackage", -1)) | 220 | else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"ExePackage", -1, FALSE)) |
| 221 | { | 221 | { |
| 222 | pPackage->type = BURN_PACKAGE_TYPE_EXE; | 222 | pPackage->type = BURN_PACKAGE_TYPE_EXE; |
| 223 | 223 | ||
| 224 | hr = ExeEngineParsePackageFromXml(pixnNode, pPackage); // TODO: Modularization | 224 | hr = ExeEngineParsePackageFromXml(pixnNode, pPackage); // TODO: Modularization |
| 225 | ExitOnFailure(hr, "Failed to parse EXE package."); | 225 | ExitOnFailure(hr, "Failed to parse EXE package."); |
| 226 | } | 226 | } |
| 227 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"MsiPackage", -1)) | 227 | else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"MsiPackage", -1, FALSE)) |
| 228 | { | 228 | { |
| 229 | pPackage->type = BURN_PACKAGE_TYPE_MSI; | 229 | pPackage->type = BURN_PACKAGE_TYPE_MSI; |
| 230 | 230 | ||
| 231 | hr = MsiEngineParsePackageFromXml(pixnNode, pPackage); // TODO: Modularization | 231 | hr = MsiEngineParsePackageFromXml(pixnNode, pPackage); // TODO: Modularization |
| 232 | ExitOnFailure(hr, "Failed to parse MSI package."); | 232 | ExitOnFailure(hr, "Failed to parse MSI package."); |
| 233 | } | 233 | } |
| 234 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"MspPackage", -1)) | 234 | else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"MspPackage", -1, FALSE)) |
| 235 | { | 235 | { |
| 236 | pPackage->type = BURN_PACKAGE_TYPE_MSP; | 236 | pPackage->type = BURN_PACKAGE_TYPE_MSP; |
| 237 | 237 | ||
| @@ -240,7 +240,7 @@ extern "C" HRESULT PackagesParseFromXml( | |||
| 240 | 240 | ||
| 241 | ++cMspPackages; | 241 | ++cMspPackages; |
| 242 | } | 242 | } |
| 243 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"MsuPackage", -1)) | 243 | else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"MsuPackage", -1, FALSE)) |
| 244 | { | 244 | { |
| 245 | pPackage->type = BURN_PACKAGE_TYPE_MSU; | 245 | pPackage->type = BURN_PACKAGE_TYPE_MSU; |
| 246 | 246 | ||
| @@ -315,7 +315,7 @@ extern "C" HRESULT PackagesParseFromXml( | |||
| 315 | { | 315 | { |
| 316 | for (DWORD k = 0; k < pMsiPackage->Msi.cSlipstreamMspPackages; ++k) | 316 | for (DWORD k = 0; k < pMsiPackage->Msi.cSlipstreamMspPackages; ++k) |
| 317 | { | 317 | { |
| 318 | if (pMsiPackage->Msi.rgsczSlipstreamMspPackageIds[k] && CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pPackage->sczId, -1, pMsiPackage->Msi.rgsczSlipstreamMspPackageIds[k], -1)) | 318 | if (pMsiPackage->Msi.rgsczSlipstreamMspPackageIds[k] && CSTR_EQUAL == ::CompareStringOrdinal(pPackage->sczId, -1, pMsiPackage->Msi.rgsczSlipstreamMspPackageIds[k], -1, FALSE)) |
| 319 | { | 319 | { |
| 320 | BURN_SLIPSTREAM_MSP* pSlipstreamMsp = pMsiPackage->Msi.rgSlipstreamMsps + k; | 320 | BURN_SLIPSTREAM_MSP* pSlipstreamMsp = pMsiPackage->Msi.rgSlipstreamMsps + k; |
| 321 | pSlipstreamMsp->pMspPackage = pPackage; | 321 | pSlipstreamMsp->pMspPackage = pPackage; |
| @@ -486,7 +486,7 @@ extern "C" HRESULT PackageFindById( | |||
| 486 | { | 486 | { |
| 487 | pPackage = &pPackages->rgPackages[i]; | 487 | pPackage = &pPackages->rgPackages[i]; |
| 488 | 488 | ||
| 489 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pPackage->sczId, -1, wzId, -1)) | 489 | if (CSTR_EQUAL == ::CompareStringOrdinal(pPackage->sczId, -1, wzId, -1, FALSE)) |
| 490 | { | 490 | { |
| 491 | *ppPackage = pPackage; | 491 | *ppPackage = pPackage; |
| 492 | ExitFunction1(hr = S_OK); | 492 | ExitFunction1(hr = S_OK); |
| @@ -508,7 +508,7 @@ extern "C" HRESULT PackageFindRelatedById( | |||
| 508 | { | 508 | { |
| 509 | HRESULT hr = S_OK; | 509 | HRESULT hr = S_OK; |
| 510 | BURN_RELATED_BUNDLE* pRelatedBundle = NULL; | 510 | BURN_RELATED_BUNDLE* pRelatedBundle = NULL; |
| 511 | 511 | ||
| 512 | hr = RelatedBundleFindById(pRelatedBundles, wzId, &pRelatedBundle); | 512 | hr = RelatedBundleFindById(pRelatedBundles, wzId, &pRelatedBundle); |
| 513 | *ppPackage = FAILED(hr) ? NULL : &pRelatedBundle->package; | 513 | *ppPackage = FAILED(hr) ? NULL : &pRelatedBundle->package; |
| 514 | 514 | ||
| @@ -551,7 +551,7 @@ extern "C" HRESULT PackageGetProperty( | |||
| 551 | { | 551 | { |
| 552 | const BURN_MSIPROPERTY* pProperty = &rgProperties[i]; | 552 | const BURN_MSIPROPERTY* pProperty = &rgProperties[i]; |
| 553 | 553 | ||
| 554 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pProperty->sczId, -1, wzProperty, -1)) | 554 | if (CSTR_EQUAL == ::CompareStringOrdinal(pProperty->sczId, -1, wzProperty, -1, FALSE)) |
| 555 | { | 555 | { |
| 556 | if (psczValue) | 556 | if (psczValue) |
| 557 | { | 557 | { |
| @@ -580,7 +580,7 @@ extern "C" HRESULT PackageFindRollbackBoundaryById( | |||
| 580 | { | 580 | { |
| 581 | pRollbackBoundary = &pPackages->rgRollbackBoundaries[i]; | 581 | pRollbackBoundary = &pPackages->rgRollbackBoundaries[i]; |
| 582 | 582 | ||
| 583 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pRollbackBoundary->sczId, -1, wzId, -1)) | 583 | if (CSTR_EQUAL == ::CompareStringOrdinal(pRollbackBoundary->sczId, -1, wzId, -1, FALSE)) |
| 584 | { | 584 | { |
| 585 | *ppRollbackBoundary = pRollbackBoundary; | 585 | *ppRollbackBoundary = pRollbackBoundary; |
| 586 | ExitFunction1(hr = S_OK); | 586 | ExitFunction1(hr = S_OK); |
| @@ -730,7 +730,7 @@ static HRESULT FindRollbackBoundaryById( | |||
| 730 | { | 730 | { |
| 731 | pRollbackBoundary = &pPackages->rgRollbackBoundaries[i]; | 731 | pRollbackBoundary = &pPackages->rgRollbackBoundaries[i]; |
| 732 | 732 | ||
| 733 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pRollbackBoundary->sczId, -1, wzId, -1)) | 733 | if (CSTR_EQUAL == ::CompareStringOrdinal(pRollbackBoundary->sczId, -1, wzId, -1, FALSE)) |
| 734 | { | 734 | { |
| 735 | *ppRollbackBoundary = pRollbackBoundary; | 735 | *ppRollbackBoundary = pRollbackBoundary; |
| 736 | ExitFunction1(hr = S_OK); | 736 | ExitFunction1(hr = S_OK); |
diff --git a/src/burn/engine/payload.cpp b/src/burn/engine/payload.cpp index 270da6aa..a2649f97 100644 --- a/src/burn/engine/payload.cpp +++ b/src/burn/engine/payload.cpp | |||
| @@ -80,11 +80,11 @@ extern "C" HRESULT PayloadsParseFromXml( | |||
| 80 | hr = XmlGetAttributeEx(pixnNode, L"Packaging", &scz); | 80 | hr = XmlGetAttributeEx(pixnNode, L"Packaging", &scz); |
| 81 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Packaging."); | 81 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Packaging."); |
| 82 | 82 | ||
| 83 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"embedded", -1)) | 83 | if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"embedded", -1, FALSE)) |
| 84 | { | 84 | { |
| 85 | pPayload->packaging = BURN_PAYLOAD_PACKAGING_EMBEDDED; | 85 | pPayload->packaging = BURN_PAYLOAD_PACKAGING_EMBEDDED; |
| 86 | } | 86 | } |
| 87 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"external", -1)) | 87 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"external", -1, FALSE)) |
| 88 | { | 88 | { |
| 89 | pPayload->packaging = BURN_PAYLOAD_PACKAGING_EXTERNAL; | 89 | pPayload->packaging = BURN_PAYLOAD_PACKAGING_EXTERNAL; |
| 90 | } | 90 | } |
diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp index 7994dd32..edc09033 100644 --- a/src/burn/engine/plan.cpp +++ b/src/burn/engine/plan.cpp | |||
| @@ -376,20 +376,6 @@ extern "C" HRESULT PlanDefaultPackageRequestState( | |||
| 376 | break; | 376 | break; |
| 377 | } | 377 | } |
| 378 | } | 378 | } |
| 379 | else if (BOOTSTRAPPER_RELATION_PATCH == relationType && BURN_PACKAGE_TYPE_MSP == packageType) | ||
| 380 | { | ||
| 381 | // For patch related bundles, only install a patch if currently absent during install, modify, or repair. | ||
| 382 | if (BOOTSTRAPPER_PACKAGE_STATE_ABSENT != currentState) | ||
| 383 | { | ||
| 384 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; | ||
| 385 | } | ||
| 386 | else if (BOOTSTRAPPER_ACTION_INSTALL == action || | ||
| 387 | BOOTSTRAPPER_ACTION_MODIFY == action || | ||
| 388 | BOOTSTRAPPER_ACTION_REPAIR == action) | ||
| 389 | { | ||
| 390 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; | ||
| 391 | } | ||
| 392 | } | ||
| 393 | else // pick the best option for the action state and install condition. | 379 | else // pick the best option for the action state and install condition. |
| 394 | { | 380 | { |
| 395 | hr = GetActionDefaultRequestState(action, currentState, &defaultRequestState); | 381 | hr = GetActionDefaultRequestState(action, currentState, &defaultRequestState); |
| @@ -397,12 +383,28 @@ extern "C" HRESULT PlanDefaultPackageRequestState( | |||
| 397 | 383 | ||
| 398 | if (BOOTSTRAPPER_ACTION_UNINSTALL != action && BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL != action) | 384 | if (BOOTSTRAPPER_ACTION_UNINSTALL != action && BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL != action) |
| 399 | { | 385 | { |
| 386 | // For patch related bundles, only install a patch if currently absent during install, modify, or repair. | ||
| 387 | if (BOOTSTRAPPER_RELATION_PATCH == relationType && BURN_PACKAGE_TYPE_MSP == packageType) | ||
| 388 | { | ||
| 389 | if (BOOTSTRAPPER_PACKAGE_STATE_ABSENT != currentState) | ||
| 390 | { | ||
| 391 | defaultRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; | ||
| 392 | } | ||
| 393 | else if (BOOTSTRAPPER_ACTION_INSTALL == action || | ||
| 394 | BOOTSTRAPPER_ACTION_MODIFY == action || | ||
| 395 | BOOTSTRAPPER_ACTION_REPAIR == action) | ||
| 396 | { | ||
| 397 | defaultRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; | ||
| 398 | } | ||
| 399 | } | ||
| 400 | |||
| 400 | // If we're not doing an uninstall, use the install condition | 401 | // If we're not doing an uninstall, use the install condition |
| 401 | // to determine whether to use the default request state or make the package absent. | 402 | // to determine whether to use the default request state or make the package absent. |
| 402 | if (BOOTSTRAPPER_PACKAGE_CONDITION_FALSE == installCondition) | 403 | if (BOOTSTRAPPER_PACKAGE_CONDITION_FALSE == installCondition) |
| 403 | { | 404 | { |
| 404 | defaultRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT; | 405 | defaultRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT; |
| 405 | } | 406 | } |
| 407 | |||
| 406 | // Obsolete means the package is not on the machine and should not be installed, | 408 | // Obsolete means the package is not on the machine and should not be installed, |
| 407 | // *except* patches can be obsolete and present. | 409 | // *except* patches can be obsolete and present. |
| 408 | // Superseded means the package is on the machine but not active, so only uninstall operations are allowed. | 410 | // Superseded means the package is on the machine but not active, so only uninstall operations are allowed. |
| @@ -1540,7 +1542,7 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
| 1540 | 1542 | ||
| 1541 | if (fBundle && BOOTSTRAPPER_ACTION_STATE_NONE != packageAction) | 1543 | if (fBundle && BOOTSTRAPPER_ACTION_STATE_NONE != packageAction) |
| 1542 | { | 1544 | { |
| 1543 | if (pPackage->cDependencyProviders) | 1545 | if (pPackage && pPackage->cDependencyProviders) |
| 1544 | { | 1546 | { |
| 1545 | // Bundles only support a single provider key. | 1547 | // Bundles only support a single provider key. |
| 1546 | const BURN_DEPENDENCY_PROVIDER* pProvider = pPackage->rgDependencyProviders; | 1548 | const BURN_DEPENDENCY_PROVIDER* pProvider = pPackage->rgDependencyProviders; |
| @@ -1554,7 +1556,7 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
| 1554 | 1556 | ||
| 1555 | for (DWORD i = 0; i < pRegistration->relatedBundles.cRelatedBundles; ++i) | 1557 | for (DWORD i = 0; i < pRegistration->relatedBundles.cRelatedBundles; ++i) |
| 1556 | { | 1558 | { |
| 1557 | DWORD *pdwInsertIndex = NULL; | 1559 | DWORD* pdwInsertIndex = NULL; |
| 1558 | BURN_RELATED_BUNDLE* pRelatedBundle = pRegistration->relatedBundles.rgpPlanSortedRelatedBundles[i]; | 1560 | BURN_RELATED_BUNDLE* pRelatedBundle = pRegistration->relatedBundles.rgpPlanSortedRelatedBundles[i]; |
| 1559 | BOOL fDependent = BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DEPENDENT_ADDON == pRelatedBundle->planRelationType || | 1561 | BOOL fDependent = BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DEPENDENT_ADDON == pRelatedBundle->planRelationType || |
| 1560 | BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DEPENDENT_PATCH == pRelatedBundle->planRelationType; | 1562 | BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DEPENDENT_PATCH == pRelatedBundle->planRelationType; |
| @@ -2013,6 +2015,7 @@ extern "C" HRESULT PlanRollbackBoundaryComplete( | |||
| 2013 | 2015 | ||
| 2014 | // Add checkpoints. | 2016 | // Add checkpoints. |
| 2015 | hr = PlanExecuteCheckpoint(pPlan); | 2017 | hr = PlanExecuteCheckpoint(pPlan); |
| 2018 | ExitOnFailure(hr, "Failed to append execute checkpoint for rollback boundary complete."); | ||
| 2016 | 2019 | ||
| 2017 | // Add complete rollback boundary to execute plan. | 2020 | // Add complete rollback boundary to execute plan. |
| 2018 | hr = PlanAppendExecuteAction(pPlan, &pExecuteAction); | 2021 | hr = PlanAppendExecuteAction(pPlan, &pExecuteAction); |
| @@ -2948,9 +2951,9 @@ static void ExecuteActionLog( | |||
| 2948 | 2951 | ||
| 2949 | case BURN_EXECUTE_ACTION_TYPE_PACKAGE_DEPENDENCY: | 2952 | case BURN_EXECUTE_ACTION_TYPE_PACKAGE_DEPENDENCY: |
| 2950 | LogStringLine(PlanDumpLevel, "%ls action[%u]: PACKAGE_DEPENDENCY package id: %ls, bundle provider key: %ls", wzBase, iAction, pAction->packageDependency.pPackage->sczId, pAction->packageDependency.sczBundleProviderKey); | 2953 | LogStringLine(PlanDumpLevel, "%ls action[%u]: PACKAGE_DEPENDENCY package id: %ls, bundle provider key: %ls", wzBase, iAction, pAction->packageDependency.pPackage->sczId, pAction->packageDependency.sczBundleProviderKey); |
| 2951 | for (DWORD j = 0; j < pAction->packageProvider.pPackage->cDependencyProviders; ++j) | 2954 | for (DWORD j = 0; j < pAction->packageDependency.pPackage->cDependencyProviders; ++j) |
| 2952 | { | 2955 | { |
| 2953 | const BURN_DEPENDENCY_PROVIDER* pProvider = pAction->packageProvider.pPackage->rgDependencyProviders + j; | 2956 | const BURN_DEPENDENCY_PROVIDER* pProvider = pAction->packageDependency.pPackage->rgDependencyProviders + j; |
| 2954 | LogStringLine(PlanDumpLevel, " Provider[%u]: key: %ls, action: %hs", j, pProvider->sczKey, LoggingDependencyActionToString(fRollback ? pProvider->dependentRollback : pProvider->dependentExecute)); | 2957 | LogStringLine(PlanDumpLevel, " Provider[%u]: key: %ls, action: %hs", j, pProvider->sczKey, LoggingDependencyActionToString(fRollback ? pProvider->dependentRollback : pProvider->dependentExecute)); |
| 2955 | } | 2958 | } |
| 2956 | break; | 2959 | break; |
diff --git a/src/burn/engine/pseudobundle.cpp b/src/burn/engine/pseudobundle.cpp index f0d67068..ff7f185c 100644 --- a/src/burn/engine/pseudobundle.cpp +++ b/src/burn/engine/pseudobundle.cpp | |||
| @@ -127,8 +127,8 @@ extern "C" HRESULT PseudoBundleInitializePassthrough( | |||
| 127 | ExitOnFailure(hr, "Failed to copy cache id for passthrough pseudo bundle."); | 127 | ExitOnFailure(hr, "Failed to copy cache id for passthrough pseudo bundle."); |
| 128 | 128 | ||
| 129 | // Log variables - best effort | 129 | // Log variables - best effort |
| 130 | StrAllocFormatted(&pPackage->sczLogPathVariable, L"WixBundleLog_%ls", pPackage->sczId); | 130 | StrAllocFormatted(&pPassthroughPackage->sczLogPathVariable, L"WixBundleLog_%ls", pPackage->sczId); |
| 131 | StrAllocFormatted(&pPackage->sczRollbackLogPathVariable, L"WixBundleRollbackLog_%ls", pPackage->sczId); | 131 | StrAllocFormatted(&pPassthroughPackage->sczRollbackLogPathVariable, L"WixBundleRollbackLog_%ls", pPackage->sczId); |
| 132 | 132 | ||
| 133 | hr = CoreCreatePassthroughBundleCommandLine(&sczArguments, pInternalCommand, pCommand); | 133 | hr = CoreCreatePassthroughBundleCommandLine(&sczArguments, pInternalCommand, pCommand); |
| 134 | ExitOnFailure(hr, "Failed to create command-line arguments."); | 134 | ExitOnFailure(hr, "Failed to create command-line arguments."); |
| @@ -155,6 +155,8 @@ extern "C" HRESULT PseudoBundleInitializeUpdateBundle( | |||
| 155 | { | 155 | { |
| 156 | HRESULT hr = S_OK; | 156 | HRESULT hr = S_OK; |
| 157 | BURN_PAYLOAD* pPayload = NULL; | 157 | BURN_PAYLOAD* pPayload = NULL; |
| 158 | BYTE* rgbHash = NULL; | ||
| 159 | DWORD cbHash = 0; | ||
| 158 | 160 | ||
| 159 | // Initialize the single payload, and fill out all the necessary fields | 161 | // Initialize the single payload, and fill out all the necessary fields |
| 160 | pPackage->payloads.rgItems = (BURN_PAYLOAD_GROUP_ITEM*)MemAlloc(sizeof(BURN_PAYLOAD_GROUP_ITEM), TRUE); | 162 | pPackage->payloads.rgItems = (BURN_PAYLOAD_GROUP_ITEM*)MemAlloc(sizeof(BURN_PAYLOAD_GROUP_ITEM), TRUE); |
| @@ -185,9 +187,6 @@ extern "C" HRESULT PseudoBundleInitializeUpdateBundle( | |||
| 185 | 187 | ||
| 186 | if (wzHash && *wzHash) | 188 | if (wzHash && *wzHash) |
| 187 | { | 189 | { |
| 188 | BYTE* rgbHash = NULL; | ||
| 189 | DWORD cbHash = 0; | ||
| 190 | |||
| 191 | hr = StrAllocHexDecode(wzHash, &rgbHash, &cbHash); | 190 | hr = StrAllocHexDecode(wzHash, &rgbHash, &cbHash); |
| 192 | ExitOnFailure(hr, "Failed to decode hash string: %ls.", wzHash); | 191 | ExitOnFailure(hr, "Failed to decode hash string: %ls.", wzHash); |
| 193 | 192 | ||
| @@ -223,5 +222,7 @@ extern "C" HRESULT PseudoBundleInitializeUpdateBundle( | |||
| 223 | ExitOnFailure(hr, "Failed to copy install arguments for update bundle package"); | 222 | ExitOnFailure(hr, "Failed to copy install arguments for update bundle package"); |
| 224 | 223 | ||
| 225 | LExit: | 224 | LExit: |
| 225 | ReleaseStr(rgbHash); | ||
| 226 | |||
| 226 | return hr; | 227 | return hr; |
| 227 | } | 228 | } |
diff --git a/src/burn/engine/registration.cpp b/src/burn/engine/registration.cpp index 85c006f7..9733e92c 100644 --- a/src/burn/engine/registration.cpp +++ b/src/burn/engine/registration.cpp | |||
| @@ -223,15 +223,15 @@ extern "C" HRESULT RegistrationParseFromXml( | |||
| 223 | 223 | ||
| 224 | if (fFoundXml) | 224 | if (fFoundXml) |
| 225 | { | 225 | { |
| 226 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"button", -1)) | 226 | if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"button", -1, FALSE)) |
| 227 | { | 227 | { |
| 228 | pRegistration->modify = BURN_REGISTRATION_MODIFY_DISABLE_BUTTON; | 228 | pRegistration->modify = BURN_REGISTRATION_MODIFY_DISABLE_BUTTON; |
| 229 | } | 229 | } |
| 230 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"yes", -1)) | 230 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"yes", -1, FALSE)) |
| 231 | { | 231 | { |
| 232 | pRegistration->modify = BURN_REGISTRATION_MODIFY_DISABLE; | 232 | pRegistration->modify = BURN_REGISTRATION_MODIFY_DISABLE; |
| 233 | } | 233 | } |
| 234 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"no", -1)) | 234 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"no", -1, FALSE)) |
| 235 | { | 235 | { |
| 236 | pRegistration->modify = BURN_REGISTRATION_MODIFY_ENABLED; | 236 | pRegistration->modify = BURN_REGISTRATION_MODIFY_ENABLED; |
| 237 | } | 237 | } |
| @@ -808,13 +808,6 @@ extern "C" HRESULT RegistrationSessionBegin( | |||
| 808 | ExitOnFailure(hr, "Failed to write software tags."); | 808 | ExitOnFailure(hr, "Failed to write software tags."); |
| 809 | } | 809 | } |
| 810 | 810 | ||
| 811 | // Update registration. | ||
| 812 | if (pRegistration->update.fRegisterUpdate) | ||
| 813 | { | ||
| 814 | hr = WriteUpdateRegistration(pRegistration, pVariables); | ||
| 815 | ExitOnFailure(hr, "Failed to write update registration."); | ||
| 816 | } | ||
| 817 | |||
| 818 | // Only set install date and initial estimated size here for the first time. | 811 | // Only set install date and initial estimated size here for the first time. |
| 819 | // Estimated size will always get updated at the end of the session. | 812 | // Estimated size will always get updated at the end of the session. |
| 820 | if (fCreated) | 813 | if (fCreated) |
| @@ -904,6 +897,13 @@ extern "C" HRESULT RegistrationSessionEnd( | |||
| 904 | 897 | ||
| 905 | hr = UpdateEstimatedSize(hkRegistration, qwEstimatedSize); | 898 | hr = UpdateEstimatedSize(hkRegistration, qwEstimatedSize); |
| 906 | ExitOnFailure(hr, "Failed to update estimated size."); | 899 | ExitOnFailure(hr, "Failed to update estimated size."); |
| 900 | |||
| 901 | // Update registration. | ||
| 902 | if (pRegistration->update.fRegisterUpdate) | ||
| 903 | { | ||
| 904 | hr = WriteUpdateRegistration(pRegistration, pVariables); | ||
| 905 | ExitOnFailure(hr, "Failed to write update registration."); | ||
| 906 | } | ||
| 907 | } | 907 | } |
| 908 | 908 | ||
| 909 | // Update resume mode. | 909 | // Update resume mode. |
| @@ -1512,7 +1512,7 @@ static HRESULT RemoveUpdateRegistration( | |||
| 1512 | hr = RegReadString(hkKey, L"PackageVersion", &sczPackageVersion); | 1512 | hr = RegReadString(hkKey, L"PackageVersion", &sczPackageVersion); |
| 1513 | if (SUCCEEDED(hr)) | 1513 | if (SUCCEEDED(hr)) |
| 1514 | { | 1514 | { |
| 1515 | if (CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, 0, sczPackageVersion, -1, pRegistration->sczDisplayVersion, -1)) | 1515 | if (CSTR_EQUAL != ::CompareStringOrdinal(sczPackageVersion, -1, pRegistration->sczDisplayVersion, -1, FALSE)) |
| 1516 | { | 1516 | { |
| 1517 | fDeleteRegKey = FALSE; | 1517 | fDeleteRegKey = FALSE; |
| 1518 | } | 1518 | } |
diff --git a/src/burn/engine/relatedbundle.cpp b/src/burn/engine/relatedbundle.cpp index 938b24d7..c9aa7170 100644 --- a/src/burn/engine/relatedbundle.cpp +++ b/src/burn/engine/relatedbundle.cpp | |||
| @@ -116,7 +116,7 @@ extern "C" HRESULT RelatedBundleFindById( | |||
| 116 | pRelatedBundle = pRelatedBundles->rgRelatedBundles + i; | 116 | pRelatedBundle = pRelatedBundles->rgRelatedBundles + i; |
| 117 | pPackage = &pRelatedBundle->package; | 117 | pPackage = &pRelatedBundle->package; |
| 118 | 118 | ||
| 119 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pPackage->sczId, -1, wzId, -1)) | 119 | if (CSTR_EQUAL == ::CompareStringOrdinal(pPackage->sczId, -1, wzId, -1, FALSE)) |
| 120 | { | 120 | { |
| 121 | *ppRelatedBundle = pRelatedBundle; | 121 | *ppRelatedBundle = pRelatedBundle; |
| 122 | ExitFunction1(hr = S_OK); | 122 | ExitFunction1(hr = S_OK); |
| @@ -206,7 +206,7 @@ static __callback int __cdecl CompareRelatedBundlesDetect( | |||
| 206 | VerCompareParsedVersions(pBundleLeft->pVersion, pBundleRight->pVersion, &ret); | 206 | VerCompareParsedVersions(pBundleLeft->pVersion, pBundleRight->pVersion, &ret); |
| 207 | if (0 == ret) | 207 | if (0 == ret) |
| 208 | { | 208 | { |
| 209 | ret = ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pBundleLeft->package.sczId, -1, pBundleRight->package.sczId, -1) - 2; | 209 | ret = ::CompareStringOrdinal(pBundleLeft->package.sczId, -1, pBundleRight->package.sczId, -1, TRUE) - 2; |
| 210 | } | 210 | } |
| 211 | } | 211 | } |
| 212 | 212 | ||
| @@ -249,7 +249,7 @@ static __callback int __cdecl CompareRelatedBundlesPlan( | |||
| 249 | VerCompareParsedVersions(pBundleLeft->pVersion, pBundleRight->pVersion, &ret); | 249 | VerCompareParsedVersions(pBundleLeft->pVersion, pBundleRight->pVersion, &ret); |
| 250 | if (0 == ret) | 250 | if (0 == ret) |
| 251 | { | 251 | { |
| 252 | ret = ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pBundleLeft->package.sczId, -1, pBundleRight->package.sczId, -1) - 2; | 252 | ret = ::CompareStringOrdinal(pBundleLeft->package.sczId, -1, pBundleRight->package.sczId, -1, TRUE) - 2; |
| 253 | } | 253 | } |
| 254 | } | 254 | } |
| 255 | 255 | ||
| @@ -284,7 +284,7 @@ static HRESULT LoadIfRelatedBundle( | |||
| 284 | BURN_RELATED_BUNDLE* pRelatedBundle = NULL; | 284 | BURN_RELATED_BUNDLE* pRelatedBundle = NULL; |
| 285 | 285 | ||
| 286 | // If we found our bundle code, it's not a related bundle. | 286 | // If we found our bundle code, it's not a related bundle. |
| 287 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pBundle->wzBundleCode, -1, pRegistration->sczCode, -1)) | 287 | if (CSTR_EQUAL == ::CompareStringOrdinal(pBundle->wzBundleCode, -1, pRegistration->sczCode, -1, TRUE)) |
| 288 | { | 288 | { |
| 289 | ExitFunction1(hr = S_FALSE); | 289 | ExitFunction1(hr = S_FALSE); |
| 290 | } | 290 | } |
diff --git a/src/burn/engine/search.cpp b/src/burn/engine/search.cpp index a1b6b74a..a60215fe 100644 --- a/src/burn/engine/search.cpp +++ b/src/burn/engine/search.cpp | |||
| @@ -106,7 +106,7 @@ extern "C" HRESULT SearchesParseFromXml( | |||
| 106 | ExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get @Condition."); | 106 | ExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get @Condition."); |
| 107 | 107 | ||
| 108 | // read type specific attributes | 108 | // read type specific attributes |
| 109 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"DirectorySearch", -1)) | 109 | if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"DirectorySearch", -1, FALSE)) |
| 110 | { | 110 | { |
| 111 | pSearch->Type = BURN_SEARCH_TYPE_DIRECTORY; | 111 | pSearch->Type = BURN_SEARCH_TYPE_DIRECTORY; |
| 112 | 112 | ||
| @@ -118,11 +118,11 @@ extern "C" HRESULT SearchesParseFromXml( | |||
| 118 | hr = XmlGetAttributeEx(pixnNode, L"Type", &scz); | 118 | hr = XmlGetAttributeEx(pixnNode, L"Type", &scz); |
| 119 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Type."); | 119 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Type."); |
| 120 | 120 | ||
| 121 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"exists", -1)) | 121 | if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"exists", -1, FALSE)) |
| 122 | { | 122 | { |
| 123 | pSearch->DirectorySearch.Type = BURN_DIRECTORY_SEARCH_TYPE_EXISTS; | 123 | pSearch->DirectorySearch.Type = BURN_DIRECTORY_SEARCH_TYPE_EXISTS; |
| 124 | } | 124 | } |
| 125 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"path", -1)) | 125 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"path", -1, FALSE)) |
| 126 | { | 126 | { |
| 127 | pSearch->DirectorySearch.Type = BURN_DIRECTORY_SEARCH_TYPE_PATH; | 127 | pSearch->DirectorySearch.Type = BURN_DIRECTORY_SEARCH_TYPE_PATH; |
| 128 | } | 128 | } |
| @@ -131,7 +131,7 @@ extern "C" HRESULT SearchesParseFromXml( | |||
| 131 | ExitWithRootFailure(hr, E_INVALIDARG, "Invalid value for @Type: %ls", scz); | 131 | ExitWithRootFailure(hr, E_INVALIDARG, "Invalid value for @Type: %ls", scz); |
| 132 | } | 132 | } |
| 133 | } | 133 | } |
| 134 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"FileSearch", -1)) | 134 | else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"FileSearch", -1, FALSE)) |
| 135 | { | 135 | { |
| 136 | pSearch->Type = BURN_SEARCH_TYPE_FILE; | 136 | pSearch->Type = BURN_SEARCH_TYPE_FILE; |
| 137 | 137 | ||
| @@ -147,15 +147,15 @@ extern "C" HRESULT SearchesParseFromXml( | |||
| 147 | hr = XmlGetAttributeEx(pixnNode, L"Type", &scz); | 147 | hr = XmlGetAttributeEx(pixnNode, L"Type", &scz); |
| 148 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Type."); | 148 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Type."); |
| 149 | 149 | ||
| 150 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"exists", -1)) | 150 | if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"exists", -1, FALSE)) |
| 151 | { | 151 | { |
| 152 | pSearch->FileSearch.Type = BURN_FILE_SEARCH_TYPE_EXISTS; | 152 | pSearch->FileSearch.Type = BURN_FILE_SEARCH_TYPE_EXISTS; |
| 153 | } | 153 | } |
| 154 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"version", -1)) | 154 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"version", -1, FALSE)) |
| 155 | { | 155 | { |
| 156 | pSearch->FileSearch.Type = BURN_FILE_SEARCH_TYPE_VERSION; | 156 | pSearch->FileSearch.Type = BURN_FILE_SEARCH_TYPE_VERSION; |
| 157 | } | 157 | } |
| 158 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"path", -1)) | 158 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"path", -1, FALSE)) |
| 159 | { | 159 | { |
| 160 | pSearch->FileSearch.Type = BURN_FILE_SEARCH_TYPE_PATH; | 160 | pSearch->FileSearch.Type = BURN_FILE_SEARCH_TYPE_PATH; |
| 161 | } | 161 | } |
| @@ -164,7 +164,7 @@ extern "C" HRESULT SearchesParseFromXml( | |||
| 164 | ExitWithRootFailure(hr, E_INVALIDARG, "Invalid value for @Type: %ls", scz); | 164 | ExitWithRootFailure(hr, E_INVALIDARG, "Invalid value for @Type: %ls", scz); |
| 165 | } | 165 | } |
| 166 | } | 166 | } |
| 167 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"RegistrySearch", -1)) | 167 | else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"RegistrySearch", -1, FALSE)) |
| 168 | { | 168 | { |
| 169 | pSearch->Type = BURN_SEARCH_TYPE_REGISTRY; | 169 | pSearch->Type = BURN_SEARCH_TYPE_REGISTRY; |
| 170 | 170 | ||
| @@ -172,19 +172,19 @@ extern "C" HRESULT SearchesParseFromXml( | |||
| 172 | hr = XmlGetAttributeEx(pixnNode, L"Root", &scz); | 172 | hr = XmlGetAttributeEx(pixnNode, L"Root", &scz); |
| 173 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Root."); | 173 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Root."); |
| 174 | 174 | ||
| 175 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"HKCR", -1)) | 175 | if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"HKCR", -1, FALSE)) |
| 176 | { | 176 | { |
| 177 | pSearch->RegistrySearch.hRoot = HKEY_CLASSES_ROOT; | 177 | pSearch->RegistrySearch.hRoot = HKEY_CLASSES_ROOT; |
| 178 | } | 178 | } |
| 179 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"HKCU", -1)) | 179 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"HKCU", -1, FALSE)) |
| 180 | { | 180 | { |
| 181 | pSearch->RegistrySearch.hRoot = HKEY_CURRENT_USER; | 181 | pSearch->RegistrySearch.hRoot = HKEY_CURRENT_USER; |
| 182 | } | 182 | } |
| 183 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"HKLM", -1)) | 183 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"HKLM", -1, FALSE)) |
| 184 | { | 184 | { |
| 185 | pSearch->RegistrySearch.hRoot = HKEY_LOCAL_MACHINE; | 185 | pSearch->RegistrySearch.hRoot = HKEY_LOCAL_MACHINE; |
| 186 | } | 186 | } |
| 187 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"HKU", -1)) | 187 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"HKU", -1, FALSE)) |
| 188 | { | 188 | { |
| 189 | pSearch->RegistrySearch.hRoot = HKEY_USERS; | 189 | pSearch->RegistrySearch.hRoot = HKEY_USERS; |
| 190 | } | 190 | } |
| @@ -208,11 +208,11 @@ extern "C" HRESULT SearchesParseFromXml( | |||
| 208 | hr = XmlGetYesNoAttribute(pixnNode, L"Win64", &pSearch->RegistrySearch.fWin64); | 208 | hr = XmlGetYesNoAttribute(pixnNode, L"Win64", &pSearch->RegistrySearch.fWin64); |
| 209 | ExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get Win64 attribute."); | 209 | ExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get Win64 attribute."); |
| 210 | 210 | ||
| 211 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"exists", -1)) | 211 | if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"exists", -1, FALSE)) |
| 212 | { | 212 | { |
| 213 | pSearch->RegistrySearch.Type = BURN_REGISTRY_SEARCH_TYPE_EXISTS; | 213 | pSearch->RegistrySearch.Type = BURN_REGISTRY_SEARCH_TYPE_EXISTS; |
| 214 | } | 214 | } |
| 215 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"value", -1)) | 215 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"value", -1, FALSE)) |
| 216 | { | 216 | { |
| 217 | pSearch->RegistrySearch.Type = BURN_REGISTRY_SEARCH_TYPE_VALUE; | 217 | pSearch->RegistrySearch.Type = BURN_REGISTRY_SEARCH_TYPE_VALUE; |
| 218 | 218 | ||
| @@ -224,19 +224,19 @@ extern "C" HRESULT SearchesParseFromXml( | |||
| 224 | hr = XmlGetAttributeEx(pixnNode, L"VariableType", &scz); | 224 | hr = XmlGetAttributeEx(pixnNode, L"VariableType", &scz); |
| 225 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @VariableType."); | 225 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @VariableType."); |
| 226 | 226 | ||
| 227 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"formatted", -1)) | 227 | if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"formatted", -1, FALSE)) |
| 228 | { | 228 | { |
| 229 | pSearch->RegistrySearch.VariableType = BURN_VARIANT_TYPE_FORMATTED; | 229 | pSearch->RegistrySearch.VariableType = BURN_VARIANT_TYPE_FORMATTED; |
| 230 | } | 230 | } |
| 231 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"numeric", -1)) | 231 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"numeric", -1, FALSE)) |
| 232 | { | 232 | { |
| 233 | pSearch->RegistrySearch.VariableType = BURN_VARIANT_TYPE_NUMERIC; | 233 | pSearch->RegistrySearch.VariableType = BURN_VARIANT_TYPE_NUMERIC; |
| 234 | } | 234 | } |
| 235 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"string", -1)) | 235 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"string", -1, FALSE)) |
| 236 | { | 236 | { |
| 237 | pSearch->RegistrySearch.VariableType = BURN_VARIANT_TYPE_STRING; | 237 | pSearch->RegistrySearch.VariableType = BURN_VARIANT_TYPE_STRING; |
| 238 | } | 238 | } |
| 239 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"version", -1)) | 239 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"version", -1, FALSE)) |
| 240 | { | 240 | { |
| 241 | pSearch->RegistrySearch.VariableType = BURN_VARIANT_TYPE_VERSION; | 241 | pSearch->RegistrySearch.VariableType = BURN_VARIANT_TYPE_VERSION; |
| 242 | } | 242 | } |
| @@ -250,7 +250,7 @@ extern "C" HRESULT SearchesParseFromXml( | |||
| 250 | ExitWithRootFailure(hr, E_INVALIDARG, "Invalid value for @Type: %ls", scz); | 250 | ExitWithRootFailure(hr, E_INVALIDARG, "Invalid value for @Type: %ls", scz); |
| 251 | } | 251 | } |
| 252 | } | 252 | } |
| 253 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"MsiComponentSearch", -1)) | 253 | else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"MsiComponentSearch", -1, FALSE)) |
| 254 | { | 254 | { |
| 255 | pSearch->Type = BURN_SEARCH_TYPE_MSI_COMPONENT; | 255 | pSearch->Type = BURN_SEARCH_TYPE_MSI_COMPONENT; |
| 256 | 256 | ||
| @@ -266,15 +266,15 @@ extern "C" HRESULT SearchesParseFromXml( | |||
| 266 | hr = XmlGetAttributeEx(pixnNode, L"Type", &scz); | 266 | hr = XmlGetAttributeEx(pixnNode, L"Type", &scz); |
| 267 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Type."); | 267 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Type."); |
| 268 | 268 | ||
| 269 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"keyPath", -1)) | 269 | if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"keyPath", -1, FALSE)) |
| 270 | { | 270 | { |
| 271 | pSearch->MsiComponentSearch.Type = BURN_MSI_COMPONENT_SEARCH_TYPE_KEYPATH; | 271 | pSearch->MsiComponentSearch.Type = BURN_MSI_COMPONENT_SEARCH_TYPE_KEYPATH; |
| 272 | } | 272 | } |
| 273 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"state", -1)) | 273 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"state", -1, FALSE)) |
| 274 | { | 274 | { |
| 275 | pSearch->MsiComponentSearch.Type = BURN_MSI_COMPONENT_SEARCH_TYPE_STATE; | 275 | pSearch->MsiComponentSearch.Type = BURN_MSI_COMPONENT_SEARCH_TYPE_STATE; |
| 276 | } | 276 | } |
| 277 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"directory", -1)) | 277 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"directory", -1, FALSE)) |
| 278 | { | 278 | { |
| 279 | pSearch->MsiComponentSearch.Type = BURN_MSI_COMPONENT_SEARCH_TYPE_DIRECTORY; | 279 | pSearch->MsiComponentSearch.Type = BURN_MSI_COMPONENT_SEARCH_TYPE_DIRECTORY; |
| 280 | } | 280 | } |
| @@ -283,7 +283,7 @@ extern "C" HRESULT SearchesParseFromXml( | |||
| 283 | ExitWithRootFailure(hr, E_INVALIDARG, "Invalid value for @Type: %ls", scz); | 283 | ExitWithRootFailure(hr, E_INVALIDARG, "Invalid value for @Type: %ls", scz); |
| 284 | } | 284 | } |
| 285 | } | 285 | } |
| 286 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"MsiProductSearch", -1)) | 286 | else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"MsiProductSearch", -1, FALSE)) |
| 287 | { | 287 | { |
| 288 | pSearch->Type = BURN_SEARCH_TYPE_MSI_PRODUCT; | 288 | pSearch->Type = BURN_SEARCH_TYPE_MSI_PRODUCT; |
| 289 | pSearch->MsiProductSearch.GuidType = BURN_MSI_PRODUCT_SEARCH_GUID_TYPE_NONE; | 289 | pSearch->MsiProductSearch.GuidType = BURN_MSI_PRODUCT_SEARCH_GUID_TYPE_NONE; |
| @@ -318,28 +318,32 @@ extern "C" HRESULT SearchesParseFromXml( | |||
| 318 | hr = XmlGetAttributeEx(pixnNode, L"Type", &scz); | 318 | hr = XmlGetAttributeEx(pixnNode, L"Type", &scz); |
| 319 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Type."); | 319 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Type."); |
| 320 | 320 | ||
| 321 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"version", -1)) | 321 | if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"version", -1, FALSE)) |
| 322 | { | 322 | { |
| 323 | pSearch->MsiProductSearch.Type = BURN_MSI_PRODUCT_SEARCH_TYPE_VERSION; | 323 | pSearch->MsiProductSearch.Type = BURN_MSI_PRODUCT_SEARCH_TYPE_VERSION; |
| 324 | } | 324 | } |
| 325 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"language", -1)) | 325 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"language", -1, FALSE)) |
| 326 | { | 326 | { |
| 327 | pSearch->MsiProductSearch.Type = BURN_MSI_PRODUCT_SEARCH_TYPE_LANGUAGE; | 327 | pSearch->MsiProductSearch.Type = BURN_MSI_PRODUCT_SEARCH_TYPE_LANGUAGE; |
| 328 | } | 328 | } |
| 329 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"state", -1)) | 329 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"state", -1, FALSE)) |
| 330 | { | 330 | { |
| 331 | pSearch->MsiProductSearch.Type = BURN_MSI_PRODUCT_SEARCH_TYPE_STATE; | 331 | pSearch->MsiProductSearch.Type = BURN_MSI_PRODUCT_SEARCH_TYPE_STATE; |
| 332 | } | 332 | } |
| 333 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"assignment", -1)) | 333 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"assignment", -1, FALSE)) |
| 334 | { | 334 | { |
| 335 | pSearch->MsiProductSearch.Type = BURN_MSI_PRODUCT_SEARCH_TYPE_ASSIGNMENT; | 335 | pSearch->MsiProductSearch.Type = BURN_MSI_PRODUCT_SEARCH_TYPE_ASSIGNMENT; |
| 336 | } | 336 | } |
| 337 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"exists", -1, FALSE)) | ||
| 338 | { | ||
| 339 | pSearch->MsiProductSearch.Type = BURN_MSI_PRODUCT_SEARCH_TYPE_EXISTS; | ||
| 340 | } | ||
| 337 | else | 341 | else |
| 338 | { | 342 | { |
| 339 | ExitWithRootFailure(hr, E_INVALIDARG, "Invalid value for @Type: %ls", scz); | 343 | ExitWithRootFailure(hr, E_INVALIDARG, "Invalid value for @Type: %ls", scz); |
| 340 | } | 344 | } |
| 341 | } | 345 | } |
| 342 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"ExtensionSearch", -1)) | 346 | else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"ExtensionSearch", -1, FALSE)) |
| 343 | { | 347 | { |
| 344 | pSearch->Type = BURN_SEARCH_TYPE_EXTENSION; | 348 | pSearch->Type = BURN_SEARCH_TYPE_EXTENSION; |
| 345 | 349 | ||
| @@ -350,7 +354,7 @@ extern "C" HRESULT SearchesParseFromXml( | |||
| 350 | hr = BurnExtensionFindById(pBurnExtensions, scz, &pSearch->ExtensionSearch.pExtension); | 354 | hr = BurnExtensionFindById(pBurnExtensions, scz, &pSearch->ExtensionSearch.pExtension); |
| 351 | ExitOnRootFailure(hr, "Failed to find extension '%ls' for search '%ls'", scz, pSearch->sczKey); | 355 | ExitOnRootFailure(hr, "Failed to find extension '%ls' for search '%ls'", scz, pSearch->sczKey); |
| 352 | } | 356 | } |
| 353 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"SetVariable", -1)) | 357 | else if (CSTR_EQUAL == ::CompareStringOrdinal(bstrNodeName, -1, L"SetVariable", -1, FALSE)) |
| 354 | { | 358 | { |
| 355 | pSearch->Type = BURN_SEARCH_TYPE_SET_VARIABLE; | 359 | pSearch->Type = BURN_SEARCH_TYPE_SET_VARIABLE; |
| 356 | 360 | ||
| @@ -367,19 +371,19 @@ extern "C" HRESULT SearchesParseFromXml( | |||
| 367 | hr = XmlGetAttributeEx(pixnNode, L"Type", &scz); | 371 | hr = XmlGetAttributeEx(pixnNode, L"Type", &scz); |
| 368 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Type."); | 372 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Type."); |
| 369 | 373 | ||
| 370 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"formatted", -1)) | 374 | if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"formatted", -1, FALSE)) |
| 371 | { | 375 | { |
| 372 | pSearch->SetVariable.targetType = BURN_VARIANT_TYPE_FORMATTED; | 376 | pSearch->SetVariable.targetType = BURN_VARIANT_TYPE_FORMATTED; |
| 373 | } | 377 | } |
| 374 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"numeric", -1)) | 378 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"numeric", -1, FALSE)) |
| 375 | { | 379 | { |
| 376 | pSearch->SetVariable.targetType = BURN_VARIANT_TYPE_NUMERIC; | 380 | pSearch->SetVariable.targetType = BURN_VARIANT_TYPE_NUMERIC; |
| 377 | } | 381 | } |
| 378 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"string", -1)) | 382 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"string", -1, FALSE)) |
| 379 | { | 383 | { |
| 380 | pSearch->SetVariable.targetType = BURN_VARIANT_TYPE_STRING; | 384 | pSearch->SetVariable.targetType = BURN_VARIANT_TYPE_STRING; |
| 381 | } | 385 | } |
| 382 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"version", -1)) | 386 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"version", -1, FALSE)) |
| 383 | { | 387 | { |
| 384 | pSearch->SetVariable.targetType = BURN_VARIANT_TYPE_VERSION; | 388 | pSearch->SetVariable.targetType = BURN_VARIANT_TYPE_VERSION; |
| 385 | } | 389 | } |
| @@ -1144,6 +1148,7 @@ static HRESULT MsiProductSearch( | |||
| 1144 | case BURN_MSI_PRODUCT_SEARCH_TYPE_LANGUAGE: | 1148 | case BURN_MSI_PRODUCT_SEARCH_TYPE_LANGUAGE: |
| 1145 | wzProperty = INSTALLPROPERTY_LANGUAGE; | 1149 | wzProperty = INSTALLPROPERTY_LANGUAGE; |
| 1146 | break; | 1150 | break; |
| 1151 | case BURN_MSI_PRODUCT_SEARCH_TYPE_EXISTS: __fallthrough; | ||
| 1147 | case BURN_MSI_PRODUCT_SEARCH_TYPE_STATE: | 1152 | case BURN_MSI_PRODUCT_SEARCH_TYPE_STATE: |
| 1148 | wzProperty = INSTALLPROPERTY_PRODUCTSTATE; | 1153 | wzProperty = INSTALLPROPERTY_PRODUCTSTATE; |
| 1149 | break; | 1154 | break; |
| @@ -1218,6 +1223,7 @@ static HRESULT MsiProductSearch( | |||
| 1218 | case BURN_MSI_PRODUCT_SEARCH_TYPE_LANGUAGE: | 1223 | case BURN_MSI_PRODUCT_SEARCH_TYPE_LANGUAGE: |
| 1219 | // is supposed to remain empty | 1224 | // is supposed to remain empty |
| 1220 | break; | 1225 | break; |
| 1226 | case BURN_MSI_PRODUCT_SEARCH_TYPE_EXISTS: __fallthrough; | ||
| 1221 | case BURN_MSI_PRODUCT_SEARCH_TYPE_STATE: | 1227 | case BURN_MSI_PRODUCT_SEARCH_TYPE_STATE: |
| 1222 | value.Type = BURN_VARIANT_TYPE_NUMERIC; | 1228 | value.Type = BURN_VARIANT_TYPE_NUMERIC; |
| 1223 | value.llValue = INSTALLSTATE_ABSENT; | 1229 | value.llValue = INSTALLSTATE_ABSENT; |
| @@ -1237,6 +1243,7 @@ static HRESULT MsiProductSearch( | |||
| 1237 | case BURN_MSI_PRODUCT_SEARCH_TYPE_LANGUAGE: | 1243 | case BURN_MSI_PRODUCT_SEARCH_TYPE_LANGUAGE: |
| 1238 | type = BURN_VARIANT_TYPE_STRING; | 1244 | type = BURN_VARIANT_TYPE_STRING; |
| 1239 | break; | 1245 | break; |
| 1246 | case BURN_MSI_PRODUCT_SEARCH_TYPE_EXISTS: __fallthrough; | ||
| 1240 | case BURN_MSI_PRODUCT_SEARCH_TYPE_STATE: __fallthrough; | 1247 | case BURN_MSI_PRODUCT_SEARCH_TYPE_STATE: __fallthrough; |
| 1241 | case BURN_MSI_PRODUCT_SEARCH_TYPE_ASSIGNMENT: | 1248 | case BURN_MSI_PRODUCT_SEARCH_TYPE_ASSIGNMENT: |
| 1242 | type = BURN_VARIANT_TYPE_NUMERIC; | 1249 | type = BURN_VARIANT_TYPE_NUMERIC; |
| @@ -1245,6 +1252,13 @@ static HRESULT MsiProductSearch( | |||
| 1245 | hr = BVariantChangeType(&value, type); | 1252 | hr = BVariantChangeType(&value, type); |
| 1246 | ExitOnFailure(hr, "Failed to change value type."); | 1253 | ExitOnFailure(hr, "Failed to change value type."); |
| 1247 | 1254 | ||
| 1255 | // When testing if a product exists, replace the value with a numeric "true" or "false" | ||
| 1256 | // based on the calculated install state. | ||
| 1257 | if (BURN_MSI_PRODUCT_SEARCH_TYPE_EXISTS == pSearch->MsiProductSearch.Type) | ||
| 1258 | { | ||
| 1259 | value.llValue = (value.llValue == INSTALLSTATE_ABSENT) ? 0 : 1; | ||
| 1260 | } | ||
| 1261 | |||
| 1248 | // Set variable. | 1262 | // Set variable. |
| 1249 | hr = VariableSetVariant(pVariables, pSearch->sczVariable, &value); | 1263 | hr = VariableSetVariant(pVariables, pSearch->sczVariable, &value); |
| 1250 | ExitOnFailure(hr, "Failed to set variable."); | 1264 | ExitOnFailure(hr, "Failed to set variable."); |
diff --git a/src/burn/engine/search.h b/src/burn/engine/search.h index 341fe1aa..e70645c5 100644 --- a/src/burn/engine/search.h +++ b/src/burn/engine/search.h | |||
| @@ -58,6 +58,7 @@ enum BURN_MSI_PRODUCT_SEARCH_TYPE | |||
| 58 | BURN_MSI_PRODUCT_SEARCH_TYPE_LANGUAGE, | 58 | BURN_MSI_PRODUCT_SEARCH_TYPE_LANGUAGE, |
| 59 | BURN_MSI_PRODUCT_SEARCH_TYPE_STATE, | 59 | BURN_MSI_PRODUCT_SEARCH_TYPE_STATE, |
| 60 | BURN_MSI_PRODUCT_SEARCH_TYPE_ASSIGNMENT, | 60 | BURN_MSI_PRODUCT_SEARCH_TYPE_ASSIGNMENT, |
| 61 | BURN_MSI_PRODUCT_SEARCH_TYPE_EXISTS, | ||
| 61 | }; | 62 | }; |
| 62 | 63 | ||
| 63 | enum BURN_MSI_PRODUCT_SEARCH_GUID_TYPE | 64 | enum BURN_MSI_PRODUCT_SEARCH_GUID_TYPE |
diff --git a/src/burn/engine/splashscreen.cpp b/src/burn/engine/splashscreen.cpp index 0bfa00aa..21ddfa98 100644 --- a/src/burn/engine/splashscreen.cpp +++ b/src/burn/engine/splashscreen.cpp | |||
| @@ -371,6 +371,7 @@ static void OnEraseBkgnd( | |||
| 371 | HDC hdc = reinterpret_cast<HDC>(wParam); | 371 | HDC hdc = reinterpret_cast<HDC>(wParam); |
| 372 | HDC hdcMem = ::CreateCompatibleDC(hdc); | 372 | HDC hdcMem = ::CreateCompatibleDC(hdc); |
| 373 | HBITMAP hDefaultBitmap = static_cast<HBITMAP>(::SelectObject(hdcMem, pSplashScreen->hBitmap)); | 373 | HBITMAP hDefaultBitmap = static_cast<HBITMAP>(::SelectObject(hdcMem, pSplashScreen->hBitmap)); |
| 374 | ::SetStretchBltMode(hdc, HALFTONE); | ||
| 374 | ::StretchBlt(hdc, 0, 0, pSplashScreen->size.cx, pSplashScreen->size.cy, hdcMem, 0, 0, pSplashScreen->defaultDpiSize.cx, pSplashScreen->defaultDpiSize.cy, SRCCOPY); | 375 | ::StretchBlt(hdc, 0, 0, pSplashScreen->size.cx, pSplashScreen->size.cy, hdcMem, 0, 0, pSplashScreen->defaultDpiSize.cx, pSplashScreen->defaultDpiSize.cy, SRCCOPY); |
| 375 | ::SelectObject(hdcMem, hDefaultBitmap); | 376 | ::SelectObject(hdcMem, hDefaultBitmap); |
| 376 | ::DeleteDC(hdcMem); | 377 | ::DeleteDC(hdcMem); |
diff --git a/src/burn/engine/variable.cpp b/src/burn/engine/variable.cpp index 9d0aec52..a795d76c 100644 --- a/src/burn/engine/variable.cpp +++ b/src/burn/engine/variable.cpp | |||
| @@ -397,7 +397,7 @@ extern "C" HRESULT VariablesParseFromXml( | |||
| 397 | hr = XmlGetAttributeEx(pixnNode, L"Type", &scz); | 397 | hr = XmlGetAttributeEx(pixnNode, L"Type", &scz); |
| 398 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Type."); | 398 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Type."); |
| 399 | 399 | ||
| 400 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"formatted", -1)) | 400 | if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"formatted", -1, FALSE)) |
| 401 | { | 401 | { |
| 402 | if (!fHidden) | 402 | if (!fHidden) |
| 403 | { | 403 | { |
| @@ -405,7 +405,7 @@ extern "C" HRESULT VariablesParseFromXml( | |||
| 405 | } | 405 | } |
| 406 | valueType = BURN_VARIANT_TYPE_FORMATTED; | 406 | valueType = BURN_VARIANT_TYPE_FORMATTED; |
| 407 | } | 407 | } |
| 408 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"numeric", -1)) | 408 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"numeric", -1, FALSE)) |
| 409 | { | 409 | { |
| 410 | if (!fHidden) | 410 | if (!fHidden) |
| 411 | { | 411 | { |
| @@ -413,7 +413,7 @@ extern "C" HRESULT VariablesParseFromXml( | |||
| 413 | } | 413 | } |
| 414 | valueType = BURN_VARIANT_TYPE_NUMERIC; | 414 | valueType = BURN_VARIANT_TYPE_NUMERIC; |
| 415 | } | 415 | } |
| 416 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"string", -1)) | 416 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"string", -1, FALSE)) |
| 417 | { | 417 | { |
| 418 | if (!fHidden) | 418 | if (!fHidden) |
| 419 | { | 419 | { |
| @@ -421,7 +421,7 @@ extern "C" HRESULT VariablesParseFromXml( | |||
| 421 | } | 421 | } |
| 422 | valueType = BURN_VARIANT_TYPE_STRING; | 422 | valueType = BURN_VARIANT_TYPE_STRING; |
| 423 | } | 423 | } |
| 424 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"version", -1)) | 424 | else if (CSTR_EQUAL == ::CompareStringOrdinal(scz, -1, L"version", -1, FALSE)) |
| 425 | { | 425 | { |
| 426 | if (!fHidden) | 426 | if (!fHidden) |
| 427 | { | 427 | { |
| @@ -1144,7 +1144,7 @@ extern "C" BOOL VariableIsHiddenCommandLine( | |||
| 1144 | { | 1144 | { |
| 1145 | pVariable = pVariables->rgVariables + i; | 1145 | pVariable = pVariables->rgVariables + i; |
| 1146 | 1146 | ||
| 1147 | if (pVariable->fHidden && CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pVariable->sczName, -1, wzVariable, -1)) | 1147 | if (pVariable->fHidden && CSTR_EQUAL == ::CompareStringOrdinal(pVariable->sczName, -1, wzVariable, -1, TRUE)) |
| 1148 | { | 1148 | { |
| 1149 | fHidden = TRUE; | 1149 | fHidden = TRUE; |
| 1150 | break; | 1150 | break; |
| @@ -1556,7 +1556,7 @@ static HRESULT FindVariableIndexByName( | |||
| 1556 | DWORD iPosition = cRangeLength / 2; | 1556 | DWORD iPosition = cRangeLength / 2; |
| 1557 | BURN_VARIABLE* pVariable = &pVariables->rgVariables[iRangeFirst + iPosition]; | 1557 | BURN_VARIABLE* pVariable = &pVariables->rgVariables[iRangeFirst + iPosition]; |
| 1558 | 1558 | ||
| 1559 | switch (::CompareStringW(LOCALE_INVARIANT, SORT_STRINGSORT, wzVariable, -1, pVariable->sczName, -1)) | 1559 | switch (::CompareStringOrdinal(wzVariable, -1, pVariable->sczName, -1, FALSE)) |
| 1560 | { | 1560 | { |
| 1561 | case CSTR_LESS_THAN: | 1561 | case CSTR_LESS_THAN: |
| 1562 | // restrict range to elements before the current | 1562 | // restrict range to elements before the current |
| @@ -1591,7 +1591,7 @@ static HRESULT InsertUserVariable( | |||
| 1591 | { | 1591 | { |
| 1592 | HRESULT hr = S_OK; | 1592 | HRESULT hr = S_OK; |
| 1593 | 1593 | ||
| 1594 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, wzVariable, 3, L"Wix", 3)) | 1594 | if (CSTR_EQUAL == ::CompareStringOrdinal(wzVariable, 3, L"Wix", 3, FALSE)) |
| 1595 | { | 1595 | { |
| 1596 | ExitWithRootFailure(hr, E_INVALIDARG, "Attempted to insert variable with reserved prefix: %ls", wzVariable); | 1596 | ExitWithRootFailure(hr, E_INVALIDARG, "Attempted to insert variable with reserved prefix: %ls", wzVariable); |
| 1597 | } | 1597 | } |
diff --git a/src/burn/engine/variant.cpp b/src/burn/engine/variant.cpp index 2267ee7b..3fc02aa8 100644 --- a/src/burn/engine/variant.cpp +++ b/src/burn/engine/variant.cpp | |||
| @@ -10,6 +10,9 @@ static HRESULT GetVersionInternal( | |||
| 10 | __in BOOL fSilent, | 10 | __in BOOL fSilent, |
| 11 | __out VERUTIL_VERSION** ppValue | 11 | __out VERUTIL_VERSION** ppValue |
| 12 | ); | 12 | ); |
| 13 | static void FreeVariantValue( | ||
| 14 | __in BURN_VARIANT* pVariant | ||
| 15 | ); | ||
| 13 | 16 | ||
| 14 | // function definitions | 17 | // function definitions |
| 15 | 18 | ||
| @@ -17,12 +20,7 @@ extern "C" void BVariantUninitialize( | |||
| 17 | __in BURN_VARIANT* pVariant | 20 | __in BURN_VARIANT* pVariant |
| 18 | ) | 21 | ) |
| 19 | { | 22 | { |
| 20 | if (BURN_VARIANT_TYPE_FORMATTED == pVariant->Type || | 23 | FreeVariantValue(pVariant); |
| 21 | BURN_VARIANT_TYPE_STRING == pVariant->Type) | ||
| 22 | { | ||
| 23 | StrSecureZeroFreeString(pVariant->sczValue); | ||
| 24 | } | ||
| 25 | SecureZeroMemory(pVariant, sizeof(BURN_VARIANT)); | ||
| 26 | } | 24 | } |
| 27 | 25 | ||
| 28 | extern "C" HRESULT BVariantGetNumeric( | 26 | extern "C" HRESULT BVariantGetNumeric( |
| @@ -164,12 +162,8 @@ extern "C" HRESULT BVariantSetNumeric( | |||
| 164 | { | 162 | { |
| 165 | HRESULT hr = S_OK; | 163 | HRESULT hr = S_OK; |
| 166 | 164 | ||
| 167 | if (BURN_VARIANT_TYPE_FORMATTED == pVariant->Type || | 165 | FreeVariantValue(pVariant); |
| 168 | BURN_VARIANT_TYPE_STRING == pVariant->Type) | 166 | |
| 169 | { | ||
| 170 | StrSecureZeroFreeString(pVariant->sczValue); | ||
| 171 | } | ||
| 172 | memset(pVariant, 0, sizeof(BURN_VARIANT)); | ||
| 173 | pVariant->llValue = llValue; | 167 | pVariant->llValue = llValue; |
| 174 | pVariant->Type = BURN_VARIANT_TYPE_NUMERIC; | 168 | pVariant->Type = BURN_VARIANT_TYPE_NUMERIC; |
| 175 | 169 | ||
| @@ -194,7 +188,7 @@ extern "C" HRESULT BVariantSetString( | |||
| 194 | if (BURN_VARIANT_TYPE_FORMATTED != pVariant->Type && | 188 | if (BURN_VARIANT_TYPE_FORMATTED != pVariant->Type && |
| 195 | BURN_VARIANT_TYPE_STRING != pVariant->Type) | 189 | BURN_VARIANT_TYPE_STRING != pVariant->Type) |
| 196 | { | 190 | { |
| 197 | memset(pVariant, 0, sizeof(BURN_VARIANT)); | 191 | FreeVariantValue(pVariant); |
| 198 | } | 192 | } |
| 199 | 193 | ||
| 200 | hr = StrAllocStringSecure(&pVariant->sczValue, wzValue, cchValue); | 194 | hr = StrAllocStringSecure(&pVariant->sczValue, wzValue, cchValue); |
| @@ -220,12 +214,8 @@ extern "C" HRESULT BVariantSetVersion( | |||
| 220 | } | 214 | } |
| 221 | else // assign the value. | 215 | else // assign the value. |
| 222 | { | 216 | { |
| 223 | if (BURN_VARIANT_TYPE_FORMATTED == pVariant->Type || | 217 | FreeVariantValue(pVariant); |
| 224 | BURN_VARIANT_TYPE_STRING == pVariant->Type) | 218 | |
| 225 | { | ||
| 226 | StrSecureZeroFreeString(pVariant->sczValue); | ||
| 227 | } | ||
| 228 | memset(pVariant, 0, sizeof(BURN_VARIANT)); | ||
| 229 | hr = VerCopyVersion(pValue, &pVariant->pValue); | 219 | hr = VerCopyVersion(pValue, &pVariant->pValue); |
| 230 | pVariant->Type = BURN_VARIANT_TYPE_VERSION; | 220 | pVariant->Type = BURN_VARIANT_TYPE_VERSION; |
| 231 | } | 221 | } |
| @@ -319,3 +309,20 @@ extern "C" HRESULT BVariantChangeType( | |||
| 319 | LExit: | 309 | LExit: |
| 320 | return hr; | 310 | return hr; |
| 321 | } | 311 | } |
| 312 | |||
| 313 | static void FreeVariantValue( | ||
| 314 | __in BURN_VARIANT* pVariant | ||
| 315 | ) | ||
| 316 | { | ||
| 317 | if ((BURN_VARIANT_TYPE_FORMATTED == pVariant->Type || BURN_VARIANT_TYPE_STRING == pVariant->Type) && | ||
| 318 | pVariant->sczValue) | ||
| 319 | { | ||
| 320 | StrSecureZeroFreeString(pVariant->sczValue); | ||
| 321 | } | ||
| 322 | else if (BURN_VARIANT_TYPE_VERSION == pVariant->Type && pVariant->pValue) | ||
| 323 | { | ||
| 324 | VerFreeVersion(pVariant->pValue); | ||
| 325 | } | ||
| 326 | |||
| 327 | SecureZeroMemory(pVariant, sizeof(BURN_VARIANT)); | ||
| 328 | } | ||
diff --git a/src/burn/stub/WixToolset.Burn.props b/src/burn/stub/WixToolset.Burn.props index 38cd333e..debcffd0 100644 --- a/src/burn/stub/WixToolset.Burn.props +++ b/src/burn/stub/WixToolset.Burn.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 xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> | 4 | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
| 5 | <ItemGroup> | 5 | <ItemGroup> |
| 6 | <BurnExes Include="$(MSBuildThisFileDirectory)..\tools\**\burn.exe" /> | 6 | <BurnExes Include="$(MSBuildThisFileDirectory)..\tools\**\burn.exe" /> |
| 7 | <None Include="@(BurnExes)"> | 7 | <None Include="@(BurnExes)"> |
diff --git a/src/burn/stub/precomp.h b/src/burn/stub/precomp.h index 46239a6c..b72cd012 100644 --- a/src/burn/stub/precomp.h +++ b/src/burn/stub/precomp.h | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <strutil.h> | 13 | #include <strutil.h> |
| 14 | #include <fileutil.h> | 14 | #include <fileutil.h> |
| 15 | #include <pathutil.h> | 15 | #include <pathutil.h> |
| 16 | #include <polcutil.h> | ||
| 16 | #include <logutil.h> | 17 | #include <logutil.h> |
| 17 | 18 | ||
| 18 | #include "engine.h" | 19 | #include "engine.h" |
diff --git a/src/burn/stub/stub.cpp b/src/burn/stub/stub.cpp index d8cee9f1..ea5d88f0 100644 --- a/src/burn/stub/stub.cpp +++ b/src/burn/stub/stub.cpp | |||
| @@ -34,6 +34,8 @@ int WINAPI wWinMain( | |||
| 34 | L"feclient.dll", // unsafely loaded by DecryptFile(). | 34 | L"feclient.dll", // unsafely loaded by DecryptFile(). |
| 35 | }; | 35 | }; |
| 36 | 36 | ||
| 37 | AppSetDefaultProcessMitigationPolicy(POLICY_BURN_REGISTRY_PATH); | ||
| 38 | |||
| 37 | // Best effort attempt to get our file handle as soon as possible. | 39 | // Best effort attempt to get our file handle as soon as possible. |
| 38 | hr = PathForCurrentProcess(&sczPath, NULL); | 40 | hr = PathForCurrentProcess(&sczPath, NULL); |
| 39 | if (SUCCEEDED(hr)) | 41 | if (SUCCEEDED(hr)) |
diff --git a/src/burn/stub/stub.vcxproj b/src/burn/stub/stub.vcxproj index d07b8da7..54825b95 100644 --- a/src/burn/stub/stub.vcxproj +++ b/src/burn/stub/stub.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|Win32"> | 6 | <ProjectConfiguration Include="Debug|Win32"> |
| 7 | <Configuration>Debug</Configuration> | 7 | <Configuration>Debug</Configuration> |
diff --git a/src/burn/test/BurnUnitTest/ApprovedExeTest.cpp b/src/burn/test/BurnUnitTest/ApprovedExeTest.cpp new file mode 100644 index 00000000..da51f1f8 --- /dev/null +++ b/src/burn/test/BurnUnitTest/ApprovedExeTest.cpp | |||
| @@ -0,0 +1,312 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | #include "precomp.h" | ||
| 4 | |||
| 5 | namespace Microsoft | ||
| 6 | { | ||
| 7 | namespace Tools | ||
| 8 | { | ||
| 9 | namespace WindowsInstallerXml | ||
| 10 | { | ||
| 11 | namespace Test | ||
| 12 | { | ||
| 13 | namespace Bootstrapper | ||
| 14 | { | ||
| 15 | using namespace System; | ||
| 16 | using namespace System::IO; | ||
| 17 | using namespace Xunit; | ||
| 18 | |||
| 19 | public ref class ApprovedExeTest : BurnUnitTest | ||
| 20 | { | ||
| 21 | public: | ||
| 22 | ApprovedExeTest(BurnTestFixture^ fixture) : BurnUnitTest(fixture) | ||
| 23 | { | ||
| 24 | } | ||
| 25 | |||
| 26 | [Fact] | ||
| 27 | void ApprovedExesVerifyPFilesTest() | ||
| 28 | { | ||
| 29 | HRESULT hr = S_OK; | ||
| 30 | BURN_CACHE cache = { }; | ||
| 31 | BURN_ENGINE_COMMAND internalCommand = { }; | ||
| 32 | BURN_VARIABLES variables = { }; | ||
| 33 | LPWSTR scz = NULL; | ||
| 34 | LPWSTR scz2 = NULL; | ||
| 35 | |||
| 36 | try | ||
| 37 | { | ||
| 38 | hr = VariableInitialize(&variables); | ||
| 39 | NativeAssert::Succeeded(hr, L"Failed to initialize variables."); | ||
| 40 | |||
| 41 | hr = CacheInitialize(&cache, &internalCommand); | ||
| 42 | NativeAssert::Succeeded(hr, "Failed to initialize cache."); | ||
| 43 | |||
| 44 | hr = VariableGetString(&variables, L"ProgramFilesFolder", &scz); | ||
| 45 | NativeAssert::Succeeded(hr, "Failed to get variable ProgramFilesFolder."); | ||
| 46 | |||
| 47 | hr = PathConcat(scz, L"a.exe", &scz2); | ||
| 48 | NativeAssert::Succeeded(hr, "Failed to combine paths"); | ||
| 49 | |||
| 50 | hr = ApprovedExesVerifySecureLocation(&cache, &variables, scz2, 0, NULL); | ||
| 51 | NativeAssert::Succeeded(hr, "Failed to test secure location under ProgramFilesFolder"); | ||
| 52 | Assert::True((hr == S_OK), "Path under ProgramFilesFolder was expected to be safe"); | ||
| 53 | } | ||
| 54 | finally | ||
| 55 | { | ||
| 56 | ReleaseStr(internalCommand.sczEngineWorkingDirectory); | ||
| 57 | ReleaseStr(scz); | ||
| 58 | ReleaseStr(scz2); | ||
| 59 | |||
| 60 | CacheUninitialize(&cache); | ||
| 61 | VariablesUninitialize(&variables); | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 65 | [Fact] | ||
| 66 | void ApprovedExesVerifyPFilesWithRelativeTest() | ||
| 67 | { | ||
| 68 | HRESULT hr = S_OK; | ||
| 69 | BURN_CACHE cache = { }; | ||
| 70 | BURN_ENGINE_COMMAND internalCommand = { }; | ||
| 71 | BURN_VARIABLES variables = { }; | ||
| 72 | LPWSTR scz = NULL; | ||
| 73 | LPWSTR scz2 = NULL; | ||
| 74 | |||
| 75 | try | ||
| 76 | { | ||
| 77 | hr = VariableInitialize(&variables); | ||
| 78 | NativeAssert::Succeeded(hr, L"Failed to initialize variables."); | ||
| 79 | |||
| 80 | hr = CacheInitialize(&cache, &internalCommand); | ||
| 81 | NativeAssert::Succeeded(hr, "Failed to initialize cache."); | ||
| 82 | cache.fPerMachineCacheRootVerified = TRUE; | ||
| 83 | cache.fOriginalPerMachineCacheRootVerified = TRUE; | ||
| 84 | |||
| 85 | hr = VariableGetString(&variables, L"ProgramFilesFolder", &scz); | ||
| 86 | NativeAssert::Succeeded(hr, "Failed to get variable ProgramFilesFolder."); | ||
| 87 | |||
| 88 | hr = PathConcat(scz, L"..\\a.exe", &scz2); | ||
| 89 | NativeAssert::Succeeded(hr, "Failed to combine paths"); | ||
| 90 | |||
| 91 | hr = ApprovedExesVerifySecureLocation(&cache, &variables, scz2, 0, NULL); | ||
| 92 | NativeAssert::Succeeded(hr, "Failed to test secure location under ProgramFilesFolder"); | ||
| 93 | Assert::True((hr == S_FALSE), "Path pretending to be under ProgramFilesFolder was expected to be unsafe"); | ||
| 94 | } | ||
| 95 | finally | ||
| 96 | { | ||
| 97 | ReleaseStr(internalCommand.sczEngineWorkingDirectory); | ||
| 98 | ReleaseStr(scz); | ||
| 99 | ReleaseStr(scz2); | ||
| 100 | |||
| 101 | CacheUninitialize(&cache); | ||
| 102 | VariablesUninitialize(&variables); | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | [Fact] | ||
| 107 | void ApprovedExesVerifyPFiles64Test() | ||
| 108 | { | ||
| 109 | HRESULT hr = S_OK; | ||
| 110 | BURN_CACHE cache = { }; | ||
| 111 | BURN_ENGINE_COMMAND internalCommand = { }; | ||
| 112 | BURN_VARIABLES variables = { }; | ||
| 113 | LPWSTR scz = NULL; | ||
| 114 | LPWSTR scz2 = NULL; | ||
| 115 | |||
| 116 | try | ||
| 117 | { | ||
| 118 | hr = VariableInitialize(&variables); | ||
| 119 | NativeAssert::Succeeded(hr, L"Failed to initialize variables."); | ||
| 120 | |||
| 121 | hr = CacheInitialize(&cache, &internalCommand); | ||
| 122 | NativeAssert::Succeeded(hr, "Failed to initialize cache."); | ||
| 123 | |||
| 124 | hr = VariableGetString(&variables, L"ProgramFiles64Folder", &scz); | ||
| 125 | NativeAssert::Succeeded(hr, "Failed to get variable ProgramFiles64Folder."); | ||
| 126 | |||
| 127 | hr = PathConcat(scz, L"a.exe", &scz2); | ||
| 128 | NativeAssert::Succeeded(hr, "Failed to combine paths"); | ||
| 129 | |||
| 130 | hr = ApprovedExesVerifySecureLocation(&cache, &variables, scz2, 0, NULL); | ||
| 131 | NativeAssert::Succeeded(hr, "Failed to test secure location under ProgramFiles64Folder"); | ||
| 132 | Assert::True((hr == S_OK), "Path under ProgramFiles64Folder was expected to be safe"); | ||
| 133 | } | ||
| 134 | finally | ||
| 135 | { | ||
| 136 | ReleaseStr(internalCommand.sczEngineWorkingDirectory); | ||
| 137 | ReleaseStr(scz); | ||
| 138 | ReleaseStr(scz2); | ||
| 139 | |||
| 140 | CacheUninitialize(&cache); | ||
| 141 | VariablesUninitialize(&variables); | ||
| 142 | } | ||
| 143 | } | ||
| 144 | |||
| 145 | [Fact] | ||
| 146 | void ApprovedExesVerifySys64FolderTest() | ||
| 147 | { | ||
| 148 | HRESULT hr = S_OK; | ||
| 149 | BURN_CACHE cache = { }; | ||
| 150 | BURN_ENGINE_COMMAND internalCommand = { }; | ||
| 151 | BURN_VARIABLES variables = { }; | ||
| 152 | LPWSTR scz = NULL; | ||
| 153 | LPWSTR scz2 = NULL; | ||
| 154 | |||
| 155 | try | ||
| 156 | { | ||
| 157 | hr = VariableInitialize(&variables); | ||
| 158 | NativeAssert::Succeeded(hr, L"Failed to initialize variables."); | ||
| 159 | |||
| 160 | hr = CacheInitialize(&cache, &internalCommand); | ||
| 161 | NativeAssert::Succeeded(hr, "Failed to initialize cache."); | ||
| 162 | cache.fPerMachineCacheRootVerified = TRUE; | ||
| 163 | cache.fOriginalPerMachineCacheRootVerified = TRUE; | ||
| 164 | |||
| 165 | hr = VariableGetString(&variables, L"System64Folder", &scz); | ||
| 166 | NativeAssert::Succeeded(hr, "Failed to get variable System64Folder."); | ||
| 167 | |||
| 168 | hr = PathConcat(scz, L"a.exe", &scz2); | ||
| 169 | NativeAssert::Succeeded(hr, "Failed to combine paths"); | ||
| 170 | |||
| 171 | hr = ApprovedExesVerifySecureLocation(&cache, &variables, scz2, 0, NULL); | ||
| 172 | NativeAssert::Succeeded(hr, "Failed to test secure location under System64Folder"); | ||
| 173 | Assert::True((hr == S_FALSE), "Path under System64Folder was expected to be unsafe"); | ||
| 174 | } | ||
| 175 | finally | ||
| 176 | { | ||
| 177 | ReleaseStr(internalCommand.sczEngineWorkingDirectory); | ||
| 178 | ReleaseStr(scz); | ||
| 179 | ReleaseStr(scz2); | ||
| 180 | |||
| 181 | CacheUninitialize(&cache); | ||
| 182 | VariablesUninitialize(&variables); | ||
| 183 | } | ||
| 184 | } | ||
| 185 | |||
| 186 | [Fact] | ||
| 187 | void ApprovedExesVerifySys64Rundll32UnsafeTest() | ||
| 188 | { | ||
| 189 | HRESULT hr = S_OK; | ||
| 190 | BURN_CACHE cache = { }; | ||
| 191 | BURN_ENGINE_COMMAND internalCommand = { }; | ||
| 192 | BURN_VARIABLES variables = { }; | ||
| 193 | LPWSTR scz = NULL; | ||
| 194 | LPWSTR scz2 = NULL; | ||
| 195 | LPWSTR szArgs = NULL; | ||
| 196 | |||
| 197 | try | ||
| 198 | { | ||
| 199 | hr = VariableInitialize(&variables); | ||
| 200 | NativeAssert::Succeeded(hr, L"Failed to initialize variables."); | ||
| 201 | |||
| 202 | hr = CacheInitialize(&cache, &internalCommand); | ||
| 203 | NativeAssert::Succeeded(hr, "Failed to initialize cache."); | ||
| 204 | cache.fPerMachineCacheRootVerified = TRUE; | ||
| 205 | cache.fOriginalPerMachineCacheRootVerified = TRUE; | ||
| 206 | |||
| 207 | hr = VariableGetString(&variables, L"System64Folder", &scz); | ||
| 208 | NativeAssert::Succeeded(hr, "Failed to get variable System64Folder."); | ||
| 209 | |||
| 210 | hr = PathConcat(scz, L"rundll32.exe", &scz2); | ||
| 211 | NativeAssert::Succeeded(hr, "Failed to combine paths"); | ||
| 212 | |||
| 213 | hr = ApprovedExesVerifySecureLocation(&cache, &variables, scz2, 1, const_cast<LPCWSTR*>(&scz2)); | ||
| 214 | NativeAssert::Succeeded(hr, "Failed to test secure location under System64Folder"); | ||
| 215 | Assert::True((hr == S_FALSE), "Path under System64Folder was expected to be unsafe for rundll32 target"); | ||
| 216 | } | ||
| 217 | finally | ||
| 218 | { | ||
| 219 | ReleaseStr(internalCommand.sczEngineWorkingDirectory); | ||
| 220 | ReleaseStr(scz); | ||
| 221 | ReleaseStr(scz2); | ||
| 222 | ReleaseStr(szArgs); | ||
| 223 | |||
| 224 | CacheUninitialize(&cache); | ||
| 225 | VariablesUninitialize(&variables); | ||
| 226 | } | ||
| 227 | } | ||
| 228 | |||
| 229 | [Fact] | ||
| 230 | void ApprovedExesVerifySys64Rundll32SafeTest() | ||
| 231 | { | ||
| 232 | HRESULT hr = S_OK; | ||
| 233 | BURN_CACHE cache = { }; | ||
| 234 | BURN_ENGINE_COMMAND internalCommand = { }; | ||
| 235 | BURN_VARIABLES variables = { }; | ||
| 236 | LPWSTR scz = NULL; | ||
| 237 | LPWSTR scz2 = NULL; | ||
| 238 | LPWSTR scz3 = NULL; | ||
| 239 | |||
| 240 | try | ||
| 241 | { | ||
| 242 | hr = VariableInitialize(&variables); | ||
| 243 | NativeAssert::Succeeded(hr, L"Failed to initialize variables."); | ||
| 244 | |||
| 245 | hr = CacheInitialize(&cache, &internalCommand); | ||
| 246 | NativeAssert::Succeeded(hr, "Failed to initialize cache."); | ||
| 247 | cache.fPerMachineCacheRootVerified = TRUE; | ||
| 248 | cache.fOriginalPerMachineCacheRootVerified = TRUE; | ||
| 249 | |||
| 250 | // System64Folder | ||
| 251 | hr = VariableGetString(&variables, L"System64Folder", &scz); | ||
| 252 | NativeAssert::Succeeded(hr, "Failed to get variable System64Folder."); | ||
| 253 | |||
| 254 | hr = PathConcat(scz, L"rundll32.exe", &scz2); | ||
| 255 | NativeAssert::Succeeded(hr, "Failed to combine paths"); | ||
| 256 | |||
| 257 | hr = VariableGetString(&variables, L"ProgramFiles64Folder", &scz); | ||
| 258 | NativeAssert::Succeeded(hr, "Failed to get variable ProgramFiles64Folder."); | ||
| 259 | |||
| 260 | hr = PathConcat(scz, L"a.dll", &scz3); | ||
| 261 | NativeAssert::Succeeded(hr, "Failed to combine paths"); | ||
| 262 | |||
| 263 | hr = ApprovedExesVerifySecureLocation(&cache, &variables, scz2, 1, const_cast<LPCWSTR*>(&scz3)); | ||
| 264 | NativeAssert::Succeeded(hr, "Failed to test secure location under ProgramFiles64Folder for System64Folder/rundll32 target"); | ||
| 265 | Assert::True((hr == S_OK), "Path under ProgramFiles64Folder was expected to be safe for System64Folder/rundll32 target"); | ||
| 266 | |||
| 267 | hr = PathConcat(scz, L"a.dll,somthing else", &scz3); | ||
| 268 | NativeAssert::Succeeded(hr, "Failed to combine paths"); | ||
| 269 | |||
| 270 | hr = ApprovedExesVerifySecureLocation(&cache, &variables, scz2, 1, const_cast<LPCWSTR*>(&scz3)); | ||
| 271 | NativeAssert::Succeeded(hr, "Failed to test secure location under ProgramFiles64Folder for rundll32 target"); | ||
| 272 | Assert::True((hr == S_OK), "Path under ProgramFiles64Folder was expected to be safe for System64Folder/rundll32 target"); | ||
| 273 | |||
| 274 | // SystemFolder | ||
| 275 | hr = VariableGetString(&variables, L"SystemFolder", &scz); | ||
| 276 | NativeAssert::Succeeded(hr, "Failed to get variable System64Folder."); | ||
| 277 | |||
| 278 | hr = PathConcat(scz, L"rundll32.exe", &scz2); | ||
| 279 | NativeAssert::Succeeded(hr, "Failed to combine paths"); | ||
| 280 | |||
| 281 | hr = ApprovedExesVerifySecureLocation(&cache, &variables, scz2, 1, const_cast<LPCWSTR*>(&scz3)); | ||
| 282 | NativeAssert::Succeeded(hr, "Failed to test secure location under ProgramFiles64Folder for SystemFolder/rundll32 target"); | ||
| 283 | Assert::True((hr == S_OK), "Path under ProgramFiles64Folder was expected to be safe for SystemFolder/rundll32 target"); | ||
| 284 | |||
| 285 | // Sysnative | ||
| 286 | hr = PathSystemWindowsSubdirectory(L"SysNative\\", &scz); | ||
| 287 | NativeAssert::Succeeded(hr, "Failed to get SysNative Folder."); | ||
| 288 | |||
| 289 | hr = PathConcat(scz, L"rundll32.exe", &scz2); | ||
| 290 | NativeAssert::Succeeded(hr, "Failed to combine paths"); | ||
| 291 | |||
| 292 | hr = ApprovedExesVerifySecureLocation(&cache, &variables, scz2, 1, const_cast<LPCWSTR*>(&scz3)); | ||
| 293 | NativeAssert::Succeeded(hr, "Failed to test secure location under ProgramFiles64Folder for Sysnative/rundll32 target"); | ||
| 294 | Assert::True((hr == S_OK), "Path under ProgramFiles64Folder was expected to be safe for Sysnative/rundll32 target"); | ||
| 295 | } | ||
| 296 | finally | ||
| 297 | { | ||
| 298 | ReleaseStr(internalCommand.sczEngineWorkingDirectory); | ||
| 299 | ReleaseStr(scz); | ||
| 300 | ReleaseStr(scz2); | ||
| 301 | ReleaseStr(scz3); | ||
| 302 | |||
| 303 | CacheUninitialize(&cache); | ||
| 304 | VariablesUninitialize(&variables); | ||
| 305 | } | ||
| 306 | } | ||
| 307 | }; | ||
| 308 | } | ||
| 309 | } | ||
| 310 | } | ||
| 311 | } | ||
| 312 | } | ||
diff --git a/src/burn/test/BurnUnitTest/BurnUnitTest.vcxproj b/src/burn/test/BurnUnitTest/BurnUnitTest.vcxproj index 331d237b..9704efa5 100644 --- a/src/burn/test/BurnUnitTest/BurnUnitTest.vcxproj +++ b/src/burn/test/BurnUnitTest/BurnUnitTest.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"> |
| @@ -45,6 +45,7 @@ | |||
| 45 | 45 | ||
| 46 | <ItemGroup> | 46 | <ItemGroup> |
| 47 | <ClCompile Include="AssemblyInfo.cpp" /> | 47 | <ClCompile Include="AssemblyInfo.cpp" /> |
| 48 | <ClCompile Include="ApprovedExeTest.cpp" /> | ||
| 48 | <ClCompile Include="CacheTest.cpp" /> | 49 | <ClCompile Include="CacheTest.cpp" /> |
| 49 | <ClCompile Include="ElevationTest.cpp" /> | 50 | <ClCompile Include="ElevationTest.cpp" /> |
| 50 | <ClCompile Include="EmbeddedTest.cpp" /> | 51 | <ClCompile Include="EmbeddedTest.cpp" /> |
diff --git a/src/burn/test/BurnUnitTest/BurnUnitTest.vcxproj.filters b/src/burn/test/BurnUnitTest/BurnUnitTest.vcxproj.filters index 82725436..aac5ab8b 100644 --- a/src/burn/test/BurnUnitTest/BurnUnitTest.vcxproj.filters +++ b/src/burn/test/BurnUnitTest/BurnUnitTest.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> |
| @@ -66,6 +66,9 @@ | |||
| 66 | <ClCompile Include="VariantTest.cpp"> | 66 | <ClCompile Include="VariantTest.cpp"> |
| 67 | <Filter>Source Files</Filter> | 67 | <Filter>Source Files</Filter> |
| 68 | </ClCompile> | 68 | </ClCompile> |
| 69 | <ClCompile Include="ApprovedExeTest.cpp"> | ||
| 70 | <Filter>Source Files</Filter> | ||
| 71 | </ClCompile> | ||
| 69 | </ItemGroup> | 72 | </ItemGroup> |
| 70 | <ItemGroup> | 73 | <ItemGroup> |
| 71 | <ClInclude Include="BurnTestException.h"> | 74 | <ClInclude Include="BurnTestException.h"> |
| @@ -95,4 +98,4 @@ | |||
| 95 | <Filter>Resource Files</Filter> | 98 | <Filter>Resource Files</Filter> |
| 96 | </ResourceCompile> | 99 | </ResourceCompile> |
| 97 | </ItemGroup> | 100 | </ItemGroup> |
| 98 | </Project> \ No newline at end of file | 101 | </Project> |
diff --git a/src/burn/test/BurnUnitTest/PlanTest.cpp b/src/burn/test/BurnUnitTest/PlanTest.cpp index e426cb09..e2850a62 100644 --- a/src/burn/test/BurnUnitTest/PlanTest.cpp +++ b/src/burn/test/BurnUnitTest/PlanTest.cpp | |||
| @@ -2990,6 +2990,18 @@ namespace Bootstrapper | |||
| 2990 | ValidateNonPermanentPackageExpectedStates(&pEngineState->packages.rgPackages[1], L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, BURN_PACKAGE_REGISTRATION_STATE_PRESENT); | 2990 | ValidateNonPermanentPackageExpectedStates(&pEngineState->packages.rgPackages[1], L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, BURN_PACKAGE_REGISTRATION_STATE_PRESENT); |
| 2991 | } | 2991 | } |
| 2992 | 2992 | ||
| 2993 | [Fact] | ||
| 2994 | void ValidateCacheVariables() | ||
| 2995 | { | ||
| 2996 | BURN_ENGINE_STATE engineState = { }; | ||
| 2997 | BURN_ENGINE_STATE* pEngineState = &engineState; | ||
| 2998 | |||
| 2999 | InitializeEngineStateForCorePlan(wzSlipstreamModifiedManifestFileName, pEngineState); | ||
| 3000 | |||
| 3001 | Assert::EndsWith(gcnew String(L".exe"), VariableGetStringHelper(&pEngineState->variables, BURN_BUNDLE_SOURCE_PROCESS_PATH)); | ||
| 3002 | Assert::EndsWith(gcnew String(L"\\"), VariableGetStringHelper(&pEngineState->variables, BURN_BUNDLE_SOURCE_PROCESS_FOLDER)); | ||
| 3003 | } | ||
| 3004 | |||
| 2993 | private: | 3005 | private: |
| 2994 | // This doesn't initialize everything, just enough for CorePlan to work. | 3006 | // This doesn't initialize everything, just enough for CorePlan to work. |
| 2995 | void InitializeEngineStateForCorePlan(LPCWSTR wzManifestFileName, BURN_ENGINE_STATE* pEngineState) | 3007 | void InitializeEngineStateForCorePlan(LPCWSTR wzManifestFileName, BURN_ENGINE_STATE* pEngineState) |
| @@ -3149,12 +3161,12 @@ namespace Bootstrapper | |||
| 3149 | 3161 | ||
| 3150 | if (pDependencies->fSelfDependent || pDependencies->fActiveParent) | 3162 | if (pDependencies->fSelfDependent || pDependencies->fActiveParent) |
| 3151 | { | 3163 | { |
| 3152 | if (pDependencies->fActiveParent && CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pDependencies->wzActiveParent, -1, wzId, -1)) | 3164 | if (pDependencies->fActiveParent && CSTR_EQUAL == ::CompareStringOrdinal(pDependencies->wzActiveParent, -1, wzId, -1, TRUE)) |
| 3153 | { | 3165 | { |
| 3154 | pRegistration->fParentRegisteredAsDependent = TRUE; | 3166 | pRegistration->fParentRegisteredAsDependent = TRUE; |
| 3155 | } | 3167 | } |
| 3156 | 3168 | ||
| 3157 | if (pDependencies->fSelfDependent && CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pDependencies->wzSelfDependent, -1, wzId, -1)) | 3169 | if (pDependencies->fSelfDependent && CSTR_EQUAL == ::CompareStringOrdinal(pDependencies->wzSelfDependent, -1, wzId, -1, TRUE)) |
| 3158 | { | 3170 | { |
| 3159 | pRegistration->fSelfRegisteredAsDependent = TRUE; | 3171 | pRegistration->fSelfRegisteredAsDependent = TRUE; |
| 3160 | } | 3172 | } |
diff --git a/src/burn/test/BurnUnitTest/SearchTest.cpp b/src/burn/test/BurnUnitTest/SearchTest.cpp index a8e397c2..e3c714cb 100644 --- a/src/burn/test/BurnUnitTest/SearchTest.cpp +++ b/src/burn/test/BurnUnitTest/SearchTest.cpp | |||
| @@ -410,6 +410,8 @@ namespace Bootstrapper | |||
| 410 | L" <MsiProductSearch Id='Search4' Type='state' ProductCode='{600D0000-0000-0000-0000-000000000000}' Variable='Variable4' />" | 410 | L" <MsiProductSearch Id='Search4' Type='state' ProductCode='{600D0000-0000-0000-0000-000000000000}' Variable='Variable4' />" |
| 411 | L" <MsiProductSearch Id='Search5' Type='assignment' ProductCode='{600D0000-0000-0000-0000-000000000000}' Variable='Variable5' />" | 411 | L" <MsiProductSearch Id='Search5' Type='assignment' ProductCode='{600D0000-0000-0000-0000-000000000000}' Variable='Variable5' />" |
| 412 | L" <MsiProductSearch Id='Search6' Type='version' ProductCode='{600D0000-1000-0000-0000-000000000000}' Variable='Variable6' />" | 412 | L" <MsiProductSearch Id='Search6' Type='version' ProductCode='{600D0000-1000-0000-0000-000000000000}' Variable='Variable6' />" |
| 413 | L" <MsiProductSearch Id='Search7' Type='exists' ProductCode='{600D0000-0000-0000-0000-000000000000}' Variable='Variable7' />" | ||
| 414 | L" <MsiProductSearch Id='Search8' Type='exists' ProductCode='{BAD00000-0000-0000-0000-000000000000}' Variable='Variable8' />" | ||
| 413 | L"</Bundle>"; | 415 | L"</Bundle>"; |
| 414 | 416 | ||
| 415 | // load XML document | 417 | // load XML document |
| @@ -429,6 +431,8 @@ namespace Bootstrapper | |||
| 429 | Assert::Equal(5ll, VariableGetNumericHelper(&variables, L"Variable4")); | 431 | Assert::Equal(5ll, VariableGetNumericHelper(&variables, L"Variable4")); |
| 430 | Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable5")); | 432 | Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable5")); |
| 431 | Assert::Equal<String^>(gcnew String(L"1.0.0.0"), VariableGetVersionHelper(&variables, L"Variable6")); | 433 | Assert::Equal<String^>(gcnew String(L"1.0.0.0"), VariableGetVersionHelper(&variables, L"Variable6")); |
| 434 | Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable7")); | ||
| 435 | Assert::Equal(0ll, VariableGetNumericHelper(&variables, L"Variable8")); | ||
| 432 | } | 436 | } |
| 433 | finally | 437 | finally |
| 434 | { | 438 | { |
diff --git a/src/burn/test/BurnUnitTest/precomp.h b/src/burn/test/BurnUnitTest/precomp.h index f07f5968..ec6fb7d1 100644 --- a/src/burn/test/BurnUnitTest/precomp.h +++ b/src/burn/test/BurnUnitTest/precomp.h | |||
| @@ -74,6 +74,7 @@ | |||
| 74 | #include "splashscreen.h" | 74 | #include "splashscreen.h" |
| 75 | #include "detect.h" | 75 | #include "detect.h" |
| 76 | #include "externalengine.h" | 76 | #include "externalengine.h" |
| 77 | #include "approvedexe.h" | ||
| 77 | 78 | ||
| 78 | #include "engine.version.h" | 79 | #include "engine.version.h" |
| 79 | 80 | ||
