Skip to content

Commit

Permalink
Launch a thread to log premature termination of companion elevated pr…
Browse files Browse the repository at this point in the history
…ocess
  • Loading branch information
Nir Bar committed Aug 21, 2024
1 parent 3821072 commit 03e0ad7
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 4 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ This repository contains the PanelSwWix4: A custom WiX Toolset codebase
- Un-plan MSI transaction if it contains less than 2 packages
- Add BA methods OnPlanMsiTransaction, OnPlanMsiTransactionComplete: Let BA opt-out of MSI transactions.
- Not overwriting log files when retrying to execute a package
- Support sending custom messages on embedded pipe
- Support sending custom messages on embedded pipe
- Best effort to log premature termination of companion process
15 changes: 12 additions & 3 deletions src/burn/engine/burnpipe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ void BurnPipeConnectionUninitialize(
ReleasePipeHandle(pConnection->hLoggingPipe);
ReleasePipeHandle(pConnection->hCachePipe);
ReleasePipeHandle(pConnection->hPipe);
ReleaseHandle(pConnection->hQuitRequested);
ReleaseHandle(pConnection->hQuitMonitorThread);
ReleaseHandle(pConnection->hProcess);
ReleaseStr(pConnection->sczSecret);
ReleaseStr(pConnection->sczName);
Expand Down Expand Up @@ -375,6 +377,11 @@ extern "C" HRESULT BurnPipeTerminateChildProcess(
SIZE_T cbData = 0;
BOOL fTimedOut = FALSE;

if (pConnection->hQuitRequested)
{
::SetEvent(pConnection->hQuitRequested);
}

// Prepare the exit message.
hr = BuffWriteNumber(&pbData, &cbData, dwParentExitCode);
ExitOnFailure(hr, "Failed to write exit code to message buffer.");
Expand Down Expand Up @@ -436,7 +443,6 @@ extern "C" HRESULT BurnPipeChildConnect(
{
Assert(pConnection->sczName);
Assert(pConnection->sczSecret);
Assert(!pConnection->hProcess);
Assert(INVALID_HANDLE_VALUE == pConnection->hPipe);
Assert(INVALID_HANDLE_VALUE == pConnection->hCachePipe);
Assert(INVALID_HANDLE_VALUE == pConnection->hLoggingPipe);
Expand Down Expand Up @@ -477,8 +483,11 @@ extern "C" HRESULT BurnPipeChildConnect(
ExitOnFailure(hr, "Failed to verify parent logging pipe: %ls", sczPipeName);
}

pConnection->hProcess = ::OpenProcess(SYNCHRONIZE, FALSE, pConnection->dwProcessId);
ExitOnNullWithLastError(pConnection->hProcess, hr, "Failed to open companion process with PID: %u", pConnection->dwProcessId);
if (!pConnection->hProcess)
{
pConnection->hProcess = ::OpenProcess(SYNCHRONIZE, FALSE, pConnection->dwProcessId);
ExitOnNullWithLastError(pConnection->hProcess, hr, "Failed to open companion process with PID: %u", pConnection->dwProcessId);
}

LExit:
ReleaseStr(sczPipeName);
Expand Down
2 changes: 2 additions & 0 deletions src/burn/engine/burnpipe.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ typedef struct _BURN_PIPE_CONNECTION
HANDLE hPipe;
HANDLE hCachePipe;
HANDLE hLoggingPipe;
HANDLE hQuitRequested;
HANDLE hQuitMonitorThread;
} BURN_PIPE_CONNECTION;

typedef enum _BURN_PIPE_MESSAGE_TYPE : DWORD
Expand Down
43 changes: 43 additions & 0 deletions src/burn/engine/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ static void LogRelatedBundles(
static void LogRollbackBoundary(
__in const BURN_ROLLBACK_BOUNDARY* pRollbackBoundary
);
static DWORD WINAPI MonitorCompanionProcessThreadProc(
__in LPVOID lpParameter
);


// function definitions
Expand Down Expand Up @@ -605,12 +608,52 @@ extern "C" HRESULT CoreElevate(

pEngineState->hUnelevatedLoggingThread = ::CreateThread(NULL, 0, LoggingThreadProc, pEngineState, 0, NULL);
ExitOnNullWithLastError(pEngineState->hUnelevatedLoggingThread, hr, "Failed to create unelevated logging thread.");

// Best effort to log premature termination of the elevated process
pEngineState->companionConnection.hProcess = ::OpenProcess(SYNCHRONIZE, FALSE, pEngineState->companionConnection.dwProcessId);
if (pEngineState->companionConnection.hProcess)
{
pEngineState->companionConnection.hQuitRequested = ::CreateEvent(NULL, TRUE, FALSE, NULL);
if (pEngineState->companionConnection.hQuitRequested)
{
pEngineState->companionConnection.hQuitMonitorThread = ::CreateThread(NULL, 0, MonitorCompanionProcessThreadProc, &pEngineState->companionConnection, 0, NULL);
}
}
}

LExit:
return hr;
}

static DWORD WINAPI MonitorCompanionProcessThreadProc(
__in LPVOID lpParameter
)
{
BURN_PIPE_CONNECTION* pConnection = (BURN_PIPE_CONNECTION*)lpParameter;
HANDLE rghHandles[2] = { pConnection->hQuitRequested, pConnection->hProcess };
DWORD dwRes = ERROR_SUCCESS;
HRESULT hr = S_OK;

dwRes = ::WaitForMultipleObjects(ARRAYSIZE(rghHandles), rghHandles, FALSE, INFINITE);
switch (dwRes)
{
case WAIT_OBJECT_0:
hr = S_OK;
break;
case WAIT_OBJECT_0 + 1:
LogRedirect(NULL, NULL);
hr = E_SUSPECTED_AV_INTERFERENCE;
ExitOnFailure(hr, "Companion elevated process has been terminated prematurely.");
break;
default:
ExitWithLastError(hr, "Failed to monitor proper termination of companion process.");
break;
}

LExit:
return HRESULT_CODE(hr);
}

extern "C" HRESULT CoreApply(
__in BURN_ENGINE_STATE* pEngineState,
__in_opt HWND hwndParent
Expand Down

0 comments on commit 03e0ad7

Please sign in to comment.