aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2020-08-29 21:28:49 -0500
committerSean Hall <r.sean.hall@gmail.com>2020-10-24 20:03:38 -0500
commit281ad838c5001f988aeea06a6f06ce2cc6c0991d (patch)
tree2f346a5cf45d3397ed24d78144fc7435b03cf04a
parente8b32195c04a62ffd636ed260a3c28f0cd8f87b3 (diff)
downloadwix-281ad838c5001f988aeea06a6f06ce2cc6c0991d.tar.gz
wix-281ad838c5001f988aeea06a6f06ce2cc6c0991d.tar.bz2
wix-281ad838c5001f988aeea06a6f06ce2cc6c0991d.zip
Add butil exit macros.
-rw-r--r--src/dutil/butil.cpp106
-rw-r--r--src/dutil/inc/butil.h35
2 files changed, 78 insertions, 63 deletions
diff --git a/src/dutil/butil.cpp b/src/dutil/butil.cpp
index 243befce..e04b52e9 100644
--- a/src/dutil/butil.cpp
+++ b/src/dutil/butil.cpp
@@ -1,7 +1,19 @@
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. 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 2
3#include "precomp.h" 3#include "precomp.h"
4#include "butil.h" 4
5// Exit macros
6#define ButilExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_BUTIL, x, s, __VA_ARGS__)
7#define ButilExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_BUTIL, x, s, __VA_ARGS__)
8#define ButilExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_BUTIL, x, s, __VA_ARGS__)
9#define ButilExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_BUTIL, x, s, __VA_ARGS__)
10#define ButilExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_BUTIL, x, s, __VA_ARGS__)
11#define ButilExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_BUTIL, x, s, __VA_ARGS__)
12#define ButilExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_BUTIL, p, x, e, s, __VA_ARGS__)
13#define ButilExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_BUTIL, p, x, s, __VA_ARGS__)
14#define ButilExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_BUTIL, p, x, e, s, __VA_ARGS__)
15#define ButilExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_BUTIL, p, x, s, __VA_ARGS__)
16#define ButilExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_BUTIL, e, x, s, __VA_ARGS__)
5 17
6// constants 18// constants
7// From engine/registration.h 19// From engine/registration.h
@@ -10,31 +22,20 @@ const LPCWSTR BUNDLE_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE = L"BundleUpgrade
10const LPCWSTR BUNDLE_REGISTRATION_REGISTRY_BUNDLE_PROVIDER_KEY = L"BundleProviderKey"; 22const LPCWSTR BUNDLE_REGISTRATION_REGISTRY_BUNDLE_PROVIDER_KEY = L"BundleProviderKey";
11 23
12// Forward declarations. 24// Forward declarations.
25/********************************************************************
26OpenBundleKey - Opens the bundle uninstallation key for a given bundle
27
28NOTE: caller is responsible for closing key
29********************************************************************/
13static HRESULT OpenBundleKey( 30static HRESULT OpenBundleKey(
14 __in LPCWSTR wzBundleId, 31 __in_z LPCWSTR wzBundleId,
15 __in BUNDLE_INSTALL_CONTEXT context, 32 __in BUNDLE_INSTALL_CONTEXT context,
16 __inout HKEY *key); 33 __inout HKEY *key);
17 34
18/******************************************************************** 35
19BundleGetBundleInfo - Queries the bundle installation metadata for a given property
20
21RETURNS:
22 E_INVALIDARG
23 An invalid parameter was passed to the function.
24 HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT)
25 The bundle is not installed
26 HRESULT_FROM_WIN32(ERROR_UNKNOWN_PROPERTY)
27 The property is unrecognized
28 HRESULT_FROM_WIN32(ERROR_MORE_DATA)
29 A buffer is too small to hold the requested data.
30 E_NOTIMPL:
31 Tried to read a bundle attribute for a type which has not been implemented
32
33 All other returns are unexpected returns from other dutil methods.
34********************************************************************/
35extern "C" HRESULT DAPI BundleGetBundleInfo( 36extern "C" HRESULT DAPI BundleGetBundleInfo(
36 __in LPCWSTR wzBundleId, 37 __in_z LPCWSTR wzBundleId,
37 __in LPCWSTR wzAttribute, 38 __in_z LPCWSTR wzAttribute,
38 __out_ecount_opt(*pcchValueBuf) LPWSTR lpValueBuf, 39 __out_ecount_opt(*pcchValueBuf) LPWSTR lpValueBuf,
39 __inout_opt LPDWORD pcchValueBuf 40 __inout_opt LPDWORD pcchValueBuf
40 ) 41 )
@@ -51,39 +52,39 @@ extern "C" HRESULT DAPI BundleGetBundleInfo(
51 52
52 if ((lpValueBuf && !pcchValueBuf) || !wzBundleId || !wzAttribute) 53 if ((lpValueBuf && !pcchValueBuf) || !wzBundleId || !wzAttribute)
53 { 54 {
54 ExitOnFailure(hr = E_INVALIDARG, "An invalid parameter was passed to the function."); 55 ButilExitOnFailure(hr = E_INVALIDARG, "An invalid parameter was passed to the function.");
55 } 56 }
56 57
57 if (FAILED(hr = OpenBundleKey(wzBundleId, context = BUNDLE_INSTALL_CONTEXT_MACHINE, &hkBundle)) && 58 if (FAILED(hr = OpenBundleKey(wzBundleId, context = BUNDLE_INSTALL_CONTEXT_MACHINE, &hkBundle)) &&
58 FAILED(hr = OpenBundleKey(wzBundleId, context = BUNDLE_INSTALL_CONTEXT_USER, &hkBundle))) 59 FAILED(hr = OpenBundleKey(wzBundleId, context = BUNDLE_INSTALL_CONTEXT_USER, &hkBundle)))
59 { 60 {
60 ExitOnFailure(E_FILENOTFOUND == hr ? HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT) : hr, "Failed to locate bundle uninstall key path."); 61 ButilExitOnFailure(E_FILENOTFOUND == hr ? HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT) : hr, "Failed to locate bundle uninstall key path.");
61 } 62 }
62 63
63 // If the bundle doesn't have the property defined, return ERROR_UNKNOWN_PROPERTY 64 // If the bundle doesn't have the property defined, return ERROR_UNKNOWN_PROPERTY
64 hr = RegGetType(hkBundle, wzAttribute, &dwType); 65 hr = RegGetType(hkBundle, wzAttribute, &dwType);
65 ExitOnFailure(E_FILENOTFOUND == hr ? HRESULT_FROM_WIN32(ERROR_UNKNOWN_PROPERTY) : hr, "Failed to locate bundle property."); 66 ButilExitOnFailure(E_FILENOTFOUND == hr ? HRESULT_FROM_WIN32(ERROR_UNKNOWN_PROPERTY) : hr, "Failed to locate bundle property.");
66 67
67 switch (dwType) 68 switch (dwType)
68 { 69 {
69 case REG_SZ: 70 case REG_SZ:
70 hr = RegReadString(hkBundle, wzAttribute, &sczValue); 71 hr = RegReadString(hkBundle, wzAttribute, &sczValue);
71 ExitOnFailure(hr, "Failed to read string property."); 72 ButilExitOnFailure(hr, "Failed to read string property.");
72 break; 73 break;
73 case REG_DWORD: 74 case REG_DWORD:
74 hr = RegReadNumber(hkBundle, wzAttribute, &dwValue); 75 hr = RegReadNumber(hkBundle, wzAttribute, &dwValue);
75 ExitOnFailure(hr, "Failed to read dword property."); 76 ButilExitOnFailure(hr, "Failed to read dword property.");
76 77
77 hr = StrAllocFormatted(&sczValue, L"%d", dwValue); 78 hr = StrAllocFormatted(&sczValue, L"%d", dwValue);
78 ExitOnFailure(hr, "Failed to format dword property as string."); 79 ButilExitOnFailure(hr, "Failed to format dword property as string.");
79 break; 80 break;
80 default: 81 default:
81 ExitOnFailure(hr = E_NOTIMPL, "Reading bundle info of type 0x%x not implemented.", dwType); 82 ButilExitOnFailure(hr = E_NOTIMPL, "Reading bundle info of type 0x%x not implemented.", dwType);
82 83
83 } 84 }
84 85
85 hr = ::StringCchLengthW(sczValue, STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchSource)); 86 hr = ::StringCchLengthW(sczValue, STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchSource));
86 ExitOnFailure(hr, "Failed to calculate length of string"); 87 ButilExitOnFailure(hr, "Failed to calculate length of string");
87 88
88 if (lpValueBuf) 89 if (lpValueBuf)
89 { 90 {
@@ -91,11 +92,11 @@ extern "C" HRESULT DAPI BundleGetBundleInfo(
91 if (*pcchValueBuf <= cchSource) 92 if (*pcchValueBuf <= cchSource)
92 { 93 {
93 *pcchValueBuf = ++cchSource; 94 *pcchValueBuf = ++cchSource;
94 ExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_MORE_DATA), "A buffer is too small to hold the requested data."); 95 ButilExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_MORE_DATA), "A buffer is too small to hold the requested data.");
95 } 96 }
96 97
97 hr = ::StringCchCatNExW(lpValueBuf, *pcchValueBuf, sczValue, cchSource, NULL, NULL, STRSAFE_FILL_BEHIND_NULL); 98 hr = ::StringCchCatNExW(lpValueBuf, *pcchValueBuf, sczValue, cchSource, NULL, NULL, STRSAFE_FILL_BEHIND_NULL);
98 ExitOnFailure(hr, "Failed to copy the property value to the output buffer."); 99 ButilExitOnFailure(hr, "Failed to copy the property value to the output buffer.");
99 100
100 *pcchValueBuf = cchSource++; 101 *pcchValueBuf = cchSource++;
101 } 102 }
@@ -107,19 +108,8 @@ LExit:
107 return hr; 108 return hr;
108} 109}
109 110
110/********************************************************************
111BundleEnumRelatedBundle - Queries the bundle installation metadata for installs with the given upgrade code
112
113NOTE: lpBundleIdBuff is a buffer to receive the bundle GUID. This buffer must be 39 characters long.
114 The first 38 characters are for the GUID, and the last character is for the terminating null character.
115RETURNS:
116 E_INVALIDARG
117 An invalid parameter was passed to the function.
118
119 All other returns are unexpected returns from other dutil methods.
120********************************************************************/
121HRESULT DAPI BundleEnumRelatedBundle( 111HRESULT DAPI BundleEnumRelatedBundle(
122 __in LPCWSTR wzUpgradeCode, 112 __in_z LPCWSTR wzUpgradeCode,
123 __in BUNDLE_INSTALL_CONTEXT context, 113 __in BUNDLE_INSTALL_CONTEXT context,
124 __inout PDWORD pdwStartIndex, 114 __inout PDWORD pdwStartIndex,
125 __out_ecount(MAX_GUID_CHARS+1) LPWSTR lpBundleIdBuf 115 __out_ecount(MAX_GUID_CHARS+1) LPWSTR lpBundleIdBuf
@@ -141,22 +131,22 @@ HRESULT DAPI BundleEnumRelatedBundle(
141 131
142 if (!wzUpgradeCode || !lpBundleIdBuf || !pdwStartIndex) 132 if (!wzUpgradeCode || !lpBundleIdBuf || !pdwStartIndex)
143 { 133 {
144 ExitOnFailure(hr = E_INVALIDARG, "An invalid parameter was passed to the function."); 134 ButilExitOnFailure(hr = E_INVALIDARG, "An invalid parameter was passed to the function.");
145 } 135 }
146 136
147 hr = RegOpen(hkRoot, BUNDLE_REGISTRATION_REGISTRY_UNINSTALL_KEY, KEY_READ, &hkUninstall); 137 hr = RegOpen(hkRoot, BUNDLE_REGISTRATION_REGISTRY_UNINSTALL_KEY, KEY_READ, &hkUninstall);
148 ExitOnFailure(hr, "Failed to open bundle uninstall key path."); 138 ButilExitOnFailure(hr, "Failed to open bundle uninstall key path.");
149 139
150 for (DWORD dwIndex = *pdwStartIndex; !fUpgradeCodeFound; dwIndex++) 140 for (DWORD dwIndex = *pdwStartIndex; !fUpgradeCodeFound; dwIndex++)
151 { 141 {
152 hr = RegKeyEnum(hkUninstall, dwIndex, &sczUninstallSubKey); 142 hr = RegKeyEnum(hkUninstall, dwIndex, &sczUninstallSubKey);
153 ExitOnFailure(hr, "Failed to enumerate bundle uninstall key path."); 143 ButilExitOnFailure(hr, "Failed to enumerate bundle uninstall key path.");
154 144
155 hr = StrAllocFormatted(&sczUninstallSubKeyPath, L"%ls\\%ls", BUNDLE_REGISTRATION_REGISTRY_UNINSTALL_KEY, sczUninstallSubKey); 145 hr = StrAllocFormatted(&sczUninstallSubKeyPath, L"%ls\\%ls", BUNDLE_REGISTRATION_REGISTRY_UNINSTALL_KEY, sczUninstallSubKey);
156 ExitOnFailure(hr, "Failed to allocate bundle uninstall key path."); 146 ButilExitOnFailure(hr, "Failed to allocate bundle uninstall key path.");
157 147
158 hr = RegOpen(hkRoot, sczUninstallSubKeyPath, KEY_READ, &hkBundle); 148 hr = RegOpen(hkRoot, sczUninstallSubKeyPath, KEY_READ, &hkBundle);
159 ExitOnFailure(hr, "Failed to open uninstall key path."); 149 ButilExitOnFailure(hr, "Failed to open uninstall key path.");
160 150
161 // If it's a bundle, it should have a BundleUpgradeCode value of type REG_SZ (old) or REG_MULTI_SZ 151 // If it's a bundle, it should have a BundleUpgradeCode value of type REG_SZ (old) or REG_MULTI_SZ
162 hr = RegGetType(hkBundle, BUNDLE_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE, &dwType); 152 hr = RegGetType(hkBundle, BUNDLE_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE, &dwType);
@@ -173,7 +163,7 @@ HRESULT DAPI BundleEnumRelatedBundle(
173 { 163 {
174 case REG_SZ: 164 case REG_SZ:
175 hr = RegReadString(hkBundle, BUNDLE_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE, &sczValue); 165 hr = RegReadString(hkBundle, BUNDLE_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE, &sczValue);
176 ExitOnFailure(hr, "Failed to read BundleUpgradeCode string property."); 166 ButilExitOnFailure(hr, "Failed to read BundleUpgradeCode string property.");
177 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, sczValue, -1, wzUpgradeCode, -1)) 167 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, sczValue, -1, wzUpgradeCode, -1))
178 { 168 {
179 *pdwStartIndex = dwIndex; 169 *pdwStartIndex = dwIndex;
@@ -186,7 +176,7 @@ HRESULT DAPI BundleEnumRelatedBundle(
186 break; 176 break;
187 case REG_MULTI_SZ: 177 case REG_MULTI_SZ:
188 hr = RegReadStringArray(hkBundle, BUNDLE_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE, &rgsczBundleUpgradeCodes, &cBundleUpgradeCodes); 178 hr = RegReadStringArray(hkBundle, BUNDLE_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE, &rgsczBundleUpgradeCodes, &cBundleUpgradeCodes);
189 ExitOnFailure(hr, "Failed to read BundleUpgradeCode multi-string property."); 179 ButilExitOnFailure(hr, "Failed to read BundleUpgradeCode multi-string property.");
190 180
191 for (DWORD i = 0; i < cBundleUpgradeCodes; i++) 181 for (DWORD i = 0; i < cBundleUpgradeCodes; i++)
192 { 182 {
@@ -206,7 +196,7 @@ HRESULT DAPI BundleEnumRelatedBundle(
206 break; 196 break;
207 197
208 default: 198 default:
209 ExitOnFailure(hr = E_NOTIMPL, "BundleUpgradeCode of type 0x%x not implemented.", dwType); 199 ButilExitOnFailure(hr = E_NOTIMPL, "BundleUpgradeCode of type 0x%x not implemented.", dwType);
210 200
211 } 201 }
212 202
@@ -215,10 +205,10 @@ HRESULT DAPI BundleEnumRelatedBundle(
215 if (lpBundleIdBuf) 205 if (lpBundleIdBuf)
216 { 206 {
217 hr = ::StringCchLengthW(sczUninstallSubKey, STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchUninstallSubKey)); 207 hr = ::StringCchLengthW(sczUninstallSubKey, STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchUninstallSubKey));
218 ExitOnFailure(hr, "Failed to calculate length of string"); 208 ButilExitOnFailure(hr, "Failed to calculate length of string");
219 209
220 hr = ::StringCchCopyNExW(lpBundleIdBuf, MAX_GUID_CHARS + 1, sczUninstallSubKey, cchUninstallSubKey, NULL, NULL, STRSAFE_FILL_BEHIND_NULL); 210 hr = ::StringCchCopyNExW(lpBundleIdBuf, MAX_GUID_CHARS + 1, sczUninstallSubKey, cchUninstallSubKey, NULL, NULL, STRSAFE_FILL_BEHIND_NULL);
221 ExitOnFailure(hr, "Failed to copy the property value to the output buffer."); 211 ButilExitOnFailure(hr, "Failed to copy the property value to the output buffer.");
222 } 212 }
223 213
224 break; 214 break;
@@ -241,13 +231,9 @@ LExit:
241 return hr; 231 return hr;
242} 232}
243 233
244/********************************************************************
245OpenBundleKey - Opens the bundle uninstallation key for a given bundle
246 234
247NOTE: caller is responsible for closing key
248********************************************************************/
249HRESULT OpenBundleKey( 235HRESULT OpenBundleKey(
250 __in LPCWSTR wzBundleId, 236 __in_z LPCWSTR wzBundleId,
251 __in BUNDLE_INSTALL_CONTEXT context, 237 __in BUNDLE_INSTALL_CONTEXT context,
252 __inout HKEY *key) 238 __inout HKEY *key)
253{ 239{
@@ -259,10 +245,10 @@ HRESULT OpenBundleKey(
259 LPWSTR sczKeypath = NULL; 245 LPWSTR sczKeypath = NULL;
260 246
261 hr = StrAllocFormatted(&sczKeypath, L"%ls\\%ls", BUNDLE_REGISTRATION_REGISTRY_UNINSTALL_KEY, wzBundleId); 247 hr = StrAllocFormatted(&sczKeypath, L"%ls\\%ls", BUNDLE_REGISTRATION_REGISTRY_UNINSTALL_KEY, wzBundleId);
262 ExitOnFailure(hr, "Failed to allocate bundle uninstall key path."); 248 ButilExitOnFailure(hr, "Failed to allocate bundle uninstall key path.");
263 249
264 hr = RegOpen(hkRoot, sczKeypath, KEY_READ, key); 250 hr = RegOpen(hkRoot, sczKeypath, KEY_READ, key);
265 ExitOnFailure(hr, "Failed to open bundle uninstall key path."); 251 ButilExitOnFailure(hr, "Failed to open bundle uninstall key path.");
266 252
267LExit: 253LExit:
268 ReleaseStr(sczKeypath); 254 ReleaseStr(sczKeypath);
diff --git a/src/dutil/inc/butil.h b/src/dutil/inc/butil.h
index a42cac11..d1ec73bc 100644
--- a/src/dutil/inc/butil.h
+++ b/src/dutil/inc/butil.h
@@ -12,15 +12,44 @@ enum BUNDLE_INSTALL_CONTEXT
12 BUNDLE_INSTALL_CONTEXT_USER, 12 BUNDLE_INSTALL_CONTEXT_USER,
13}; 13};
14 14
15
16/********************************************************************
17BundleGetBundleInfo - Queries the bundle installation metadata for a given property
18
19RETURNS:
20 E_INVALIDARG
21 An invalid parameter was passed to the function.
22 HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT)
23 The bundle is not installed
24 HRESULT_FROM_WIN32(ERROR_UNKNOWN_PROPERTY)
25 The property is unrecognized
26 HRESULT_FROM_WIN32(ERROR_MORE_DATA)
27 A buffer is too small to hold the requested data.
28 E_NOTIMPL:
29 Tried to read a bundle attribute for a type which has not been implemented
30
31 All other returns are unexpected returns from other dutil methods.
32********************************************************************/
15HRESULT DAPI BundleGetBundleInfo( 33HRESULT DAPI BundleGetBundleInfo(
16 __in LPCWSTR szBundleId, // Bundle code 34 __in_z LPCWSTR szBundleId, // Bundle code
17 __in LPCWSTR szAttribute, // attribute name 35 __in_z LPCWSTR szAttribute, // attribute name
18 __out_ecount_opt(*pcchValueBuf) LPWSTR lpValueBuf, // returned value, NULL if not desired 36 __out_ecount_opt(*pcchValueBuf) LPWSTR lpValueBuf, // returned value, NULL if not desired
19 __inout_opt LPDWORD pcchValueBuf // in/out buffer character count 37 __inout_opt LPDWORD pcchValueBuf // in/out buffer character count
20 ); 38 );
21 39
40/********************************************************************
41BundleEnumRelatedBundle - Queries the bundle installation metadata for installs with the given upgrade code
42
43NOTE: lpBundleIdBuff is a buffer to receive the bundle GUID. This buffer must be 39 characters long.
44 The first 38 characters are for the GUID, and the last character is for the terminating null character.
45RETURNS:
46 E_INVALIDARG
47 An invalid parameter was passed to the function.
48
49 All other returns are unexpected returns from other dutil methods.
50********************************************************************/
22HRESULT DAPI BundleEnumRelatedBundle( 51HRESULT DAPI BundleEnumRelatedBundle(
23 __in LPCWSTR lpUpgradeCode, 52 __in_z LPCWSTR lpUpgradeCode,
24 __in BUNDLE_INSTALL_CONTEXT context, 53 __in BUNDLE_INSTALL_CONTEXT context,
25 __inout PDWORD pdwStartIndex, 54 __inout PDWORD pdwStartIndex,
26 __out_ecount(MAX_GUID_CHARS+1) LPWSTR lpBundleIdBuf 55 __out_ecount(MAX_GUID_CHARS+1) LPWSTR lpBundleIdBuf