diff options
| author | Jacob Hoover <jacob.hoover@greenheck.com> | 2021-06-11 17:05:06 -0500 |
|---|---|---|
| committer | Sean Hall <r.sean.hall@gmail.com> | 2021-07-18 14:41:21 -0500 |
| commit | f3c96bcab560cb09355e9366eac3f4195479d95d (patch) | |
| tree | 1585c1f2af7e3582e14663c29c033702e910d12f /src/burn/engine | |
| parent | 5b2b06c9bffb4e6f17409cec41bc0b4b8dab4c90 (diff) | |
| download | wix-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/engine')
| -rw-r--r-- | src/burn/engine/registration.cpp | 92 |
1 files changed, 92 insertions, 0 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"; | |||
| 32 | const LPCWSTR REGISTRY_BUNDLE_VERSION_MAJOR = L"VersionMajor"; | 32 | const LPCWSTR REGISTRY_BUNDLE_VERSION_MAJOR = L"VersionMajor"; |
| 33 | const LPCWSTR REGISTRY_BUNDLE_VERSION_MINOR = L"VersionMinor"; | 33 | const LPCWSTR REGISTRY_BUNDLE_VERSION_MINOR = L"VersionMinor"; |
| 34 | const LPCWSTR SWIDTAG_FOLDER = L"swidtag"; | 34 | const LPCWSTR SWIDTAG_FOLDER = L"swidtag"; |
| 35 | const 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( | |||
| 985 | LExit: | 998 | LExit: |
| 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 | } | ||
| 1014 | LExit: | 1100 | LExit: |
| 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 | ||
