@joebigelow / wix / commits / c294fb86

Add functions to start/end MSI transactions and check whether or not it is supported on the target machine (#22)

* Add functions to start/end MSI transactions and check whether or not it is supported on the target machine * Add log mode parameter to MSI transaction functions. * No default log mode for WiuEndTransaction

Nir Bar committed Jan 11, 2021 at 20:07 UTC c294fb860ed7710c80fc004af6c9ebb09779c70c
2 files changed +99
src/dutil/inc/wiutil.h
+24
@@ -226,6 +226,15 @@ typedef UINT (WINAPI *PFN_MSISOURCELISTADDSOURCEEXW)(
226 __in LPCWSTR szSource,
227 __in_opt DWORD dwIndex
228 );
229 +typedef UINT(WINAPI* PFN_MSIBEGINTRANSACTIONW)(
230 + __in LPCWSTR szName,
231 + __in DWORD dwTransactionAttributes,
232 + __out MSIHANDLE* phTransactionHandle,
233 + __out HANDLE* phChangeOfOwnerEvent
234 + );
235 +typedef UINT(WINAPI* PFN_MSIENDTRANSACTION)(
236 + __in DWORD dwTransactionState
237 + );
238
239
240 HRESULT DAPI WiuInitialize(
@@ -372,6 +381,21 @@ HRESULT DAPI WiuSourceListAddSourceEx(
381 __in_z LPCWSTR wzSource,
382 __in_opt DWORD dwIndex
383 );
384 +HRESULT DAPI WiuBeginTransaction(
385 + __in_z LPCWSTR szName,
386 + __in DWORD dwTransactionAttributes,
387 + __out MSIHANDLE* phTransactionHandle,
388 + __out HANDLE* phChangeOfOwnerEvent,
389 + __in DWORD dwLogMode,
390 + __in_z LPCWSTR szLogPath
391 + );
392 +HRESULT DAPI WiuEndTransaction(
393 + __in DWORD dwTransactionState,
394 + __in DWORD dwLogMode,
395 + __in_z LPCWSTR szLogPath
396 + );
397 +BOOL DAPI WiuIsMsiTransactionSupported(
398 + );
399
400 #ifdef __cplusplus
401 }
src/dutil/wiutil.cpp
+75
@@ -42,6 +42,11 @@ static PFN_MSIGETPATCHINFOEXW vpfnMsiGetPatchInfoExWFromLibrary = NULL;
42 static PFN_MSIGETPRODUCTINFOEXW vpfnMsiGetProductInfoExWFromLibrary = NULL;
43 static PFN_MSISETEXTERNALUIRECORD vpfnMsiSetExternalUIRecordFromLibrary = NULL;
44 static PFN_MSISOURCELISTADDSOURCEEXW vpfnMsiSourceListAddSourceExWFromLibrary = NULL;
45 +
46 +// MSI Transactions v4.5+
47 +static PFN_MSIBEGINTRANSACTIONW vpfnMsiBeginTransaction = NULL;
48 +static PFN_MSIENDTRANSACTION vpfnMsiEndTransaction = NULL;
49 +
50 static BOOL vfWiuInitialized = FALSE;
51
52 // globals
@@ -176,6 +181,17 @@ extern "C" HRESULT DAPI WiuInitialize(
181 vpfnMsiSourceListAddSourceExW = vpfnMsiSourceListAddSourceExWFromLibrary;
182 }
183
184 + // MSI Transaction functions
185 + if (NULL == vpfnMsiBeginTransaction)
186 + {
187 + vpfnMsiBeginTransaction = reinterpret_cast<PFN_MSIBEGINTRANSACTIONW>(::GetProcAddress(vhMsiDll, "MsiBeginTransactionW"));
188 + }
189 +
190 + if (NULL == vpfnMsiEndTransaction)
191 + {
192 + vpfnMsiEndTransaction = reinterpret_cast<PFN_MSIENDTRANSACTION>(::GetProcAddress(vhMsiDll, "MsiEndTransaction"));
193 + }
194 +
195 vfWiuInitialized = TRUE;
196
197 LExit:
@@ -202,6 +218,8 @@ extern "C" void DAPI WiuUninitialize(
218 vpfnMsiDetermineApplicablePatchesWFromLibrary = NULL;
219 vpfnMsiDeterminePatchSequenceWFromLibrary = NULL;
220 vpfnMsiSourceListAddSourceExWFromLibrary = NULL;
221 + vpfnMsiBeginTransaction = NULL;
222 + vpfnMsiEndTransaction = NULL;
223 }
224
225 vfWiuInitialized = FALSE;
@@ -886,6 +904,63 @@ LExit:
904 return hr;
905 }
906
907 +extern "C" BOOL DAPI WiuIsMsiTransactionSupported(
908 + )
909 +{
910 + return vpfnMsiBeginTransaction && vpfnMsiEndTransaction;
911 +}
912 +
913 +extern "C" HRESULT DAPI WiuBeginTransaction(
914 + __in_z LPCWSTR szName,
915 + __in DWORD dwTransactionAttributes,
916 + __out MSIHANDLE * phTransactionHandle,
917 + __out HANDLE * phChangeOfOwnerEvent,
918 + __in DWORD dwLogMode,
919 + __in_z LPCWSTR szLogPath
920 + )
921 +{
922 + HRESULT hr = S_OK;
923 + DWORD er = ERROR_SUCCESS;
924 +
925 + if (!WiuIsMsiTransactionSupported())
926 + {
927 + ExitOnFailure(hr = E_NOTIMPL, "Msi transactions are not supported");
928 + }
929 +
930 + hr = WiuEnableLog(dwLogMode, szLogPath, INSTALLLOGATTRIBUTES_APPEND);
931 + ExitOnFailure(hr, "Failed to enable logging for MSI transaction");
932 +
933 + er = vpfnMsiBeginTransaction(szName, dwTransactionAttributes, phTransactionHandle, phChangeOfOwnerEvent);
934 + ExitOnWin32Error(er, hr, "Failed to begin transaction.");
935 +
936 +LExit:
937 + return hr;
938 +}
939 +
940 +extern "C" HRESULT DAPI WiuEndTransaction(
941 + __in DWORD dwTransactionState,
942 + __in DWORD dwLogMode,
943 + __in_z LPCWSTR szLogPath
944 + )
945 +{
946 + HRESULT hr = S_OK;
947 + DWORD er = ERROR_SUCCESS;
948 +
949 + if (!WiuIsMsiTransactionSupported())
950 + {
951 + ExitOnFailure(hr = E_NOTIMPL, "Msi transactions are not supported");
952 + }
953 +
954 + hr = WiuEnableLog(dwLogMode, szLogPath, INSTALLLOGATTRIBUTES_APPEND);
955 + ExitOnFailure(hr, "Failed to enable logging for MSI transaction");
956 +
957 + er = vpfnMsiEndTransaction(dwTransactionState);
958 + ExitOnWin32Error(er, hr, "Failed to end transaction.");
959 +
960 +LExit:
961 + return hr;
962 +}
963 +
964
965
966 static DWORD CheckForRestartErrorCode(