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/libs/dutil/WixToolset.DUtil/butil.cpp | |
| 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/libs/dutil/WixToolset.DUtil/butil.cpp')
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/butil.cpp | 105 |
1 files changed, 94 insertions, 11 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/butil.cpp b/src/libs/dutil/WixToolset.DUtil/butil.cpp index e04b52e9..cda2a658 100644 --- a/src/libs/dutil/WixToolset.DUtil/butil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/butil.cpp | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | const LPCWSTR BUNDLE_REGISTRATION_REGISTRY_UNINSTALL_KEY = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; | 20 | const LPCWSTR BUNDLE_REGISTRATION_REGISTRY_UNINSTALL_KEY = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; |
| 21 | const LPCWSTR BUNDLE_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE = L"BundleUpgradeCode"; | 21 | const LPCWSTR BUNDLE_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE = L"BundleUpgradeCode"; |
| 22 | const LPCWSTR BUNDLE_REGISTRATION_REGISTRY_BUNDLE_PROVIDER_KEY = L"BundleProviderKey"; | 22 | const LPCWSTR BUNDLE_REGISTRATION_REGISTRY_BUNDLE_PROVIDER_KEY = L"BundleProviderKey"; |
| 23 | const LPCWSTR BUNDLE_REGISTRATION_REGISTRY_BUNDLE_VARIABLE_KEY = L"variables"; | ||
| 23 | 24 | ||
| 24 | // Forward declarations. | 25 | // Forward declarations. |
| 25 | /******************************************************************** | 26 | /******************************************************************** |
| @@ -29,10 +30,13 @@ NOTE: caller is responsible for closing key | |||
| 29 | ********************************************************************/ | 30 | ********************************************************************/ |
| 30 | static HRESULT OpenBundleKey( | 31 | static HRESULT OpenBundleKey( |
| 31 | __in_z LPCWSTR wzBundleId, | 32 | __in_z LPCWSTR wzBundleId, |
| 32 | __in BUNDLE_INSTALL_CONTEXT context, | 33 | __in BUNDLE_INSTALL_CONTEXT context, |
| 33 | __inout HKEY *key); | 34 | __in_opt LPCWSTR szSubKey, |
| 34 | 35 | __inout HKEY* key); | |
| 35 | 36 | ||
| 37 | /******************************************************************** | ||
| 38 | BundleGetBundleInfo - Read the registration data for a gven bundle | ||
| 39 | ********************************************************************/ | ||
| 36 | extern "C" HRESULT DAPI BundleGetBundleInfo( | 40 | extern "C" HRESULT DAPI BundleGetBundleInfo( |
| 37 | __in_z LPCWSTR wzBundleId, | 41 | __in_z LPCWSTR wzBundleId, |
| 38 | __in_z LPCWSTR wzAttribute, | 42 | __in_z LPCWSTR wzAttribute, |
| @@ -43,7 +47,6 @@ extern "C" HRESULT DAPI BundleGetBundleInfo( | |||
| 43 | Assert(wzBundleId && wzAttribute); | 47 | Assert(wzBundleId && wzAttribute); |
| 44 | 48 | ||
| 45 | HRESULT hr = S_OK; | 49 | HRESULT hr = S_OK; |
| 46 | BUNDLE_INSTALL_CONTEXT context = BUNDLE_INSTALL_CONTEXT_MACHINE; | ||
| 47 | LPWSTR sczValue = NULL; | 50 | LPWSTR sczValue = NULL; |
| 48 | HKEY hkBundle = NULL; | 51 | HKEY hkBundle = NULL; |
| 49 | DWORD cchSource = 0; | 52 | DWORD cchSource = 0; |
| @@ -55,8 +58,8 @@ extern "C" HRESULT DAPI BundleGetBundleInfo( | |||
| 55 | ButilExitOnFailure(hr = E_INVALIDARG, "An invalid parameter was passed to the function."); | 58 | ButilExitOnFailure(hr = E_INVALIDARG, "An invalid parameter was passed to the function."); |
| 56 | } | 59 | } |
| 57 | 60 | ||
| 58 | if (FAILED(hr = OpenBundleKey(wzBundleId, context = BUNDLE_INSTALL_CONTEXT_MACHINE, &hkBundle)) && | 61 | if (FAILED(hr = OpenBundleKey(wzBundleId, BUNDLE_INSTALL_CONTEXT_MACHINE, NULL, &hkBundle)) && |
| 59 | FAILED(hr = OpenBundleKey(wzBundleId, context = BUNDLE_INSTALL_CONTEXT_USER, &hkBundle))) | 62 | FAILED(hr = OpenBundleKey(wzBundleId, BUNDLE_INSTALL_CONTEXT_USER, NULL, &hkBundle))) |
| 60 | { | 63 | { |
| 61 | ButilExitOnFailure(E_FILENOTFOUND == hr ? HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT) : hr, "Failed to locate bundle uninstall key path."); | 64 | ButilExitOnFailure(E_FILENOTFOUND == hr ? HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT) : hr, "Failed to locate bundle uninstall key path."); |
| 62 | } | 65 | } |
| @@ -108,7 +111,10 @@ LExit: | |||
| 108 | return hr; | 111 | return hr; |
| 109 | } | 112 | } |
| 110 | 113 | ||
| 111 | HRESULT DAPI BundleEnumRelatedBundle( | 114 | /******************************************************************** |
| 115 | ********************************************************************/ | ||
| 116 | |||
| 117 | extern "C" HRESULT DAPI BundleEnumRelatedBundle( | ||
| 112 | __in_z LPCWSTR wzUpgradeCode, | 118 | __in_z LPCWSTR wzUpgradeCode, |
| 113 | __in BUNDLE_INSTALL_CONTEXT context, | 119 | __in BUNDLE_INSTALL_CONTEXT context, |
| 114 | __inout PDWORD pdwStartIndex, | 120 | __inout PDWORD pdwStartIndex, |
| @@ -231,11 +237,80 @@ LExit: | |||
| 231 | return hr; | 237 | return hr; |
| 232 | } | 238 | } |
| 233 | 239 | ||
| 240 | /******************************************************************** | ||
| 241 | BundleGetBundleVariable - Queries the bundle installation metadata for a given variable, | ||
| 242 | the caller is expected to free the memory returned vis psczValue | ||
| 243 | RETURNS: | ||
| 244 | S_OK | ||
| 245 | Success, if the variable had a value, it's returned in psczValue | ||
| 246 | E_INVALIDARG | ||
| 247 | An invalid parameter was passed to the function. | ||
| 248 | HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT) | ||
| 249 | The bundle is not installed | ||
| 250 | HRESULT_FROM_WIN32(ERROR_UNKNOWN_PROPERTY) | ||
| 251 | The variable is unrecognized | ||
| 252 | E_NOTIMPL: | ||
| 253 | Tried to read a bundle variable for a type which has not been implemented | ||
| 254 | |||
| 255 | All other returns are unexpected returns from other dutil methods. | ||
| 256 | ********************************************************************/ | ||
| 257 | |||
| 258 | extern "C" HRESULT DAPI BundleGetBundleVariable( | ||
| 259 | __in_z LPCWSTR wzBundleId, | ||
| 260 | __in_z LPCWSTR wzVariable, | ||
| 261 | __deref_out_z LPWSTR * psczValue | ||
| 262 | ) | ||
| 263 | { | ||
| 264 | Assert(wzBundleId && wzVariable); | ||
| 265 | |||
| 266 | HRESULT hr = S_OK; | ||
| 267 | BUNDLE_INSTALL_CONTEXT context = BUNDLE_INSTALL_CONTEXT_MACHINE; | ||
| 268 | HKEY hkBundle = NULL; | ||
| 269 | DWORD dwType = 0; | ||
| 270 | |||
| 271 | if (!wzBundleId || !wzVariable || !psczValue) | ||
| 272 | { | ||
| 273 | ButilExitOnFailure(hr = E_INVALIDARG, "An invalid parameter was passed to the function."); | ||
| 274 | } | ||
| 275 | |||
| 276 | if (FAILED(hr = OpenBundleKey(wzBundleId, context = BUNDLE_INSTALL_CONTEXT_MACHINE, BUNDLE_REGISTRATION_REGISTRY_BUNDLE_VARIABLE_KEY, &hkBundle)) && | ||
| 277 | FAILED(hr = OpenBundleKey(wzBundleId, context = BUNDLE_INSTALL_CONTEXT_USER, BUNDLE_REGISTRATION_REGISTRY_BUNDLE_VARIABLE_KEY, &hkBundle))) | ||
| 278 | { | ||
| 279 | ButilExitOnFailure(E_FILENOTFOUND == hr ? HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT) : hr, "Failed to locate bundle uninstall key variable path."); | ||
| 280 | } | ||
| 281 | |||
| 282 | // If the bundle doesn't have the shared variable defined, return ERROR_UNKNOWN_PROPERTY | ||
| 283 | hr = RegGetType(hkBundle, wzVariable, &dwType); | ||
| 284 | ButilExitOnFailure(E_FILENOTFOUND == hr ? HRESULT_FROM_WIN32(ERROR_UNKNOWN_PROPERTY) : hr, "Failed to locate bundle variable."); | ||
| 285 | |||
| 286 | switch (dwType) | ||
| 287 | { | ||
| 288 | case REG_SZ: | ||
| 289 | hr = RegReadString(hkBundle, wzVariable, psczValue); | ||
| 290 | ButilExitOnFailure(hr, "Failed to read string shared variable."); | ||
| 291 | break; | ||
| 292 | case REG_NONE: | ||
| 293 | hr = S_OK; | ||
| 294 | break; | ||
| 295 | default: | ||
| 296 | ButilExitOnFailure(hr = E_NOTIMPL, "Reading bundle variable of type 0x%x not implemented.", dwType); | ||
| 297 | |||
| 298 | } | ||
| 299 | |||
| 300 | LExit: | ||
| 301 | ReleaseRegKey(hkBundle); | ||
| 234 | 302 | ||
| 303 | return hr; | ||
| 304 | |||
| 305 | } | ||
| 306 | /******************************************************************** | ||
| 307 | * | ||
| 308 | ********************************************************************/ | ||
| 235 | HRESULT OpenBundleKey( | 309 | HRESULT OpenBundleKey( |
| 236 | __in_z LPCWSTR wzBundleId, | 310 | __in_z LPCWSTR wzBundleId, |
| 237 | __in BUNDLE_INSTALL_CONTEXT context, | 311 | __in BUNDLE_INSTALL_CONTEXT context, |
| 238 | __inout HKEY *key) | 312 | __in_opt LPCWSTR szSubKey, |
| 313 | __inout HKEY* key) | ||
| 239 | { | 314 | { |
| 240 | Assert(key && wzBundleId); | 315 | Assert(key && wzBundleId); |
| 241 | AssertSz(NULL == *key, "*key should be null"); | 316 | AssertSz(NULL == *key, "*key should be null"); |
| @@ -244,9 +319,16 @@ HRESULT OpenBundleKey( | |||
| 244 | HKEY hkRoot = BUNDLE_INSTALL_CONTEXT_USER == context ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; | 319 | HKEY hkRoot = BUNDLE_INSTALL_CONTEXT_USER == context ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; |
| 245 | LPWSTR sczKeypath = NULL; | 320 | LPWSTR sczKeypath = NULL; |
| 246 | 321 | ||
| 247 | hr = StrAllocFormatted(&sczKeypath, L"%ls\\%ls", BUNDLE_REGISTRATION_REGISTRY_UNINSTALL_KEY, wzBundleId); | 322 | if (szSubKey) |
| 323 | { | ||
| 324 | hr = StrAllocFormatted(&sczKeypath, L"%ls\\%ls\\%ls", BUNDLE_REGISTRATION_REGISTRY_UNINSTALL_KEY, wzBundleId, szSubKey); | ||
| 325 | } | ||
| 326 | else | ||
| 327 | { | ||
| 328 | hr = StrAllocFormatted(&sczKeypath, L"%ls\\%ls", BUNDLE_REGISTRATION_REGISTRY_UNINSTALL_KEY, wzBundleId); | ||
| 329 | } | ||
| 248 | ButilExitOnFailure(hr, "Failed to allocate bundle uninstall key path."); | 330 | ButilExitOnFailure(hr, "Failed to allocate bundle uninstall key path."); |
| 249 | 331 | ||
| 250 | hr = RegOpen(hkRoot, sczKeypath, KEY_READ, key); | 332 | hr = RegOpen(hkRoot, sczKeypath, KEY_READ, key); |
| 251 | ButilExitOnFailure(hr, "Failed to open bundle uninstall key path."); | 333 | ButilExitOnFailure(hr, "Failed to open bundle uninstall key path."); |
| 252 | 334 | ||
| @@ -255,3 +337,4 @@ LExit: | |||
| 255 | 337 | ||
| 256 | return hr; | 338 | return hr; |
| 257 | } | 339 | } |
| 340 | |||
