Skip to content

Commit 75c22ec

Browse files
committed
Support sending custom messages on embedded pipe
1 parent eef4ae2 commit 75c22ec

15 files changed

+224
-0
lines changed

Readme.md

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
- Changes by WiX up to git commit 376423b8101f4b59ee865e8a255cfe190fa5a7f1
3636
- Build for .NET Framework 4.0
3737
- Not overwriting log files when retrying to execute a package
38+
- Support sending custom messages on embedded pipe
3839

3940
# WiX Toolset on GitHub
4041
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:

src/burn/engine/EngineForApplication.cpp

+33
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,39 @@ class CEngineForApplication : public IBootstrapperEngine, public IMarshal
370370
return hr;
371371
}
372372

373+
virtual STDMETHODIMP SendEmbeddedCustomMessage(
374+
__in DWORD dwCode,
375+
__in_z_opt LPCWSTR wzMessage,
376+
__out int* pnResult
377+
)
378+
{
379+
HRESULT hr = S_OK;
380+
BYTE* pbData = NULL;
381+
DWORD cbData = 0;
382+
DWORD dwResult = 0;
383+
384+
if (BURN_MODE_EMBEDDED != m_pEngineState->mode)
385+
{
386+
hr = HRESULT_FROM_WIN32(ERROR_INVALID_STATE);
387+
ExitOnRootFailure(hr, "Application requested to send embedded progress message when not in embedded mode.");
388+
}
389+
390+
hr = BuffWriteNumber(&pbData, &cbData, dwCode);
391+
ExitOnFailure(hr, "Failed to write code to message buffer.");
392+
393+
hr = BuffWriteString(&pbData, &cbData, wzMessage ? wzMessage : L"");
394+
ExitOnFailure(hr, "Failed to write text to message buffer.");
395+
396+
hr = PipeSendMessage(m_pEngineState->embeddedConnection.hPipe, BURN_EMBEDDED_MESSAGE_TYPE_CUSTOM, pbData, cbData, NULL, NULL, &dwResult);
397+
ExitOnFailure(hr, "Failed to send embedded progress message over pipe.");
398+
399+
*pnResult = static_cast<int>(dwResult);
400+
401+
LExit:
402+
ReleaseBuffer(pbData);
403+
return hr;
404+
}
405+
373406
virtual STDMETHODIMP SetUpdate(
374407
__in_z_opt LPCWSTR wzLocalSource,
375408
__in_z_opt LPCWSTR wzDownloadSource,

src/burn/engine/apply.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -2492,6 +2492,10 @@ static int GenericExecuteMessageHandler(
24922492
case GENERIC_EXECUTE_MESSAGE_FILES_IN_USE:
24932493
nResult = pContext->pUX->pUserExperience->OnExecuteFilesInUse(pContext->pExecutingPackage->sczId, pMessage->filesInUse.cFiles, pMessage->filesInUse.rgwzFiles);
24942494
break;
2495+
2496+
case GENERIC_EXECUTE_MESSAGE_CUSTOM:
2497+
nResult = pContext->pUX->pUserExperience->OnEmbeddedCustomMessage(pContext->pExecutingPackage->sczId, pMessage->custom.dwCode, pMessage->custom.wzMessage);
2498+
break;
24952499
}
24962500

24972501
nResult = UserExperienceCheckExecuteResult(pContext->pUX, pContext->fRollback, pMessage->dwAllowedResults, nResult);

src/burn/engine/apply.h

+6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ enum GENERIC_EXECUTE_MESSAGE_TYPE
1313
GENERIC_EXECUTE_MESSAGE_ERROR,
1414
GENERIC_EXECUTE_MESSAGE_PROGRESS,
1515
GENERIC_EXECUTE_MESSAGE_FILES_IN_USE,
16+
GENERIC_EXECUTE_MESSAGE_CUSTOM,
1617
};
1718

1819
typedef struct _APPLY_AUTHENTICATION_REQUIRED_DATA
@@ -43,6 +44,11 @@ typedef struct _GENERIC_EXECUTE_MESSAGE
4344
DWORD cFiles;
4445
LPCWSTR* rgwzFiles;
4546
} filesInUse;
47+
struct
48+
{
49+
DWORD dwCode;
50+
LPCWSTR wzMessage;
51+
} custom;
4652
};
4753
} GENERIC_EXECUTE_MESSAGE;
4854

src/burn/engine/embedded.cpp

+46
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ static HRESULT OnEmbeddedProgress(
3232
__in DWORD cbData,
3333
__out DWORD* pdwResult
3434
);
35+
static HRESULT OnEmbeddedCustomMessage(
36+
__in PFN_GENERICMESSAGEHANDLER pfnMessageHandler,
37+
__in LPVOID pvContext,
38+
__in_bcount(cbData) BYTE* pbData,
39+
__in DWORD cbData,
40+
__out DWORD* pdwResult
41+
);
3542

3643
// function definitions
3744

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

137+
case BURN_EMBEDDED_MESSAGE_TYPE_CUSTOM:
138+
hr = OnEmbeddedCustomMessage(pContext->pfnGenericMessageHandler, pContext->pvContext, static_cast<BYTE*>(pMsg->pvData), pMsg->cbData, &dwResult);
139+
ExitOnFailure(hr, "Failed to process embedded custom message.");
140+
break;
141+
130142
default:
131143
hr = E_INVALIDARG;
132144
ExitOnRootFailure1(hr, "Unexpected embedded message sent to child process, msg: %u", pMsg->dwMessage);
@@ -172,6 +184,40 @@ static HRESULT OnEmbeddedErrorMessage(
172184
return hr;
173185
}
174186

187+
static HRESULT OnEmbeddedCustomMessage(
188+
__in PFN_GENERICMESSAGEHANDLER pfnMessageHandler,
189+
__in LPVOID pvContext,
190+
__in_bcount(cbData) BYTE* pbData,
191+
__in DWORD cbData,
192+
__out DWORD* pdwResult
193+
)
194+
{
195+
HRESULT hr = S_OK;
196+
DWORD iData = 0;
197+
GENERIC_EXECUTE_MESSAGE message = { };
198+
LPWSTR sczMessage = NULL;
199+
200+
message.type = GENERIC_EXECUTE_MESSAGE_CUSTOM;
201+
202+
hr = BuffReadNumber(pbData, cbData, &iData, &message.custom.dwCode);
203+
ExitOnFailure(hr, "Failed to read custom code from buffer.");
204+
205+
hr = BuffReadString(pbData, cbData, &iData, &sczMessage);
206+
ExitOnFailure(hr, "Failed to read custom message from buffer.");
207+
208+
message.custom.wzMessage = sczMessage;
209+
210+
hr = BuffReadNumber(pbData, cbData, &iData, &message.dwAllowedResults);
211+
ExitOnFailure(hr, "Failed to read UI hint from buffer.");
212+
213+
*pdwResult = (DWORD)pfnMessageHandler(&message, pvContext);
214+
215+
LExit:
216+
ReleaseStr(sczMessage);
217+
218+
return hr;
219+
}
220+
175221
static HRESULT OnEmbeddedProgress(
176222
__in PFN_GENERICMESSAGEHANDLER pfnMessageHandler,
177223
__in LPVOID pvContext,

src/burn/engine/embedded.h

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ typedef enum _BURN_EMBEDDED_MESSAGE_TYPE
1111
BURN_EMBEDDED_MESSAGE_TYPE_UNKNOWN,
1212
BURN_EMBEDDED_MESSAGE_TYPE_ERROR,
1313
BURN_EMBEDDED_MESSAGE_TYPE_PROGRESS,
14+
BURN_EMBEDDED_MESSAGE_TYPE_CUSTOM,
1415
} BURN_EMBEDDED_MESSAGE_TYPE;
1516

1617

src/burn/inc/IBootstrapperApplication.h

+10
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,16 @@ DECLARE_INTERFACE_IID_(IBootstrapperApplication, IUnknown, "53C31D56-49C0-426B-A
725725
__in DWORD cFiles,
726726
__in_ecount_z(cFiles) LPCWSTR* rgwzFiles
727727
) = 0;
728+
729+
// OnEmbeddedCustomMessage - called when an embedded burn package send a SendEmbeddedCustomMessage(...).
730+
//
731+
// Return:
732+
// Any code that the sender and recipient agree on.
733+
STDMETHOD_(int, OnEmbeddedCustomMessage)(
734+
__in_z LPCWSTR wzPackageId,
735+
__in DWORD dwCode,
736+
__in_z LPCWSTR wzMessage
737+
) = 0;
728738

729739
// OnExecutePackageComplete - called when a package execution is complete.
730740
//

src/burn/inc/IBootstrapperEngine.h

+6
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,12 @@ DECLARE_INTERFACE_IID_(IBootstrapperEngine, IUnknown, "6480D616-27A0-44D7-905B-8
158158
__out int* pnResult
159159
) = 0;
160160

161+
STDMETHOD(SendEmbeddedCustomMessage)(
162+
__in DWORD dwCode,
163+
__in_z_opt LPCWSTR wzMessage,
164+
__out int* pnResult
165+
) = 0;
166+
161167
STDMETHOD(SetUpdate)(
162168
__in_z_opt LPCWSTR wzLocalSource,
163169
__in_z_opt LPCWSTR wzDownloadSource,

src/ext/BalExtension/mba/core/BootstrapperApplication.cs

+26
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,11 @@ protected BootstrapperApplication()
315315
/// </summary>
316316
public event EventHandler<ExecuteFilesInUseEventArgs> ExecuteFilesInUse;
317317

318+
/// <summary>
319+
/// Fired when an embedded burn package sends a SendEmbeddedCustomMessage(...)
320+
/// </summary>
321+
public event EventHandler<EmbeddedCustomMessageEventArgs> EmbeddedCustomMessage;
322+
318323
/// <summary>
319324
/// Fired when the engine has completed installing a specific package.
320325
/// </summary>
@@ -1141,6 +1146,19 @@ protected virtual void OnExecuteFilesInUse(ExecuteFilesInUseEventArgs args)
11411146
}
11421147
}
11431148

1149+
/// <summary>
1150+
/// Called when an embedded burn package sends a SendEmbeddedCustomMessage(...).
1151+
/// </summary>
1152+
/// <param name="args">Additional arguments for this event.</param>
1153+
protected virtual void OnEmbeddedCustomMessage(EmbeddedCustomMessageEventArgs args)
1154+
{
1155+
EventHandler<EmbeddedCustomMessageEventArgs> handler = this.EmbeddedCustomMessage;
1156+
if (null != handler)
1157+
{
1158+
handler(this, args);
1159+
}
1160+
}
1161+
11441162
/// <summary>
11451163
/// Called when the engine has completed installing a specific package.
11461164
/// </summary>
@@ -1638,6 +1656,14 @@ Result IBootstrapperApplication.OnExecuteFilesInUse(string wzPackageId, int cFil
16381656
return args.Result;
16391657
}
16401658

1659+
Result IBootstrapperApplication.OnEmbeddedCustomMessage(string wzPackageId, int dwCode, string wzMessage)
1660+
{
1661+
EmbeddedCustomMessageEventArgs args = new EmbeddedCustomMessageEventArgs(wzPackageId, dwCode, wzMessage);
1662+
this.OnEmbeddedCustomMessage(args);
1663+
1664+
return args.Result;
1665+
}
1666+
16411667
Result IBootstrapperApplication.OnExecutePackageComplete(string wzPackageId, int hrExitCode, ApplyRestart restart, int nRecommendation)
16421668
{
16431669
ExecutePackageCompleteEventArgs args = new ExecutePackageCompleteEventArgs(wzPackageId, hrExitCode, restart, nRecommendation);

src/ext/BalExtension/mba/core/Engine.cs

+12
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,18 @@ public int SendEmbeddedProgress(int progressPercentage, int overallPercentage)
440440
return result;
441441
}
442442

443+
/// <summary>
444+
/// Sends a custom embedded message.
445+
/// </summary>
446+
/// <param name="errorCode">Custom message code.</param>
447+
/// <param name="message">Optional text.</param>
448+
public int SendEmbeddedCustomMessage(int code, string message)
449+
{
450+
int result = 0;
451+
this.engine.SendEmbeddedCustomMessage(code, message, out result);
452+
return result;
453+
}
454+
443455
/// <summary>
444456
/// Shuts down the engine.
445457
/// </summary>

src/ext/BalExtension/mba/core/EventArgs.cs

+47
Original file line numberDiff line numberDiff line change
@@ -1943,6 +1943,53 @@ public IList<string> Files
19431943
get { return this.files; }
19441944
}
19451945
}
1946+
1947+
/// <summary>
1948+
/// Additional arugments used for embedded custom messages.
1949+
/// </summary>
1950+
[Serializable]
1951+
public class EmbeddedCustomMessageEventArgs : ResultEventArgs
1952+
{
1953+
private string packageId;
1954+
private int code;
1955+
private string message;
1956+
1957+
/// <summary>
1958+
/// Creates a new instance of the <see cref="EmbeddedCustomMessageEventArgs"/> class.
1959+
/// </summary>
1960+
/// <param name="packageId">The identity of the package that yielded the files in use message.</param>
1961+
/// <param name="EmbeddedCustomMessageEventArgs">The list of files in use.</param>
1962+
public EmbeddedCustomMessageEventArgs(string packageId, int code, string message)
1963+
{
1964+
this.packageId = packageId;
1965+
this.code = code;
1966+
this.message = message;
1967+
}
1968+
1969+
/// <summary>
1970+
/// Gets the identity of the package that yielded the files in use message.
1971+
/// </summary>
1972+
public string PackageId
1973+
{
1974+
get { return this.packageId; }
1975+
}
1976+
1977+
/// <summary>
1978+
/// Gets the message code.
1979+
/// </summary>
1980+
public int Code
1981+
{
1982+
get { return this.code; }
1983+
}
1984+
1985+
/// <summary>
1986+
/// Gets the message text.
1987+
/// </summary>
1988+
public string Message
1989+
{
1990+
get { return this.message; }
1991+
}
1992+
}
19461993

19471994
/// <summary>
19481995
/// Additional arguments used when the engine has completed installing a specific package.

src/ext/BalExtension/mba/core/IBootstrapperApplication.cs

+8
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,14 @@ Result OnExecuteFilesInUse(
389389
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1, ArraySubType = UnmanagedType.LPWStr), In] string[] rgwzFiles
390390
);
391391

392+
[PreserveSig]
393+
[return: MarshalAs(UnmanagedType.I4)]
394+
Result OnEmbeddedCustomMessage(
395+
[MarshalAs(UnmanagedType.LPWStr)] string wzPackageId,
396+
[MarshalAs(UnmanagedType.U4)] int code,
397+
[MarshalAs(UnmanagedType.LPWStr)] string wzMessage
398+
);
399+
392400
[PreserveSig]
393401
[return: MarshalAs(UnmanagedType.I4)]
394402
Result OnExecutePackageComplete(

src/ext/BalExtension/mba/core/IBootstrapperEngine.cs

+6
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ void SendEmbeddedError(
7070
[MarshalAs(UnmanagedType.I4)] out int pnResult
7171
);
7272

73+
void SendEmbeddedCustomMessage(
74+
[MarshalAs(UnmanagedType.U4)] int dwCode,
75+
[MarshalAs(UnmanagedType.LPWStr)] string wzMessage,
76+
[MarshalAs(UnmanagedType.I4)] out int pnResult
77+
);
78+
7379
void SendEmbeddedProgress(
7480
[MarshalAs(UnmanagedType.U4)] int dwProgressPercentage,
7581
[MarshalAs(UnmanagedType.U4)] int dwOverallProgressPercentage,

src/libs/balutil/inc/BalBaseBaFunctions.h

+9
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,15 @@ class BalBaseBaFunctions : public IBootstrapperApplication
538538
return IDNOACTION;
539539
}
540540

541+
virtual STDMETHODIMP_(int) OnEmbeddedCustomMessage(
542+
__in_z LPCWSTR /*wzPackageId*/,
543+
__in DWORD /*dwCode*/,
544+
__in_z LPCWSTR /*wzMessage*/
545+
)
546+
{
547+
return IDNOACTION;
548+
}
549+
541550
virtual STDMETHODIMP_(int) OnExecutePackageComplete(
542551
__in_z LPCWSTR /*wzPackageId*/,
543552
__in HRESULT /*hrExitCode*/,

src/libs/balutil/inc/BalBaseBootstrapperApplication.h

+9
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,15 @@ class CBalBaseBootstrapperApplication : public IBootstrapperApplication
606606
return CheckCanceled() ? IDCANCEL : IDNOACTION;
607607
}
608608

609+
virtual STDMETHODIMP_(int) OnEmbeddedCustomMessage(
610+
__in_z LPCWSTR /*wzPackageId*/,
611+
__in DWORD /*dwCode*/,
612+
__in_z LPCWSTR /*wzMessage*/
613+
)
614+
{
615+
return CheckCanceled() ? IDCANCEL : IDNOACTION;
616+
}
617+
609618
virtual STDMETHODIMP_(int) OnExecutePackageComplete(
610619
__in_z LPCWSTR wzPackageId,
611620
__in HRESULT hrExitCode,

0 commit comments

Comments
 (0)