/******************************************************************* PipePumpMessages - *******************************************************************/ extern "C" HRESULT PipePumpMessages( __in HANDLE hPipe, __in_opt PFN_PIPE_MESSAGE_CALLBACK pfnCallback, __in_opt LPVOID pvContext, __in BURN_PIPE_RESULT* pResult ) { HRESULT hr = S_OK; BURN_PIPE_MESSAGE msg = { }; SIZE_T iData = 0; LPSTR sczMessage = NULL; DWORD dwResult = 0; // Pump messages from child process. while (S_OK == (hr = GetPipeMessage(hPipe, &msg))) { switch (msg.dwMessage) { case BURN_PIPE_MESSAGE_TYPE_LOG: iData = 0; hr = BuffReadStringAnsi((BYTE*)msg.pvData, msg.cbData, &iData, &sczMessage); ExitOnFailure(hr, "Failed to read log message."); hr = LogStringWorkRaw(sczMessage); ExitOnFailure1(hr, "Failed to write log message:'%hs'.", sczMessage); dwResult = static_cast<DWORD>(hr); break; case BURN_PIPE_MESSAGE_TYPE_COMPLETE: if (!msg.pvData || sizeof(DWORD) != msg.cbData) { hr = E_INVALIDARG; ExitOnRootFailure(hr, "No status returned to PipePumpMessages()"); } pResult->dwResult = *static_cast<DWORD*>(msg.pvData); ExitFunction1(hr = S_OK); // exit loop. case BURN_PIPE_MESSAGE_TYPE_TERMINATE: iData = 0; hr = BuffReadNumber(static_cast<BYTE*>(msg.pvData), msg.cbData, &iData, &pResult->dwResult); ExitOnFailure(hr, "Failed to read returned result to PipePumpMessages()"); if (sizeof(DWORD) * 2 == msg.cbData) { hr = BuffReadNumber(static_cast<BYTE*>(msg.pvData), msg.cbData, &iData, (DWORD*)&pResult->fRestart); ExitOnFailure(hr, "Failed to read returned restart to PipePumpMessages()"); } ExitFunction1(hr = S_OK); // exit loop. default: if (pfnCallback) { hr = pfnCallback(&msg, pvContext, &dwResult); } else { hr = E_INVALIDARG; } ExitOnFailure1(hr, "Failed to process message: %u", msg.dwMessage); break; } // post result hr = WritePipeMessage(hPipe, static_cast<DWORD>(BURN_PIPE_MESSAGE_TYPE_COMPLETE), &dwResult, sizeof(dwResult)); ExitOnFailure(hr, "Failed to post result to child process."); FreePipeMessage(&msg); } ExitOnFailure(hr, "Failed to get message over pipe"); if (S_FALSE == hr) { hr = S_OK; } LExit: ReleaseStr(sczMessage); FreePipeMessage(&msg); return hr; }
static HRESULT OnEmbeddedErrorMessage( __in PFN_GENERICMESSAGEHANDLER pfnMessageHandler, __in LPVOID pvContext, __in_bcount(cbData) BYTE* pbData, __in DWORD cbData, __out DWORD* pdwResult ) { HRESULT hr = S_OK; DWORD iData = 0; GENERIC_EXECUTE_MESSAGE message = { }; LPWSTR sczMessage = NULL; message.type = GENERIC_EXECUTE_MESSAGE_ERROR; hr = BuffReadNumber(pbData, cbData, &iData, &message.error.dwErrorCode); ExitOnFailure(hr, "Failed to read error code from buffer."); hr = BuffReadString(pbData, cbData, &iData, &sczMessage); ExitOnFailure(hr, "Failed to read error message from buffer."); message.error.wzMessage = sczMessage; hr = BuffReadNumber(pbData, cbData, &iData, &message.dwAllowedResults); ExitOnFailure(hr, "Failed to read UI hint from buffer."); *pdwResult = (DWORD)pfnMessageHandler(&message, pvContext); LExit: ReleaseStr(sczMessage);