Registry Parser
All articles

The transactional registry: KTM and TxR explained

9 min read

The transactional registry is the feature most analysts have never knowingly touched and have nonetheless been staring at for years. If you have ever looked inside C:\Windows\System32\config\ and wondered what the .blf and .regtrans-ms files are doing next to the hives, that is the Kernel Transaction Manager (KTM) and its registry resource manager, TxR. The transacted registry APIs — RegCreateKeyTransacted, RegOpenKeyTransacted, and friends — were Microsoft's attempt to give the registry database-style transactions: change a dozen keys across the tree, then commit them all or none. The idea was sound. The adoption was not, and the result is a subsystem that sits in every modern Windows install while almost no application deliberately uses it. This post explains what KTM actually provides, how the transacted registry differs from a plain key write, why it stayed a curiosity, and what it means for analysts and for anyone writing a parser.

If you have not read the regf hive overview yet, skim it first — the cell and HBIN vocabulary below assumes it.

What KTM actually provides

Single registry operations are already atomic in a narrow sense. When you call RegSetValueEx to write one value, that write either lands or it does not; you never see a half-written DWORD. The kernel's write-ahead logging guarantees that much. What it does not give you is atomicity across operations. If your installer needs to create a service key, set six values under it, and flip a flag elsewhere in the tree, and the machine loses power after the third write, you are left in a torn state: the service key exists, half-configured, and your flag never moved. Recovering from that is the application developer's problem.

KTM is the kernel component that closes that gap. Introduced with Windows Vista (and Server 2008), it implements general-purpose transactions in kernel mode. You begin a transaction with CreateTransaction, which hands back a transaction handle. You enlist resource managers in that transaction, perform your operations, and then call CommitTransaction or RollbackTransaction. Either every enlisted change becomes durable as a unit, or none of them do. The registry participates as one such resource manager — that participant is TxR, the transactional registry. NTFS participates as another, called TxF. Because both ride the same KTM transaction, you can in principle bracket a file write and a registry change inside one atomic commit, and even pull SQL Server or MSMQ into the same transaction through the Distributed Transaction Coordinator. That cross-store atomicity was the headline pitch.

The transacted registry APIs

The mechanism is deliberately bolted onto the existing Win32 surface. Instead of new verbs for "set value transacted", you open a handle in a transactional context and the ordinary calls inherit it. RegCreateKeyTransacted and RegOpenKeyTransacted take an extra hTransaction argument — the handle from CreateTransaction — and return a key handle whose subsequent operations are part of that transaction. RegSetValueEx and RegQueryValueEx on such a handle are transacted automatically. Deletes are the exception: RegDeleteKeyEx is not transacted even on a transacted handle, so there is a dedicated RegDeleteKeyTransacted. These live in Advapi32.dll and have been present since Vista.

Two details from Microsoft's own documentation are worth internalising, because they explain a lot of the feature's reputation:

  • A non-transacted operation on a transacted key rolls the transaction back. If any code touches that key outside the transaction before you commit, the whole transaction is abandoned. After a commit or rollback you must re-open the key with an active transaction handle to make further work transactional.
  • Transactions do not recurse into subkeys. Opening a key transactionally does not make operations on its subkeys transacted; each key you intend to change has to be opened in the transaction itself. This is exactly the kind of footgun that turns "atomic across multiple keys" into "atomic across the specific keys you remembered to enlist."

So the model is real and it does deliver all-or-nothing semantics — but only over the precise set of handles you explicitly bound to the transaction, and only as long as nothing else writes through the back door.

Why it stayed niche, and got discouraged

Atomic multi-key commits sound like something every installer would want, so why did almost nobody adopt it? Microsoft has been unusually candid here. The companion feature, Transactional NTFS, carries an explicit deprecation banner on its documentation: extremely limited developer interest since Vista, driven by complexity and the many nuances developers have to account for, and a stated possibility that the TxF APIs may be removed in a future Windows version. Microsoft "strongly recommends" alternatives. The transactional registry is the registry-side sibling of that same KTM machinery and shares its fate in practice — a powerful, complex subsystem that the platform owner now steers developers away from.

The recommended alternatives are telling. For the common case of updating several related keys, Microsoft points developers at simpler patterns: write your state under a single key as one structured blob, or stage changes and swap them in, rather than reaching for distributed-transaction infrastructure. For backing up or restoring system state, the transacted-API docs themselves redirect you to Volume Shadow Copy. When the platform's own reference pages route you elsewhere on the first paragraph, you can infer how the feature is regarded internally.

The upshot: the plumbing ships in every modern Windows install because the OS itself relies on KTM-backed recovery for its own hives, but third-party use of the transacted APIs is rare. The capability is present and discouraged at the same time — a combination that is exactly why it surprises people.

This is not the .LOG crash-recovery scheme

This is the distinction that trips up analysts, so be precise about it. The registry has two completely separate mechanisms that both involve the word "log."

The first is the dual .LOG1 / .LOG2 write-ahead logging covered in the transaction logs and crash recovery post. Those are low-level, per-hive dirty-page journals. Their only job is to make a single hive recoverable to a consistent state after an unclean shutdown — the kernel replays the dirty pages so a torn flush does not corrupt the file. They know nothing about application intent. There is no "abort this set of changes" concept; there is only "finish writing what was already in flight."

The second is TxR, the subject of this post. It is a higher-level, semantic mechanism: it groups operations the application declared as one logical unit and commits or rolls them back as a unit, potentially spanning multiple keys and even other resource managers. Its on-disk footprint is different too. TxR's state lives in Common Log File System artifacts — the .blf (base log file) and .regtrans-ms files. Per Google Project Zero's hive writeup, the system-wide TxR logs sit under C:\Windows\System32\config\TxR, transactional support is wired up for the system hives under HKLM and for per-user NTUSER.DAT and UsrClass.dat, and it is disabled for application hives and differencing hives. There is even a REG_HIVE_NO_RM load flag to force a hive open without its resource manager.

In one line: .LOG1/.LOG2 keep one hive from corrupting; TxR/KTM let an application commit or abort a multi-key change. Different layer, different files, different purpose.

What it means for analysts and for parsers

For an analyst, three practical points follow.

First, the .blf and .regtrans-ms files are not hives and a regf parser will reject them outright — that is correct behaviour, not a bug. They are CLFS structures, and parsing them is a separate, sparsely tooled problem. Do not waste time pointing a hive parser at them; do collect them, because pending or recently committed TxR state can in principle contain registry changes that are not yet reflected in the primary hive. Treat them the way you treat any volatile recovery artifact: acquire, preserve, and note that public tooling for interpreting them is thin.

Second, TxR is a recovery vector with the same caveat as .LOG replay, and the two are easy to conflate. When you reason about whether a hive is "complete," remember there can be state outside the regf file — both in the dirty-page logs and, on hives that have a resource manager attached, in the TxR logs. The mature path is still log replay against a cleanly acquired primary hive; just be clear about which logs you mean.

Third, do not expect transacted writes to leave a distinctive fingerprint inside the hive cells themselves. Once a transaction commits, the resulting keys and values are ordinary nk and vk records — there is no "this was written transactionally" flag for you to surface. The transactional nature is a property of how the change was applied, recorded in the CLFS logs, not a property of the committed data. An aborted transaction simply never lands, so it leaves nothing in the hive at all (and at most leaves traces in the TxR logs).

For a parser author, the lesson is narrower but firmer: a hive parser's job is to parse hives. Recognise the .blf / .regtrans-ms companions so you can skip or report them cleanly rather than crashing or, worse, emitting garbage. The robustness win is the same one that applies to log replay — know that your regf file may not be the whole story, and fail loud rather than silently present a stale or partial view. If you want to see what a clean hive parse looks like with the logs accounted for, parse a hive in your browser and check the consistency warnings.

Closing notes

The transactional registry — KTM providing the engine, TxR enlisting the registry, and RegCreateKeyTransacted / RegOpenKeyTransacted exposing it to applications — is a genuinely capable feature that history has left as background plumbing. It gives true atomic, all-or-nothing commits across multiple keys, which a single RegSetValueEx write never will, but the complexity, the easy footguns (non-transacted writes silently aborting the transaction; subkeys not inheriting it), and Microsoft's own steer toward simpler alternatives kept it out of mainstream use even as the machinery shipped in every Windows release since Vista. For the analyst, the takeaways are modest and concrete: know that .blf and .regtrans-ms are CLFS, not hives; know that TxR is a distinct recovery layer from the .LOG files; and know that committed transactional writes look like any other record once they land.

For the broader picture, start with the Windows registry internals overview and the regf format notes.

Further reading