diff --git a/PInvoke/KtmW32/KtmW32.cs b/PInvoke/KtmW32/KtmW32.cs
new file mode 100644
index 00000000..b820ada9
--- /dev/null
+++ b/PInvoke/KtmW32/KtmW32.cs
@@ -0,0 +1,1736 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
+using static Vanara.PInvoke.Kernel32;
+
+namespace Vanara.PInvoke
+{
+ /// Kernel Transaction Manager (KTM) functions and structures.
+ public static partial class KtmW32
+ {
+ /// An optional enlistment instruction.
+ [PInvokeData("ktmw32.h", MSDNShortId = "7bc06468-947f-48ec-8e58-20df58ed93bd")]
+ [Flags]
+ public enum CreateEnlistmentOptions
+ {
+ /// Enlist as a superior transaction manager.
+ ENLISTMENT_SUPERIOR = 1
+ }
+
+ /// Optional attributes for the new RM.
+ [PInvokeData("ktmw32.h", MSDNShortId = "ad88e478-1dff-4f35-a0e3-6bda8bb45711")]
+ [Flags]
+ public enum CreateRMOptions
+ {
+ /// Indicates that the RM is volatile, and does not perform recovery.
+ RESOURCE_MANAGER_VOLATILE = 1,
+
+ ///
+ RESOURCE_MANAGER_COMMUNICATION = 2
+ }
+
+ /// Optional attributes for the new TM.
+ [PInvokeData("ktmw32.h", MSDNShortId = "f5b7d0c1-9cd0-48fc-8125-d4da040951c4")]
+ [Flags]
+ public enum CreateTrxnMgrOptions
+ {
+ ///
+ TRANSACTION_MANAGER_COMMIT_DEFAULT = 0x00000000,
+
+ /// Indicates that the TM is volatile, and does not perform recovery.
+ TRANSACTION_MANAGER_VOLATILE = 0x00000001,
+
+ ///
+ TRANSACTION_MANAGER_COMMIT_SYSTEM_VOLUME = 0x00000002,
+
+ ///
+ TRANSACTION_MANAGER_COMMIT_SYSTEM_HIVES = 0x00000004,
+
+ ///
+ TRANSACTION_MANAGER_COMMIT_LOWEST = 0x00000008,
+
+ ///
+ TRANSACTION_MANAGER_CORRUPT_FOR_RECOVERY = 0x00000010,
+
+ ///
+ TRANSACTION_MANAGER_CORRUPT_FOR_PROGRESS = 0x00000020,
+ }
+
+ /// Optional transaction instructions.
+ [PInvokeData("ktmw32.h", MSDNShortId = "578bda35-bd35-4f6d-8366-a4bfb4dbfe42")]
+ [Flags]
+ public enum CreateTrxnOptions
+ {
+ /// The transaction cannot be distributed.
+ TRANSACTION_DO_NOT_PROMOTE = 1
+ }
+
+ /// KTM defines the following enlistment access masks to be used when opening enlistments.
+ // https://docs.microsoft.com/en-us/windows/win32/ktm/enlistment-access-masks
+ [PInvokeData("winnt.h", MSDNShortId = "93773eb7-141a-49f3-9306-ffbda2f4ab9f")]
+ [Flags]
+ public enum EnlistmentAccess : uint
+ {
+ /// The caller can query KTM for information about the enlistment.
+ ENLISTMENT_QUERY_INFORMATION = 0x00001,
+
+ /// The caller can set information about the enlistment.
+ ENLISTMENT_SET_INFORMATION = 0x00002,
+
+ /// The caller can recover an enlistment.
+ ENLISTMENT_RECOVER = 0x00004,
+
+ ///
+ ///
+ /// The caller can complete actions that a resource manager does on behalf of the transaction. The following is a list of actions:
+ ///
+ ///
+ /// - CommitComplete
+ /// - PrepareComplete
+ /// - PrePrepareComplete
+ /// - RollbackComplete
+ /// - ReadOnlyEnlistment
+ /// - RollbackEnlistment
+ /// - SinglePhaseReject
+ ///
+ ///
+ ENLISTMENT_SUBORDINATE_RIGHTS = 0x00008,
+
+ /// The caller can enlist in the transaction as a superior transaction manager.
+ ENLISTMENT_SUPERIOR_RIGHTS = 0x00010,
+
+ /// The caller has the following privileges: STANDARD_RIGHTS_READ and ENLISTMENT_QUERY_INFORMATION.
+ ENLISTMENT_GENERIC_READ = 0x20001,
+
+ /// The caller has the following privileges: STANDARD_RIGHTS_WRITE, ENLISTMENT_SET_INFORMATION, and ENLISTMENT_RECOVER.
+ ENLISTMENT_GENERIC_WRITE = 0x2001E,
+
+ /// The caller has the following privileges: STANDARD_RIGHTS_EXECUTE, ENLISTMENT_RECOVER, and ENLISTMENT_SUBORDINATE_RIGHTS.
+ ENLISTMENT_GENERIC_EXECUTE = 0x2001C,
+
+ /// This value sets all valid bits for an enlistment access value.
+ ENLISTMENT_ALL_ACCESS = 0xF001F,
+ }
+
+ /// Lists the different types of notifications that can be received by an enlistment.
+ // https://docs.microsoft.com/en-us/windows/win32/ktm/notification-mask
+ [PInvokeData("winnt.h", MSDNShortId = "65db8ba5-193c-439b-8e8c-6cb4a9bd4efd")]
+ [Flags]
+ public enum NOTIFICATION_MASK : uint
+ {
+ /// A mask that indicates all valid bits for a transaction notification.
+ TRANSACTION_NOTIFY_MASK = 0x3FFFFFFF,
+
+ ///
+ /// This notification is called after a client calls CommitTransaction and either no resource manager (RM) supports single-phase
+ /// commit or a superior transaction manager (TM) calls PrePrepareEnlistment. This notification is received by the RMs indicating
+ /// that they should complete any work that could cause other RMs to need to enlist in a transaction, such as flushing its cache.
+ /// After completing these operations the RM must call PrePrepareComplete. To receive this notification the RM must also support
+ /// TRANSACTION_NOTIFY_PREPARE and TRANSACTION_NOTIFY_COMMIT.
+ ///
+ TRANSACTION_NOTIFY_PREPREPARE = 0x00000001,
+
+ ///
+ /// This notification is called after the TRANSACTION_NOTIFY_PREPREPARE processing is complete. It signals the RM to complete all
+ /// the work that is associated with this enlistment so that it can guarantee that a commit operation could succeed and an abort
+ /// operation could also succeed. Typically, the bulk of the work for a transaction is done during the prepare phase. For durable
+ /// RMs, they must log their state prior to calling the PrepareComplete function. This is the last chance for the RM to request
+ /// that the transaction be rolled back.
+ ///
+ TRANSACTION_NOTIFY_PREPARE = 0x00000002,
+
+ ///
+ /// This notification signals the RM to complete all the work that is associated with this enlistment. Typically, the RM releases
+ /// any locks, releases any information necessary to roll back the transaction. The RM must respond by calling the CommitComplete
+ /// function when it has finished these operations.
+ ///
+ TRANSACTION_NOTIFY_COMMIT = 0x00000004,
+
+ /// This notification signals the RM to undo all the work it has done that is associated with the transaction.
+ TRANSACTION_NOTIFY_ROLLBACK = 0x00000008,
+
+ /// This notification signals to the superior TM that a pre-prepare operation was completed successfully.
+ TRANSACTION_NOTIFY_PREPREPARE_COMPLETE = 0x00000010,
+
+ /// This notification signals to the superior TM that a prepare operation was completed successfully.
+ TRANSACTION_NOTIFY_PREPARE_COMPLETE = 0x00000020,
+
+ /// This notification signals to the superior TM that a commit operation was completed successfully.
+ TRANSACTION_NOTIFY_COMMIT_COMPLETE = 0x00000040,
+
+ /// This notification signals to the superior TM that a rollback operation was completed successfully.
+ TRANSACTION_NOTIFY_ROLLBACK_COMPLETE = 0x00000080,
+
+ ///
+ /// This notification signals to RMs that they should recover their state because a transaction outcome must be redelivered. For
+ /// example, when an RM is recovered, and when there are transactions left in-doubt. This notification is delivered once the
+ /// in-doubt state is resolved.
+ ///
+ TRANSACTION_NOTIFY_RECOVER = 0x00000100,
+
+ ///
+ /// This notification signals the RM to complete and commit the transaction without using a two-phase commit protocol. If the RM
+ /// wants to use a two-phase operation, it must respond by calling the SinglePhaseReject function.
+ ///
+ TRANSACTION_NOTIFY_SINGLE_PHASE_COMMIT = 0x00000200,
+
+ /// KTM is signaling to the superior TM to perform a commit operation.
+ TRANSACTION_NOTIFY_DELEGATE_COMMIT = 0x00000400,
+
+ /// KTM is signaling to the superior TM to query the status of an in-doubt transaction.
+ TRANSACTION_NOTIFY_RECOVER_QUERY = 0x00000800,
+
+ ///
+ /// This notification signals to the superior TM that pre-prepare notifications must be delivered on the specified enlistment.
+ ///
+ TRANSACTION_NOTIFY_ENLIST_PREPREPARE = 0x00001000,
+
+ /// This notification indicates that the recovery operation is complete for this RM.
+ TRANSACTION_NOTIFY_LAST_RECOVER = 0x00002000,
+
+ ///
+ /// The specified transaction is in an in-doubt state. The RM receives this notification during recovery operations when a
+ /// transaction has been prepared, but there is no superior transaction manager (TM) available. For example, when a transaction
+ /// involves a remote TM and that node is unavailable, its node is unavailable, or the local Distributed Transaction Coordinator
+ /// service is unavailable, the transaction state is in-doubt.
+ ///
+ TRANSACTION_NOTIFY_INDOUBT = 0x00004000,
+
+ /// The TM is online and accepting requests.
+ TRANSACTION_NOTIFY_TM_ONLINE = 0x02000000,
+
+ ///
+ /// Signals to RMs that there is outcome information available, and that a request for that information should be made.
+ ///
+ TRANSACTION_NOTIFY_REQUEST_OUTCOME = 0x20000000,
+
+ /// Reserved.
+ TRANSACTION_NOTIFY_COMMIT_FINALIZE = 0x40000000,
+ }
+
+ /// KTM defines the following enlistment access masks to be used when opening a resource manager.
+ // https://docs.microsoft.com/en-us/windows/win32/ktm/resource-manager-access-masks
+ [PInvokeData("winnt.h", MSDNShortId = "6b901b73-516d-4f27-b258-3b93a8f9675f")]
+ [Flags]
+ public enum ResourceManagerAccess : uint
+ {
+ /// The caller can query for the resource manager (RM) information.
+ RESOURCEMANAGER_QUERY_INFORMATION = 0x0001,
+
+ /// The caller can set the RM information.
+ RESOURCEMANAGER_SET_INFORMATION = 0x0002,
+
+ /// The caller can recover the specified RM.
+ RESOURCEMANAGER_RECOVER = 0x0004,
+
+ /// The caller can enlist an RM in a transaction.
+ RESOURCEMANAGER_ENLIST = 0x0008,
+
+ /// The caller can receive a notification for an RM.
+ RESOURCEMANAGER_GET_NOTIFICATION = 0x0010,
+
+ ///
+ RESOURCEMANAGER_REGISTER_PROTOCOL = 0x0020,
+
+ ///
+ RESOURCEMANAGER_COMPLETE_PROPAGATION = 0x0040,
+
+ /// The caller has the following privileges: STANDARD_RIGHTS_READ, RESOURCEMANAGER_QUERY_INFORMATION, and RESOURCEMANAGER_RECOVER.
+ RESOURCEMANAGER_GENERIC_READ = ACCESS_MASK.STANDARD_RIGHTS_READ | RESOURCEMANAGER_QUERY_INFORMATION | ACCESS_MASK.SYNCHRONIZE,
+
+ ///
+ /// The caller has the following privileges: STANDARD_RIGHTS_WRITE, RESOURCEMANAGER_SET_INFORMATION, RESOURCEMANAGER_ENLIST, and RESOURCEMANAGER_GET_NOTIFICATION.
+ ///
+ RESOURCEMANAGER_GENERIC_WRITE = ACCESS_MASK.STANDARD_RIGHTS_WRITE | RESOURCEMANAGER_SET_INFORMATION | RESOURCEMANAGER_RECOVER | RESOURCEMANAGER_ENLIST | RESOURCEMANAGER_GET_NOTIFICATION | RESOURCEMANAGER_REGISTER_PROTOCOL | RESOURCEMANAGER_COMPLETE_PROPAGATION | ACCESS_MASK.SYNCHRONIZE,
+
+ /// The caller has the following privileges: STANDARD_RIGHTS_EXECUTE, RESOURCEMANAGER_ENLIST, and RESOURCEMANAGER_GET_NOTIFICATION.
+ RESOURCEMANAGER_GENERIC_EXECUTE = ACCESS_MASK.STANDARD_RIGHTS_EXECUTE | RESOURCEMANAGER_RECOVER | RESOURCEMANAGER_ENLIST | RESOURCEMANAGER_GET_NOTIFICATION | RESOURCEMANAGER_COMPLETE_PROPAGATION | ACCESS_MASK.SYNCHRONIZE,
+
+ /// The caller has the following privilege: STANDARD_RIGHTS_REQUIRED.
+ RESOURCEMANAGER_ALL_ACCESS = ACCESS_MASK.STANDARD_RIGHTS_REQUIRED | RESOURCEMANAGER_GENERIC_READ | RESOURCEMANAGER_GENERIC_WRITE | RESOURCEMANAGER_GENERIC_EXECUTE,
+ }
+
+ /// Defines the outcomes (results) that KTM can assign to a transaction.
+ // https://docs.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-transaction_outcome typedef enum _TRANSACTION_OUTCOME {
+ // TransactionOutcomeUndetermined, TransactionOutcomeCommitted, TransactionOutcomeAborted } TRANSACTION_OUTCOME;
+ [PInvokeData("winnt.h", MSDNShortId = "d4315a62-b65f-4744-8084-2317ad39c32c")]
+ public enum TRANSACTION_OUTCOME
+ {
+ /// The transaction has not yet been committed or rolled back.
+ TransactionOutcomeUndetermined = 1,
+
+ /// The transaction has been committed.
+ TransactionOutcomeCommitted,
+
+ /// The transaction has been rolled back.
+ TransactionOutcomeAborted,
+ }
+
+ /// KTM defines the following transaction access masks to be used when opening a transaction.
+ ///
+ /// It is recommended that resource managers, when enlisting in a transaction, specify TRANSACTION_RESOURCE_MANAGER_RIGHTS
+ /// when opening a transaction.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/ktm/transaction-access-masks
+ [PInvokeData("winnt.h", MSDNShortId = "93ef3098-b3cc-4b24-ae82-1c10d937f14f")]
+ [Flags]
+ public enum TransactionAccess : uint
+ {
+ /// The caller can query transaction information.
+ TRANSACTION_QUERY_INFORMATION = 0x000001,
+
+ /// The caller can set transaction information.
+ TRANSACTION_SET_INFORMATION = 0x000002,
+
+ /// The caller can enlist in this transaction.
+ TRANSACTION_ENLIST = 0x000004,
+
+ /// The caller can commit this transaction.
+ TRANSACTION_COMMIT = 0x000008,
+
+ /// The caller can roll back this transaction.
+ TRANSACTION_ROLLBACK = 0x000010,
+
+ ///
+ /// The caller can propagate this transaction to a superior resource manager, such as the Distributed Transaction Coordinator (DTC).
+ ///
+ TRANSACTION_PROPAGATE = 0x000020,
+
+ /// The caller has the following privileges: STANDARD_RIGHTS_READ, TRANSACTION_QUERY_INFORMATION, and SYNCHRONIZE.
+ TRANSACTION_GENERIC_READ = 0x120001,
+
+ ///
+ /// The caller has the following privileges: STANDARD_RIGHTS_WRITE, TRANSACTION_SET_INFORMATION, TRANSACTION_COMMIT,
+ /// TRANSACTION_ENLIST, TRANSACTION_ROLLBACK, TRANSACTION_PROPAGATE, and SYNCHRONIZE.
+ ///
+ TRANSACTION_GENERIC_WRITE = 0x12003E,
+
+ ///
+ /// The caller has the following privileges: STANDARD_RIGHTS_EXECUTE, TRANSACTION_COMMIT, TRANSACTION_ROLLBACK, and SYNCHRONIZE.
+ ///
+ TRANSACTION_GENERIC_EXECUTE = 0x120018,
+
+ ///
+ /// The caller has the following privilege: STANDARD_RIGHTS_REQUIRED, TRANSACTION_GENERIC_READ, TRANSACTION_GENERIC_WRITE, and TRANSACTION_GENERIC_EXECUTE.
+ ///
+ TRANSACTION_ALL_ACCESS = 0x12003F,
+
+ ///
+ /// The caller has the following privileges: TRANSACTION_GENERIC_READ, STANDARD_RIGHTS_WRITE, TRANSACTION_SET_INFORMATION,
+ /// TRANSACTION_ROLLBACK, TRANSACTION_ENLIST, TRANSACTION_PROPAGATE, and SYNCHRONIZE.
+ ///
+ TRANSACTION_RESOURCE_MANAGER_RIGHTS = 0x120037,
+ }
+
+ /// KTM defines the following enlistment access masks to be used when opening a transaction manager (TM).
+ // https://docs.microsoft.com/en-us/windows/win32/ktm/transaction-manager-access-masks
+ [PInvokeData("winnt.h", MSDNShortId = "8f9b9d3d-e7ea-4df2-82b1-2d4c3e0766c0")]
+ [Flags]
+ public enum TransactionMgrAccess
+ {
+ /// The caller can query information about this TM.
+ TRANSACTIONMANAGER_QUERY_INFORMATION = 0x00001,
+
+ /// The caller can set information about this TM.
+ TRANSACTIONMANAGER_SET_INFORMATION = 0x00002,
+
+ /// The caller can recover this TM.
+ TRANSACTIONMANAGER_RECOVER = 0x00004,
+
+ /// The caller can rename a TM instance.
+ TRANSACTIONMANAGER_RENAME = 0x00008,
+
+ /// The caller can create a resource manager that is associated with this TM.
+ TRANSACTIONMANAGER_CREATE_RM = 0x00010,
+
+ /// This value is reserved.
+ TRANSACTIONMANAGER_BIND_TRANSACTION = 0x00020,
+
+ /// The caller has the following privileges: STANDARD_RIGHTS_READ and TRANSACTIONMANAGER_QUERY_INFORMATION.
+ TRANSACTIONMANAGER_GENERIC_READ = 0x20001,
+
+ ///
+ /// The caller has the following privileges: STANDARD_RIGHTS_WRITE, TRANSACTIONMANAGER_SET_INFORMATION,
+ /// TRANSACTIONMANAGER_RECOVER, TRANSACTIONMANAGER_RENAME, and TRANSACTIONMANAGER_CREATE_RM.
+ ///
+ TRANSACTIONMANAGER_GENERIC_WRITE = 0x2001E,
+
+ /// The caller has the following privilege: STANDARD_RIGHTS_EXECUTE.
+ TRANSACTIONMANAGER_GENERIC_EXECUTE = 0x20000,
+
+ /// This value sets all valid bits for a TM access value.
+ TRANSACTIONMANAGER_ALL_ACCESS = 0xF003F,
+ }
+
+ ///
+ /// Indicates that a resource manager (RM) has finished committing a transaction that was requested by the transaction manager (TM).
+ ///
+ /// A handle to the enlistment for which the commit operation is completed.
+ ///
+ ///
+ /// The latest virtual clock value received for this transaction. If you specify NULL, the virtual clock value is not changed.
+ /// See LARGE_INTEGER.
+ ///
+ /// To change the virtual clock value, this value must be greater than the current value returned in the COMMIT notification.
+ ///
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero (0). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-commitcomplete BOOL CommitComplete( IN HANDLE
+ // EnlistmentHandle, IN PLARGE_INTEGER TmVirtualClock );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "de3e3a26-3e56-4732-8e7c-945b45593aed")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CommitComplete([In] HENLISTMENT EnlistmentHandle, in long TmVirtualClock);
+
+ ///
+ /// Indicates that a resource manager (RM) has finished committing a transaction that was requested by the transaction manager (TM).
+ ///
+ /// A handle to the enlistment for which the commit operation is completed.
+ ///
+ ///
+ /// The latest virtual clock value received for this transaction. If you specify NULL, the virtual clock value is not changed.
+ /// See LARGE_INTEGER.
+ ///
+ /// To change the virtual clock value, this value must be greater than the current value returned in the COMMIT notification.
+ ///
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero (0). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-commitcomplete BOOL CommitComplete( IN HANDLE
+ // EnlistmentHandle, IN PLARGE_INTEGER TmVirtualClock );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "de3e3a26-3e56-4732-8e7c-945b45593aed")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CommitComplete([In] HENLISTMENT EnlistmentHandle, [Optional] IntPtr TmVirtualClock);
+
+ ///
+ /// Commits the transaction associated with this enlistment handle. This function is used by communication resource managers
+ /// (sometimes called superior transaction managers).
+ ///
+ /// A handle to the enlistment to commit.
+ ///
+ ///
+ /// A pointer to the latest virtual clock value received for this enlistment. If you specify NULL, the virtual clock value is
+ /// not changed.
+ ///
+ /// To change the virtual clock value, this value must be greater than the current value returned by a subordinate TM.
+ ///
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is 0 (zero). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-commitenlistment BOOL CommitEnlistment( IN HANDLE
+ // EnlistmentHandle, IN PLARGE_INTEGER TmVirtualClock );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "d1e1043d-2db3-4f05-affc-2d32744baf10")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CommitEnlistment([In] HENLISTMENT EnlistmentHandle, in long TmVirtualClock);
+
+ ///
+ /// Commits the transaction associated with this enlistment handle. This function is used by communication resource managers
+ /// (sometimes called superior transaction managers).
+ ///
+ /// A handle to the enlistment to commit.
+ ///
+ ///
+ /// A pointer to the latest virtual clock value received for this enlistment. If you specify NULL, the virtual clock value is
+ /// not changed.
+ ///
+ /// To change the virtual clock value, this value must be greater than the current value returned by a subordinate TM.
+ ///
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is 0 (zero). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-commitenlistment BOOL CommitEnlistment( IN HANDLE
+ // EnlistmentHandle, IN PLARGE_INTEGER TmVirtualClock );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "d1e1043d-2db3-4f05-affc-2d32744baf10")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CommitEnlistment([In] HENLISTMENT EnlistmentHandle, [Optional] IntPtr TmVirtualClock);
+
+ /// Requests that the specified transaction be committed.
+ ///
+ /// A handle to the transaction to be committed.
+ ///
+ /// This handle must have been opened with the TRANSACTION_COMMIT access right. For more information, see KTM Security and Access Rights.
+ ///
+ ///
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is 0 (zero). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ ///
+ ///
+ /// You can commit any transaction handle that has been opened or created using the TRANSACTION_COMMIT permission; any application
+ /// can commit a transaction, not just the creator.
+ ///
+ /// This function can only be called if the transaction is still active, not prepared, pre-prepared, or rolled back.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-committransaction BOOL CommitTransaction( IN HANDLE
+ // TransactionHandle );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "17db5e1f-685b-46f0-bac6-dff4c18bb515")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CommitTransaction([In] HTRXN TransactionHandle);
+
+ /// Requests that the specified transaction be committed.
+ ///
+ /// A handle to the transaction to be committed.
+ ///
+ /// This handle must have been opened with the TRANSACTION_COMMIT access right. For more information, see KTM Security and Access Rights.
+ ///
+ ///
+ ///
+ ///
+ /// If the function succeeds, the return value is nonzero. Success means that the function completed synchronously, and the calling
+ /// application does not need to wait for pending results.
+ ///
+ /// If the function fails, the return value is 0 (zero). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-committransactionasync BOOL CommitTransactionAsync( IN HANDLE
+ // TransactionHandle );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "cc0f4314-e216-490b-a49a-14bb850e0762")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CommitTransactionAsync([In] HTRXN TransactionHandle);
+
+ /// Creates an enlistment, sets its initial state, and opens a handle to the enlistment with the specified access.
+ ///
+ /// A pointer to a SECURITY_ATTRIBUTES structure that contains the security attributes for the enlistment manager. Specify
+ /// NULL to obtain the default attributes.
+ ///
+ /// A handle to the resource manager (RM) to enlist.
+ /// A handle to the transaction in which the RM is enlisting.
+ ///
+ /// The notifications this RM is requesting for the TransactionHandle parameter. For a list of valid values, see NOTIFICATION_MASK.
+ ///
+ ///
+ /// Any optional enlistment instructions.
+ ///
+ ///
+ /// Value
+ /// Meaning
+ ///
+ /// -
+ /// ENLISTMENT_SUPERIOR 1
+ /// Enlist as a superior transaction manager.
+ ///
+ ///
+ ///
+ ///
+ /// A pointer to a user-defined structure used by the RM that is returned when a notification is sent in the TRANSACTION_NOTIFICATION
+ /// structure. This is typically used to associate a private structure with this specific transaction.
+ ///
+ ///
+ /// If the function succeeds, the return value is a handle to the enlistment.
+ ///
+ /// If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call the GetLastError function.
+ ///
+ /// The following list identifies the possible error codes:
+ ///
+ ///
+ /// Windows Vista: Any attempt to enlist during the pre-prepare phase or later will fail.
+ ///
+ /// If you do not specify within your notification mask that you accept a single-phase commit request, KTM always performs a
+ /// two-phase commit operation.
+ ///
+ /// Keep the following notification rules in mind when enlisting in transactions:
+ ///
+ /// -
+ /// The RM must always request rollback notification.
+ ///
+ /// -
+ /// If the RM requests prepare notification, it must also request commit notification.
+ ///
+ /// -
+ /// If the RM requests a single-phase commit operation, it must also specify prepare and commit notifications.
+ ///
+ /// -
+ ///
+ /// The only time an RM is not required to request commit notifications is when it is requesting at least a pair of pre-prepare and
+ /// rollback notifications.
+ ///
+ ///
+ ///
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-createenlistment HANDLE CreateEnlistment( IN
+ // LPSECURITY_ATTRIBUTES lpEnlistmentAttributes, IN HANDLE ResourceManagerHandle, IN HANDLE TransactionHandle, IN NOTIFICATION_MASK
+ // NotificationMask, IN DWORD CreateOptions, IN PVOID EnlistmentKey );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "7bc06468-947f-48ec-8e58-20df58ed93bd")]
+ public static extern SafeHENLISTMENT CreateEnlistment([In, Optional] SECURITY_ATTRIBUTES lpEnlistmentAttributes, [In] HRESMGR ResourceManagerHandle, [In] HTRXN TransactionHandle, [In] NOTIFICATION_MASK NotificationMask, [In, Optional] CreateEnlistmentOptions CreateOptions, [In, Optional] IntPtr EnlistmentKey);
+
+ /// Creates a new resource manager (RM) object, and associates the RM with a transaction manager (TM).
+ ///
+ /// A pointer to a SECURITY_ATTRIBUTES structure that contains the security attributes for the resource manager. Specify NULL
+ /// to obtain the default attributes.
+ ///
+ /// A pointer the resource manager GUID. This parameter is required and must not be NULL.
+ ///
+ /// Any optional attributes for the new RM.
+ ///
+ ///
+ /// Value
+ /// Meaning
+ ///
+ /// -
+ /// RESOURCE_MANAGER_VOLATILE
+ /// Indicates that the RM is volatile, and does not perform recovery.
+ ///
+ ///
+ ///
+ /// A handle to the TM that will manage the transactions for this RM.
+ /// A description for this RM.
+ ///
+ /// If the function succeeds, the return value is a handle to the RM.
+ ///
+ /// If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call the GetLastError function.
+ ///
+ /// The following list identifies the possible error codes:
+ ///
+ ///
+ /// Immediately after calling this function, you must call RecoverResourceManager.
+ /// An RM is an endpoint for TM notifications regarding transactions that the RM has enlisted in.
+ ///
+ /// RMs are typically persistent, meaning that after a system failure, they must be reopened to perform certain operations. Volatile,
+ /// or transient, RMs can be created by calling the CreateResourceManager function and by specifying
+ /// RESOURCE_MANAGER_VOLATILE. Volatile RMs do not perform recovery operations, but do require notifications about a transaction.
+ ///
+ /// You can create a volatile RM on a durable TM, but you cannot create a durable RM on a volatile TM.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-createresourcemanager HANDLE CreateResourceManager( IN
+ // LPSECURITY_ATTRIBUTES lpResourceManagerAttributes, IN LPGUID ResourceManagerId, IN DWORD CreateOptions, IN HANDLE TmHandle, LPWSTR
+ // Description );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "ad88e478-1dff-4f35-a0e3-6bda8bb45711")]
+ public static extern SafeHRESMGR CreateResourceManager([In, Optional] SECURITY_ATTRIBUTES lpResourceManagerAttributes, [In] in Guid ResourceManagerId, [In, Optional] CreateRMOptions CreateOptions, [In] HTRXNMGR TmHandle, [MarshalAs(UnmanagedType.LPWStr), Optional] string Description);
+
+ /// Creates a new transaction object.
+ ///
+ ///
+ /// A pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If
+ /// this parameter is NULL, the handle cannot be inherited.
+ ///
+ ///
+ /// The lpSecurityDescriptor member of the structure specifies a security descriptor for the new event. If
+ /// lpTransactionAttributes is NULL, the object gets a default security descriptor. The access control lists (ACL) in the
+ /// default security descriptor for a transaction come from the primary or impersonation token of the creator.
+ ///
+ ///
+ /// Reserved. Must be zero (0).
+ ///
+ /// Any optional transaction instructions.
+ ///
+ ///
+ /// Value
+ /// Meaning
+ ///
+ /// -
+ /// TRANSACTION_DO_NOT_PROMOTE
+ /// The transaction cannot be distributed.
+ ///
+ ///
+ ///
+ /// Reserved; specify zero (0).
+ /// Reserved; specify zero (0).
+ ///
+ ///
+ /// The time-out interval, in milliseconds. If a nonzero value is specified, the transaction will be aborted when the interval
+ /// elapses if it has not already reached the prepared state.
+ ///
+ /// Specify zero (0) or INFINITE to provide an infinite time-out.
+ ///
+ /// A user-readable description of the transaction.
+ ///
+ /// If the function succeeds, the return value is a handle to the transaction.
+ ///
+ /// If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call the GetLastError function.
+ ///
+ /// The following list identifies the possible error codes:
+ ///
+ ///
+ ///
+ /// Use the CloseHandle function to close the transaction handle. If the last transaction handle is closed before a client calls the
+ /// CommitTransaction function with the transaction handle, then KTM rolls back the transaction.
+ ///
+ ///
+ /// If the transaction might need to be promotable to a distributed transaction, then you must grant the Distributed Transaction
+ /// Coordinator (DTC) access rights to enlist in the transaction. To do this, the lpTransactionAttributes parameter needs to contain
+ /// an access control entry with the DTC’s SID (S-1-5-80-2818357584-3387065753-4000393942-342927828-138088443) and the
+ /// TRANSACTION_ENLIST right. For more information, see Distributed Transaction Coordinator and Access Control Components.
+ ///
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-createtransaction HANDLE CreateTransaction( IN
+ // LPSECURITY_ATTRIBUTES lpTransactionAttributes, IN LPGUID UOW, IN DWORD CreateOptions, IN DWORD IsolationLevel, IN DWORD
+ // IsolationFlags, IN DWORD Timeout, LPWSTR Description );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "578bda35-bd35-4f6d-8366-a4bfb4dbfe42")]
+ public static extern SafeHTRXN CreateTransaction([In, Optional] SECURITY_ATTRIBUTES lpTransactionAttributes, [In, Optional] IntPtr UOW, [In, Optional] CreateTrxnOptions CreateOptions, [In, Optional] uint IsolationLevel, [In, Optional] uint IsolationFlags, [In, Optional] uint Timeout, [MarshalAs(UnmanagedType.LPWStr), Optional] string Description);
+
+ /// Creates a new transaction manager (TM) object and returns a handle with the specified access.
+ /// The transaction SECURITY_ATTRIBUTES (ACLs) for the TM object.
+ ///
+ /// The log file stream name. If the stream does not exist in the log, it is created. To create a volatile TM, this parameter must be
+ /// NULL and CreateOptions must specify TRANSACTION_MANAGER_VOLATILE, this transaction manager is considered volatile.
+ ///
+ ///
+ /// Any optional attributes for the new TM.
+ ///
+ ///
+ /// Value
+ /// Meaning
+ ///
+ /// -
+ /// TRANSACTION_MANAGER_VOLATILE
+ /// Indicates that the TM is volatile, and does not perform recovery.
+ ///
+ ///
+ ///
+ /// Reserved; specify zero.
+ ///
+ /// If the function succeeds, the return value is a handle to the transaction manager.
+ ///
+ /// If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call the GetLastError function.
+ ///
+ /// The following list identifies the possible error codes:
+ ///
+ ///
+ /// Immediately after calling this function, you must call RecoverTransactionManager.
+ /// If your transaction manager is volatile, all your resource managers must also be volatile.
+ /// You must call RecoverTransactionManager after creating a TM in order for the TM to function correctly.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-createtransactionmanager HANDLE CreateTransactionManager( IN
+ // LPSECURITY_ATTRIBUTES lpTransactionAttributes, LPWSTR LogFileName, IN ULONG CreateOptions, IN ULONG CommitStrength );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "f5b7d0c1-9cd0-48fc-8125-d4da040951c4")]
+ public static extern SafeHTRXNMGR CreateTransactionManager([In, Optional] SECURITY_ATTRIBUTES lpTransactionAttributes, [MarshalAs(UnmanagedType.LPWStr), Optional] string LogFileName, [In, Optional] CreateTrxnMgrOptions CreateOptions, uint CommitStrength = 0);
+
+ /// Obtains a virtual clock value from a transaction manager.
+ /// A handle to the transaction manager to obtain a virtual clock value for.
+ /// The latest virtual clock value for the transaction manager. See LARGE_INTEGER.
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is 0 (zero). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-getcurrentclocktransactionmanager BOOL
+ // GetCurrentClockTransactionManager( IN HANDLE TransactionManagerHandle, OUT PLARGE_INTEGER TmVirtualClock );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "21d7c0fa-3a49-43b3-9325-d3dfdabbcb98")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool GetCurrentClockTransactionManager([In] HTRXNMGR TransactionManagerHandle, out long TmVirtualClock);
+
+ /// Obtains the identifier (ID) for the specified enlistment.
+ /// A handle to the enlistment.
+ /// A pointer to a variables that receives the ID of the enlistment.
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is 0 (zero). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-getenlistmentid BOOL GetEnlistmentId( IN HANDLE
+ // EnlistmentHandle, OUT LPGUID EnlistmentId );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "ffd37a2e-6bac-4566-bb15-eafce8a11c3b")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool GetEnlistmentId([In] HENLISTMENT EnlistmentHandle, out Guid EnlistmentId);
+
+ ///
+ /// Retrieves an opaque structure of recovery data from KTM. Recovery information is stored in a log on behalf of a resource manager
+ /// (RM) by calling the SetEnlistmentRecoveryInformation function. After a failure, the RM can use the
+ /// GetEnlistmentRecoveryInformation function to retrieve the information.
+ ///
+ /// A handle to the enlistment.
+ /// The size of the Buffer parameter, in bytes.
+ /// A pointer to a buffer that receives the enlistment recovery information.
+ /// A pointer to a variable that receives the actual number of bytes returned in the Buffer parameter.
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is 0 (zero). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ /// This call cannot be used with volatile transaction managers.
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-getenlistmentrecoveryinformation BOOL
+ // GetEnlistmentRecoveryInformation( IN HANDLE EnlistmentHandle, IN ULONG BufferSize, OUT PVOID Buffer, OUT PULONG BufferUsed );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "05bfbe81-5f3d-4e32-b4fa-4532227f522e")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool GetEnlistmentRecoveryInformation([In] HENLISTMENT EnlistmentHandle, [In] uint BufferSize, IntPtr Buffer, out uint BufferUsed);
+
+ ///
+ /// Requests and receives a notification for a resource manager (RM). This function is used by the RM register to receive
+ /// notifications when a transaction changes state.
+ ///
+ /// A handle to the resource manager.
+ /// A pointer to a TRANSACTION_NOTIFICATION structure that receives the first available notification.
+ /// The size of the TransactionNotification buffer, in bytes.
+ ///
+ /// The time, in milliseconds, for which the calling application is blocking while waiting for the notification to become available.
+ /// If no notifications are available when the timeout expires, ERROR_TIMEOUT is returned.
+ ///
+ ///
+ /// A pointer to a variable that receives the actual size of the notification received by the TransactionNotification parameter.
+ ///
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero (0). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ ///
+ /// All resource managers must register to receive TRANSACTION_NOTIFY_PREPREPARE, TRANSACTION_NOTIFY_PREPARE, and
+ /// TRANSACTION_NOTIFY_COMMIT notifications, even if they subsequently call ReadOnlyEnlistment to mark an enlistment as
+ /// read-only. Resource managers can support TRANSACTION_NOTIFY_SINGLE_PHASE_COMMIT, but they must also support the
+ /// multi-phase pre-prepare, prepare, and commit notifications. For the list of all notifications that resource managers can receive,
+ /// see TRANSACTION_NOTIFICATION.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-getnotificationresourcemanager BOOL
+ // GetNotificationResourceManager( IN HANDLE ResourceManagerHandle, OUT PTRANSACTION_NOTIFICATION TransactionNotification, IN ULONG
+ // NotificationLength, IN DWORD dwMilliseconds, OUT PULONG ReturnLength );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "d606f960-e843-4478-8ba7-5201f85c44ce")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool GetNotificationResourceManager([In] HRESMGR ResourceManagerHandle, IntPtr TransactionNotification, [In] uint NotificationLength, [In, Optional] uint dwMilliseconds, out uint ReturnLength);
+
+ ///
+ /// Requests and receives asynchronous notification for a resource manager (RM). This function is used by the RM register to receive
+ /// notifications when a transaction changes state.
+ ///
+ /// A handle to the resource manager.
+ /// A pointer to a TRANSACTION_NOTIFICATION structure that receives the first available notification.
+ /// The size of the TransactionNotification buffer, in bytes.
+ ///
+ /// A pointer to a variable that receives the actual size of the notification received by the TransactionNotification parameter.
+ ///
+ /// A pointer to an OVERLAPPED structure that is required for asynchronous operation.
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero (0). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ ///
+ ///
+ /// All resource managers must register to receive TRANSACTION_NOTIFY_PREPREPARE, TRANSACTION_NOTIFY_PREPARE, and
+ /// TRANSACTION_NOTIFY_COMMIT notifications, even if they subsequently call ReadOnlyEnlistment to mark an enlistment as
+ /// read-only. Resource managers can support TRANSACTION_NOTIFY_SINGLE_PHASE_COMMIT, but they must also support the
+ /// multi-phase pre-prepare, prepare, and commit notifications. For the list of all notifications that resource managers can receive,
+ /// see TRANSACTION_NOTIFICATION.
+ ///
+ ///
+ /// Resource managers (RM) may want to call this function more than once to provide multiple buffers for KTM to use when delivering
+ /// notifications. The number of calls to this function depends on how much load your RM is carrying.
+ ///
+ /// This function must be called after the SetResourceManagerCompletionPort function is called.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-getnotificationresourcemanagerasync BOOL
+ // GetNotificationResourceManagerAsync( IN HANDLE ResourceManagerHandle, OUT PTRANSACTION_NOTIFICATION TransactionNotification, IN
+ // ULONG TransactionNotificationLength, OUT PULONG ReturnLength, IN LPOVERLAPPED lpOverlapped );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "c83e104b-6cd7-4399-8232-7c2e7b408f1a")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern unsafe bool GetNotificationResourceManagerAsync([In] HRESMGR ResourceManagerHandle, IntPtr TransactionNotification, [In] uint TransactionNotificationLength, out uint ReturnLength, [In] NativeOverlapped* lpOverlapped);
+
+ /// Obtains the identifier (ID) for the specified transaction.
+ /// A handle to the transaction.
+ /// A pointer to a variable that receives the ID of the transaction.
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is 0 (zero). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-gettransactionid BOOL GetTransactionId( IN HANDLE
+ // TransactionHandle, OUT LPGUID TransactionId );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "10f4729f-3e6e-469a-8f72-48c29735e7b1")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool GetTransactionId([In] HTRXN TransactionHandle, out Guid TransactionId);
+
+ /// Returns the requested information about the specified transaction.
+ ///
+ /// A handle to the transaction. The handle must have the TRANSACTION_QUERY_INFORMATION permission to retrieve the information.
+ ///
+ ///
+ /// A pointer to a buffer that receives the current outcome of the transaction. If the call to the GetTransactionInformation
+ /// function is successful, this value will be one of the TRANSACTION_OUTCOME enumeration values.
+ ///
+ /// Reserved.
+ /// Reserved.
+ /// A pointer to a variable that receives the timeout value, in milliseconds, for this transaction.
+ ///
+ /// The size of the Description parameter, in bytes. The buffer length value cannot be longer than the value of MAX_TRANSACTION_DESCRIPTION_LENGTH.
+ ///
+ /// A pointer to a buffer that receives the user-defined description of the transaction.
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero. To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-gettransactioninformation BOOL GetTransactionInformation( IN
+ // HANDLE TransactionHandle, OUT PDWORD Outcome, OUT PDWORD IsolationLevel, OUT PDWORD IsolationFlags, OUT PDWORD Timeout, DWORD
+ // BufferLength, LPWSTR Description );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "5ce3c96a-629e-49d0-8ec4-f9bf76af99ac")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool GetTransactionInformation([In] HTRXN TransactionHandle, out TRANSACTION_OUTCOME Outcome, [Optional] IntPtr IsolationLevel, [Optional] IntPtr IsolationFlags, out uint Timeout, uint BufferLength, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder Description);
+
+ /// Obtains an identifier for the specified transaction manager.
+ /// A handle to the transaction manager.
+ /// A pointer to a variable that receives the identifier for the transaction manager.
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is 0 (zero). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-gettransactionmanagerid BOOL GetTransactionManagerId( IN
+ // HANDLE TransactionManagerHandle, OUT LPGUID TransactionManagerId );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "e1aa573d-add9-42b7-8b2b-773dc12aa51b")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool GetTransactionManagerId([In] HTRXNMGR TransactionManagerHandle, out Guid TransactionManagerId);
+
+ /// Opens an existing enlistment object, and returns a handle to the enlistment.
+ /// The access requested for this enlistment. See Enlistment Access Masks for a list of valid values.
+ /// A handle to the resource manager.
+ /// The enlistment identifier.
+ ///
+ /// If the function succeeds, the return value is a handle to the enlistment.
+ ///
+ /// If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call the GetLastError function.
+ ///
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-openenlistment HANDLE OpenEnlistment( IN DWORD
+ // dwDesiredAccess, IN HANDLE ResourceManagerHandle, IN LPGUID EnlistmentId );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "2c403e22-3feb-415a-b65b-572802764548")]
+ public static extern SafeHENLISTMENT OpenEnlistment([In] EnlistmentAccess dwDesiredAccess, [In] HRESMGR ResourceManagerHandle, [In] in Guid EnlistmentId);
+
+ /// Opens an existing resource manager (RM).
+ /// The access requested for the RM. See Resource Manager Access Masks for a list of valid values.
+ /// A handle to the transaction manager.
+ /// The identifier for this resource manager.
+ ///
+ /// If the function succeeds, the return value is a handle to the resource manager.
+ ///
+ /// If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call the GetLastError function.
+ ///
+ /// The following list identifies the possible error codes:
+ ///
+ /// Immediately after calling this function, you must call RecoverResourceManager.
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-openresourcemanager HANDLE OpenResourceManager( IN DWORD
+ // dwDesiredAccess, IN HANDLE TmHandle, IN LPGUID ResourceManagerId );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "396b586f-c594-4481-b095-862e9058519c")]
+ public static extern SafeHRESMGR OpenResourceManager([In] ResourceManagerAccess dwDesiredAccess, [In] HTRXNMGR TmHandle, [In] in Guid ResourceManagerId);
+
+ /// Opens an existing transaction.
+ ///
+ /// The access to the transaction object. You must have read and write access to work with a transaction. See Transaction Access
+ /// Masks for a list of valid values.
+ ///
+ ///
+ /// The GUID that identifies the transaction to be opened. This is commonly referred to as a unit of work for the transaction.
+ ///
+ ///
+ /// If the function succeeds, the return value is a handle to the transaction.
+ ///
+ /// If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call the GetLastError function.
+ ///
+ /// The following list identifies the possible error codes:
+ ///
+ ///
+ /// Clients close the transaction handle by using the CloseHandle function. If the last transaction handle is closed without anyone
+ /// calling the CommitTransaction function on the transaction, then the KTM implicitly rolls back the transaction.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-opentransaction HANDLE OpenTransaction( IN DWORD
+ // dwDesiredAccess, IN LPGUID TransactionId );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "d95f15e4-d0fd-4665-849d-eecac8fc542b")]
+ public static extern SafeHTRXN OpenTransaction([In] TransactionAccess dwDesiredAccess, [In] in Guid TransactionId);
+
+ /// Opens an existing transaction manager.
+ /// The name of the log stream. This stream must exist within a CLFS log file.
+ /// The access requested. See Transaction Manager Access Masks for a list of valid values.
+ /// Reserved; specify zero.
+ ///
+ /// If the function succeeds, the return value is a handle to the transaction manager.
+ ///
+ /// If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call the GetLastError function.
+ ///
+ /// The following list identifies the possible error codes:
+ ///
+ ///
+ /// Immediately after calling this function, you must call RecoverTransactionManager.
+ ///
+ /// The LogFileName must be specified using the NT file format. For example: <drive>:<path>. Do not use the .BLF extension.
+ ///
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-opentransactionmanager HANDLE OpenTransactionManager( LPWSTR
+ // LogFileName, IN ACCESS_MASK DesiredAccess, IN ULONG OpenOptions );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "6b53609a-b956-441c-b5b5-9a8e6aa489c9")]
+ public static extern SafeHTRXNMGR OpenTransactionManager([MarshalAs(UnmanagedType.LPWStr)] string LogFileName, [In] TransactionMgrAccess DesiredAccess, uint OpenOptions = 0);
+
+ /// Opens an existing transaction manager.
+ /// The identifier of the transaction to open.
+ /// The access requested. See Transaction Manager Access Masks for a list of valid values.
+ /// Reserved; specify zero.
+ ///
+ /// If the function succeeds, the return value is a handle to the transaction manager.
+ ///
+ /// If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call the GetLastError function.
+ ///
+ /// The following list identifies the possible error codes:
+ ///
+ /// Immediately after calling this function, you must call RecoverTransactionManager.
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-opentransactionmanagerbyid HANDLE OpenTransactionManagerById(
+ // LPGUID TransactionManagerId, IN ACCESS_MASK DesiredAccess, IN ULONG OpenOptions );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "4724383d-8ecf-40cb-8159-15a6d5ddfd1b")]
+ public static extern SafeHTRXNMGR OpenTransactionManagerById(in Guid TransactionManagerId, [In] TransactionMgrAccess DesiredAccess, uint OpenOptions = 0);
+
+ ///
+ /// Indicates that the resource manager (RM) has completed all processing necessary to guarantee that a commit or abort operation
+ /// will succeed for the specified transaction.
+ ///
+ /// A handle to the enlistment.
+ ///
+ ///
+ /// The latest virtual clock value received for this prepare complete notification. If you specify NULL, the virtual clock
+ /// value is not changed. See LARGE_INTEGER.
+ ///
+ /// To change the virtual clock value, this value must be greater than the current value returned in the COMMIT notification.
+ ///
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero (0). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-preparecomplete BOOL PrepareComplete( IN HANDLE
+ // EnlistmentHandle, IN PLARGE_INTEGER TmVirtualClock );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "47488c70-3409-4544-bcca-3415f91e7194")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool PrepareComplete([In] HENLISTMENT EnlistmentHandle, in long TmVirtualClock);
+
+ ///
+ /// Indicates that the resource manager (RM) has completed all processing necessary to guarantee that a commit or abort operation
+ /// will succeed for the specified transaction.
+ ///
+ /// A handle to the enlistment.
+ ///
+ ///
+ /// The latest virtual clock value received for this prepare complete notification. If you specify NULL, the virtual clock
+ /// value is not changed. See LARGE_INTEGER.
+ ///
+ /// To change the virtual clock value, this value must be greater than the current value returned in the COMMIT notification.
+ ///
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero (0). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-preparecomplete BOOL PrepareComplete( IN HANDLE
+ // EnlistmentHandle, IN PLARGE_INTEGER TmVirtualClock );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "47488c70-3409-4544-bcca-3415f91e7194")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool PrepareComplete([In] HENLISTMENT EnlistmentHandle, [Optional] IntPtr TmVirtualClock);
+
+ ///
+ /// Prepares the transaction associated with this enlistment handle. This function is used by communication resource managers
+ /// (sometimes called superior transaction managers).
+ ///
+ /// A handle to the enlistment for which the prepare operation has completed.
+ /// A pointer to the latest virtual clock value received for this transaction.
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero (0). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-prepareenlistment BOOL PrepareEnlistment( IN HANDLE
+ // EnlistmentHandle, IN PLARGE_INTEGER TmVirtualClock );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "5f1b1eb2-e2f5-4daf-b549-7f0c195414f0")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool PrepareEnlistment([In] HENLISTMENT EnlistmentHandle, in long TmVirtualClock);
+
+ ///
+ /// Signals that this resource manager has completed its pre-prepare work, so that other resource managers can now begin their
+ /// prepare operations.
+ ///
+ /// A handle to the enlistment.
+ ///
+ ///
+ /// The latest virtual clock value received for this pre-prepare operation. If you specify NULL, the virtual clock value is
+ /// not changed. See LARGE_INTEGER.
+ ///
+ /// To change the virtual clock value, this value must be greater than the current value returned in the COMMIT notification.
+ ///
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero (0). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-prepreparecomplete BOOL PrePrepareComplete( IN HANDLE
+ // EnlistmentHandle, IN PLARGE_INTEGER TmVirtualClock );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "b4a70a51-2c49-4626-9fca-9ca6e0d21a53")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool PrePrepareComplete([In] HENLISTMENT EnlistmentHandle, in long TmVirtualClock);
+
+ ///
+ /// Signals that this resource manager has completed its pre-prepare work, so that other resource managers can now begin their
+ /// prepare operations.
+ ///
+ /// A handle to the enlistment.
+ ///
+ ///
+ /// The latest virtual clock value received for this pre-prepare operation. If you specify NULL, the virtual clock value is
+ /// not changed. See LARGE_INTEGER.
+ ///
+ /// To change the virtual clock value, this value must be greater than the current value returned in the COMMIT notification.
+ ///
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero (0). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-prepreparecomplete BOOL PrePrepareComplete( IN HANDLE
+ // EnlistmentHandle, IN PLARGE_INTEGER TmVirtualClock );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "b4a70a51-2c49-4626-9fca-9ca6e0d21a53")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool PrePrepareComplete([In] HENLISTMENT EnlistmentHandle, [Optional] IntPtr TmVirtualClock);
+
+ ///
+ /// Pre-prepares the transaction associated with this enlistment handle. This function is used by communication resource managers
+ /// (sometimes called superior transaction managers).
+ ///
+ /// A handle to the enlistment for which the prepare operation has completed.
+ /// A pointer to the latest virtual clock value received for this transaction.
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero (0). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-preprepareenlistment BOOL PrePrepareEnlistment( IN HANDLE
+ // EnlistmentHandle, IN PLARGE_INTEGER TmVirtualClock );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "7a336267-4bee-4aac-abff-ec112650789a")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool PrePrepareEnlistment([In] HENLISTMENT EnlistmentHandle, in long TmVirtualClock);
+
+ ///
+ /// Requests that the specified enlistment be converted to a read-only enlistment. A read-only enlistment cannot participate in the
+ /// outcome of the transaction and is not durably recorded for recovery.
+ ///
+ /// A handle to the enlistment.
+ ///
+ ///
+ /// The latest virtual clock value received for this enlistment. If you specify NULL, the virtual clock value is not changed.
+ /// See LARGE_INTEGER.
+ ///
+ /// To change the virtual clock value, this value must be greater than the current value returned in the COMMIT notification.
+ ///
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero (0). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ ///
+ /// If a resource manager no longer needs to participate in a transaction without rolling back the transaction, it should call
+ /// ReadOnlyEnlistment prior to closing the enlistment handle.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-readonlyenlistment BOOL ReadOnlyEnlistment( IN HANDLE
+ // EnlistmentHandle, IN PLARGE_INTEGER TmVirtualClock );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "a6411fad-8ad0-4a31-9e09-0c18dd384634")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool ReadOnlyEnlistment([In] HENLISTMENT EnlistmentHandle, in long TmVirtualClock);
+
+ ///
+ /// Requests that the specified enlistment be converted to a read-only enlistment. A read-only enlistment cannot participate in the
+ /// outcome of the transaction and is not durably recorded for recovery.
+ ///
+ /// A handle to the enlistment.
+ ///
+ ///
+ /// The latest virtual clock value received for this enlistment. If you specify NULL, the virtual clock value is not changed.
+ /// See LARGE_INTEGER.
+ ///
+ /// To change the virtual clock value, this value must be greater than the current value returned in the COMMIT notification.
+ ///
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero (0). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ ///
+ /// If a resource manager no longer needs to participate in a transaction without rolling back the transaction, it should call
+ /// ReadOnlyEnlistment prior to closing the enlistment handle.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-readonlyenlistment BOOL ReadOnlyEnlistment( IN HANDLE
+ // EnlistmentHandle, IN PLARGE_INTEGER TmVirtualClock );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "a6411fad-8ad0-4a31-9e09-0c18dd384634")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool ReadOnlyEnlistment([In] HENLISTMENT EnlistmentHandle, [Optional] IntPtr TmVirtualClock);
+
+ /// Recovers an enlistment's state.
+ /// A handle to the enlistment.
+ /// The key to the enlistment to be recovered.
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero (0). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-recoverenlistment BOOL RecoverEnlistment( IN HANDLE
+ // EnlistmentHandle, IN PVOID EnlistmentKey );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "5c36732f-bf4f-4071-959e-3359be0b2363")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool RecoverEnlistment([In] HENLISTMENT EnlistmentHandle, [In, Optional] IntPtr EnlistmentKey);
+
+ /// Recovers a resource manager's state from its log file.
+ /// A handle to the resource manager.
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero (0). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-recoverresourcemanager BOOL RecoverResourceManager( IN HANDLE
+ // ResourceManagerHandle );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "616ff873-c0d0-464e-9b1b-74a426b99abd")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool RecoverResourceManager([In] HRESMGR ResourceManagerHandle);
+
+ /// Recovers a transaction manager's state from its log file.
+ /// A handle to the transaction manager.
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero (0). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ /// This function must be called after you call CreateTransactionManager.
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-recovertransactionmanager BOOL RecoverTransactionManager( IN
+ // HANDLE TransactionManagerHandle );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "6f217ebb-3423-41d3-acff-eb21838c9751")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool RecoverTransactionManager([In] HTRXNMGR TransactionManagerHandle);
+
+ ///
+ /// Renames a transaction manager (TM) object. This function can only be used on named TM handles. A new GUID for the TM is
+ /// selected and can be retrieved using the GetTransactionManagerID function.
+ ///
+ /// The name of the log stream. This stream must exist within a CLFS log file.
+ /// A value that specifies the current name of the TM.
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero (0). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-renametransactionmanager BOOL RenameTransactionManager( LPWSTR
+ // LogFileName, IN LPGUID ExistingTransactionManagerGuid );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "2767e689-1342-458f-a215-a29d774c0648")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool RenameTransactionManager([MarshalAs(UnmanagedType.LPWStr)] string LogFileName, in Guid ExistingTransactionManagerGuid);
+
+ /// Indicates that the resource manager (RM) has successfully completed rolling back a transaction.
+ /// A handle the enlistment.
+ /// The latest virtual clock value received for this transaction. See LARGE_INTEGER.
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero (0). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ ///
+ /// If the RM was not able to successfully roll back a transaction, the RM should request a full rollback by calling the
+ /// RollbackTransaction function.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-rollbackcomplete BOOL RollbackComplete( IN HANDLE
+ // EnlistmentHandle, IN PLARGE_INTEGER TmVirtualClock );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "c9d53777-eef9-4c60-921d-50b0fbf8d005")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool RollbackComplete([In] HENLISTMENT EnlistmentHandle, in long TmVirtualClock);
+
+ ///
+ /// Rolls back the specified transaction that is associated with an enlistment. This function cannot be called for read-only enlistments.
+ ///
+ /// A handle to the enlistment.
+ /// The latest virtual clock value received for this enlistment. See LARGE_INTEGER.
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero (0). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ ///
+ ///
+ /// This function is used by an RM to roll back a transaction in which it is enlisted. All work associated with the transaction is
+ /// rolled back.
+ ///
+ /// Rollbacks are allowed by enlistments at any time before it issues a prepare complete notification.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-rollbackenlistment BOOL RollbackEnlistment( IN HANDLE
+ // EnlistmentHandle, IN PLARGE_INTEGER TmVirtualClock );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "e62c0c81-6802-4a76-94bb-617933490e83")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool RollbackEnlistment([In] HENLISTMENT EnlistmentHandle, in long TmVirtualClock);
+
+ /// Requests that the specified transaction be rolled back. This function is synchronous.
+ /// A handle to the transaction.
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ ///
+ /// If the function fails, the return value is zero. To get extended error information, call the GetLastError function. The following
+ /// list identifies the possible error codes:
+ ///
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-rollbacktransaction BOOL RollbackTransaction( IN HANDLE
+ // TransactionHandle );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "7d3522b8-ddf0-449e-8ab4-09e679ba1f15")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool RollbackTransaction([In] HTRXN TransactionHandle);
+
+ /// Requests that the specified transaction be rolled back. This function returns asynchronously.
+ /// A handle to the transaction.
+ ///
+ /// If the function succeeds, the return value is nonzero, and GetLastError returns ERROR_IO_PENDING.
+ ///
+ /// If the function fails, the return value is zero. To get extended error information, call the GetLastError function. The following
+ /// list identifies the possible error codes:
+ ///
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-rollbacktransactionasync BOOL RollbackTransactionAsync( IN
+ // HANDLE TransactionHandle );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "df23e5af-c37e-4e60-b160-6ffa8f6a26e3")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool RollbackTransactionAsync([In] HTRXN TransactionHandle);
+
+ /// Recovers information only to the specified virtual clock value.
+ /// A handle to the transaction manager.
+ /// A pointer to the latest virtual clock value received for this transaction.
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is 0 (zero). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-rollforwardtransactionmanager BOOL
+ // RollforwardTransactionManager( IN HANDLE TransactionManagerHandle, IN PLARGE_INTEGER TmVirtualClock );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "13492b74-8707-46bb-93f1-59c3c5ceab6d")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool RollforwardTransactionManager([In] HTRXNMGR TransactionManagerHandle, in long TmVirtualClock);
+
+ ///
+ /// Sets an opaque, user-defined structure of recovery data from KTM. Recovery information is stored in a log on behalf of a resource
+ /// manager (RM) by calling SetEnlistmentRecoveryInformation. After a failure, the RM can use GetEnlistmentRecoveryInformation
+ /// to retrieve the information.
+ ///
+ /// A handle to the enlistment.
+ /// The size of Buffer, in bytes.
+ /// The recovery information.
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is 0 (zero). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ ///
+ /// This call cannot be used with volatile transaction managers.
+ ///
+ /// The information that is provided by the user may not be durably stored in the log at the completion of this operation, but it
+ /// will be durably stored by the end of the next commit operation for this enlistment.
+ ///
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-setenlistmentrecoveryinformation BOOL
+ // SetEnlistmentRecoveryInformation( IN HANDLE EnlistmentHandle, IN ULONG BufferSize, IN PVOID Buffer );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "54e7526f-57f0-40cd-9624-fce0644a0884")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool SetEnlistmentRecoveryInformation([In] HENLISTMENT EnlistmentHandle, [In] uint BufferSize, [In] IntPtr Buffer);
+
+ ///
+ /// Associates the specified I/O completion port with the specified resource manager (RM). This port receives all notifications for
+ /// the RM.
+ ///
+ /// A handle to the resource manager.
+ /// A handle to the I/O completion port.
+ ///
+ /// The user-defined identifier. Typically, it is used to associate the receive notification with a specific resource manager.
+ ///
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is 0 (zero). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ ///
+ ///
+ /// This function must be used in conjunction with the GetNotificationResourceManagerAsync function, which provides the buffers that
+ /// KTM uses to deliver notifications asynchronously. These functions provide a different way to receive notifications from KTM. You
+ /// can use these two functions instead of the GetNotificationResourceManager function.
+ ///
+ /// This function must be called before calling GetNotificationResourceManagerAsync.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-setresourcemanagercompletionport BOOL
+ // SetResourceManagerCompletionPort( IN HANDLE ResourceManagerHandle, IN HANDLE IoCompletionPortHandle, IN ULONG_PTR CompletionKey );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "219fc899-84ee-474f-9f86-6ebf9c721810")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool SetResourceManagerCompletionPort([In] HRESMGR ResourceManagerHandle, [In] IntPtr IoCompletionPortHandle, [In] IntPtr CompletionKey);
+
+ /// Sets the transaction information for the specified transaction.
+ ///
+ /// A handle to the transaction. The handle must have the TRANSACTION_SET_INFORMATION permission to set the transaction information.
+ ///
+ /// Reserved; specify zero.
+ /// Reserved.
+ /// The timeout value, in milliseconds, for this transaction.
+ /// The user-defined description of this transaction.
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is 0 (zero). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-settransactioninformation BOOL SetTransactionInformation( IN
+ // HANDLE TransactionHandle, IN DWORD IsolationLevel, IN DWORD IsolationFlags, IN DWORD Timeout, LPWSTR Description );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "e33d221b-cd06-4f20-a4b5-407a04362ba0")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool SetTransactionInformation([In] HTRXN TransactionHandle, [In, Optional] uint IsolationLevel, [In, Optional] uint IsolationFlags, [In, Optional] uint Timeout, [MarshalAs(UnmanagedType.LPWStr), Optional] string Description);
+
+ ///
+ /// Indicates that the resource manager (RM) is refusing a single-phase request. When a transaction manager (TM) receives this call,
+ /// it initiates a two-phase commit and sends a prepare request to all enlisted RMs.
+ ///
+ /// A handle to the enlistment.
+ ///
+ ///
+ /// The latest virtual clock value received from the single-phase request notification. If you specify NULL, the virtual clock
+ /// value is not changed. See LARGE_INTEGER.
+ ///
+ /// To change the virtual clock value, this value must be greater than the current value returned in the COMMIT notification.
+ ///
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero (0). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-singlephasereject BOOL SinglePhaseReject( IN HANDLE
+ // EnlistmentHandle, IN PLARGE_INTEGER TmVirtualClock );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "8cc77686-e130-4b82-b2f5-70121b40e052")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool SinglePhaseReject([In] HENLISTMENT EnlistmentHandle, in long TmVirtualClock);
+
+ ///
+ /// Indicates that the resource manager (RM) is refusing a single-phase request. When a transaction manager (TM) receives this call,
+ /// it initiates a two-phase commit and sends a prepare request to all enlisted RMs.
+ ///
+ /// A handle to the enlistment.
+ ///
+ ///
+ /// The latest virtual clock value received from the single-phase request notification. If you specify NULL, the virtual clock
+ /// value is not changed. See LARGE_INTEGER.
+ ///
+ /// To change the virtual clock value, this value must be greater than the current value returned in the COMMIT notification.
+ ///
+ ///
+ /// If the function succeeds, the return value is nonzero.
+ /// If the function fails, the return value is zero (0). To get extended error information, call the GetLastError function.
+ /// The following list identifies the possible error codes:
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmw32/nf-ktmw32-singlephasereject BOOL SinglePhaseReject( IN HANDLE
+ // EnlistmentHandle, IN PLARGE_INTEGER TmVirtualClock );
+ [DllImport(Lib.Ktmw32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("ktmw32.h", MSDNShortId = "8cc77686-e130-4b82-b2f5-70121b40e052")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool SinglePhaseReject([In] HENLISTMENT EnlistmentHandle, [Optional] IntPtr TmVirtualClock);
+
+ /// Provides a handle to an enlistment.
+ [StructLayout(LayoutKind.Sequential)]
+ public struct HENLISTMENT : IKernelHandle
+ {
+ private readonly IntPtr handle;
+
+ /// Initializes a new instance of the struct.
+ /// An object that represents the pre-existing handle to use.
+ public HENLISTMENT(IntPtr preexistingHandle) => handle = preexistingHandle;
+
+ /// Returns an invalid handle by instantiating a object with .
+ public static HENLISTMENT NULL => new HENLISTMENT(IntPtr.Zero);
+
+ /// Gets a value indicating whether this instance is a null handle.
+ public bool IsNull => handle == IntPtr.Zero;
+
+ /// Performs an explicit conversion from to .
+ /// The handle.
+ /// The result of the conversion.
+ public static explicit operator IntPtr(HENLISTMENT h) => h.handle;
+
+ /// Performs an implicit conversion from to .
+ /// The pointer to a handle.
+ /// The result of the conversion.
+ public static implicit operator HENLISTMENT(IntPtr h) => new HENLISTMENT(h);
+
+ /// Implements the operator !=.
+ /// The first handle.
+ /// The second handle.
+ /// The result of the operator.
+ public static bool operator !=(HENLISTMENT h1, HENLISTMENT h2) => !(h1 == h2);
+
+ /// Implements the operator ==.
+ /// The first handle.
+ /// The second handle.
+ /// The result of the operator.
+ public static bool operator ==(HENLISTMENT h1, HENLISTMENT h2) => h1.Equals(h2);
+
+ ///
+ public override bool Equals(object obj) => obj is HENLISTMENT h ? handle == h.handle : false;
+
+ ///
+ public override int GetHashCode() => handle.GetHashCode();
+
+ ///
+ public IntPtr DangerousGetHandle() => handle;
+ }
+
+ /// Provides a handle to a resource manager.
+ [StructLayout(LayoutKind.Sequential)]
+ public struct HRESMGR : IKernelHandle
+ {
+ private readonly IntPtr handle;
+
+ /// Initializes a new instance of the struct.
+ /// An object that represents the pre-existing handle to use.
+ public HRESMGR(IntPtr preexistingHandle) => handle = preexistingHandle;
+
+ /// Returns an invalid handle by instantiating a object with .
+ public static HRESMGR NULL => new HRESMGR(IntPtr.Zero);
+
+ /// Gets a value indicating whether this instance is a null handle.
+ public bool IsNull => handle == IntPtr.Zero;
+
+ /// Performs an explicit conversion from to .
+ /// The handle.
+ /// The result of the conversion.
+ public static explicit operator IntPtr(HRESMGR h) => h.handle;
+
+ /// Performs an implicit conversion from to .
+ /// The pointer to a handle.
+ /// The result of the conversion.
+ public static implicit operator HRESMGR(IntPtr h) => new HRESMGR(h);
+
+ /// Implements the operator !=.
+ /// The first handle.
+ /// The second handle.
+ /// The result of the operator.
+ public static bool operator !=(HRESMGR h1, HRESMGR h2) => !(h1 == h2);
+
+ /// Implements the operator ==.
+ /// The first handle.
+ /// The second handle.
+ /// The result of the operator.
+ public static bool operator ==(HRESMGR h1, HRESMGR h2) => h1.Equals(h2);
+
+ ///
+ public override bool Equals(object obj) => obj is HRESMGR h ? handle == h.handle : false;
+
+ ///
+ public override int GetHashCode() => handle.GetHashCode();
+
+ ///
+ public IntPtr DangerousGetHandle() => handle;
+ }
+
+ /// Provides a handle to a Transaction Manager (TM).
+ [StructLayout(LayoutKind.Sequential)]
+ public struct HTRXNMGR : IKernelHandle
+ {
+ private readonly IntPtr handle;
+
+ /// Initializes a new instance of the struct.
+ /// An object that represents the pre-existing handle to use.
+ public HTRXNMGR(IntPtr preexistingHandle) => handle = preexistingHandle;
+
+ /// Returns an invalid handle by instantiating a object with .
+ public static HTRXNMGR NULL => new HTRXNMGR(IntPtr.Zero);
+
+ /// Gets a value indicating whether this instance is a null handle.
+ public bool IsNull => handle == IntPtr.Zero;
+
+ /// Performs an explicit conversion from to .
+ /// The handle.
+ /// The result of the conversion.
+ public static explicit operator IntPtr(HTRXNMGR h) => h.handle;
+
+ /// Performs an implicit conversion from to .
+ /// The pointer to a handle.
+ /// The result of the conversion.
+ public static implicit operator HTRXNMGR(IntPtr h) => new HTRXNMGR(h);
+
+ /// Implements the operator !=.
+ /// The first handle.
+ /// The second handle.
+ /// The result of the operator.
+ public static bool operator !=(HTRXNMGR h1, HTRXNMGR h2) => !(h1 == h2);
+
+ /// Implements the operator ==.
+ /// The first handle.
+ /// The second handle.
+ /// The result of the operator.
+ public static bool operator ==(HTRXNMGR h1, HTRXNMGR h2) => h1.Equals(h2);
+
+ ///
+ public override bool Equals(object obj) => obj is HTRXNMGR h ? handle == h.handle : false;
+
+ ///
+ public override int GetHashCode() => handle.GetHashCode();
+
+ ///
+ public IntPtr DangerousGetHandle() => handle;
+ }
+
+ /// Contains the data that is associated with a transaction notification.
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmtypes/ns-ktmtypes-transaction_notification typedef struct
+ // _TRANSACTION_NOTIFICATION { PVOID TransactionKey; ULONG TransactionNotification; LARGE_INTEGER TmVirtualClock; ULONG
+ // ArgumentLength; } TRANSACTION_NOTIFICATION, *PTRANSACTION_NOTIFICATION;
+ [PInvokeData("ktmtypes.h", MSDNShortId = "4f87de9d-a068-4ab9-8f38-b75f20552b1d")]
+ [StructLayout(LayoutKind.Sequential)]
+ public struct TRANSACTION_NOTIFICATION
+ {
+ /// The user-defined, opaque ID for this transaction.
+ public IntPtr TransactionKey;
+
+ /// The NOTIFICATION_MASK value for this transaction.
+ public NOTIFICATION_MASK TransactionNotification;
+
+ /// The latest virtual clock value that is associated with this transaction. See LARGE_INTEGER.
+ public long TmVirtualClock;
+
+ ///
+ /// Indicates the number of bytes for the TRANSACTION_NOTIFICATION_RECOVERY_ARGUMENT structure that follow this
+ /// TRANSACTION_NOTIFICATION structure.
+ ///
+ public uint ArgumentLength;
+ }
+
+ /// Indicates the transaction to be recovered. This structure is sent with a recovery notification.
+ // https://docs.microsoft.com/en-us/windows/win32/api/ktmtypes/ns-ktmtypes-transaction_notification_recovery_argument typedef struct
+ // _TRANSACTION_NOTIFICATION_RECOVERY_ARGUMENT { GUID EnlistmentId; UOW UOW; } TRANSACTION_NOTIFICATION_RECOVERY_ARGUMENT, *PTRANSACTION_NOTIFICATION_RECOVERY_ARGUMENT;
+ [PInvokeData("ktmtypes.h", MSDNShortId = "29a32b89-22d1-4d26-8927-a2051dd5d37a")]
+ [StructLayout(LayoutKind.Sequential)]
+ public struct TRANSACTION_NOTIFICATION_RECOVERY_ARGUMENT
+ {
+ /// The enlistment identifier.
+ public Guid EnlistmentId;
+
+ /// The transaction identifier, sometimes called the unit of work.
+ public Guid UOW;
+ }
+
+ /// Provides a for that is disposed using .
+ public class SafeHENLISTMENT : SafeKernelHandle
+ {
+ /// Initializes a new instance of the class and assigns an existing handle.
+ /// An object that represents the pre-existing handle to use.
+ ///
+ /// to reliably release the handle during the finalization phase; otherwise, (not recommended).
+ ///
+ public SafeHENLISTMENT(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
+
+ /// Initializes a new instance of the class.
+ private SafeHENLISTMENT() : base() { }
+
+ /// Performs an implicit conversion from to .
+ /// The safe handle instance.
+ /// The result of the conversion.
+ public static implicit operator HENLISTMENT(SafeHENLISTMENT h) => h.handle;
+
+ ///
+ protected override bool InternalReleaseHandle() => CloseHandle(handle);
+ }
+
+ /// Provides a for that is disposed using .
+ public class SafeHRESMGR : SafeKernelHandle
+ {
+ /// Initializes a new instance of the class and assigns an existing handle.
+ /// An object that represents the pre-existing handle to use.
+ ///
+ /// to reliably release the handle during the finalization phase; otherwise, (not recommended).
+ ///
+ public SafeHRESMGR(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
+
+ /// Initializes a new instance of the class.
+ private SafeHRESMGR() : base() { }
+
+ /// Performs an implicit conversion from to .
+ /// The safe handle instance.
+ /// The result of the conversion.
+ public static implicit operator HRESMGR(SafeHRESMGR h) => h.handle;
+
+ ///
+ protected override bool InternalReleaseHandle() => CloseHandle(handle);
+ }
+
+ /// Provides a for that is disposed using .
+ public class SafeHTRXN : SafeKernelHandle
+ {
+ /// Initializes a new instance of the class and assigns an existing handle.
+ /// An object that represents the pre-existing handle to use.
+ ///
+ /// to reliably release the handle during the finalization phase; otherwise, (not recommended).
+ ///
+ public SafeHTRXN(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
+
+ /// Initializes a new instance of the class.
+ private SafeHTRXN() : base() { }
+
+ /// Performs an implicit conversion from to .
+ /// The safe handle instance.
+ /// The result of the conversion.
+ public static implicit operator HTRXN(SafeHTRXN h) => h.handle;
+
+ ///
+ protected override bool InternalReleaseHandle() => CloseHandle(handle);
+ }
+
+ /// Provides a for that is disposed using .
+ public class SafeHTRXNMGR : SafeKernelHandle
+ {
+ /// Initializes a new instance of the class and assigns an existing handle.
+ /// An object that represents the pre-existing handle to use.
+ ///
+ /// to reliably release the handle during the finalization phase; otherwise, (not recommended).
+ ///
+ public SafeHTRXNMGR(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
+
+ /// Initializes a new instance of the class.
+ private SafeHTRXNMGR() : base() { }
+
+ /// Performs an implicit conversion from to .
+ /// The safe handle instance.
+ /// The result of the conversion.
+ public static implicit operator HTRXNMGR(SafeHTRXNMGR h) => h.handle;
+
+ ///
+ protected override bool InternalReleaseHandle() => CloseHandle(handle);
+ }
+ }
+}
\ No newline at end of file
diff --git a/PInvoke/KtmW32/Vanara.PInvoke.KtmW32.csproj b/PInvoke/KtmW32/Vanara.PInvoke.KtmW32.csproj
new file mode 100644
index 00000000..27e763e8
--- /dev/null
+++ b/PInvoke/KtmW32/Vanara.PInvoke.KtmW32.csproj
@@ -0,0 +1,51 @@
+
+
+
+ PInvoke API (methods, structures and constants imported from Windows KtmW32.dll.
+ Copyright © 2017-2019
+ $(AssemblyName)
+ 3.0.0
+ net20;net35;net40;net45;netstandard2.0;netcoreapp2.0;netcoreapp2.1
+ Vanara.PInvoke.KtmW32
+ $(AssemblyName)
+ Vanara.PInvoke
+ David Hall
+ https://github.com/dahall/vanara
+ MIT
+ https://raw.githubusercontent.com/dahall/Vanara/master/docs/icons/Vanara48x48.png
+ https://github.com/dahall/vanara
+ Git
+ pinvoke;vanara;net-extensions;interop;ktmw32;transactions
+ en-US
+ true
+ true
+ GitHub Community
+ Vanara
+ True
+
+ latest
+ true
+ ..\..\Vanara.snk
+
+
+ true
+ bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PInvoke/Shared/Lib.cs b/PInvoke/Shared/Lib.cs
index 90f19ce7..2c146618 100644
--- a/PInvoke/Shared/Lib.cs
+++ b/PInvoke/Shared/Lib.cs
@@ -42,6 +42,9 @@
/// The kernel base
public const string KernelBase = "kernelbase.dll";
+ /// The Kernel Transaction Manager (KTM)
+ public const string Ktmw32 = "ktmw32.dll";
+
/// The MPR
public const string Mpr = "mpr.dll";
diff --git a/UnitTests/PInvoke/KtmW32/KtmW32.csproj b/UnitTests/PInvoke/KtmW32/KtmW32.csproj
new file mode 100644
index 00000000..c3e873dd
--- /dev/null
+++ b/UnitTests/PInvoke/KtmW32/KtmW32.csproj
@@ -0,0 +1,82 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {8BC51B6B-77FA-4571-8E1C-EA75ED4DCD56}
+ Library
+ Properties
+ Vanara.PInvoke.Tests
+ UnitTest.PInvoke.KtmW32
+ v4.7.2
+ 512
+ latest
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ x64
+ true
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ true
+ x64
+
+
+
+
+
+
+
+
+
+ {241f73ee-9298-45c9-b869-a045dff94c03}
+ Vanara.Core
+
+
+ {842d436f-598c-47d7-b5aa-12399f8ccfe9}
+ Vanara.PInvoke.Kernel32
+
+
+ {c325c0a4-b8cf-442b-b393-c65fc9174045}
+ Vanara.PInvoke.KtmW32
+
+
+ {a5e519e9-feba-4fe3-93a5-b8269bef72f4}
+ Vanara.PInvoke.Shared
+
+
+ {a96cff10-0967-429a-8700-4a86c97c5603}
+ Shared
+
+
+
+
+ 3.12.0
+
+
+ 3.13.0
+
+
+
+
+
\ No newline at end of file
diff --git a/UnitTests/PInvoke/KtmW32/KtmW32Tests.cs b/UnitTests/PInvoke/KtmW32/KtmW32Tests.cs
new file mode 100644
index 00000000..9e3552cf
--- /dev/null
+++ b/UnitTests/PInvoke/KtmW32/KtmW32Tests.cs
@@ -0,0 +1,163 @@
+using NUnit.Framework;
+using System;
+using System.Text;
+using Vanara.InteropServices;
+using static Vanara.PInvoke.Kernel32;
+using static Vanara.PInvoke.KtmW32;
+
+namespace Vanara.PInvoke.Tests
+{
+ [TestFixture()]
+ public class KtmW32Tests
+ {
+ private const string txnDesc = "MyTransaction";
+
+ [Test]
+ public void CommitTransactionAsyncTest()
+ {
+ using (var hTR = CreateTransaction(null, default, 0, 0, 0, 0, txnDesc))
+ {
+ Assert.That(hTR, ResultIs.ValidHandle);
+ Assert.That(CommitTransactionAsync(hTR), ResultIs.Successful);
+ }
+ }
+
+ [Test]
+ public void CommitTransactionTest()
+ {
+ using (var hTR = CreateTransaction(null, default, 0, 0, 0, 0, txnDesc))
+ {
+ Assert.That(hTR, ResultIs.ValidHandle);
+ Assert.That(CommitTransaction(hTR), ResultIs.Successful);
+ }
+ }
+
+ [Test]
+ public unsafe void CreateTMNVTest()
+ {
+ using (var tmp = new TempFile(null))
+ using (var hTM = CreateTransactionManager(null, tmp.FullName))
+ {
+ Assert.That(hTM, ResultIs.ValidHandle);
+
+ Assert.That(RenameTransactionManager(tmp.FullName, Guid.NewGuid()), ResultIs.Failure);
+
+ Assert.That(RecoverTransactionManager(hTM), ResultIs.Successful);
+
+ using (var hTM2 = OpenTransactionManager(tmp.FullName, TransactionMgrAccess.TRANSACTIONMANAGER_ALL_ACCESS))
+ Assert.That(hTM2, ResultIs.ValidHandle);
+
+ var rmId = Guid.NewGuid();
+ using (var hRM = CreateResourceManager(null, rmId, 0, hTM, "MyRM"))
+ {
+ Assert.That(hRM, ResultIs.ValidHandle);
+
+ Assert.That(RecoverResourceManager(hRM), ResultIs.Successful);
+
+ using (var pTn = new SafeHGlobalHandle(4096))
+ Assert.That(GetNotificationResourceManagerAsync(hRM, pTn, pTn.Size, out _, null), ResultIs.Failure);
+
+ using (var hRM2 = OpenResourceManager(ResourceManagerAccess.RESOURCEMANAGER_ALL_ACCESS, hTM, rmId))
+ Assert.That(hRM2, ResultIs.ValidHandle);
+ }
+
+ Assert.That(RollforwardTransactionManager(hTM, 255L), ResultIs.Successful);
+ }
+ }
+
+ [Test]
+ public void CreateTMRMGetInfoTest()
+ {
+ using (var hTM = CreateTransactionManager(CreateOptions: CreateTrxnMgrOptions.TRANSACTION_MANAGER_VOLATILE))
+ {
+ Assert.That(hTM, ResultIs.ValidHandle);
+
+ Assert.That(GetCurrentClockTransactionManager(hTM, out var clock), ResultIs.Successful);
+ TestContext.WriteLine($"TMClock=0x{clock:X}");
+
+ Assert.That(GetTransactionManagerId(hTM, out var tmguid), ResultIs.Successful);
+ TestContext.WriteLine($"TMID={tmguid}");
+
+ using (var hTM2 = OpenTransactionManagerById(tmguid, TransactionMgrAccess.TRANSACTIONMANAGER_ALL_ACCESS))
+ Assert.That(hTM2, ResultIs.ValidHandle);
+
+ Assert.That(RecoverTransactionManager(hTM), ResultIs.FailureCode(Win32Error.ERROR_TM_VOLATILE));
+
+ using (var hRM = CreateResourceManager(null, Guid.Empty, CreateRMOptions.RESOURCE_MANAGER_VOLATILE, hTM, null))
+ {
+ Assert.That(hRM, ResultIs.ValidHandle);
+
+ using (var pTn = new SafeHGlobalHandle(4096))
+ Assert.That(GetNotificationResourceManager(hRM, pTn, pTn.Size, 10, out var req), ResultIs.FailureCode(Win32Error.WAIT_TIMEOUT));
+
+ Assert.That(RecoverResourceManager(hRM), ResultIs.FailureCode(Win32Error.ERROR_TM_VOLATILE));
+ }
+ }
+ }
+
+ [Test]
+ public void GetSetTransactionInformationTest()
+ {
+ using (var hTR = CreateTransaction(null, default, 0, 0, 0, 0, txnDesc))
+ {
+ Assert.That(hTR, ResultIs.ValidHandle);
+
+ Assert.That(GetTransactionId(hTR, out var trguid), ResultIs.Successful);
+ TestContext.WriteLine($"TrID={trguid}");
+
+ using (var hTR2 = OpenTransaction(TransactionAccess.TRANSACTION_ALL_ACCESS, trguid))
+ Assert.That(hTR2, ResultIs.ValidHandle);
+
+ var sb = new StringBuilder(255);
+ Assert.That(GetTransactionInformation(hTR, out var troutcome, default, default, out var trTO, 255, sb), ResultIs.Successful);
+ TestContext.WriteLine($"TrInf={troutcome}, {trTO}, {sb}");
+
+ sb.Append("2");
+ Assert.That(SetTransactionInformation(hTR, 0, 0, 5000, sb.ToString()), ResultIs.Successful);
+ }
+ }
+
+ // Despite hours of trying, I cannot successfully create an enlistment nor find working code on the internet. So, I'm punting and
+ // just doing non-functional testing for all enlistment functions. -- Sigh --
+ [Test]
+ public void NonFunctionalTest()
+ {
+ Assert.That(CommitComplete(HENLISTMENT.NULL), ResultIs.Failure);
+ Assert.That(CommitEnlistment(HENLISTMENT.NULL), ResultIs.Failure);
+ Assert.That(CreateEnlistment(null, HRESMGR.NULL, HTRXN.NULL, 0).DangerousGetHandle(), Is.EqualTo((IntPtr)HFILE.INVALID_HANDLE_VALUE));
+ Assert.That(GetEnlistmentId(HENLISTMENT.NULL, out _), ResultIs.Failure);
+ Assert.That(GetEnlistmentRecoveryInformation(HENLISTMENT.NULL, 0, default, out _), ResultIs.Failure);
+ Assert.That(OpenEnlistment(EnlistmentAccess.ENLISTMENT_ALL_ACCESS, HRESMGR.NULL, Guid.NewGuid()).DangerousGetHandle(), Is.EqualTo((IntPtr)HFILE.INVALID_HANDLE_VALUE));
+ Assert.That(PrepareComplete(HENLISTMENT.NULL), ResultIs.Failure);
+ Assert.That(PrepareEnlistment(HENLISTMENT.NULL, 0L), ResultIs.Failure);
+ Assert.That(PrePrepareComplete(HENLISTMENT.NULL), ResultIs.Failure);
+ Assert.That(PrePrepareEnlistment(HENLISTMENT.NULL, 0L), ResultIs.Failure);
+ Assert.That(ReadOnlyEnlistment(HENLISTMENT.NULL), ResultIs.Failure);
+ Assert.That(RecoverEnlistment(HENLISTMENT.NULL), ResultIs.Failure);
+ Assert.That(RollbackComplete(HENLISTMENT.NULL, 0L), ResultIs.Failure);
+ Assert.That(RollbackEnlistment(HENLISTMENT.NULL, 0L), ResultIs.Failure);
+ Assert.That(SetEnlistmentRecoveryInformation(HENLISTMENT.NULL, 0, default), ResultIs.Failure);
+ Assert.That(SinglePhaseReject(HENLISTMENT.NULL), ResultIs.Failure);
+ }
+
+ [Test]
+ public void RollbackTransactionAsyncTest()
+ {
+ using (var hTR = CreateTransaction(null, default, 0, 0, 0, 0, txnDesc))
+ {
+ Assert.That(hTR, ResultIs.ValidHandle);
+ Assert.That(RollbackTransactionAsync(hTR), ResultIs.Successful);
+ }
+ }
+
+ [Test]
+ public void RollbackTransactionTest()
+ {
+ using (var hTR = CreateTransaction(null, default, 0, 0, 0, 0, txnDesc))
+ {
+ Assert.That(hTR, ResultIs.ValidHandle);
+ Assert.That(RollbackTransaction(hTR), ResultIs.Successful);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Vanara.sln b/Vanara.sln
index fe67cfd7..e7d1db3c 100644
--- a/Vanara.sln
+++ b/Vanara.sln
@@ -161,6 +161,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared", "UnitTests\CSharpR
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vanara.PInvoke.Wer", "PInvoke\Wer\Vanara.PInvoke.Wer.csproj", "{FA58DCE9-60A6-4321-982C-37C0DACC371D}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vanara.PInvoke.KtmW32", "PInvoke\KtmW32\Vanara.PInvoke.KtmW32.csproj", "{C325C0A4-B8CF-442B-B393-C65FC9174045}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KtmW32", "UnitTests\PInvoke\KtmW32\KtmW32.csproj", "{632795F2-F552-4907-9373-4929CB9ACE09}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug (no Unit Tests)|Any CPU = Debug (no Unit Tests)|Any CPU
@@ -521,6 +525,18 @@ Global
{FA58DCE9-60A6-4321-982C-37C0DACC371D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FA58DCE9-60A6-4321-982C-37C0DACC371D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FA58DCE9-60A6-4321-982C-37C0DACC371D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C325C0A4-B8CF-442B-B393-C65FC9174045}.Debug (no Unit Tests)|Any CPU.ActiveCfg = Debug|Any CPU
+ {C325C0A4-B8CF-442B-B393-C65FC9174045}.Debug (no Unit Tests)|Any CPU.Build.0 = Debug|Any CPU
+ {C325C0A4-B8CF-442B-B393-C65FC9174045}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C325C0A4-B8CF-442B-B393-C65FC9174045}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C325C0A4-B8CF-442B-B393-C65FC9174045}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C325C0A4-B8CF-442B-B393-C65FC9174045}.Release|Any CPU.Build.0 = Release|Any CPU
+ {632795F2-F552-4907-9373-4929CB9ACE09}.Debug (no Unit Tests)|Any CPU.ActiveCfg = Debug|Any CPU
+ {632795F2-F552-4907-9373-4929CB9ACE09}.Debug (no Unit Tests)|Any CPU.Build.0 = Debug|Any CPU
+ {632795F2-F552-4907-9373-4929CB9ACE09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {632795F2-F552-4907-9373-4929CB9ACE09}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {632795F2-F552-4907-9373-4929CB9ACE09}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {632795F2-F552-4907-9373-4929CB9ACE09}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -591,6 +607,8 @@ Global
{3EDE955E-50DE-4E1D-97E8-31E4E6A83E7D} = {212ABBD0-B724-4CFA-9D6D-E3891547FA90}
{A96CFF10-0967-429A-8700-4A86C97C5603} = {3EC6B40D-71D3-4E59-A0E0-544EC605FE11}
{FA58DCE9-60A6-4321-982C-37C0DACC371D} = {212ABBD0-B724-4CFA-9D6D-E3891547FA90}
+ {C325C0A4-B8CF-442B-B393-C65FC9174045} = {212ABBD0-B724-4CFA-9D6D-E3891547FA90}
+ {632795F2-F552-4907-9373-4929CB9ACE09} = {385CAD2D-0A5E-4F80-927B-D5499D126B90}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {543FAC75-2AF1-4EF1-9609-B242B63FEED4}