Skip to content

Commit e9f1a09

Browse files
nirbarNir Bar
authored and
Nir Bar
committed
Launch a thread to log premature termination of companion elevated process
1 parent 0211704 commit e9f1a09

File tree

4 files changed

+59
-4
lines changed

4 files changed

+59
-4
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ This repository contains the PanelSwWix4: A custom WiX Toolset codebase
2222
- [7778](https://github.com/wixtoolset/issues/issues/7778): Bundle/@Wix3DependencyMode=yes/no. If yes, then default MSI/MSP provider key uses the ProductCode/PatchCode. Use only if a WiX4 bundle chains packages of a WiX3 bundle.
2323
- [4889](https://github.com/wixtoolset/issues/issues/4889): Support custom container compressions using bundle extensions
2424
- Not overwriting log files when retrying to execute a package
25-
- Support sending custom messages on embedded pipe
25+
- Support sending custom messages on embedded pipe
26+
- Best effort to log premature termination of companion process

src/burn/engine/core.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ static void LogRelatedBundles(
8686
static void LogRollbackBoundary(
8787
__in const BURN_ROLLBACK_BOUNDARY* pRollbackBoundary
8888
);
89+
static DWORD WINAPI MonitorCompanionProcessThreadProc(
90+
__in LPVOID lpParameter
91+
);
8992

9093

9194
// function definitions
@@ -622,12 +625,52 @@ extern "C" HRESULT CoreElevate(
622625

623626
pEngineState->hUnelevatedLoggingThread = ::CreateThread(NULL, 0, LoggingThreadProc, pEngineState, 0, NULL);
624627
ExitOnNullWithLastError(pEngineState->hUnelevatedLoggingThread, hr, "Failed to create unelevated logging thread.");
628+
629+
// Best effort to log premature termination of the elevated process
630+
pEngineState->companionConnection.hProcess = ::OpenProcess(SYNCHRONIZE, FALSE, pEngineState->companionConnection.dwProcessId);
631+
if (pEngineState->companionConnection.hProcess)
632+
{
633+
pEngineState->companionConnection.hQuitRequested = ::CreateEvent(NULL, TRUE, FALSE, NULL);
634+
if (pEngineState->companionConnection.hQuitRequested)
635+
{
636+
pEngineState->companionConnection.hQuitMonitorThread = ::CreateThread(NULL, 0, MonitorCompanionProcessThreadProc, &pEngineState->companionConnection, 0, NULL);
637+
}
638+
}
625639
}
626640

627641
LExit:
628642
return hr;
629643
}
630644

645+
static DWORD WINAPI MonitorCompanionProcessThreadProc(
646+
__in LPVOID lpParameter
647+
)
648+
{
649+
BURN_PIPE_CONNECTION* pConnection = (BURN_PIPE_CONNECTION*)lpParameter;
650+
HANDLE rghHandles[2] = { pConnection->hQuitRequested, pConnection->hProcess };
651+
DWORD dwRes = ERROR_SUCCESS;
652+
HRESULT hr = S_OK;
653+
654+
dwRes = ::WaitForMultipleObjects(ARRAYSIZE(rghHandles), rghHandles, FALSE, INFINITE);
655+
switch (dwRes)
656+
{
657+
case WAIT_OBJECT_0:
658+
hr = S_OK;
659+
break;
660+
case WAIT_OBJECT_0 + 1:
661+
LogRedirect(NULL, NULL);
662+
hr = E_SUSPECTED_AV_INTERFERENCE;
663+
ExitOnFailure(hr, "Companion elevated process has been terminated prematurely.");
664+
break;
665+
default:
666+
ExitWithLastError(hr, "Failed to monitor proper termination of companion process.");
667+
break;
668+
}
669+
670+
LExit:
671+
return HRESULT_CODE(hr);
672+
}
673+
631674
extern "C" HRESULT CoreApply(
632675
__in BURN_ENGINE_STATE* pEngineState,
633676
__in_opt HWND hwndParent

src/burn/engine/pipe.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ void PipeConnectionUninitialize(
6363
ReleaseFileHandle(pConnection->hLoggingPipe);
6464
ReleaseFileHandle(pConnection->hCachePipe);
6565
ReleaseFileHandle(pConnection->hPipe);
66+
ReleaseHandle(pConnection->hQuitRequested);
67+
ReleaseHandle(pConnection->hQuitMonitorThread);
6668
ReleaseHandle(pConnection->hProcess);
6769
ReleaseStr(pConnection->sczSecret);
6870
ReleaseStr(pConnection->sczName);
@@ -462,6 +464,11 @@ extern "C" HRESULT PipeTerminateChildProcess(
462464
SIZE_T cbData = 0;
463465
BOOL fTimedOut = FALSE;
464466

467+
if (pConnection->hQuitRequested)
468+
{
469+
::SetEvent(pConnection->hQuitRequested);
470+
}
471+
465472
// Prepare the exit message.
466473
hr = BuffWriteNumber(&pbData, &cbData, dwParentExitCode);
467474
ExitOnFailure(hr, "Failed to write exit code to message buffer.");
@@ -523,7 +530,6 @@ extern "C" HRESULT PipeChildConnect(
523530
{
524531
Assert(pConnection->sczName);
525532
Assert(pConnection->sczSecret);
526-
Assert(!pConnection->hProcess);
527533
Assert(INVALID_HANDLE_VALUE == pConnection->hPipe);
528534
Assert(INVALID_HANDLE_VALUE == pConnection->hCachePipe);
529535
Assert(INVALID_HANDLE_VALUE == pConnection->hLoggingPipe);
@@ -591,8 +597,11 @@ extern "C" HRESULT PipeChildConnect(
591597
ExitOnFailure(hr, "Failed to verify parent logging pipe: %ls", sczPipeName);
592598
}
593599

594-
pConnection->hProcess = ::OpenProcess(SYNCHRONIZE, FALSE, pConnection->dwProcessId);
595-
ExitOnNullWithLastError(pConnection->hProcess, hr, "Failed to open companion process with PID: %u", pConnection->dwProcessId);
600+
if (!pConnection->hProcess)
601+
{
602+
pConnection->hProcess = ::OpenProcess(SYNCHRONIZE, FALSE, pConnection->dwProcessId);
603+
ExitOnNullWithLastError(pConnection->hProcess, hr, "Failed to open companion process with PID: %u", pConnection->dwProcessId);
604+
}
596605

597606
LExit:
598607
ReleaseStr(sczPipeName);

src/burn/engine/pipe.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ typedef struct _BURN_PIPE_CONNECTION
2727
HANDLE hPipe;
2828
HANDLE hCachePipe;
2929
HANDLE hLoggingPipe;
30+
HANDLE hQuitRequested;
31+
HANDLE hQuitMonitorThread;
3032
} BURN_PIPE_CONNECTION;
3133

3234
typedef enum _BURN_PIPE_MESSAGE_TYPE : DWORD

0 commit comments

Comments
 (0)