@joebigelow / wix / commits / a37208d9

Make sure error codes are translated correctly for per-machine packages.

Sean Hall committed Aug 25, 2022 at 15:06 UTC a37208d9a26ec7886870cc17f0726676a285bf7f
14 files changed +554 -165
src/burn/engine/bundlepackageengine.cpp
+1 -1
@@ -1014,7 +1014,7 @@ static HRESULT ExecuteBundle(
1014 ExitOnFailure(hr, "Failed to run BUNDLE process");
1015 }
1016
1017 - hr = ExeEngineHandleExitCode(pPackage->Bundle.rgExitCodes, pPackage->Bundle.cExitCodes, dwExitCode, pRestart);
1017 + hr = ExeEngineHandleExitCode(pPackage->Bundle.rgExitCodes, pPackage->Bundle.cExitCodes, pPackage->sczId, dwExitCode, pRestart);
1018 ExitOnRootFailure(hr, "Process returned error: 0x%x", dwExitCode);
1019
1020 LExit:
src/burn/engine/elevation.cpp
+144 -156
@@ -53,6 +53,7 @@ typedef enum _BURN_ELEVATION_MESSAGE_TYPE
53 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_NETFX_FILES_IN_USE,
54 BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE_PROCESSID,
55 BURN_ELEVATION_MESSAGE_TYPE_PROGRESS_ROUTINE,
56 + BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ACTION_COMPLETE,
57 } BURN_ELEVATION_MESSAGE_TYPE;
58
59
@@ -76,12 +77,14 @@ typedef struct _BURN_ELEVATION_GENERIC_MESSAGE_CONTEXT
77 {
78 PFN_GENERICMESSAGEHANDLER pfnGenericMessageHandler;
79 LPVOID pvContext;
80 + BOOTSTRAPPER_APPLY_RESTART restart;
81 } BURN_ELEVATION_GENERIC_MESSAGE_CONTEXT;
82
83 typedef struct _BURN_ELEVATION_MSI_MESSAGE_CONTEXT
84 {
85 PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler;
86 LPVOID pvContext;
87 + BOOTSTRAPPER_APPLY_RESTART restart;
88 } BURN_ELEVATION_MSI_MESSAGE_CONTEXT;
89
90 typedef struct _BURN_ELEVATION_LAUNCH_APPROVED_EXE_MESSAGE_CONTEXT
@@ -166,9 +169,11 @@ static HRESULT ProcessElevatedChildCacheMessage(
169 __in_opt LPVOID pvContext,
170 __out DWORD* pdwResult
171 );
169 -static HRESULT ProcessResult(
170 - __in DWORD dwResult,
171 - __out BOOTSTRAPPER_APPLY_RESTART* pRestart
172 +static HRESULT ProcessExecuteActionCompleteMessage(
173 + __in BYTE* pbData,
174 + __in DWORD cbData,
175 + __out BOOTSTRAPPER_APPLY_RESTART* pRestart,
176 + __out DWORD* pdwResult
177 );
178 static HRESULT OnApplyInitialize(
179 __in HANDLE hPipe,
@@ -246,7 +251,8 @@ static HRESULT OnExecuteRelatedBundle(
251 __in BURN_RELATED_BUNDLES* pRelatedBundles,
252 __in BURN_VARIABLES* pVariables,
253 __in BYTE* pbData,
249 - __in SIZE_T cbData
254 + __in SIZE_T cbData,
255 + __out BOOTSTRAPPER_APPLY_RESTART* pRestart
256 );
257 static HRESULT OnExecuteBundlePackage(
258 __in HANDLE hPipe,
@@ -254,7 +260,8 @@ static HRESULT OnExecuteBundlePackage(
260 __in BURN_PACKAGES* pPackages,
261 __in BURN_VARIABLES* pVariables,
262 __in BYTE* pbData,
257 - __in SIZE_T cbData
263 + __in SIZE_T cbData,
264 + __out BOOTSTRAPPER_APPLY_RESTART* pRestart
265 );
266 static HRESULT OnExecuteExePackage(
267 __in HANDLE hPipe,
@@ -262,7 +269,8 @@ static HRESULT OnExecuteExePackage(
269 __in BURN_PACKAGES* pPackages,
270 __in BURN_VARIABLES* pVariables,
271 __in BYTE* pbData,
265 - __in SIZE_T cbData
272 + __in SIZE_T cbData,
273 + __out BOOTSTRAPPER_APPLY_RESTART* pRestart
274 );
275 static HRESULT OnExecuteMsiPackage(
276 __in HANDLE hPipe,
@@ -270,7 +278,8 @@ static HRESULT OnExecuteMsiPackage(
278 __in BURN_PACKAGES* pPackages,
279 __in BURN_VARIABLES* pVariables,
280 __in BYTE* pbData,
273 - __in SIZE_T cbData
281 + __in SIZE_T cbData,
282 + __out BOOTSTRAPPER_APPLY_RESTART* pRestart
283 );
284 static HRESULT OnExecuteMspPackage(
285 __in HANDLE hPipe,
@@ -278,7 +287,8 @@ static HRESULT OnExecuteMspPackage(
287 __in BURN_PACKAGES* pPackages,
288 __in BURN_VARIABLES* pVariables,
289 __in BYTE* pbData,
281 - __in SIZE_T cbData
290 + __in SIZE_T cbData,
291 + __out BOOTSTRAPPER_APPLY_RESTART* pRestart
292 );
293 static HRESULT OnExecuteMsuPackage(
294 __in HANDLE hPipe,
@@ -286,7 +296,8 @@ static HRESULT OnExecuteMsuPackage(
296 __in BURN_PACKAGES* pPackages,
297 __in BURN_VARIABLES* pVariables,
298 __in BYTE* pbData,
289 - __in SIZE_T cbData
299 + __in SIZE_T cbData,
300 + __out BOOTSTRAPPER_APPLY_RESTART* pRestart
301 );
302 static HRESULT OnUninstallMsiCompatiblePackage(
303 __in HANDLE hPipe,
@@ -294,7 +305,8 @@ static HRESULT OnUninstallMsiCompatiblePackage(
305 __in BURN_PACKAGES* pPackages,
306 __in BURN_VARIABLES* pVariables,
307 __in BYTE* pbData,
297 - __in SIZE_T cbData
308 + __in SIZE_T cbData,
309 + __out BOOTSTRAPPER_APPLY_RESTART* pRestart
310 );
311 static HRESULT OnExecutePackageProviderAction(
312 __in BURN_PACKAGES* pPackages,
@@ -380,6 +392,10 @@ static HRESULT ElevatedOnSystemRestorePointComplete(
392 __in HANDLE hPipe,
393 __in HRESULT hrStatus
394 );
395 +static HRESULT ElevatedOnExecuteActionComplete(
396 + __in HANDLE hPipe,
397 + __in BOOTSTRAPPER_APPLY_RESTART restart
398 + );
399
400
401 // function definitions
@@ -868,7 +884,8 @@ extern "C" HRESULT ElevationExecuteRelatedBundle(
884 hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_RELATED_BUNDLE, pbData, cbData, ProcessGenericExecuteMessages, &context, &dwResult);
885 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_RELATED_BUNDLE message to per-machine process.");
886
871 - hr = ProcessResult(dwResult, pRestart);
887 + hr = static_cast<HRESULT>(dwResult);
888 + *pRestart = context.restart;
889
890 LExit:
891 ReleaseBuffer(pbData);
@@ -931,7 +948,8 @@ extern "C" HRESULT ElevationExecuteBundlePackage(
948 hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_BUNDLE_PACKAGE, pbData, cbData, ProcessGenericExecuteMessages, &context, &dwResult);
949 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_BUNDLE_PACKAGE message to per-machine process.");
950
934 - hr = ProcessResult(dwResult, pRestart);
951 + hr = static_cast<HRESULT>(dwResult);
952 + *pRestart = context.restart;
953
954 LExit:
955 ReleaseBuffer(pbData);
@@ -985,7 +1003,8 @@ extern "C" HRESULT ElevationExecuteExePackage(
1003 hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_EXE_PACKAGE, pbData, cbData, ProcessGenericExecuteMessages, &context, &dwResult);
1004 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_EXE_PACKAGE message to per-machine process.");
1005
988 - hr = ProcessResult(dwResult, pRestart);
1006 + hr = static_cast<HRESULT>(dwResult);
1007 + *pRestart = context.restart;
1008
1009 LExit:
1010 ReleaseBuffer(pbData);
@@ -1155,7 +1174,8 @@ extern "C" HRESULT ElevationExecuteMsiPackage(
1174 hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_PACKAGE, pbData, cbData, ProcessMsiPackageMessages, &context, &dwResult);
1175 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_PACKAGE message to per-machine process.");
1176
1158 - hr = ProcessResult(dwResult, pRestart);
1177 + hr = static_cast<HRESULT>(dwResult);
1178 + *pRestart = context.restart;
1179
1180 LExit:
1181 ReleaseBuffer(pbData);
@@ -1234,7 +1254,8 @@ extern "C" HRESULT ElevationExecuteMspPackage(
1254 hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSP_PACKAGE, pbData, cbData, ProcessMsiPackageMessages, &context, &dwResult);
1255 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSP_PACKAGE message to per-machine process.");
1256
1237 - hr = ProcessResult(dwResult, pRestart);
1257 + hr = static_cast<HRESULT>(dwResult);
1258 + *pRestart = context.restart;
1259
1260 LExit:
1261 ReleaseBuffer(pbData);
@@ -1285,7 +1306,8 @@ extern "C" HRESULT ElevationExecuteMsuPackage(
1306 hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSU_PACKAGE, pbData, cbData, ProcessGenericExecuteMessages, &context, &dwResult);
1307 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSU_PACKAGE message to per-machine process.");
1308
1288 - hr = ProcessResult(dwResult, pRestart);
1309 + hr = static_cast<HRESULT>(dwResult);
1310 + *pRestart = context.restart;
1311
1312 LExit:
1313 ReleaseBuffer(pbData);
@@ -1337,7 +1359,8 @@ extern "C" HRESULT ElevationUninstallMsiCompatiblePackage(
1359 hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE, pbData, cbData, ProcessMsiPackageMessages, &context, &dwResult);
1360 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE message to per-machine process.");
1361
1340 - hr = ProcessResult(dwResult, pRestart);
1362 + hr = static_cast<HRESULT>(dwResult);
1363 + *pRestart = context.restart;
1364
1365 LExit:
1366 ReleaseBuffer(pbData);
@@ -1355,7 +1378,6 @@ extern "C" HRESULT ElevationExecutePackageProviderAction(
1378 BYTE* pbData = NULL;
1379 SIZE_T cbData = 0;
1380 DWORD dwResult = 0;
1358 - BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE;
1381
1382 // Serialize the message data.
1383 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->packageProvider.pPackage->sczId);
@@ -1377,9 +1399,6 @@ extern "C" HRESULT ElevationExecutePackageProviderAction(
1399 hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_PROVIDER, pbData, cbData, NULL, NULL, &dwResult);
1400 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_PROVIDER message to per-machine process.");
1401
1380 - // Ignore the restart since this action only results in registry writes.
1381 - hr = ProcessResult(dwResult, &restart);
1382 -
1402 LExit:
1403 ReleaseBuffer(pbData);
1404
@@ -1396,7 +1415,6 @@ extern "C" HRESULT ElevationExecutePackageDependencyAction(
1415 BYTE* pbData = NULL;
1416 SIZE_T cbData = 0;
1417 DWORD dwResult = 0;
1399 - BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE;
1418
1419 // Serialize the message data.
1420 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->packageDependency.pPackage->sczId);
@@ -1421,9 +1439,6 @@ extern "C" HRESULT ElevationExecutePackageDependencyAction(
1439 hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_DEPENDENCY, pbData, cbData, NULL, NULL, &dwResult);
1440 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_DEPENDENCY message to per-machine process.");
1441
1424 - // Ignore the restart since this action only results in registry writes.
1425 - hr = ProcessResult(dwResult, &restart);
1426 -
1442 LExit:
1443 ReleaseBuffer(pbData);
1444
@@ -1839,6 +1854,14 @@ static HRESULT ProcessGenericExecuteMessages(
1854 LPWSTR* rgwzFiles = NULL;
1855 GENERIC_EXECUTE_MESSAGE message = { };
1856
1857 + if (BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ACTION_COMPLETE == pMsg->dwMessage)
1858 + {
1859 + hr = ProcessExecuteActionCompleteMessage((BYTE*)pMsg->pvData, pMsg->cbData, &pContext->restart, pdwResult);
1860 + ExitOnFailure(hr, "Failed to process BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ACTION_COMPLETE message.");
1861 +
1862 + ExitFunction();
1863 + }
1864 +
1865 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.dwUIHint);
1866 ExitOnFailure(hr, "Failed to allowed results.");
1867
@@ -1939,6 +1962,14 @@ static HRESULT ProcessMsiPackageMessages(
1962 LPWSTR sczMessage = NULL;
1963 BOOL fRestartManager = FALSE;
1964
1965 + if (BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ACTION_COMPLETE == pMsg->dwMessage)
1966 + {
1967 + hr = ProcessExecuteActionCompleteMessage((BYTE*)pMsg->pvData, pMsg->cbData, &pContext->restart, pdwResult);
1968 + ExitOnFailure(hr, "Failed to process BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ACTION_COMPLETE message.");
1969 +
1970 + ExitFunction();
1971 + }
1972 +
1973 // Read MSI extended message data.
1974 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &cMsiData);
1975 ExitOnFailure(hr, "Failed to read MSI data count.");
@@ -2102,7 +2133,8 @@ static HRESULT ProcessElevatedChildMessage(
2133 HRESULT hr = S_OK;
2134 BURN_ELEVATION_CHILD_MESSAGE_CONTEXT* pContext = static_cast<BURN_ELEVATION_CHILD_MESSAGE_CONTEXT*>(pvContext);
2135 HRESULT hrResult = S_OK;
2105 - DWORD dwPid = 0;
2136 + BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE;
2137 + BOOL fSendRestart = FALSE;
2138
2139 switch (pMsg->dwMessage)
2140 {
@@ -2143,27 +2175,33 @@ static HRESULT ProcessElevatedChildMessage(
2175 break;
2176
2177 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_RELATED_BUNDLE:
2146 - hrResult = OnExecuteRelatedBundle(pContext->hPipe, pContext->pCache, &pContext->pRegistration->relatedBundles, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData);
2178 + hrResult = OnExecuteRelatedBundle(pContext->hPipe, pContext->pCache, &pContext->pRegistration->relatedBundles, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData, &restart);
2179 + fSendRestart = TRUE;
2180 break;
2181
2182 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_BUNDLE_PACKAGE:
2150 - hrResult = OnExecuteBundlePackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData);
2183 + hrResult = OnExecuteBundlePackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData, &restart);
2184 + fSendRestart = TRUE;
2185 break;
2186
2187 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_EXE_PACKAGE:
2154 - hrResult = OnExecuteExePackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData);
2188 + hrResult = OnExecuteExePackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData, &restart);
2189 + fSendRestart = TRUE;
2190 break;
2191
2192 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_PACKAGE:
2158 - hrResult = OnExecuteMsiPackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData);
2193 + hrResult = OnExecuteMsiPackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData, &restart);
2194 + fSendRestart = TRUE;
2195 break;
2196
2197 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSP_PACKAGE:
2162 - hrResult = OnExecuteMspPackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData);
2198 + hrResult = OnExecuteMspPackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData, &restart);
2199 + fSendRestart = TRUE;
2200 break;
2201
2202 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSU_PACKAGE:
2166 - hrResult = OnExecuteMsuPackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData);
2203 + hrResult = OnExecuteMsuPackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData, &restart);
2204 + fSendRestart = TRUE;
2205 break;
2206
2207 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_PROVIDER:
@@ -2183,7 +2221,8 @@ static HRESULT ProcessElevatedChildMessage(
2221 break;
2222
2223 case BURN_ELEVATION_MESSAGE_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE:
2186 - hrResult = OnUninstallMsiCompatiblePackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData);
2224 + hrResult = OnUninstallMsiCompatiblePackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData, &restart);
2225 + fSendRestart = TRUE;
2226 break;
2227
2228 case BURN_ELEVATION_MESSAGE_TYPE_CLEAN_COMPATIBLE_PACKAGE:
@@ -2191,11 +2230,16 @@ static HRESULT ProcessElevatedChildMessage(
2230 break;
2231
2232 default:
2194 - hr = E_INVALIDARG;
2195 - ExitOnRootFailure(hr, "Unexpected elevated message sent to child process, msg: %u", pMsg->dwMessage);
2233 + ExitWithRootFailure(hr, E_INVALIDARG, "Unexpected elevated message sent to child process, msg: %u", pMsg->dwMessage);
2234 }
2235
2198 - *pdwResult = dwPid ? dwPid : (DWORD)hrResult;
2236 + if (fSendRestart)
2237 + {
2238 + hr = ElevatedOnExecuteActionComplete(pContext->hPipe, restart);
2239 + ExitOnFailure(hr, "ElevatedOnExecuteActionComplete failed.");
2240 + }
2241 +
2242 + *pdwResult = (DWORD)hrResult;
2243
2244 LExit:
2245 return hr;
@@ -2245,23 +2289,22 @@ LExit:
2289 return hr;
2290 }
2291
2248 -static HRESULT ProcessResult(
2249 - __in DWORD dwResult,
2250 - __out BOOTSTRAPPER_APPLY_RESTART* pRestart
2292 +static HRESULT ProcessExecuteActionCompleteMessage(
2293 + __in BYTE* pbData,
2294 + __in DWORD cbData,
2295 + __out BOOTSTRAPPER_APPLY_RESTART* pRestart,
2296 + __out DWORD* pdwResult
2297 )
2298 {
2253 - HRESULT hr = static_cast<HRESULT>(dwResult);
2254 - if (HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED) == hr)
2255 - {
2256 - *pRestart = BOOTSTRAPPER_APPLY_RESTART_REQUIRED;
2257 - hr = S_OK;
2258 - }
2259 - else if (HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_INITIATED) == hr)
2260 - {
2261 - *pRestart = BOOTSTRAPPER_APPLY_RESTART_INITIATED;
2262 - hr = S_OK;
2263 - }
2299 + HRESULT hr = S_OK;
2300 + SIZE_T iData = 0;
2301 +
2302 + hr = BuffReadNumber(pbData, cbData, &iData, reinterpret_cast<DWORD*>(pRestart));
2303 + ExitOnFailure(hr, "Failed to read execute action restart result.");
2304 +
2305 + *pdwResult = (DWORD)hr;
2306
2307 +LExit:
2308 return hr;
2309 }
2310
@@ -2759,7 +2802,8 @@ static HRESULT OnExecuteRelatedBundle(
2802 __in BURN_RELATED_BUNDLES* pRelatedBundles,
2803 __in BURN_VARIABLES* pVariables,
2804 __in BYTE* pbData,
2762 - __in SIZE_T cbData
2805 + __in SIZE_T cbData,
2806 + __out BOOTSTRAPPER_APPLY_RESTART* pRestart
2807 )
2808 {
2809 HRESULT hr = S_OK;
@@ -2771,7 +2815,7 @@ static HRESULT OnExecuteRelatedBundle(
2815 LPWSTR sczIgnoreDependencies = NULL;
2816 LPWSTR sczAncestors = NULL;
2817 LPWSTR sczEngineWorkingDirectory = NULL;
2774 - BOOTSTRAPPER_APPLY_RESTART bundleRestart = BOOTSTRAPPER_APPLY_RESTART_NONE;
2818 + *pRestart = BOOTSTRAPPER_APPLY_RESTART_NONE;
2819
2820 executeAction.type = BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE;
2821
@@ -2826,7 +2870,7 @@ static HRESULT OnExecuteRelatedBundle(
2870 }
2871
2872 // Execute related bundle.
2829 - hr = BundlePackageEngineExecuteRelatedBundle(&executeAction, pCache, pVariables, static_cast<BOOL>(dwRollback), GenericExecuteMessageHandler, hPipe, &bundleRestart);
2873 + hr = BundlePackageEngineExecuteRelatedBundle(&executeAction, pCache, pVariables, static_cast<BOOL>(dwRollback), GenericExecuteMessageHandler, hPipe, pRestart);
2874 ExitOnFailure(hr, "Failed to execute related bundle.");
2875
2876 LExit:
@@ -2836,18 +2880,6 @@ LExit:
2880 ReleaseStr(sczPackage);
2881 PlanUninitializeExecuteAction(&executeAction);
2882
2839 - if (SUCCEEDED(hr))
2840 - {
2841 - if (BOOTSTRAPPER_APPLY_RESTART_REQUIRED == bundleRestart)
2842 - {
2843 - hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED);
2844 - }
2845 - else if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == bundleRestart)
2846 - {
2847 - hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_INITIATED);
2848 - }
2849 - }
2850 -
2883 return hr;
2884 }
2885
@@ -2857,7 +2889,8 @@ static HRESULT OnExecuteBundlePackage(
2889 __in BURN_PACKAGES* pPackages,
2890 __in BURN_VARIABLES* pVariables,
2891 __in BYTE* pbData,
2860 - __in SIZE_T cbData
2892 + __in SIZE_T cbData,
2893 + __out BOOTSTRAPPER_APPLY_RESTART* pRestart
2894 )
2895 {
2896 HRESULT hr = S_OK;
@@ -2869,7 +2902,7 @@ static HRESULT OnExecuteBundlePackage(
2902 LPWSTR sczIgnoreDependencies = NULL;
2903 LPWSTR sczAncestors = NULL;
2904 LPWSTR sczEngineWorkingDirectory = NULL;
2872 - BOOTSTRAPPER_APPLY_RESTART bundleRestart = BOOTSTRAPPER_APPLY_RESTART_NONE;
2905 + *pRestart = BOOTSTRAPPER_APPLY_RESTART_NONE;
2906
2907 executeAction.type = BURN_EXECUTE_ACTION_TYPE_BUNDLE_PACKAGE;
2908
@@ -2930,7 +2963,7 @@ static HRESULT OnExecuteBundlePackage(
2963 }
2964
2965 // Execute BUNDLE package.
2933 - hr = BundlePackageEngineExecutePackage(&executeAction, pCache, pVariables, fRollback, fCacheAvailable, GenericExecuteMessageHandler, hPipe, &bundleRestart);
2966 + hr = BundlePackageEngineExecutePackage(&executeAction, pCache, pVariables, fRollback, fCacheAvailable, GenericExecuteMessageHandler, hPipe, pRestart);
2967 ExitOnFailure(hr, "Failed to execute BUNDLE package.");
2968
2969 LExit:
@@ -2940,18 +2973,6 @@ LExit:
2973 ReleaseStr(sczPackage);
2974 PlanUninitializeExecuteAction(&executeAction);
2975
2943 - if (SUCCEEDED(hr))
2944 - {
2945 - if (BOOTSTRAPPER_APPLY_RESTART_REQUIRED == bundleRestart)
2946 - {
2947 - hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED);
2948 - }
2949 - else if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == bundleRestart)
2950 - {
2951 - hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_INITIATED);
2952 - }
2953 - }
2954 -
2976 return hr;
2977 }
2978
@@ -2961,7 +2982,8 @@ static HRESULT OnExecuteExePackage(
2982 __in BURN_PACKAGES* pPackages,
2983 __in BURN_VARIABLES* pVariables,
2984 __in BYTE* pbData,
2964 - __in SIZE_T cbData
2985 + __in SIZE_T cbData,
2986 + __out BOOTSTRAPPER_APPLY_RESTART* pRestart
2987 )
2988 {
2989 HRESULT hr = S_OK;
@@ -2971,7 +2993,7 @@ static HRESULT OnExecuteExePackage(
2993 BURN_EXECUTE_ACTION executeAction = { };
2994 LPWSTR sczAncestors = NULL;
2995 LPWSTR sczEngineWorkingDirectory = NULL;
2974 - BOOTSTRAPPER_APPLY_RESTART exeRestart = BOOTSTRAPPER_APPLY_RESTART_NONE;
2996 + *pRestart = BOOTSTRAPPER_APPLY_RESTART_NONE;
2997
2998 executeAction.type = BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE;
2999
@@ -3016,7 +3038,7 @@ static HRESULT OnExecuteExePackage(
3038 }
3039
3040 // Execute EXE package.
3019 - hr = ExeEngineExecutePackage(&executeAction, pCache, pVariables, static_cast<BOOL>(dwRollback), GenericExecuteMessageHandler, hPipe, &exeRestart);
3041 + hr = ExeEngineExecutePackage(&executeAction, pCache, pVariables, static_cast<BOOL>(dwRollback), GenericExecuteMessageHandler, hPipe, pRestart);
3042 ExitOnFailure(hr, "Failed to execute EXE package.");
3043
3044 LExit:
@@ -3025,18 +3047,6 @@ LExit:
3047 ReleaseStr(sczPackage);
3048 PlanUninitializeExecuteAction(&executeAction);
3049
3028 - if (SUCCEEDED(hr))
3029 - {
3030 - if (BOOTSTRAPPER_APPLY_RESTART_REQUIRED == exeRestart)
3031 - {
3032 - hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED);
3033 - }
3034 - else if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == exeRestart)
3035 - {
3036 - hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_INITIATED);
3037 - }
3038 - }
3039 -
3050 return hr;
3051 }
3052
@@ -3046,7 +3056,8 @@ static HRESULT OnExecuteMsiPackage(
3056 __in BURN_PACKAGES* pPackages,
3057 __in BURN_VARIABLES* pVariables,
3058 __in BYTE* pbData,
3049 - __in SIZE_T cbData
3059 + __in SIZE_T cbData,
3060 + __out BOOTSTRAPPER_APPLY_RESTART* pRestart
3061 )
3062 {
3063 HRESULT hr = S_OK;
@@ -3055,7 +3066,7 @@ static HRESULT OnExecuteMsiPackage(
3066 HWND hwndParent = NULL;
3067 BOOL fRollback = FALSE;
3068 BURN_EXECUTE_ACTION executeAction = { };
3058 - BOOTSTRAPPER_APPLY_RESTART msiRestart = BOOTSTRAPPER_APPLY_RESTART_NONE;
3069 + *pRestart = BOOTSTRAPPER_APPLY_RESTART_NONE;
3070
3071 executeAction.type = BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE;
3072
@@ -3124,25 +3135,13 @@ static HRESULT OnExecuteMsiPackage(
3135 }
3136
3137 // Execute MSI package.
3127 - hr = MsiEngineExecutePackage(hwndParent, &executeAction, pCache, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, &msiRestart);
3138 + hr = MsiEngineExecutePackage(hwndParent, &executeAction, pCache, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, pRestart);
3139 ExitOnFailure(hr, "Failed to execute MSI package.");
3140
3141 LExit:
3142 ReleaseStr(sczPackage);
3143 PlanUninitializeExecuteAction(&executeAction);
3144
3134 - if (SUCCEEDED(hr))
3135 - {
3136 - if (BOOTSTRAPPER_APPLY_RESTART_REQUIRED == msiRestart)
3137 - {
3138 - hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED);
3139 - }
3140 - else if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == msiRestart)
3141 - {
3142 - hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_INITIATED);
3143 - }
3144 - }
3145 -
3145 return hr;
3146 }
3147
@@ -3152,7 +3151,8 @@ static HRESULT OnExecuteMspPackage(
3151 __in BURN_PACKAGES* pPackages,
3152 __in BURN_VARIABLES* pVariables,
3153 __in BYTE* pbData,
3155 - __in SIZE_T cbData
3154 + __in SIZE_T cbData,
3155 + __out BOOTSTRAPPER_APPLY_RESTART* pRestart
3156 )
3157 {
3158 HRESULT hr = S_OK;
@@ -3161,7 +3161,7 @@ static HRESULT OnExecuteMspPackage(
3161 HWND hwndParent = NULL;
3162 BOOL fRollback = FALSE;
3163 BURN_EXECUTE_ACTION executeAction = { };
3164 - BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE;
3164 + *pRestart = BOOTSTRAPPER_APPLY_RESTART_NONE;
3165
3166 executeAction.type = BURN_EXECUTE_ACTION_TYPE_MSP_TARGET;
3167
@@ -3228,25 +3228,13 @@ static HRESULT OnExecuteMspPackage(
3228 }
3229
3230 // Execute MSP package.
3231 - hr = MspEngineExecutePackage(hwndParent, &executeAction, pCache, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, &restart);
3231 + hr = MspEngineExecutePackage(hwndParent, &executeAction, pCache, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, pRestart);
3232 ExitOnFailure(hr, "Failed to execute MSP package.");
3233
3234 LExit:
3235 ReleaseStr(sczPackage);
3236 PlanUninitializeExecuteAction(&executeAction);
3237
3238 - if (SUCCEEDED(hr))
3239 - {
3240 - if (BOOTSTRAPPER_APPLY_RESTART_REQUIRED == restart)
3241 - {
3242 - hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED);
3243 - }
3244 - else if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == restart)
3245 - {
3246 - hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_INITIATED);
3247 - }
3248 - }
3249 -
3238 return hr;
3239 }
3240
@@ -3256,7 +3244,8 @@ static HRESULT OnExecuteMsuPackage(
3244 __in BURN_PACKAGES* pPackages,
3245 __in BURN_VARIABLES* pVariables,
3246 __in BYTE* pbData,
3259 - __in SIZE_T cbData
3247 + __in SIZE_T cbData,
3248 + __out BOOTSTRAPPER_APPLY_RESTART* pRestart
3249 )
3250 {
3251 HRESULT hr = S_OK;
@@ -3265,7 +3254,7 @@ static HRESULT OnExecuteMsuPackage(
3254 DWORD dwRollback = 0;
3255 DWORD dwStopWusaService = 0;
3256 BURN_EXECUTE_ACTION executeAction = { };
3268 - BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE;
3257 + *pRestart = BOOTSTRAPPER_APPLY_RESTART_NONE;
3258
3259 executeAction.type = BURN_EXECUTE_ACTION_TYPE_MSU_PACKAGE;
3260
@@ -3294,25 +3283,13 @@ static HRESULT OnExecuteMsuPackage(
3283 }
3284
3285 // execute MSU package
3297 - hr = MsuEngineExecutePackage(&executeAction, pCache, pVariables, static_cast<BOOL>(dwRollback), static_cast<BOOL>(dwStopWusaService), GenericExecuteMessageHandler, hPipe, &restart);
3286 + hr = MsuEngineExecutePackage(&executeAction, pCache, pVariables, static_cast<BOOL>(dwRollback), static_cast<BOOL>(dwStopWusaService), GenericExecuteMessageHandler, hPipe, pRestart);
3287 ExitOnFailure(hr, "Failed to execute MSU package.");
3288
3289 LExit:
3290 ReleaseStr(sczPackage);
3291 PlanUninitializeExecuteAction(&executeAction);
3292
3304 - if (SUCCEEDED(hr))
3305 - {
3306 - if (BOOTSTRAPPER_APPLY_RESTART_REQUIRED == restart)
3307 - {
3308 - hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED);
3309 - }
3310 - else if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == restart)
3311 - {
3312 - hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_INITIATED);
3313 - }
3314 - }
3315 -
3293 return hr;
3294 }
3295
@@ -3322,7 +3299,8 @@ static HRESULT OnUninstallMsiCompatiblePackage(
3299 __in BURN_PACKAGES* pPackages,
3300 __in BURN_VARIABLES* pVariables,
3301 __in BYTE* pbData,
3325 - __in SIZE_T cbData
3302 + __in SIZE_T cbData,
3303 + __out BOOTSTRAPPER_APPLY_RESTART* pRestart
3304 )
3305 {
3306 HRESULT hr = S_OK;
@@ -3334,7 +3312,7 @@ static HRESULT OnUninstallMsiCompatiblePackage(
3312 BURN_EXECUTE_ACTION executeAction = { };
3313 BURN_PACKAGE* pPackage = NULL;
3314 BURN_COMPATIBLE_PACKAGE* pCompatiblePackage = NULL;
3337 - BOOTSTRAPPER_APPLY_RESTART msiRestart = BOOTSTRAPPER_APPLY_RESTART_NONE;
3315 + *pRestart = BOOTSTRAPPER_APPLY_RESTART_NONE;
3316
3317 executeAction.type = BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE;
3318
@@ -3375,26 +3353,14 @@ static HRESULT OnUninstallMsiCompatiblePackage(
3353 }
3354
3355 // Uninstall MSI compatible package.
3378 - hr = MsiEngineUninstallCompatiblePackage(hwndParent, &executeAction, pCache, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, &msiRestart);
3379 - ExitOnFailure(hr, "Failed to execute MSI package.");
3356 + hr = MsiEngineUninstallCompatiblePackage(hwndParent, &executeAction, pCache, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, pRestart);
3357 + ExitOnFailure(hr, "Failed to execute compatible MSI package.");
3358
3359 LExit:
3360 ReleaseStr(sczPackageId);
3361 ReleaseStr(sczCompatiblePackageId);
3362 PlanUninitializeExecuteAction(&executeAction);
3363
3386 - if (SUCCEEDED(hr))
3387 - {
3388 - if (BOOTSTRAPPER_APPLY_RESTART_REQUIRED == msiRestart)
3389 - {
3390 - hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED);
3391 - }
3392 - else if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == msiRestart)
3393 - {
3394 - hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_INITIATED);
3395 - }
3396 - }
3397 -
3364 return hr;
3365 }
3366
@@ -4096,3 +4062,25 @@ LExit:
4062
4063 return hr;
4064 }
4065 +
4066 +static HRESULT ElevatedOnExecuteActionComplete(
4067 + __in HANDLE hPipe,
4068 + __in BOOTSTRAPPER_APPLY_RESTART restart
4069 + )
4070 +{
4071 + HRESULT hr = S_OK;
4072 + BYTE* pbSendData = NULL;
4073 + SIZE_T cbSendData = 0;
4074 + DWORD dwResult = 0;
4075 +
4076 + hr = BuffWriteNumber(&pbSendData, &cbSendData, restart);
4077 + ExitOnFailure(hr, "Failed to write the restart type to message buffer.");
4078 +
4079 + hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ACTION_COMPLETE, pbSendData, cbSendData, NULL, NULL, &dwResult);
4080 + ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ACTION_COMPLETE message to per-user process.");
4081 +
4082 +LExit:
4083 + ReleaseBuffer(pbSendData);
4084 +
4085 + return hr;
4086 +}
src/burn/engine/engine.mc
+7
@@ -982,6 +982,13 @@ Language=English
982 Skipping rollback of package: %1!ls! due to abandoning its process. Continuing...
983 .
984
985 +MessageId=366
986 +Severity=Success
987 +SymbolicName=MSG_EXECUTE_PACKAGE_PROCESS_EXITED
988 +Language=English
989 +The process for package: %1!ls! exited with code: %2!u!. The exit code has been translated to type: %3!hs! and restart: %4!hs!.
990 +.
991 +
992 MessageId=370
993 Severity=Success
994 SymbolicName=MSG_SESSION_BEGIN
src/burn/engine/exeengine.cpp
+5 -2
@@ -648,7 +648,7 @@ extern "C" HRESULT ExeEngineExecutePackage(
648 ExitOnFailure(hr, "Failed to run EXE process");
649 }
650
651 - hr = ExeEngineHandleExitCode(pPackage->Exe.rgExitCodes, pPackage->Exe.cExitCodes, dwExitCode, pRestart);
651 + hr = ExeEngineHandleExitCode(pPackage->Exe.rgExitCodes, pPackage->Exe.cExitCodes, pPackage->sczId, dwExitCode, pRestart);
652 ExitOnRootFailure(hr, "Process returned error: 0x%x", dwExitCode);
653
654 LExit:
@@ -759,7 +759,7 @@ extern "C" HRESULT ExeEngineRunProcess(
759 hr = (IDOK == nResult || IDNOACTION == nResult) ? S_OK : IDCANCEL == nResult ? HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) : HRESULT_FROM_WIN32(ERROR_INSTALL_FAILURE);
760 ExitOnRootFailure(hr, "Bootstrapper application aborted during package process progress.");
761
762 - hr = ProcWaitForCompletion(pi.hProcess, 500, pdwExitCode);
762 + hr = CoreWaitForProcCompletion(pi.hProcess, 500, pdwExitCode);
763 if (HRESULT_FROM_WIN32(WAIT_TIMEOUT) != hr)
764 {
765 ExitOnFailure(hr, "Failed to wait for executable to complete: %ls", wzExecutablePath);
@@ -948,6 +948,7 @@ LExit:
948 extern "C" HRESULT ExeEngineHandleExitCode(
949 __in BURN_EXE_EXIT_CODE* rgCustomExitCodes,
950 __in DWORD cCustomExitCodes,
951 + __in_z LPCWSTR wzId,
952 __in DWORD dwExitCode,
953 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
954 )
@@ -1029,6 +1030,8 @@ extern "C" HRESULT ExeEngineHandleExitCode(
1030 }
1031
1032 //LExit:
1033 + LogId(REPORT_STANDARD, MSG_EXECUTE_PACKAGE_PROCESS_EXITED, wzId, dwExitCode, LoggingExitCodeTypeToString(typeCode), LoggingRestartToString(*pRestart));
1034 +
1035 return hr;
1036 }
1037
src/burn/engine/exeengine.h
+1
@@ -69,6 +69,7 @@ HRESULT ExeEngineParseCommandLineArgumentsFromXml(
69 HRESULT ExeEngineHandleExitCode(
70 __in BURN_EXE_EXIT_CODE* rgCustomExitCodes,
71 __in DWORD cCustomExitCodes,
72 + __in_z LPCWSTR wzId,
73 __in DWORD dwExitCode,
74 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
75 );
src/burn/engine/logging.cpp
+19
@@ -531,6 +531,25 @@ extern "C" LPCSTR LoggingTrueFalseToString(
531 return "false";
532 }
533
534 +extern "C" LPCSTR LoggingExitCodeTypeToString(
535 + __in BURN_EXE_EXIT_CODE_TYPE exitCodeType
536 + )
537 +{
538 + switch (exitCodeType)
539 + {
540 + case BURN_EXE_EXIT_CODE_TYPE_SUCCESS:
541 + return "Success";
542 + case BURN_EXE_EXIT_CODE_TYPE_ERROR:
543 + return "Error";
544 + case BURN_EXE_EXIT_CODE_TYPE_SCHEDULE_REBOOT:
545 + return "ScheduleReboot";
546 + case BURN_EXE_EXIT_CODE_TYPE_FORCE_REBOOT:
547 + return "ForceReboot";
548 + default:
549 + return "Invalid";
550 + }
551 +}
552 +
553 extern "C" LPCSTR LoggingPackageStateToString(
554 __in BOOTSTRAPPER_PACKAGE_STATE packageState
555 )
src/burn/engine/logging.h
+4
@@ -112,6 +112,10 @@ LPCSTR LoggingTrueFalseToString(
112 __in BOOL f
113 );
114
115 +LPCSTR LoggingExitCodeTypeToString(
116 + __in BURN_EXE_EXIT_CODE_TYPE exitCodeType
117 + );
118 +
119 LPCSTR LoggingPackageStateToString(
120 __in BOOTSTRAPPER_PACKAGE_STATE packageState
121 );
src/burn/engine/pipe.cpp
+1 -1
@@ -495,7 +495,7 @@ extern "C" HRESULT PipeTerminateChildProcess(
495 HRESULT hrDebug = S_OK;
496
497 hrDebug = CoreWaitForProcCompletion(pConnection->hProcess, 0, &dwChildExitCode);
498 - if (E_ACCESSDENIED != hrDebug) // if the other process is elevated and we are not, then we'll get ERROR_ACCESS_DENIED.
498 + if (E_ACCESSDENIED != hrDebug && FAILED(hrDebug)) // if the other process is elevated and we are not, then we'll get ERROR_ACCESS_DENIED.
499 {
500 TraceError(hrDebug, "Failed to wait for child process completion.");
501 }
src/burn/test/BurnUnitTest/BurnUnitTest.vcxproj
+1
@@ -48,6 +48,7 @@
48 <ClCompile Include="CacheTest.cpp" />
49 <ClCompile Include="ElevationTest.cpp" />
50 <ClCompile Include="EmbeddedTest.cpp" />
51 + <ClCompile Include="ExitCodeTest.cpp" />
52 <ClCompile Include="LoggingTest.cpp" />
53 <ClCompile Include="ManifestHelpers.cpp" />
54 <ClCompile Include="ManifestTest.cpp" />
src/burn/test/BurnUnitTest/BurnUnitTest.vcxproj.filters
+3
@@ -27,6 +27,9 @@
27 <ClCompile Include="EmbeddedTest.cpp">
28 <Filter>Source Files</Filter>
29 </ClCompile>
30 + <ClCompile Include="ExitCodeTest.cpp">
31 + <Filter>Source Files</Filter>
32 + </ClCompile>
33 <ClCompile Include="LoggingTest.cpp">
34 <Filter>Source Files</Filter>
35 </ClCompile>
src/burn/test/BurnUnitTest/ExitCodeTest.cpp new
+361
@@ -0,0 +1,361 @@
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 +
3 +#include "precomp.h"
4 +
5 +
6 +namespace Microsoft
7 +{
8 +namespace Tools
9 +{
10 +namespace WindowsInstallerXml
11 +{
12 +namespace Test
13 +{
14 +namespace Bootstrapper
15 +{
16 + using namespace System;
17 + using namespace System::IO;
18 + using namespace System::Threading;
19 + using namespace Xunit;
20 +
21 +struct EXIT_CODE_ITEM
22 +{
23 + DWORD dwExitCode;
24 + HRESULT hrExpectedResult;
25 + BOOTSTRAPPER_APPLY_RESTART expectedRestart;
26 + LPCWSTR wzPackageId;
27 + HRESULT hrResultPerUser;
28 + BOOTSTRAPPER_APPLY_RESTART restartPerUser;
29 + HRESULT hrResultPerMachine;
30 + BOOTSTRAPPER_APPLY_RESTART restartPerMachine;
31 +};
32 +
33 +static BOOL STDAPICALLTYPE ExitCodeTest_ShellExecuteExW(
34 + __inout LPSHELLEXECUTEINFOW lpExecInfo
35 + );
36 +static DWORD CALLBACK ExitCodeTest_ElevationThreadProc(
37 + __in LPVOID lpThreadParameter
38 + );
39 +static BOOL STDAPICALLTYPE ExitCodeTest_CreateProcessW(
40 + __in_opt LPCWSTR lpApplicationName,
41 + __inout_opt LPWSTR lpCommandLine,
42 + __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,
43 + __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
44 + __in BOOL bInheritHandles,
45 + __in DWORD dwCreationFlags,
46 + __in_opt LPVOID lpEnvironment,
47 + __in_opt LPCWSTR lpCurrentDirectory,
48 + __in LPSTARTUPINFOW lpStartupInfo,
49 + __out LPPROCESS_INFORMATION lpProcessInformation
50 + );
51 +static DWORD CALLBACK ExitCodeTest_PackageThreadProc(
52 + __in LPVOID lpThreadParameter
53 + );
54 +static int ExitCodeTest_GenericMessageHandler(
55 + __in GENERIC_EXECUTE_MESSAGE* pMessage,
56 + __in LPVOID pvContext
57 + );
58 +static void LoadEngineState(
59 + __in BURN_ENGINE_STATE* pEngineState
60 + );
61 +
62 + public ref class ExitCodeTest : BurnUnitTest
63 + {
64 + public:
65 + ExitCodeTest(BurnTestFixture^ fixture) : BurnUnitTest(fixture)
66 + {
67 + }
68 +
69 + [Fact]
70 + void ExitCodeHandlingTest()
71 + {
72 + HRESULT hr = S_OK;
73 + BURN_ENGINE_STATE engineState = { };
74 + BURN_PIPE_CONNECTION* pConnection = &engineState.companionConnection;
75 + EXIT_CODE_ITEM rgExitCodeItems[] =
76 + {
77 + { 0, S_OK, BOOTSTRAPPER_APPLY_RESTART_NONE, L"Standard" },
78 + { 1, HRESULT_FROM_WIN32(1), BOOTSTRAPPER_APPLY_RESTART_NONE, L"Standard" },
79 + { ERROR_SUCCESS_REBOOT_REQUIRED, S_OK, BOOTSTRAPPER_APPLY_RESTART_REQUIRED, L"Standard" },
80 + { (DWORD)HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED), S_OK, BOOTSTRAPPER_APPLY_RESTART_REQUIRED, L"Standard" },
81 + { ERROR_SUCCESS_RESTART_REQUIRED, S_OK, BOOTSTRAPPER_APPLY_RESTART_REQUIRED, L"Standard" },
82 + { (DWORD)HRESULT_FROM_WIN32(ERROR_SUCCESS_RESTART_REQUIRED), S_OK, BOOTSTRAPPER_APPLY_RESTART_REQUIRED, L"Standard" },
83 + { ERROR_SUCCESS_REBOOT_INITIATED, S_OK, BOOTSTRAPPER_APPLY_RESTART_INITIATED, L"Standard" },
84 + { (DWORD)HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_INITIATED), S_OK, BOOTSTRAPPER_APPLY_RESTART_INITIATED, L"Standard" },
85 + { 0, E_FAIL, BOOTSTRAPPER_APPLY_RESTART_NONE, L"Custom" },
86 + { 1, S_OK, BOOTSTRAPPER_APPLY_RESTART_NONE, L"Custom" },
87 + { 3, S_OK, BOOTSTRAPPER_APPLY_RESTART_REQUIRED, L"Custom" },
88 + { 4, S_OK, BOOTSTRAPPER_APPLY_RESTART_INITIATED, L"Custom" },
89 + { ERROR_SUCCESS_REBOOT_REQUIRED, HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED), BOOTSTRAPPER_APPLY_RESTART_NONE, L"Custom" },
90 + { (DWORD)HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED), HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED), BOOTSTRAPPER_APPLY_RESTART_NONE, L"Custom" },
91 + { ERROR_SUCCESS_RESTART_REQUIRED, HRESULT_FROM_WIN32(ERROR_SUCCESS_RESTART_REQUIRED), BOOTSTRAPPER_APPLY_RESTART_NONE, L"Custom" },
92 + { (DWORD)HRESULT_FROM_WIN32(ERROR_SUCCESS_RESTART_REQUIRED), HRESULT_FROM_WIN32(ERROR_SUCCESS_RESTART_REQUIRED), BOOTSTRAPPER_APPLY_RESTART_NONE, L"Custom" },
93 + { ERROR_SUCCESS_REBOOT_INITIATED, HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_INITIATED), BOOTSTRAPPER_APPLY_RESTART_NONE, L"Custom" },
94 + { (DWORD)HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_INITIATED), HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_INITIATED), BOOTSTRAPPER_APPLY_RESTART_NONE, L"Custom" },
95 + };
96 +
97 + engineState.sczBundleEngineWorkingPath = L"tests\\ignore\\this\\path\\to\\burn.exe";
98 +
99 + try
100 + {
101 + ShelFunctionOverride(ExitCodeTest_ShellExecuteExW);
102 + CoreFunctionOverride(ExitCodeTest_CreateProcessW, ThrdWaitForCompletion);
103 +
104 + //
105 + // per-user side setup
106 + //
107 + LoadEngineState(&engineState);
108 +
109 + hr = ElevationElevate(&engineState, NULL);
110 + TestThrowOnFailure(hr, L"Failed to elevate.");
111 +
112 + for (DWORD i = 0; i < countof(rgExitCodeItems); ++i)
113 + {
114 + // "run" the package both per-user and per-machine
115 + ExecuteExePackage(&engineState, rgExitCodeItems + i);
116 + }
117 +
118 + //
119 + // initiate termination
120 + //
121 + hr = PipeTerminateChildProcess(pConnection, 0, FALSE);
122 + TestThrowOnFailure(hr, L"Failed to terminate elevated process.");
123 +
124 + // check results
125 + for (DWORD i = 0; i < countof(rgExitCodeItems); ++i)
126 + {
127 + EXIT_CODE_ITEM* pExitCode = rgExitCodeItems + i;
128 + String^ packageId = gcnew String(pExitCode->wzPackageId);
129 + String^ exitCodeString = ((UInt32)pExitCode->dwExitCode).ToString();
130 +
131 + NativeAssert::SpecificReturnCode(pExitCode->hrExpectedResult, pExitCode->hrResultPerMachine, L"Per-machine package: {0}, exit code: {1}", packageId, exitCodeString);
132 + Assert::True(pExitCode->expectedRestart == pExitCode->restartPerMachine, String::Format("Per-machine package: {0}, exit code: {1}, expected restart type '{2}' but got '{3}'", packageId, exitCodeString, gcnew String(LoggingRestartToString(pExitCode->expectedRestart)), gcnew String(LoggingRestartToString(pExitCode->restartPerMachine))));
133 +
134 + NativeAssert::SpecificReturnCode(pExitCode->hrExpectedResult, pExitCode->hrResultPerUser, L"Per-user package: {0}, exit code: {1}", packageId, exitCodeString);
135 + Assert::True(pExitCode->expectedRestart == pExitCode->restartPerUser, String::Format("Per-user package: {0}, exit code: {1}, expected restart type '{2}' but got '{3}'", packageId, exitCodeString, gcnew String(LoggingRestartToString(pExitCode->expectedRestart)), gcnew String(LoggingRestartToString(pExitCode->restartPerUser))));
136 + }
137 + }
138 + finally
139 + {
140 + VariablesUninitialize(&engineState.variables);
141 + PipeConnectionUninitialize(pConnection);
142 + }
143 + }
144 +
145 + private:
146 + void ExecuteExePackage(
147 + __in BURN_ENGINE_STATE* pEngineState,
148 + __in EXIT_CODE_ITEM* pExitCode
149 + )
150 + {
151 + HRESULT hr = S_OK;
152 + LPWSTR sczExitCode = NULL;
153 + BURN_PACKAGE* pPackage = NULL;
154 + BURN_EXECUTE_ACTION executeAction = { };
155 + BURN_PIPE_CONNECTION* pConnection = &pEngineState->companionConnection;
156 + BOOL fRollback = FALSE;
157 +
158 + hr = PackageFindById(&pEngineState->packages, pExitCode->wzPackageId, &pPackage);
159 + TestThrowOnFailure(hr, L"Failed to find package.");
160 +
161 + executeAction.type = BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE;
162 + executeAction.exePackage.action = BOOTSTRAPPER_ACTION_STATE_INSTALL;
163 + executeAction.exePackage.pPackage = pPackage;
164 +
165 + try
166 + {
167 + hr = StrAllocFormatted(&sczExitCode, L"%u", pExitCode->dwExitCode);
168 + TestThrowOnFailure(hr, L"Failed to convert exit code to string.");
169 +
170 + hr = VariableSetString(&pEngineState->variables, L"ExeExitCode", sczExitCode, FALSE, FALSE);
171 + TestThrowOnFailure(hr, L"Failed to set variable.");
172 +
173 + pExitCode->hrResultPerMachine = ElevationExecuteExePackage(pConnection->hPipe, &executeAction, &pEngineState->variables, fRollback, ExitCodeTest_GenericMessageHandler, NULL, &pExitCode->restartPerMachine);
174 +
175 + pExitCode->hrResultPerUser = ExeEngineExecutePackage(&executeAction, &pEngineState->cache, &pEngineState->variables, fRollback, ExitCodeTest_GenericMessageHandler, NULL, &pExitCode->restartPerUser);
176 + }
177 + finally
178 + {
179 + ReleaseStr(sczExitCode);
180 + }
181 + }
182 + };
183 +
184 +
185 +static BOOL STDAPICALLTYPE ExitCodeTest_ShellExecuteExW(
186 + __inout LPSHELLEXECUTEINFOW lpExecInfo
187 + )
188 +{
189 + HRESULT hr = S_OK;
190 + LPWSTR scz = NULL;
191 +
192 + hr = StrAllocString(&scz, lpExecInfo->lpParameters, 0);
193 + ExitOnFailure(hr, "Failed to copy arguments.");
194 +
195 + // Pretend this thread is the elevated process.
196 + lpExecInfo->hProcess = ::CreateThread(NULL, 0, ExitCodeTest_ElevationThreadProc, scz, 0, NULL);
197 + ExitOnNullWithLastError(lpExecInfo->hProcess, hr, "Failed to create thread.");
198 + scz = NULL;
199 +
200 +LExit:
201 + ReleaseStr(scz);
202 +
203 + return SUCCEEDED(hr);
204 +}
205 +
206 +static DWORD CALLBACK ExitCodeTest_ElevationThreadProc(
207 + __in LPVOID lpThreadParameter
208 + )
209 +{
210 + HRESULT hr = S_OK;
211 + LPWSTR sczArguments = (LPWSTR)lpThreadParameter;
212 + BURN_ENGINE_STATE engineState = { };
213 + BURN_PIPE_CONNECTION* pConnection = &engineState.companionConnection;
214 + HANDLE hLock = NULL;
215 + DWORD dwChildExitCode = 0;
216 + BOOL fRestart = FALSE;
217 + BOOL fApplying = FALSE;
218 +
219 + LoadEngineState(&engineState);
220 +
221 + StrAlloc(&pConnection->sczName, MAX_PATH);
222 + StrAlloc(&pConnection->sczSecret, MAX_PATH);
223 +
224 + // parse command line arguments
225 + if (3 != swscanf_s(sczArguments, L"-q -burn.elevated %s %s %u", pConnection->sczName, MAX_PATH, pConnection->sczSecret, MAX_PATH, &pConnection->dwProcessId))
226 + {
227 + hr = E_INVALIDARG;
228 + ExitOnFailure(hr, "Failed to parse argument string.");
229 + }
230 +
231 + // set up connection with per-user process
232 + hr = PipeChildConnect(pConnection, TRUE);
233 + ExitOnFailure(hr, "Failed to connect to per-user process.");
234 +
235 + hr = ElevationChildPumpMessages(pConnection->hPipe, pConnection->hCachePipe, &engineState.approvedExes, &engineState.cache, &engineState.containers, &engineState.packages, &engineState.payloads, &engineState.variables, &engineState.registration, &engineState.userExperience, &hLock, &dwChildExitCode, &fRestart, &fApplying);
236 + ExitOnFailure(hr, "Failed while pumping messages in child 'process'.");
237 +
238 +LExit:
239 + PipeConnectionUninitialize(pConnection);
240 + VariablesUninitialize(&engineState.variables);
241 + ReleaseStr(sczArguments);
242 +
243 + return FAILED(hr) ? (DWORD)hr : dwChildExitCode;
244 +}
245 +
246 +static BOOL STDAPICALLTYPE ExitCodeTest_CreateProcessW(
247 + __in_opt LPCWSTR /*lpApplicationName*/,
248 + __inout_opt LPWSTR lpCommandLine,
249 + __in_opt LPSECURITY_ATTRIBUTES /*lpProcessAttributes*/,
250 + __in_opt LPSECURITY_ATTRIBUTES /*lpThreadAttributes*/,
251 + __in BOOL /*bInheritHandles*/,
252 + __in DWORD /*dwCreationFlags*/,
253 + __in_opt LPVOID /*lpEnvironment*/,
254 + __in_opt LPCWSTR /*lpCurrentDirectory*/,
255 + __in LPSTARTUPINFOW /*lpStartupInfo*/,
256 + __out LPPROCESS_INFORMATION lpProcessInformation
257 + )
258 +{
259 + HRESULT hr = S_OK;
260 + LPWSTR scz = NULL;
261 + LPCWSTR wzArgs = lpCommandLine;
262 +
263 + hr = StrAllocString(&scz, wzArgs, 0);
264 + ExitOnFailure(hr, "Failed to copy arguments.");
265 +
266 + // Pretend this thread is the package process.
267 + lpProcessInformation->hProcess = ::CreateThread(NULL, 0, ExitCodeTest_PackageThreadProc, scz, 0, NULL);
268 + ExitOnNullWithLastError(lpProcessInformation->hProcess, hr, "Failed to create thread.");
269 +
270 + scz = NULL;
271 +
272 +LExit:
273 + ReleaseStr(scz);
274 +
275 + return SUCCEEDED(hr);
276 +}
277 +
278 +static DWORD CALLBACK ExitCodeTest_PackageThreadProc(
279 + __in LPVOID lpThreadParameter
280 + )
281 +{
282 + HRESULT hr = S_OK;
283 + LPWSTR sczArguments = (LPWSTR)lpThreadParameter;
284 + int argc = 0;
285 + LPWSTR* argv = NULL;
286 + DWORD dwResult = 0;
287 +
288 + hr = AppParseCommandLine(sczArguments, &argc, &argv);
289 + ExitOnFailure(hr, "Failed to parse command line: %ls", sczArguments);
290 +
291 + hr = StrStringToUInt32(argv[1], 0, reinterpret_cast<UINT*>(&dwResult));
292 + ExitOnFailure(hr, "Failed to convert %ls to DWORD.", argv[1]);
293 +
294 +LExit:
295 + AppFreeCommandLineArgs(argv);
296 + ReleaseStr(sczArguments);
297 +
298 + return FAILED(hr) ? (DWORD)hr : dwResult;
299 +}
300 +
301 +static int ExitCodeTest_GenericMessageHandler(
302 + __in GENERIC_EXECUTE_MESSAGE* /*pMessage*/,
303 + __in LPVOID /*pvContext*/
304 + )
305 +{
306 + return IDNOACTION;
307 +}
308 +
309 +static void LoadEngineState(
310 + __in BURN_ENGINE_STATE* pEngineState
311 + )
312 +{
313 + HRESULT hr = S_OK;
314 + IXMLDOMElement* pixeBundle = NULL;
315 +
316 + LPCWSTR wzDocument =
317 + L"<BurnManifest>"
318 + L" <Payload Id='test.exe' FilePath='test.exe' Packaging='external' SourcePath='test.exe' Hash='000000000000' FileSize='1' />"
319 + L" <Chain>"
320 + L" <ExePackage Id='Custom' Cache='remove' CacheId='test.exe' InstallSize='1' Size='1' PerMachine='no' Permanent='yes' Vital='yes' DetectCondition='' InstallArguments='[ExeExitCode]' UninstallArguments='' Uninstallable='no' RepairArguments='' Repairable='no' Protocol='none' DetectionType='condition'>"
321 + L" <ExitCode Code='0' Type='2' />"
322 + L" <ExitCode Code='3' Type='3' />"
323 + L" <ExitCode Code='4' Type='4' />"
324 + L" <ExitCode Code='3010' Type='2' />"
325 + L" <ExitCode Code='-2147021886' Type='2' />"
326 + L" <ExitCode Code='3011' Type='2' />"
327 + L" <ExitCode Code='-2147021885' Type='2' />"
328 + L" <ExitCode Code='1641' Type='2' />"
329 + L" <ExitCode Code='-2147023255' Type='2' />"
330 + L" <ExitCode Code='*' Type='1' />"
331 + L" <PayloadRef Id='test.exe' />"
332 + L" </ExePackage>"
333 + L" <ExePackage Id='Standard' Cache='remove' CacheId='test.exe' InstallSize='1' Size='1' PerMachine='no' Permanent='yes' Vital='yes' DetectCondition='' InstallArguments='[ExeExitCode]' UninstallArguments='' Uninstallable='no' RepairArguments='' Repairable='no' Protocol='none' DetectionType='condition'>"
334 + L" <PayloadRef Id='test.exe' />"
335 + L" </ExePackage>"
336 + L" </Chain>"
337 + L"</BurnManifest>";
338 +
339 + VariableInitialize(&pEngineState->variables);
340 +
341 + PipeConnectionInitialize(&pEngineState->companionConnection);
342 +
343 + hr = CacheInitialize(&pEngineState->cache, &pEngineState->internalCommand);
344 + TestThrowOnFailure(hr, "CacheInitialize failed.");
345 +
346 + // load XML document
347 + LoadBundleXmlHelper(wzDocument, &pixeBundle);
348 +
349 + hr = PayloadsParseFromXml(&pEngineState->payloads, &pEngineState->containers, &pEngineState->layoutPayloads, pixeBundle);
350 + TestThrowOnFailure(hr, "Failed to parse payloads from manifest.");
351 +
352 + hr = PackagesParseFromXml(&pEngineState->packages, &pEngineState->payloads, pixeBundle);
353 + TestThrowOnFailure(hr, "Failed to parse packages from manifest.");
354 +
355 + ReleaseObject(pixeBundle);
356 +}
357 +}
358 +}
359 +}
360 +}
361 +}
src/burn/test/BurnUnitTest/precomp.h
+1
@@ -13,6 +13,7 @@
13 #include "wininet.h"
14
15 #include <dutil.h>
16 +#include <apputil.h>
17 #include <verutil.h>
18 #include <cryputil.h>
19 #include <dlutil.h>
src/internal/WixBuildTools.TestSupport/XunitExtensions/SpecificReturnCodeException.cs
+5 -4
@@ -7,11 +7,12 @@ namespace WixBuildTools.TestSupport
7
8 public class SpecificReturnCodeException : XunitException
9 {
10 - public SpecificReturnCodeException(int hr, string userMessage)
10 + public SpecificReturnCodeException(int hrExpected, int hr, string userMessage)
11 : base(String.Format("WixAssert.SpecificReturnCode() Failure\r\n" +
12 - "HRESULT: 0x{0:X8}\r\n" +
13 - "Message: {1}",
14 - hr, userMessage))
12 + "Expected HRESULT: 0x{0:X8}\r\n" +
13 + "Actual HRESULT: 0x{1:X8}\r\n" +
14 + "Message: {2}",
15 + hrExpected, hr, userMessage))
16 {
17 this.HResult = hr;
18 }
src/internal/WixBuildTools.TestSupport/XunitExtensions/WixAssert.cs
+1 -1
@@ -58,7 +58,7 @@ namespace WixBuildTools.TestSupport
58 {
59 if (hrExpected != hr)
60 {
61 - throw new SpecificReturnCodeException(hr, String.Format(format, formatArgs));
61 + throw new SpecificReturnCodeException(hrExpected, hr, String.Format(format, formatArgs));
62 }
63 }
64