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(