Пусть у нас есть хендл файла, например 0xa4
По хендлу находим file object:
1: kd> !handle 00000000000000a4
PROCESS ffffa805650c2080
SessionId: 1 Cid: 1f28 Peb: 245c58000 ParentCid: 1e18
DirBase: 1f62ad002 ObjectTable: ffffb80f1473ae40 HandleCount: 42.
Image: PipeClient.exe
Handle table at ffffb80f1473ae40 with 42 entries in use
00a4: Object: ffffa80566027850 GrantedAccess: 00120196 (Inherit) Entry: ffffb80f0b4d1290
Object: ffffa80566027850 Type: (ffffa8055e0940c0) File
ObjectHeader: ffffa80566027820 (new version)
HandleCount: 1 PointerCount: 1
Directory Object: 00000000 Name: \test\testfile.txt {HarddiskVolume4}
Далее, смотрим структуру данного FILE_OBJECT:
1: kd> dt nt!_FILE_OBJECT ffffa80566027850У файла, не находящегося в транзакции поле FileObjectExtension равно нулю, а у транзакционного файла там лежит структура:
+0x000 Type : 0n5
+0x002 Size : 0n216
+0x008 DeviceObject : 0xffffa805`5ebc2060 _DEVICE_OBJECT
+0x010 Vpb : 0xffffa805`602ac5e0 _VPB
+0x018 FsContext : 0xffffb80f`14c33b80 Void
+0x020 FsContext2 : 0xffffb80f`14c33df0 Void
+0x028 SectionObjectPointer : 0xffffa805`6682a918 _SECTION_OBJECT_POINTERS
+0x030 PrivateCacheMap : (null)
+0x038 FinalStatus : 0n0
+0x040 RelatedFileObject : (null)
+0x048 LockOperation : 0 ''
+0x049 DeletePending : 0 ''
+0x04a ReadAccess : 0 ''
+0x04b WriteAccess : 0x1 ''
+0x04c DeleteAccess : 0 ''
+0x04d SharedRead : 0 ''
+0x04e SharedWrite : 0 ''
+0x04f SharedDelete : 0 ''
+0x050 Flags : 0x40042
+0x058 FileName : _UNICODE_STRING "\test\testfile.txt"
+0x068 CurrentByteOffset : _LARGE_INTEGER 0x0
+0x070 Waiters : 0
+0x074 Busy : 0
+0x078 LastLock : (null)
+0x080 Lock : _KEVENT
+0x098 Event : _KEVENT
+0x0b0 CompletionContext : (null)
+0x0b8 IrpListLock : 0
+0x0c0 IrpList : _LIST_ENTRY [ 0xffffa805`66027910 - 0xffffa805`66027910 ]
+0x0d0 FileObjectExtension : 0xffffa805`642a8f30 Void
1: kd> dqs 0xffffa805`642a8f30Я её не реверсил, но по смещению 0x8 там лежит TXN_PARAMETER_BLOCK и уже в ней лежит транзакция, к которой принадлежит исходный файл:
ffffa805`642a8f30 00000000`00000000
ffffa805`642a8f38 ffffa805`644f5e50
ffffa805`642a8f40 00000000`00000000
ffffa805`642a8f48 00000000`00000000
1: kd> dt nt!_TXN_PARAMETER_BLOCK ffffa805`644f5e50Видно, что у нее State == KTransactionActive, т.е. она не закоммичена и не откачена.
+0x000 Length : 0x10
+0x002 TxFsContext : 0xfffe
+0x008 TransactionObject : 0xffffa805`650ec060 Void
1: kd> !object 0xffffa805`650ec060
Object: ffffa805650ec060 Type: (ffffa8055e095140) TmTx
ObjectHeader: ffffa805650ec030 (new version)
HandleCount: 1 PointerCount: 32776
dt nt!_KTRANSACTION ffffa805650ec060
+0x000 OutcomeEvent : _KEVENT
+0x018 cookie : 0xb00b0001
+0x020 Mutex : _KMUTANT
+0x058 TreeTx : 0xffffa805`650ec060 _KTRANSACTION
+0x060 GlobalNamespaceLink : _KTMOBJECT_NAMESPACE_LINK
+0x088 TmNamespaceLink : _KTMOBJECT_NAMESPACE_LINK
+0x0b0 UOW : _GUID {d9403709-b1b3-11ef-988c-000c29bfd957}
+0x0c0 State : 1 ( KTransactionActive )
+0x0c4 Flags : 0x100
+0x0c8 EnlistmentHead : _LIST_ENTRY [ 0xffffa805`6306b578 - 0xffffa805`6306b328 ]
+0x0d8 EnlistmentCount : 2
+0x0dc RecoverableEnlistmentCount : 1
+0x0e0 PrePrepareRequiredEnlistmentCount : 1
+0x0e4 PrepareRequiredEnlistmentCount : 2
+0x0e8 OutcomeRequiredEnlistmentCount : 2
+0x0ec PendingResponses : 0
+0x0f0 SuperiorEnlistment : (null)
+0x0f8 LastLsn : _CLS_LSN
+0x100 PromotedEntry : _LIST_ENTRY [ 0xffffa805`650ec160 - 0xffffa805`650ec160 ]
+0x110 PromoterTransaction : (null)
+0x118 PromotePropagation : (null)
+0x120 IsolationLevel : 0
+0x124 IsolationFlags : 0
+0x128 Timeout : _LARGE_INTEGER 0x0
+0x130 Description : _UNICODE_STRING ""
+0x140 RollbackThread : (null)
+0x148 RollbackWorkItem : _WORK_QUEUE_ITEM
+0x168 RollbackDpc : _KDPC
+0x1a8 RollbackTimer : _KTIMER
+0x1e8 LsnOrderedEntry : _LIST_ENTRY [ 0xffffa805`650ec248 - 0xffffa805`650ec248 ]
+0x1f8 Outcome : 1 ( KTxOutcomeUndetermined )
+0x200 Tm : 0xffffa805`60321b30 _KTM
+0x208 CommitReservation : 0n0
+0x210 TransactionHistory : [10] _KTRANSACTION_HISTORY
+0x260 TransactionHistoryCount : 0
+0x268 DTCPrivateInformation : (null)
+0x270 DTCPrivateInformationLength : 0
+0x278 DTCPrivateInformationMutex : _KMUTANT
+0x2b0 PromotedTxSelfHandle : (null)
+0x2b8 PendingPromotionCount : 0
+0x2c0 PromotionCompletedEvent : _KEVENT
Также можно получить enlistment и ktm(transaction manager) и resource manager:
1: kd> dt nt!_KENLISTMENT 0xffffa805`6306b578-78
+0x000 cookie : 0xb00b0003
+0x008 NamespaceLink : _KTMOBJECT_NAMESPACE_LINK
+0x030 EnlistmentId : _GUID {d940370c-b1b3-11ef-988c-000c29bfd957}
+0x040 Mutex : _KMUTANT
+0x078 NextSameTx : _LIST_ENTRY [ 0xffffa805`6306b328 - 0xffffa805`650ec128 ]
+0x088 NextSameRm : _LIST_ENTRY [ 0xffffa805`60336ca0 - 0xffffa805`60336ca0 ]
+0x098 ResourceManager : 0xffffa805`60336b90 _KRESOURCEMANAGER
+0x0a0 Transaction : 0xffffa805`650ec060 _KTRANSACTION
+0x0a8 State : 100 ( KEnlistmentActive )
+0x0ac Flags : 0x30
+0x0b0 NotificationMask : 0x20f
+0x0b8 Key : (null)
+0x0c0 KeyRefCount : 1
+0x0c8 RecoveryInformation : (null)
+0x0d0 RecoveryInformationLength : 0
+0x0d8 DynamicNameInformation : (null)
+0x0e0 DynamicNameInformationLength : 0
+0x0e8 FinalNotification : 0xffffa805`6637cd90 _KTMNOTIFICATION_PACKET
+0x0f0 SupSubEnlistment : 0xffffa805`6306b750 _KENLISTMENT
+0x0f8 SupSubEnlHandle : 0xffffffff`80002b78 Void
+0x100 SubordinateTxHandle : (null)
+0x108 CrmEnlistmentEnId : _GUID {d940370d-b1b3-11ef-988c-000c29bfd957}
+0x118 CrmEnlistmentTmId : _GUID {d9403259-b1b3-11ef-988c-806e6f6e6963}
+0x128 CrmEnlistmentRmId : _GUID {d9403259-b1b3-11ef-988c-806e6f6e6963}
+0x138 NextHistory : 0
+0x13c History : [20] _KENLISTMENT_HISTORY
1: kd> dt _KRESOURCEMANAGER 0xffffa805`60336b90
nt!_KRESOURCEMANAGER
+0x000 NotificationAvailable : _KEVENT
+0x018 cookie : 0xb00b0002
+0x01c State : 2 ( KResourceManagerOnline )
+0x020 Flags : 0
+0x028 Mutex : _KMUTANT
+0x060 NamespaceLink : _KTMOBJECT_NAMESPACE_LINK
+0x088 RmId : _GUID {aac01acf-dcfb-11ed-a446-b2fd1f82aa81}
+0x098 NotificationQueue : _KQUEUE
+0x0d8 NotificationMutex : _KMUTANT
+0x110 EnlistmentHead : _LIST_ENTRY [ 0xffffa805`6306b588 - 0xffffa805`6306b588 ]
+0x120 EnlistmentCount : 1
+0x128 NotificationRoutine : 0xfffff805`0d48c3c0 long tm!TmpInternalCrmNotification+0
+0x130 Key : 0xffffffff`800002d0 Void
+0x138 ProtocolListHead : _LIST_ENTRY [ 0xffffa805`60336cc8 - 0xffffa805`60336cc8 ]
+0x148 PendingPropReqListHead : _LIST_ENTRY [ 0xffffa805`60336cd8 - 0xffffa805`60336cd8 ]
+0x158 CRMListEntry : _LIST_ENTRY [ 0x00000000`00000000 - 0x00000000`00000000 ]
+0x168 Tm : 0xffffa805`60321b30 _KTM
+0x170 Description : _UNICODE_STRING ""
+0x180 Enlistments : _KTMOBJECT_NAMESPACE
+0x228 CompletionBinding : _KRESOURCEMANAGER_COMPLETION_BINDING
1: kd> dt nt!_KTM 0xffffa805`60321b30
+0x000 cookie : 0xb00b0004
+0x008 Mutex : _KMUTANT
+0x040 State : 3 ( KKtmOnline )
+0x048 NamespaceLink : _KTMOBJECT_NAMESPACE_LINK
+0x070 TmIdentity : _GUID {aac01acf-dcfb-11ed-a446-b2fd1f82aa81}
+0x080 Flags : 0xc0
+0x084 VolatileFlags : 0
+0x088 LogFileName : _UNICODE_STRING "\Device\HarddiskVolume4\$Extend\$RmMetadata\$TxfLog\$TxfLog::KtmLog"
+0x098 LogFileObject : 0xffffa805`6035d0b0 _FILE_OBJECT
+0x0a0 MarshallingContext : 0xffffb80f`07d513a0 Void
+0x0a8 LogManagementContext : 0xffffa805`5ecb0b90 Void
+0x0b0 Transactions : _KTMOBJECT_NAMESPACE
+0x158 ResourceManagers : _KTMOBJECT_NAMESPACE
+0x200 LsnOrderedMutex : _KMUTANT
+0x238 LsnOrderedList : _LIST_ENTRY [ 0xffffa805`60321d68 - 0xffffa805`60321d68 ]
+0x248 CommitVirtualClock : _LARGE_INTEGER 0xe3
+0x250 CommitVirtualClockMutex : _FAST_MUTEX
+0x288 BaseLsn : _CLS_LSN
+0x290 CurrentReadLsn : _CLS_LSN
+0x298 LastRecoveredLsn : _CLS_LSN
+0x2a0 TmRmHandle : 0xffffffff`800002d0 Void
+0x2a8 TmRm : 0xffffa805`60336b90 _KRESOURCEMANAGER
+0x2b0 LogFullNotifyEvent : _KEVENT
+0x2c8 CheckpointWorkItem : _WORK_QUEUE_ITEM
+0x2e8 CheckpointTargetLsn : _CLS_LSN
+0x2f0 LogFullCompletedWorkItem : _WORK_QUEUE_ITEM
+0x310 LogWriteResource : _ERESOURCE
+0x378 LogFlags : 2
+0x37c LogFullStatus : 0n0
+0x380 RecoveryStatus : 0n0
+0x388 LastCheckBaseLsn : _CLS_LSN
+0x390 RestartOrderedList : _LIST_ENTRY [ 0xffffb80f`07cc7b48 - 0xffffb80f`07cc7b48 ]
+0x3a0 OfflineWorkItem : _WORK_QUEUE_ITEM
Если стоит цель программно по файловому объекту получить транзакцию, то это делается вызовом ф-ции IoGetTransactionParameterBlock, которая вернет все тот же PTXN_PARAMETER_BLOCK с объектом транзакции внутри.