MFC Integration with the Windows Transactional File System (TxF)

As the Windows
continues to evolve with each major release of the operating
system, it is critical for C++
developers that MFC
is kept up to date with the new features that have been introduced. As MFC
enters its twentieth year serving C++ developers (the first MFC
version shipped with Microsoft’s C/C++ 7.0 compiler in 1992), there are
thousands of production systems and millions of lines of MFC code in existence
that are still fit-for-purpose and will continue in operation for years if not
decades to come. These systems need to continue to evolve to support new
features, and MFC extensions, which keep feature-parity with the Windows SDK
are quite important.

As covered in previous articles (Programming
the Windows Transactional File System (TxF)
, and A Developer Introduction to the Kernel Transaction Manager (KTM) and Windows Transactional File System (TxF), the basis for transaction support in Windows Vista is the Kernel
Transaction Manager (KTM)
, with the Transactional
File System (TxF)
and Transactional
Registry (TxR)
built upon the functionality offered by the KTM. Because of
the closely related nature of the technologies, MFC (along with ATL) wrap the
bulk of the new functionality in a single class called the

CAtlTransactionManager has member functions that support all the KTM basics:
Create, Commit, Close, and Rollback all operate directly on a KTM transaction
handle. TxF functionality can also be accessed directly through
CAtlTransactionManager: CreateFile, DeleteFile, FindFirstFile,
GetFileAttributes, GetFileAttributesEx, MoveFile, and SetFileAttributes all
interact with the TxF. The final category of CAtlTransactionManager member
functions supports the TxR, with RegCreateKeyEx, RegDeleteKey, and RegOpenKeyEx
all available.

The member functions of CAtlTransactionManager are great if the file and
registry access for an application is being written from scratch, but there
will be many cases where existing code needs to have TxF and TxR functionality
retrofitted. There are two options for this – the KTM transaction handle can be
retrieved from CAtlTransactionManager using the GetHandle call, and this handle
can be used with the raw Windows SDK APIs to create a file or registry handle
that is transaction-aware, which can in turn be used to create a CFile or CRegKey
object using the overloaded constructor that takes a handle. While this option
is workable, the much more elegant solution is to use the new overloaded
constructors of CFile, CFileFind and CRegKey, which take a
CAtlTransactionManager pointer. The file and registry objects will then operate
in a transactional mode with no other code modifications other than committing
or rolling back the transaction at the end of a series of operations.

MFC has adopted a dual strategy for extensions to support all the associated
KTM functionality that shipped with Windows Vista – the all-purpose
CAtlTransactionManager has been introduced as the ‘swiss-army pocket knife’ of
KTM, giving access to all KTM operations from a single class. If direct KTM
access isn’t desirable, a transaction can simply be created with
CAtlTransactionManager and then passed to overloads on existing classes to
achieve transaction support. Despite its age, MFC continues to demonstrate that
it can be extended in simple and logical ways to support new API features and
hence continue to remain relevant to a large population of developers.

More by Author

Must Read