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