aboutsummaryrefslogtreecommitdiff
path: root/src/libs
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/libs
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/libs')
-rw-r--r--src/libs/dutil/WixToolset.DUtil/butil.cpp105
-rw-r--r--src/libs/dutil/WixToolset.DUtil/inc/butil.h11
-rw-r--r--src/libs/dutil/WixToolset.DUtil/inc/regutil.h8
-rw-r--r--src/libs/dutil/WixToolset.DUtil/regutil.cpp47
4 files changed, 158 insertions, 13 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 @@
20const LPCWSTR BUNDLE_REGISTRATION_REGISTRY_UNINSTALL_KEY = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; 20const LPCWSTR BUNDLE_REGISTRATION_REGISTRY_UNINSTALL_KEY = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
21const LPCWSTR BUNDLE_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE = L"BundleUpgradeCode"; 21const LPCWSTR BUNDLE_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE = L"BundleUpgradeCode";
22const LPCWSTR BUNDLE_REGISTRATION_REGISTRY_BUNDLE_PROVIDER_KEY = L"BundleProviderKey"; 22const LPCWSTR BUNDLE_REGISTRATION_REGISTRY_BUNDLE_PROVIDER_KEY = L"BundleProviderKey";
23const 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********************************************************************/
30static HRESULT OpenBundleKey( 31static 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/********************************************************************
38BundleGetBundleInfo - Read the registration data for a gven bundle
39********************************************************************/
36extern "C" HRESULT DAPI BundleGetBundleInfo( 40extern "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
111HRESULT DAPI BundleEnumRelatedBundle( 114/********************************************************************
115********************************************************************/
116
117extern "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/********************************************************************
241BundleGetBundleVariable - Queries the bundle installation metadata for a given variable,
242the caller is expected to free the memory returned vis psczValue
243RETURNS:
244S_OK
245 Success, if the variable had a value, it's returned in psczValue
246E_INVALIDARG
247 An invalid parameter was passed to the function.
248HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT)
249 The bundle is not installed
250HRESULT_FROM_WIN32(ERROR_UNKNOWN_PROPERTY)
251 The variable is unrecognized
252E_NOTIMPL:
253 Tried to read a bundle variable for a type which has not been implemented
254
255All other returns are unexpected returns from other dutil methods.
256********************************************************************/
257
258extern "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
300LExit:
301 ReleaseRegKey(hkBundle);
234 302
303 return hr;
304
305}
306/********************************************************************
307*
308********************************************************************/
235HRESULT OpenBundleKey( 309HRESULT 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
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/butil.h b/src/libs/dutil/WixToolset.DUtil/inc/butil.h
index d1ec73bc..d910c113 100644
--- a/src/libs/dutil/WixToolset.DUtil/inc/butil.h
+++ b/src/libs/dutil/WixToolset.DUtil/inc/butil.h
@@ -6,11 +6,11 @@
6extern "C" { 6extern "C" {
7#endif 7#endif
8 8
9enum BUNDLE_INSTALL_CONTEXT 9typedef enum BUNDLE_INSTALL_CONTEXT
10{ 10{
11 BUNDLE_INSTALL_CONTEXT_MACHINE, 11 BUNDLE_INSTALL_CONTEXT_MACHINE,
12 BUNDLE_INSTALL_CONTEXT_USER, 12 BUNDLE_INSTALL_CONTEXT_USER,
13}; 13} BUNDLE_INSTALL_CONTEXT;
14 14
15 15
16/******************************************************************** 16/********************************************************************
@@ -55,6 +55,13 @@ HRESULT DAPI BundleEnumRelatedBundle(
55 __out_ecount(MAX_GUID_CHARS+1) LPWSTR lpBundleIdBuf 55 __out_ecount(MAX_GUID_CHARS+1) LPWSTR lpBundleIdBuf
56 ); 56 );
57 57
58HRESULT DAPI BundleGetBundleVariable(
59 __in_z LPCWSTR wzBundleId,
60 __in_z LPCWSTR wzVariable,
61 __deref_out_z LPWSTR* psczValue
62);
63
64
58#ifdef __cplusplus 65#ifdef __cplusplus
59} 66}
60#endif 67#endif
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/regutil.h b/src/libs/dutil/WixToolset.DUtil/inc/regutil.h
index 75284940..fcf13054 100644
--- a/src/libs/dutil/WixToolset.DUtil/inc/regutil.h
+++ b/src/libs/dutil/WixToolset.DUtil/inc/regutil.h
@@ -178,6 +178,10 @@ HRESULT DAPI RegReadVersion(
178 __in_z_opt LPCWSTR wzName, 178 __in_z_opt LPCWSTR wzName,
179 __out DWORD64* pdw64Version 179 __out DWORD64* pdw64Version
180 ); 180 );
181HRESULT DAPI RegReadNone(
182 __in HKEY hk,
183 __in_z_opt LPCWSTR wzName
184);
181HRESULT DAPI RegReadNumber( 185HRESULT DAPI RegReadNumber(
182 __in HKEY hk, 186 __in HKEY hk,
183 __in_z_opt LPCWSTR wzName, 187 __in_z_opt LPCWSTR wzName,
@@ -211,6 +215,10 @@ HRESULT DAPI RegWriteStringFormatted(
211 __in __format_string LPCWSTR szFormat, 215 __in __format_string LPCWSTR szFormat,
212 ... 216 ...
213 ); 217 );
218HRESULT DAPI RegWriteNone(
219 __in HKEY hk,
220 __in_z_opt LPCWSTR wzName
221);
214HRESULT DAPI RegWriteNumber( 222HRESULT DAPI RegWriteNumber(
215 __in HKEY hk, 223 __in HKEY hk,
216 __in_z_opt LPCWSTR wzName, 224 __in_z_opt LPCWSTR wzName,
diff --git a/src/libs/dutil/WixToolset.DUtil/regutil.cpp b/src/libs/dutil/WixToolset.DUtil/regutil.cpp
index cb617932..458d8586 100644
--- a/src/libs/dutil/WixToolset.DUtil/regutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/regutil.cpp
@@ -672,6 +672,34 @@ LExit:
672 return hr; 672 return hr;
673} 673}
674 674
675/********************************************************************
676 RegReadNone - reads a NONE registry key value.
677
678*********************************************************************/
679extern "C" HRESULT DAPI RegReadNone(
680 __in HKEY hk,
681 __in_z_opt LPCWSTR wzName)
682{
683 HRESULT hr = S_OK;
684 DWORD er = ERROR_SUCCESS;
685 DWORD dwType = 0;
686
687 er = vpfnRegQueryValueExW(hk, wzName, NULL, &dwType, NULL, NULL);
688 if (E_FILENOTFOUND == HRESULT_FROM_WIN32(er))
689 {
690 ExitFunction1(hr = E_FILENOTFOUND);
691 }
692 RegExitOnWin32Error(er, hr, "Failed to query registry key value.");
693
694 if (REG_NONE != dwType)
695 {
696 hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE);
697 RegExitOnRootFailure(hr, "Error reading version registry value due to unexpected data type: %u", dwType);
698 }
699
700LExit:
701 return hr;
702}
675 703
676/******************************************************************** 704/********************************************************************
677 RegReadNumber - reads a DWORD registry key value as a number. 705 RegReadNumber - reads a DWORD registry key value as a number.
@@ -886,6 +914,25 @@ LExit:
886} 914}
887 915
888/******************************************************************** 916/********************************************************************
917 RegWriteNone - writes a registry key value as none.
918
919*********************************************************************/
920extern "C" HRESULT DAPI RegWriteNone(
921 __in HKEY hk,
922 __in_z_opt LPCWSTR wzName
923)
924{
925 HRESULT hr = S_OK;
926 DWORD er = ERROR_SUCCESS;
927
928 er = vpfnRegSetValueExW(hk, wzName, 0, REG_NONE, NULL, NULL);
929 RegExitOnWin32Error(er, hr, "Failed to set %ls value.", wzName);
930
931LExit:
932 return hr;
933}
934
935/********************************************************************
889 RegWriteNumber - writes a registry key value as a number. 936 RegWriteNumber - writes a registry key value as a number.
890 937
891*********************************************************************/ 938*********************************************************************/