Using TmXxx Routines
Most KTM routines use a naming format of ZwXxx. These routines are handle-based. That is, at least one of their input or output parameters is a handle to a KTM object.
KTM also provides a smaller number of routines that use a naming format of TmXxx. These routines are pointer-based. At least one of their input or output parameters is a pointer to a KTM object.
Some TmXxx routines duplicate ZwXxx routines. Other TmXxx routines do not have ZwXxx equivalents.
In most cases, you should use the ZwXxx routines. But you should use TmXxx routines in the following situations:
Your resource manager uses the ResourceManagerNotification callback routine, which provides a pointer to an enlistment object instead of a handle.
You can pass the enlistment object pointer to the enlistment object's TmXxx routines.
Your transaction processing system (TPS) component performs many rapid calls to KTM, which potentially causes system performance to be too slow.
In this case, your component can call ObReferenceObjectByHandle to convert each KTM object handle to a pointer, save the pointer, and then pass the pointer to TmXxx routines. This conversion eliminates the need for KTM to convert each handle to a pointer internally every time that a ZwXxx routine is called.
Each call to ObReferenceObectByHandle should include an access mask that contains appropriate KTM-defined flags. These flags are described on the reference pages for KTM's create and open routines.
When your component has finished using the KTM object, it must dereference the object by calling either ObDereferenceObjectDeferDelete or ObDereferenceObject.
You must use ObDereferenceObjectDeferDelete if your component, or any other component in your driver stack, is holding any system-provided locks, such as spin locks, mutex objects, or fast mutexes.
You can use ObDereferenceObject if you are sure that no component on your driver stack holds system-provided locks.
Deadlocks can occur if your component calls ObDereferenceObject while holding locks, because KTM might also be holding locks for the object namespace. Also, your component can call TmGetTransactionId to quickly obtain a transaction's identifier more efficiently than calling ZwQueryInformationTransaction.
You must have a capability that a ZwXxx routine does not provide.
Specifically, a resource manager can call the following routines:
- TmEnableCallbacks to enable asynchronous delivery of notifications by a callback routine.
- TmReferenceEnlistmentKey and TmDereferenceEnlistmentKey to increment or decrement an enlistment object's key reference count.
- TmRequestOutcomeEnlistment to request an immediate commit or rollback notification for an enlistment.
- TmIsTransactionActive to determine whether a transaction is in its active state.