Skip to content

Commit

Permalink
Support sending custom messages on embedded pipe
Browse files Browse the repository at this point in the history
  • Loading branch information
nirbar committed May 5, 2024
1 parent eef4ae2 commit 75c22ec
Show file tree
Hide file tree
Showing 15 changed files with 224 additions and 0 deletions.
1 change: 1 addition & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
- Changes by WiX up to git commit 376423b8101f4b59ee865e8a255cfe190fa5a7f1
- Build for .NET Framework 4.0
- Not overwriting log files when retrying to execute a package
- Support sending custom messages on embedded pipe

# WiX Toolset on GitHub
The WiX Toolset builds Windows installation packages from XML source code. The toolset supports a command-line environment that developers may integrate into their build processes to build Windows Installer (MSI) packages and executable bundles. The WiX GitHub project hosts the WiX source code Git repositories. The following links will take you to more details:
Expand Down
33 changes: 33 additions & 0 deletions src/burn/engine/EngineForApplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,39 @@ class CEngineForApplication : public IBootstrapperEngine, public IMarshal
return hr;
}

virtual STDMETHODIMP SendEmbeddedCustomMessage(
__in DWORD dwCode,
__in_z_opt LPCWSTR wzMessage,
__out int* pnResult
)
{
HRESULT hr = S_OK;
BYTE* pbData = NULL;
DWORD cbData = 0;
DWORD dwResult = 0;

if (BURN_MODE_EMBEDDED != m_pEngineState->mode)
{
hr = HRESULT_FROM_WIN32(ERROR_INVALID_STATE);
ExitOnRootFailure(hr, "Application requested to send embedded progress message when not in embedded mode.");
}

hr = BuffWriteNumber(&pbData, &cbData, dwCode);
ExitOnFailure(hr, "Failed to write code to message buffer.");

hr = BuffWriteString(&pbData, &cbData, wzMessage ? wzMessage : L"");
ExitOnFailure(hr, "Failed to write text to message buffer.");

hr = PipeSendMessage(m_pEngineState->embeddedConnection.hPipe, BURN_EMBEDDED_MESSAGE_TYPE_CUSTOM, pbData, cbData, NULL, NULL, &dwResult);
ExitOnFailure(hr, "Failed to send embedded progress message over pipe.");

*pnResult = static_cast<int>(dwResult);

LExit:
ReleaseBuffer(pbData);
return hr;
}

virtual STDMETHODIMP SetUpdate(
__in_z_opt LPCWSTR wzLocalSource,
__in_z_opt LPCWSTR wzDownloadSource,
Expand Down
4 changes: 4 additions & 0 deletions src/burn/engine/apply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2492,6 +2492,10 @@ static int GenericExecuteMessageHandler(
case GENERIC_EXECUTE_MESSAGE_FILES_IN_USE:
nResult = pContext->pUX->pUserExperience->OnExecuteFilesInUse(pContext->pExecutingPackage->sczId, pMessage->filesInUse.cFiles, pMessage->filesInUse.rgwzFiles);
break;

case GENERIC_EXECUTE_MESSAGE_CUSTOM:
nResult = pContext->pUX->pUserExperience->OnEmbeddedCustomMessage(pContext->pExecutingPackage->sczId, pMessage->custom.dwCode, pMessage->custom.wzMessage);
break;
}

nResult = UserExperienceCheckExecuteResult(pContext->pUX, pContext->fRollback, pMessage->dwAllowedResults, nResult);
Expand Down
6 changes: 6 additions & 0 deletions src/burn/engine/apply.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ enum GENERIC_EXECUTE_MESSAGE_TYPE
GENERIC_EXECUTE_MESSAGE_ERROR,
GENERIC_EXECUTE_MESSAGE_PROGRESS,
GENERIC_EXECUTE_MESSAGE_FILES_IN_USE,
GENERIC_EXECUTE_MESSAGE_CUSTOM,
};

typedef struct _APPLY_AUTHENTICATION_REQUIRED_DATA
Expand Down Expand Up @@ -43,6 +44,11 @@ typedef struct _GENERIC_EXECUTE_MESSAGE
DWORD cFiles;
LPCWSTR* rgwzFiles;
} filesInUse;
struct
{
DWORD dwCode;
LPCWSTR wzMessage;
} custom;
};
} GENERIC_EXECUTE_MESSAGE;

Expand Down
46 changes: 46 additions & 0 deletions src/burn/engine/embedded.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ static HRESULT OnEmbeddedProgress(
__in DWORD cbData,
__out DWORD* pdwResult
);
static HRESULT OnEmbeddedCustomMessage(
__in PFN_GENERICMESSAGEHANDLER pfnMessageHandler,
__in LPVOID pvContext,
__in_bcount(cbData) BYTE* pbData,
__in DWORD cbData,
__out DWORD* pdwResult
);

// function definitions

Expand Down Expand Up @@ -127,6 +134,11 @@ static HRESULT ProcessEmbeddedMessages(
ExitOnFailure(hr, "Failed to process embedded progress message.");
break;

case BURN_EMBEDDED_MESSAGE_TYPE_CUSTOM:
hr = OnEmbeddedCustomMessage(pContext->pfnGenericMessageHandler, pContext->pvContext, static_cast<BYTE*>(pMsg->pvData), pMsg->cbData, &dwResult);
ExitOnFailure(hr, "Failed to process embedded custom message.");
break;

default:
hr = E_INVALIDARG;
ExitOnRootFailure1(hr, "Unexpected embedded message sent to child process, msg: %u", pMsg->dwMessage);
Expand Down Expand Up @@ -172,6 +184,40 @@ static HRESULT OnEmbeddedErrorMessage(
return hr;
}

static HRESULT OnEmbeddedCustomMessage(
__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_CUSTOM;

hr = BuffReadNumber(pbData, cbData, &iData, &message.custom.dwCode);
ExitOnFailure(hr, "Failed to read custom code from buffer.");

hr = BuffReadString(pbData, cbData, &iData, &sczMessage);
ExitOnFailure(hr, "Failed to read custom message from buffer.");

message.custom.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);

return hr;
}

static HRESULT OnEmbeddedProgress(
__in PFN_GENERICMESSAGEHANDLER pfnMessageHandler,
__in LPVOID pvContext,
Expand Down
1 change: 1 addition & 0 deletions src/burn/engine/embedded.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ typedef enum _BURN_EMBEDDED_MESSAGE_TYPE
BURN_EMBEDDED_MESSAGE_TYPE_UNKNOWN,
BURN_EMBEDDED_MESSAGE_TYPE_ERROR,
BURN_EMBEDDED_MESSAGE_TYPE_PROGRESS,
BURN_EMBEDDED_MESSAGE_TYPE_CUSTOM,
} BURN_EMBEDDED_MESSAGE_TYPE;


Expand Down
10 changes: 10 additions & 0 deletions src/burn/inc/IBootstrapperApplication.h
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,16 @@ DECLARE_INTERFACE_IID_(IBootstrapperApplication, IUnknown, "53C31D56-49C0-426B-A
__in DWORD cFiles,
__in_ecount_z(cFiles) LPCWSTR* rgwzFiles
) = 0;

// OnEmbeddedCustomMessage - called when an embedded burn package send a SendEmbeddedCustomMessage(...).
//
// Return:
// Any code that the sender and recipient agree on.
STDMETHOD_(int, OnEmbeddedCustomMessage)(
__in_z LPCWSTR wzPackageId,
__in DWORD dwCode,
__in_z LPCWSTR wzMessage
) = 0;

// OnExecutePackageComplete - called when a package execution is complete.
//
Expand Down
6 changes: 6 additions & 0 deletions src/burn/inc/IBootstrapperEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,12 @@ DECLARE_INTERFACE_IID_(IBootstrapperEngine, IUnknown, "6480D616-27A0-44D7-905B-8
__out int* pnResult
) = 0;

STDMETHOD(SendEmbeddedCustomMessage)(
__in DWORD dwCode,
__in_z_opt LPCWSTR wzMessage,
__out int* pnResult
) = 0;

STDMETHOD(SetUpdate)(
__in_z_opt LPCWSTR wzLocalSource,
__in_z_opt LPCWSTR wzDownloadSource,
Expand Down
26 changes: 26 additions & 0 deletions src/ext/BalExtension/mba/core/BootstrapperApplication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,11 @@ protected BootstrapperApplication()
/// </summary>
public event EventHandler<ExecuteFilesInUseEventArgs> ExecuteFilesInUse;

/// <summary>
/// Fired when an embedded burn package sends a SendEmbeddedCustomMessage(...)
/// </summary>
public event EventHandler<EmbeddedCustomMessageEventArgs> EmbeddedCustomMessage;

/// <summary>
/// Fired when the engine has completed installing a specific package.
/// </summary>
Expand Down Expand Up @@ -1141,6 +1146,19 @@ protected virtual void OnExecuteFilesInUse(ExecuteFilesInUseEventArgs args)
}
}

/// <summary>
/// Called when an embedded burn package sends a SendEmbeddedCustomMessage(...).
/// </summary>
/// <param name="args">Additional arguments for this event.</param>
protected virtual void OnEmbeddedCustomMessage(EmbeddedCustomMessageEventArgs args)
{
EventHandler<EmbeddedCustomMessageEventArgs> handler = this.EmbeddedCustomMessage;
if (null != handler)
{
handler(this, args);
}
}

/// <summary>
/// Called when the engine has completed installing a specific package.
/// </summary>
Expand Down Expand Up @@ -1638,6 +1656,14 @@ Result IBootstrapperApplication.OnExecuteFilesInUse(string wzPackageId, int cFil
return args.Result;
}

Result IBootstrapperApplication.OnEmbeddedCustomMessage(string wzPackageId, int dwCode, string wzMessage)
{
EmbeddedCustomMessageEventArgs args = new EmbeddedCustomMessageEventArgs(wzPackageId, dwCode, wzMessage);
this.OnEmbeddedCustomMessage(args);

return args.Result;
}

Result IBootstrapperApplication.OnExecutePackageComplete(string wzPackageId, int hrExitCode, ApplyRestart restart, int nRecommendation)
{
ExecutePackageCompleteEventArgs args = new ExecutePackageCompleteEventArgs(wzPackageId, hrExitCode, restart, nRecommendation);
Expand Down
12 changes: 12 additions & 0 deletions src/ext/BalExtension/mba/core/Engine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,18 @@ public int SendEmbeddedProgress(int progressPercentage, int overallPercentage)
return result;
}

/// <summary>
/// Sends a custom embedded message.
/// </summary>
/// <param name="errorCode">Custom message code.</param>
/// <param name="message">Optional text.</param>
public int SendEmbeddedCustomMessage(int code, string message)
{
int result = 0;
this.engine.SendEmbeddedCustomMessage(code, message, out result);
return result;
}

/// <summary>
/// Shuts down the engine.
/// </summary>
Expand Down
47 changes: 47 additions & 0 deletions src/ext/BalExtension/mba/core/EventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1943,6 +1943,53 @@ public IList<string> Files
get { return this.files; }
}
}

/// <summary>
/// Additional arugments used for embedded custom messages.
/// </summary>
[Serializable]
public class EmbeddedCustomMessageEventArgs : ResultEventArgs
{
private string packageId;
private int code;
private string message;

/// <summary>
/// Creates a new instance of the <see cref="EmbeddedCustomMessageEventArgs"/> class.
/// </summary>
/// <param name="packageId">The identity of the package that yielded the files in use message.</param>
/// <param name="EmbeddedCustomMessageEventArgs">The list of files in use.</param>
public EmbeddedCustomMessageEventArgs(string packageId, int code, string message)
{
this.packageId = packageId;
this.code = code;
this.message = message;
}

/// <summary>
/// Gets the identity of the package that yielded the files in use message.
/// </summary>
public string PackageId
{
get { return this.packageId; }
}

/// <summary>
/// Gets the message code.
/// </summary>
public int Code
{
get { return this.code; }
}

/// <summary>
/// Gets the message text.
/// </summary>
public string Message
{
get { return this.message; }
}
}

/// <summary>
/// Additional arguments used when the engine has completed installing a specific package.
Expand Down
8 changes: 8 additions & 0 deletions src/ext/BalExtension/mba/core/IBootstrapperApplication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,14 @@ Result OnExecuteFilesInUse(
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1, ArraySubType = UnmanagedType.LPWStr), In] string[] rgwzFiles
);

[PreserveSig]
[return: MarshalAs(UnmanagedType.I4)]
Result OnEmbeddedCustomMessage(
[MarshalAs(UnmanagedType.LPWStr)] string wzPackageId,
[MarshalAs(UnmanagedType.U4)] int code,
[MarshalAs(UnmanagedType.LPWStr)] string wzMessage
);

[PreserveSig]
[return: MarshalAs(UnmanagedType.I4)]
Result OnExecutePackageComplete(
Expand Down
6 changes: 6 additions & 0 deletions src/ext/BalExtension/mba/core/IBootstrapperEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ void SendEmbeddedError(
[MarshalAs(UnmanagedType.I4)] out int pnResult
);

void SendEmbeddedCustomMessage(
[MarshalAs(UnmanagedType.U4)] int dwCode,
[MarshalAs(UnmanagedType.LPWStr)] string wzMessage,
[MarshalAs(UnmanagedType.I4)] out int pnResult
);

void SendEmbeddedProgress(
[MarshalAs(UnmanagedType.U4)] int dwProgressPercentage,
[MarshalAs(UnmanagedType.U4)] int dwOverallProgressPercentage,
Expand Down
9 changes: 9 additions & 0 deletions src/libs/balutil/inc/BalBaseBaFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,15 @@ class BalBaseBaFunctions : public IBootstrapperApplication
return IDNOACTION;
}

virtual STDMETHODIMP_(int) OnEmbeddedCustomMessage(
__in_z LPCWSTR /*wzPackageId*/,
__in DWORD /*dwCode*/,
__in_z LPCWSTR /*wzMessage*/
)
{
return IDNOACTION;
}

virtual STDMETHODIMP_(int) OnExecutePackageComplete(
__in_z LPCWSTR /*wzPackageId*/,
__in HRESULT /*hrExitCode*/,
Expand Down
9 changes: 9 additions & 0 deletions src/libs/balutil/inc/BalBaseBootstrapperApplication.h
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,15 @@ class CBalBaseBootstrapperApplication : public IBootstrapperApplication
return CheckCanceled() ? IDCANCEL : IDNOACTION;
}

virtual STDMETHODIMP_(int) OnEmbeddedCustomMessage(
__in_z LPCWSTR /*wzPackageId*/,
__in DWORD /*dwCode*/,
__in_z LPCWSTR /*wzMessage*/
)
{
return CheckCanceled() ? IDCANCEL : IDNOACTION;
}

virtual STDMETHODIMP_(int) OnExecutePackageComplete(
__in_z LPCWSTR wzPackageId,
__in HRESULT hrExitCode,
Expand Down

0 comments on commit 75c22ec

Please sign in to comment.