Copyright © 1998 Mark Russinovich | |
Last Updated October 3, 1998 V1.0 |
|
Introduction | Have you
ever wondered how exactly NT's two file system management
utilities, chkdsk and format, work? Maybe you've had an
application that would have been perfect if you could
have incorporated chkdsk or format functionality into it.
On this page I present Chkdskx and Formatx,
two utilities that very precisely clone the command-line
chkdsk and format utilities that come with NT. In fact,
the clones support the same switches as the standard
chkdsk and format and produce almost exactly the same
output. So while they don't do anything special, their
source code demonstrates how you can write your own
interfaces to chkdsk and format functionality. Chkdskx and Formatx work on NT 4.0. |
FMIFS | Chkdskx
and Formatx don't have to know anything about on-disk
file system layouts to their jobs because they are
clients of a system utility library that worries about
this for them. The library is FMIFS.DLL (Format Manager
for Installable File Systems is my guess at what the name
represents) and it is located in the Winnt\System32
directory. It exports a handful of functions including Chkdsk,
ChkdskEx, Format and FormatEx. When
you select Format from Explorer's volume context menu (the
one you get when you right-click on a drive icon),
Explorer uses FormatEx to format the drive, and
when you request a disk consistency check on the Tools
tab of a drive's properties dialog Explorer calls out to Chkdsk.
Actually, Explorer uses a yet higher-level function, SHFormatDrive,
in SHELL32.DLL to access FormatEx, and Chkdsk
gets called as a result of Explorer's use of Shell32's
internal function, CDrive_Properties. CDrive_Properties
creates the drive properties dialog box and pressing the
"Check Now" button results in a chkdsk dialog
that is created by Shell32's DiskToolsCommand. SHFormatDrive
and ChkdskDlgProc are what actually present the
options and progress dialog boxes that are presented in
response to either request. The FormatEx function in FMIFS.DLL is prototyped like this: VOID FormatEx( PWCHAR DriveRoot, DWORD MediaFlag, PWCHAR Format, PWCHAR Label, BOOL QuickFormat, DWORD ClusterSize, PFMIFSCALLBACK Callback ); The arguments are actually pretty self-explanatory. The callback function is used by FormatEx to communicate with its caller. The definition of PFMIFSCALLBACK is: typedef BOOLEAN (__stdcall *PFMIFSCALLBACK)( CALLBACKCOMMAND Command, DWORD SubAction, PVOID ActionInfo ); The callback function takes three arguments, interpreting the first one as a command argument that indicates what FormatEx is trying to communicate. I've made the command an enumerated type and filled in the table of roughly 16 commands with the ones that are used during typical FormatEx and Chkdsk operation. For example, one command is OUTPUT, which a callback function can respond to by intepreting the third parameter (ActionInfo) as a pointer to string and displaying the string on the screen. Another command type is a PROGRESS command. The ActionInfo parameter is a pointer to a DWORD that the callback interprets as a precentage. Thus, in a long format process the FMIFS client can keep the user informed of progress via a progress dialog or text print-outs. The Chkdsk command's definition follows a similar convention: VOID Chkdsk( PWCHAR DriveRoot, PWCHAR Format, BOOL CorrectErrors, BOOL Verbose, BOOL CheckOnlyIfDirty, BOOL ScanDrive, PVOID Unused2, PVOID Unused3, PFMIFSCALLBACK Callback ); Chkdsk's arguments are also self-explanatory and you can see that the exact same callback definition is used for Chkdsk. You might think at this point that FMIFS is where the file system on-disk structure knowledge is located. However, FMIFS is itself a client of other libraries that contain knowledge about specific file system formats. For example, UFAT.DLL is the library that actually "knows" about FAT on-disk layout so it can perform FAT formatting or consistency checking operations. UNTFS.DLL is where NTFS information is located. You'll note that both the Chkdsk and FormatEx FMIFS functions take file system type string parameters. FMIFS simply takes the file system string and creates a DLL name by placing a 'U' in front of it and a '.DLL' at the end: U<file system>.DLL. It then attempts to load the DLL of that name and calls Chkdsk or Format functions that the DLL is expected to export. UNTFS.DLL and UFAT.DLL rely on two other libraries, ULIB.DLL and IFSUTIL.DLL, to provide some low-level utility functions, like converting a DOS drive name to an NT-native version, and reading and writing from/to a disk. Neither UNTFS.DLL nor UFAT.DLL call file system drivers to take any part in a format or chkdsk operation - they directly read and write raw clusters on the drive. This hierarchical arrangment makes it easy for Microsoft to add new file system types to the system without having to write custom verions of the file system management tools. They simply write a DLL for the new file system type and make the management tools (like Explorer) aware of the new format name. |
Chkdskx and Formatx | Chkdskx and Formatx demonstrate the use of the functions in FMIFS I've described. I've made them behave almost exactly like the real command-line chkdsk and format. Interestingly, only Explorer uses the FMIFS functions, and then only indirectly through SHFormatDisk. The command-line chkdsk and format programs bypass FMIFS convenience functions and interface directly with UFAT.DLL and UNTFS.DLL The utility libraries are where most of the text output you see when you run the commands is generated, so the output of my Chkdskx and Formatx is very similar to the real chkdsk and format's output. |