aboutsummaryrefslogtreecommitdiff
path: root/src/burn
diff options
context:
space:
mode:
authorJacob Hoover <jacob.hoover@greenheck.com>2021-06-11 17:05:06 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-07-18 14:41:21 -0500
commitf3c96bcab560cb09355e9366eac3f4195479d95d (patch)
tree1585c1f2af7e3582e14663c29c033702e910d12f /src/burn
parent5b2b06c9bffb4e6f17409cec41bc0b4b8dab4c90 (diff)
downloadwix-f3c96bcab560cb09355e9366eac3f4195479d95d.tar.gz
wix-f3c96bcab560cb09355e9366eac3f4195479d95d.tar.bz2
wix-f3c96bcab560cb09355e9366eac3f4195479d95d.zip
Allow access to persisted variables from related bundles.
Implements #3704
Diffstat (limited to 'src/burn')
-rw-r--r--src/burn/engine/registration.cpp92
-rw-r--r--src/burn/test/BurnUnitTest/RegistrationTest.cpp178
-rw-r--r--src/burn/test/BurnUnitTest/precomp.h1
3 files changed, 262 insertions, 9 deletions
diff --git a/src/burn/engine/registration.cpp b/src/burn/engine/registration.cpp
index eed1fee2..4088004d 100644
--- a/src/burn/engine/registration.cpp
+++ b/src/burn/engine/registration.cpp
@@ -32,6 +32,7 @@ const LPCWSTR REGISTRY_BUNDLE_RESUME_COMMAND_LINE = L"BundleResumeCommandLine";
32const LPCWSTR REGISTRY_BUNDLE_VERSION_MAJOR = L"VersionMajor"; 32const LPCWSTR REGISTRY_BUNDLE_VERSION_MAJOR = L"VersionMajor";
33const LPCWSTR REGISTRY_BUNDLE_VERSION_MINOR = L"VersionMinor"; 33const LPCWSTR REGISTRY_BUNDLE_VERSION_MINOR = L"VersionMinor";
34const LPCWSTR SWIDTAG_FOLDER = L"swidtag"; 34const LPCWSTR SWIDTAG_FOLDER = L"swidtag";
35const LPCWSTR REGISTRY_BUNDLE_VARIABLE_KEY = L"variables";
35 36
36// internal function declarations 37// internal function declarations
37 38
@@ -909,6 +910,7 @@ extern "C" HRESULT RegistrationSessionEnd(
909{ 910{
910 HRESULT hr = S_OK; 911 HRESULT hr = S_OK;
911 LPWSTR sczRebootRequiredKey = NULL; 912 LPWSTR sczRebootRequiredKey = NULL;
913 LPWSTR sczVariableKey = NULL;
912 HKEY hkRebootRequired = NULL; 914 HKEY hkRebootRequired = NULL;
913 HKEY hkRegistration = NULL; 915 HKEY hkRegistration = NULL;
914 916
@@ -956,6 +958,17 @@ extern "C" HRESULT RegistrationSessionEnd(
956 958
957 RemoveSoftwareTags(pVariables, &pRegistration->softwareTags); 959 RemoveSoftwareTags(pVariables, &pRegistration->softwareTags);
958 960
961 // build variable registry key path
962 hr = StrAllocFormatted(&sczVariableKey, L"%s\\%s", pRegistration->sczRegistrationKey, REGISTRY_BUNDLE_VARIABLE_KEY);
963 ExitOnFailure(hr, "Failed to build variable registry key path.");
964
965 // Delete registration variable key.
966 hr = RegDelete(pRegistration->hkRoot, sczVariableKey, REG_KEY_DEFAULT, FALSE);
967 if (E_FILENOTFOUND != hr)
968 {
969 ExitOnFailure(hr, "Failed to delete registration variable key: %ls", sczVariableKey);
970 }
971
959 // Delete registration key. 972 // Delete registration key.
960 hr = RegDelete(pRegistration->hkRoot, pRegistration->sczRegistrationKey, REG_KEY_DEFAULT, FALSE); 973 hr = RegDelete(pRegistration->hkRoot, pRegistration->sczRegistrationKey, REG_KEY_DEFAULT, FALSE);
961 if (E_FILENOTFOUND != hr) 974 if (E_FILENOTFOUND != hr)
@@ -985,6 +998,7 @@ extern "C" HRESULT RegistrationSessionEnd(
985LExit: 998LExit:
986 ReleaseRegKey(hkRegistration); 999 ReleaseRegKey(hkRegistration);
987 ReleaseRegKey(hkRebootRequired); 1000 ReleaseRegKey(hkRebootRequired);
1001 ReleaseStr(sczVariableKey);
988 ReleaseStr(sczRebootRequiredKey); 1002 ReleaseStr(sczRebootRequiredKey);
989 1003
990 return hr; 1004 return hr;
@@ -1001,6 +1015,15 @@ extern "C" HRESULT RegistrationSaveState(
1001 ) 1015 )
1002{ 1016{
1003 HRESULT hr = S_OK; 1017 HRESULT hr = S_OK;
1018 BURN_VARIABLES variables = { };
1019 SIZE_T iBuffer_Unused = 0;
1020 HKEY hkRegistration = NULL;
1021 LPWSTR sczVariableKey = NULL;
1022 LPWSTR sczVariableValue = NULL;
1023 LPWSTR sczValueName = NULL;
1024 DWORD dwType = 0;
1025 DWORD dwNumberOfExistingValues = 0;
1026
1004 1027
1005 // write data to file 1028 // write data to file
1006 hr = FileWrite(pRegistration->sczStateFile, FILE_ATTRIBUTE_NORMAL, pbBuffer, cbBuffer, NULL); 1029 hr = FileWrite(pRegistration->sczStateFile, FILE_ATTRIBUTE_NORMAL, pbBuffer, cbBuffer, NULL);
@@ -1011,7 +1034,76 @@ extern "C" HRESULT RegistrationSaveState(
1011 } 1034 }
1012 ExitOnFailure(hr, "Failed to write state to file: %ls", pRegistration->sczStateFile); 1035 ExitOnFailure(hr, "Failed to write state to file: %ls", pRegistration->sczStateFile);
1013 1036
1037 ::InitializeCriticalSection(&variables.csAccess);
1038
1039 hr = VariableDeserialize(&variables, TRUE, pbBuffer, cbBuffer, &iBuffer_Unused);
1040 ExitOnFailure(hr, "Failed to read variables.");
1041
1042 // build variable registry key path
1043 hr = StrAllocFormatted(&sczVariableKey, L"%s\\%s", pRegistration->sczRegistrationKey, REGISTRY_BUNDLE_VARIABLE_KEY);
1044 ExitOnFailure(hr, "Failed to build variable registry key path.");
1045
1046 // open registration variable key
1047 hr = RegCreate(pRegistration->hkRoot, sczVariableKey, KEY_WRITE | KEY_QUERY_VALUE, &hkRegistration);
1048 ExitOnFailure(hr, "Failed to create registration variable key.");
1049
1050 hr = RegQueryInfoKey(hkRegistration, 0, 0, 0, 0, 0, 0, &dwNumberOfExistingValues, 0, 0, 0, 0);
1051 ExitOnFailure(hr, "Failed to query registration variable count.");
1052
1053 for (DWORD i = dwNumberOfExistingValues; i >= 0; --i)
1054 {
1055 hr = RegValueEnum(hkRegistration, i, &sczValueName, &dwType);
1056
1057 if (E_NOMOREITEMS == hr)
1058 {
1059 hr = S_OK;
1060 break;
1061 }
1062
1063 ExitOnFailure(hr, "Failed to enumerate value %u", i);
1064
1065 hr = RegDeleteValue(hkRegistration, sczValueName);
1066 ExitOnFailure(hr, "Failed to delete registration variable value.");
1067 }
1068
1069 // Write variables.
1070 for (DWORD i = 0; i < variables.cVariables; ++i)
1071 {
1072 BURN_VARIABLE* pVariable = &variables.rgVariables[i];
1073
1074 // Write variable value.
1075 switch (pVariable->Value.Type)
1076 {
1077 case BURN_VARIANT_TYPE_NONE:
1078 hr = RegWriteNone(hkRegistration, pVariable->sczName);
1079 ExitOnFailure(hr, "Failed to set variable value.");
1080 break;
1081 case BURN_VARIANT_TYPE_NUMERIC: __fallthrough;
1082 case BURN_VARIANT_TYPE_VERSION: __fallthrough;
1083 case BURN_VARIANT_TYPE_FORMATTED: __fallthrough;
1084 case BURN_VARIANT_TYPE_STRING:
1085 hr = BVariantGetString(&pVariable->Value, &sczVariableValue);
1086 ExitOnFailure(hr, "Failed to get variable value.");
1087
1088 hr = RegWriteString(hkRegistration, pVariable->sczName, sczVariableValue);
1089 ExitOnFailure(hr, "Failed to set variable value.");
1090
1091 ReleaseNullStrSecure(sczVariableValue);
1092
1093 break;
1094 default:
1095 hr = E_INVALIDARG;
1096 ExitOnFailure(hr, "Unsupported variable type.");
1097 }
1098
1099 }
1014LExit: 1100LExit:
1101 VariablesUninitialize(&variables);
1102 ReleaseStr(sczValueName);
1103 ReleaseStr(sczVariableValue);
1104 ReleaseStr(sczVariableKey);
1105 ReleaseRegKey(hkRegistration);
1106
1015 return hr; 1107 return hr;
1016} 1108}
1017 1109
diff --git a/src/burn/test/BurnUnitTest/RegistrationTest.cpp b/src/burn/test/BurnUnitTest/RegistrationTest.cpp
index 96bdb2bf..298d4631 100644
--- a/src/burn/test/BurnUnitTest/RegistrationTest.cpp
+++ b/src/burn/test/BurnUnitTest/RegistrationTest.cpp
@@ -8,9 +8,12 @@
8#define HKCU_PATH L"SOFTWARE\\WiX_Burn_UnitTest\\HKCU" 8#define HKCU_PATH L"SOFTWARE\\WiX_Burn_UnitTest\\HKCU"
9#define REGISTRY_UNINSTALL_KEY L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall" 9#define REGISTRY_UNINSTALL_KEY L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
10#define REGISTRY_RUN_KEY L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce" 10#define REGISTRY_RUN_KEY L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce"
11#define TEST_BUNDLE_ID L"{D54F896D-1952-43e6-9C67-B5652240618C}"
12#define TEST_BUNDLE_UPGRADE_CODE L"{89FDAE1F-8CC1-48B9-B930-3945E0D3E7F0}"
11 13
12#define TEST_UNINSTALL_KEY L"HKEY_CURRENT_USER\\" HKCU_PATH L"\\" REGISTRY_UNINSTALL_KEY L"\\{D54F896D-1952-43e6-9C67-B5652240618C}" 14#define TEST_UNINSTALL_KEY L"HKEY_CURRENT_USER\\" HKCU_PATH L"\\" REGISTRY_UNINSTALL_KEY L"\\{D54F896D-1952-43e6-9C67-B5652240618C}"
13#define TEST_RUN_KEY L"HKEY_CURRENT_USER\\" HKCU_PATH L"\\" REGISTRY_RUN_KEY 15#define TEST_RUN_KEY L"HKEY_CURRENT_USER\\" HKCU_PATH L"\\" REGISTRY_RUN_KEY
16#define TEST_VARIABLE_KEY L"HKEY_CURRENT_USER\\" HKCU_PATH L"\\" REGISTRY_UNINSTALL_KEY L"\\{D54F896D-1952-43e6-9C67-B5652240618C}\\variables"
14 17
15 18
16static LSTATUS APIENTRY RegistrationTest_RegCreateKeyExW( 19static LSTATUS APIENTRY RegistrationTest_RegCreateKeyExW(
@@ -496,30 +499,153 @@ namespace Bootstrapper
496 } 499 }
497 } 500 }
498 501
499 [Fact(Skip = "Currently fails")] 502 [Fact]
500 void ResumeTest() 503 void DUtilButilTest()
501 { 504 {
502 HRESULT hr = S_OK; 505 HRESULT hr = S_OK;
503 IXMLDOMElement* pixeBundle = NULL; 506 IXMLDOMElement* pixeBundle = NULL;
504 LPWSTR sczCurrentProcess = NULL; 507 LPWSTR sczCurrentProcess = NULL;
508 LPWSTR sczValue = NULL;
509 LPWSTR sczRelatedBundleId = NULL;
510 DWORD dwRelatedBundleIndex = 0;
505 BURN_VARIABLES variables = { }; 511 BURN_VARIABLES variables = { };
506 BURN_USER_EXPERIENCE userExperience = { }; 512 BURN_USER_EXPERIENCE userExperience = { };
507 BOOTSTRAPPER_COMMAND command = { }; 513 BOOTSTRAPPER_COMMAND command = { };
508 BURN_REGISTRATION registration = { }; 514 BURN_REGISTRATION registration = { };
509 BURN_LOGGING logging = { }; 515 BURN_LOGGING logging = { };
510 BURN_PACKAGES packages = { }; 516 BURN_PACKAGES packages = { };
511 BYTE rgbData[256] = { };
512 BOOTSTRAPPER_RESUME_TYPE resumeType = BOOTSTRAPPER_RESUME_TYPE_NONE;
513 BYTE* pbBuffer = NULL; 517 BYTE* pbBuffer = NULL;
514 SIZE_T cbBuffer = 0; 518 SIZE_T cbBuffer = 0;
519
515 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}")); 520 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"));
516 try 521 try
517 { 522 {
518 for (DWORD i = 0; i < 256; ++i) 523 // set mock API's
524 RegFunctionOverride(RegistrationTest_RegCreateKeyExW, RegistrationTest_RegOpenKeyExW, RegistrationTest_RegDeleteKeyExW, NULL, NULL, NULL, NULL, NULL, NULL);
525
526 Registry::CurrentUser->CreateSubKey(gcnew String(HKCU_PATH));
527
528 logging.sczPath = L"BurnUnitTest.txt";
529
530 LPCWSTR wzDocument =
531 L"<Bundle>"
532 L" <UX>"
533 L" <Payload Id='ux.dll' FilePath='ux.dll' Packaging='embedded' SourcePath='ux.dll' Hash='000000000000' />"
534 L" </UX>"
535 L" <RelatedBundle Id='" TEST_BUNDLE_UPGRADE_CODE "' Action='Upgrade' />"
536 L" <Registration Id='" TEST_BUNDLE_ID "' Tag='foo' ProviderKey='" TEST_BUNDLE_ID "' Version='1.0.0.0' ExecutableName='setup.exe' PerMachine='no'>"
537 L" <Arp Register='yes' Publisher='WiX Toolset' DisplayName='RegisterBasicTest' DisplayVersion='1.0.0.0' />"
538 L" </Registration>"
539 L" <Variable Id='MyBurnVariable1' Type='numeric' Value='0' Hidden='no' Persisted='yes' />"
540 L" <Variable Id='MyBurnVariable2' Type='string' Value='foo' Hidden='no' Persisted='yes' />"
541 L" <Variable Id='MyBurnVariable3' Type='version' Value='v1.1-alpha' Hidden='no' Persisted='yes' />"
542 L" <Variable Id='MyBurnVariable4' Type='string' Value='foo' Hidden='no' Persisted='no' />"
543 L" <CommandLine Variables='upperCase' />"
544 L"</Bundle>";
545
546 // load XML document
547 LoadBundleXmlHelper(wzDocument, &pixeBundle);
548
549 hr = VariableInitialize(&variables);
550 TestThrowOnFailure(hr, L"Failed to initialize variables.");
551
552 hr = VariablesParseFromXml(&variables, pixeBundle);
553 TestThrowOnFailure(hr, L"Failed to parse variables from XML.");
554
555 hr = UserExperienceParseFromXml(&userExperience, pixeBundle);
556 TestThrowOnFailure(hr, L"Failed to parse UX from XML.");
557
558 hr = RegistrationParseFromXml(&registration, pixeBundle);
559 TestThrowOnFailure(hr, L"Failed to parse registration from XML.");
560
561 hr = PlanSetResumeCommand(&registration, BOOTSTRAPPER_ACTION_INSTALL, &command, &logging);
562 TestThrowOnFailure(hr, L"Failed to set registration resume command.");
563
564 hr = PathForCurrentProcess(&sczCurrentProcess, NULL);
565 TestThrowOnFailure(hr, L"Failed to get current process path.");
566
567 // begin session
568 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
569 TestThrowOnFailure(hr, L"Failed to register bundle.");
570
571 VariableSetNumericHelper(&variables, L"MyBurnVariable1", 42);
572 VariableSetStringHelper(&variables, L"MyBurnVariable2", L"bar", FALSE);
573 VariableSetVersionHelper(&variables, L"MyBurnVariable3", L"v1.0-beta");
574
575 hr = VariableSerialize(&variables, TRUE, &pbBuffer, &cbBuffer);
576 TestThrowOnFailure(hr, "Failed to serialize variables.");
577
578 if (!Directory::Exists(cacheDirectory))
519 { 579 {
520 rgbData[i] = (BYTE)i; 580 Directory::CreateDirectory(cacheDirectory);
521 } 581 }
522 582
583 hr = RegistrationSaveState(&registration, pbBuffer, cbBuffer);
584 TestThrowOnFailure(hr, L"Failed to save state.");
585
586 ReleaseNullBuffer(pbBuffer);
587 cbBuffer = 0;
588 // Verify the variables exist
589 Assert::Equal<String^>(gcnew String(L"42"), (String^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"MyBurnVariable1"), nullptr));
590 Assert::Equal<String^>(gcnew String(L"bar"), (String^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"MyBurnVariable2"), nullptr));
591 Assert::Equal<String^>(gcnew String(L"1.0-beta"), (String^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"MyBurnVariable3"), nullptr));
592 Assert::Empty((System::Collections::IEnumerable ^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"WixBundleForcedRestartPackage"), nullptr));
593
594 hr = StrAlloc(&sczRelatedBundleId, MAX_GUID_CHARS + 1);
595
596 // Verify we can find ourself via the UpgradeCode
597 hr = BundleEnumRelatedBundle(TEST_BUNDLE_UPGRADE_CODE, BUNDLE_INSTALL_CONTEXT_USER, &dwRelatedBundleIndex, sczRelatedBundleId);
598 TestThrowOnFailure(hr, L"Failed to enumerate related bundle.");
599 Assert::Equal<String^>(gcnew String(TEST_BUNDLE_ID), gcnew String(sczRelatedBundleId));
600
601 // Verify we can read the bundle variables via the API
602 hr = BundleGetBundleVariable(TEST_BUNDLE_ID, L"MyBurnVariable1", &sczValue);
603 TestThrowOnFailure(hr, L"Failed to read MyBurnVariable1.");
604 Assert::Equal<String^>(gcnew String(L"42"), gcnew String(sczValue));
605
606 // end session
607 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
608 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
609 }
610 finally
611 {
612 ReleaseStr(sczRelatedBundleId);
613 ReleaseStr(sczCurrentProcess);
614 ReleaseObject(pixeBundle);
615 UserExperienceUninitialize(&userExperience);
616 RegistrationUninitialize(&registration);
617 VariablesUninitialize(&variables);
618
619 Registry::CurrentUser->DeleteSubKeyTree(gcnew String(ROOT_PATH));
620 if (Directory::Exists(cacheDirectory))
621 {
622 Directory::Delete(cacheDirectory, true);
623 }
624
625 RegFunctionOverride(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
626 }
627 }
628
629 [Fact]//(Skip = "Currently fails")]
630 void ResumeTest()
631 {
632 HRESULT hr = S_OK;
633 IXMLDOMElement* pixeBundle = NULL;
634 LPWSTR sczCurrentProcess = NULL;
635 LPWSTR sczValue = NULL;
636 BURN_VARIABLES variables = { };
637 BURN_USER_EXPERIENCE userExperience = { };
638 BOOTSTRAPPER_COMMAND command = { };
639 BURN_REGISTRATION registration = { };
640 BURN_LOGGING logging = { };
641 BURN_PACKAGES packages = { };
642 BOOTSTRAPPER_RESUME_TYPE resumeType = BOOTSTRAPPER_RESUME_TYPE_NONE;
643 BYTE* pbBuffer = NULL;
644 SIZE_T cbBuffer = 0;
645 SIZE_T piBuffer = 0;
646 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"));
647 try
648 {
523 // set mock API's 649 // set mock API's
524 RegFunctionOverride(RegistrationTest_RegCreateKeyExW, RegistrationTest_RegOpenKeyExW, RegistrationTest_RegDeleteKeyExW, NULL, NULL, NULL, NULL, NULL, NULL); 650 RegFunctionOverride(RegistrationTest_RegCreateKeyExW, RegistrationTest_RegOpenKeyExW, RegistrationTest_RegDeleteKeyExW, NULL, NULL, NULL, NULL, NULL, NULL);
525 651
@@ -535,6 +661,10 @@ namespace Bootstrapper
535 L" <Registration Id='{D54F896D-1952-43e6-9C67-B5652240618C}' UpgradeCode='{D54F896D-1952-43e6-9C67-B5652240618C}' Tag='foo' ProviderKey='foo' Version='1.0.0.0' ExecutableName='setup.exe' PerMachine='no'>" 661 L" <Registration Id='{D54F896D-1952-43e6-9C67-B5652240618C}' UpgradeCode='{D54F896D-1952-43e6-9C67-B5652240618C}' Tag='foo' ProviderKey='foo' Version='1.0.0.0' ExecutableName='setup.exe' PerMachine='no'>"
536 L" <Arp Register='yes' Publisher='WiX Toolset' DisplayName='RegisterBasicTest' DisplayVersion='1.0.0.0' />" 662 L" <Arp Register='yes' Publisher='WiX Toolset' DisplayName='RegisterBasicTest' DisplayVersion='1.0.0.0' />"
537 L" </Registration>" 663 L" </Registration>"
664 L" <Variable Id='MyBurnVariable1' Type='numeric' Value='0' Hidden='no' Persisted='yes' />"
665 L" <Variable Id='MyBurnVariable2' Type='string' Value='foo' Hidden='no' Persisted='yes' />"
666 L" <Variable Id='MyBurnVariable3' Type='version' Value='v1.1-alpha' Hidden='no' Persisted='yes' />"
667 L" <CommandLine Variables='upperCase' />"
538 L"</Bundle>"; 668 L"</Bundle>";
539 669
540 // load XML document 670 // load XML document
@@ -543,6 +673,9 @@ namespace Bootstrapper
543 hr = VariableInitialize(&variables); 673 hr = VariableInitialize(&variables);
544 TestThrowOnFailure(hr, L"Failed to initialize variables."); 674 TestThrowOnFailure(hr, L"Failed to initialize variables.");
545 675
676 hr = VariablesParseFromXml(&variables, pixeBundle);
677 TestThrowOnFailure(hr, L"Failed to parse variables from XML.");
678
546 hr = UserExperienceParseFromXml(&userExperience, pixeBundle); 679 hr = UserExperienceParseFromXml(&userExperience, pixeBundle);
547 TestThrowOnFailure(hr, L"Failed to parse UX from XML."); 680 TestThrowOnFailure(hr, L"Failed to parse UX from XML.");
548 681
@@ -565,9 +698,33 @@ namespace Bootstrapper
565 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 698 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
566 TestThrowOnFailure(hr, L"Failed to register bundle."); 699 TestThrowOnFailure(hr, L"Failed to register bundle.");
567 700
568 hr = RegistrationSaveState(&registration, rgbData, sizeof(rgbData)); 701 VariableSetNumericHelper(&variables, L"MyBurnVariable1", 42);
702 VariableSetStringHelper(&variables, L"MyBurnVariable2", L"bar", FALSE);
703 VariableSetVersionHelper(&variables, L"MyBurnVariable3", L"v1.0-beta");
704
705 hr = VariableSerialize(&variables, TRUE, &pbBuffer, &cbBuffer);
706 TestThrowOnFailure(hr, "Failed to serialize variables.");
707
708 if (!Directory::Exists(cacheDirectory))
709 {
710 Directory::CreateDirectory(cacheDirectory);
711 }
712
713 hr = RegistrationSaveState(&registration, pbBuffer, cbBuffer);
569 TestThrowOnFailure(hr, L"Failed to save state."); 714 TestThrowOnFailure(hr, L"Failed to save state.");
570 715
716 ReleaseNullBuffer(pbBuffer);
717 cbBuffer = 0;
718 // Verify the variables exist
719 Assert::Equal<String^>(gcnew String(L"42"), (String^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"MyBurnVariable1"), nullptr));
720 Assert::Equal<String^>(gcnew String(L"bar"), (String^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"MyBurnVariable2"), nullptr));
721 Assert::Equal<String^>(gcnew String(L"1.0-beta"), (String^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"MyBurnVariable3"), nullptr));
722 Assert::Empty((System::Collections::IEnumerable^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"WixBundleForcedRestartPackage"), nullptr));
723
724 hr = BundleGetBundleVariable(TEST_BUNDLE_ID, L"MyBurnVariable1", &sczValue);
725 TestThrowOnFailure(hr, L"Failed to read MyBurnVariable1.");
726 Assert::Equal<String^>(gcnew String(L"42"), gcnew String(sczValue));
727
571 // read interrupted resume type 728 // read interrupted resume type
572 hr = RegistrationDetectResumeType(&registration, &resumeType); 729 hr = RegistrationDetectResumeType(&registration, &resumeType);
573 TestThrowOnFailure(hr, L"Failed to read interrupted resume type."); 730 TestThrowOnFailure(hr, L"Failed to read interrupted resume type.");
@@ -591,8 +748,11 @@ namespace Bootstrapper
591 hr = RegistrationLoadState(&registration, &pbBuffer, &cbBuffer); 748 hr = RegistrationLoadState(&registration, &pbBuffer, &cbBuffer);
592 TestThrowOnFailure(hr, L"Failed to load state."); 749 TestThrowOnFailure(hr, L"Failed to load state.");
593 750
594 Assert::Equal((SIZE_T)sizeof(rgbData), cbBuffer); 751 hr = VariableDeserialize(&variables, TRUE, pbBuffer, cbBuffer, &piBuffer);
595 Assert::True(0 == memcmp(pbBuffer, rgbData, sizeof(rgbData))); 752 TestThrowOnFailure(hr, L"Failed to deserialize variables.");
753
754 //Assert::Equal((SIZE_T)sizeof(rgbData), cbBuffer);
755 //Assert::True(0 == memcmp(pbBuffer, rgbData, sizeof(rgbData)));
596 756
597 // write active resume mode 757 // write active resume mode
598 hr = RegistrationSessionResume(&registration, &variables, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 758 hr = RegistrationSessionResume(&registration, &variables, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
diff --git a/src/burn/test/BurnUnitTest/precomp.h b/src/burn/test/BurnUnitTest/precomp.h
index d2b57d61..78c44d39 100644
--- a/src/burn/test/BurnUnitTest/precomp.h
+++ b/src/burn/test/BurnUnitTest/precomp.h
@@ -30,6 +30,7 @@
30#include <xmlutil.h> 30#include <xmlutil.h>
31#include <dictutil.h> 31#include <dictutil.h>
32#include <deputil.h> 32#include <deputil.h>
33#include <butil.h>
33 34
34#include "BootstrapperEngine.h" 35#include "BootstrapperEngine.h"
35#include "BootstrapperApplication.h" 36#include "BootstrapperApplication.h"