OSRLogoOSRLogoOSRLogo x Seminar Ad

Everything Windows Driver Development

GoToHomePage xLoginx

    Thu, 14 Mar 2019     118020 members


  Online Dump Analyzer
OSR Dev Blog
The NT Insider
The Basics
File Systems
ListServer / Forum
  Express Links
  · The NT Insider Digital Edition - May-June 2016 Now Available!
  · Windows 8.1 Update: VS Express Now Supported
  · HCK Client install on Windows N versions
  · There's a WDFSTRING?
  · When CAN You Call WdfIoQueueP...ously

Play It Again, Sam -- Reparse Points in Windows

One of the interesting features in the Windows kernel is the presence of the reparse point.  While only a few commercial products appear to be using this feature (three, as of last count) it is worthy of consideration.  In this article we discuss how reparse points work.


Reparse Points 101

First, it is important to note that reparse points are a feature only present in the NTFS file system, although there is certainly no reason other file systems cannot support them.  A file system wishing to support reparse points need only set the FILE_SUPPORTS_REPARSE_POINTS attribute when responding to the FileFsAttributeInformation call to IRP_ MJ_QUERY_VOLUME_INFORMATION.  For those programmers that wish to take advantage of this feature, this call may be used to test whether or not the underlying file system actually supports them.


The basic paradigm for a reparse point is that the file or directory contains the reparse data and some component above the file system understands how to interpret that data.  If a reparse point tag is not understood by any caller, the I/O Manager will clean up and return STATUS_IO_REPARSE_ TAG_NOT_HANDLED.


For a filter above the file system layer, the first indication that a reparse point has been encountered is when the file system returns STATUS_REPARSE and the information field contains the reparse point tag value (not IO_REMOUNT or IO_REPARSE, which actually pre-date the creation of reparse points).  At that point, the filter driver can look at the reparse point data buffer, which is located in Irp->Tail.Overlay.AuxiliaryBuffer. 


This auxiliary buffer is allocated by the file system (e.g., NTFS) and is either freed by the filter driver owning the reparse point tag, or by the I/O Manager.


The format for Microsoft-defined reparse points (from ntifs.h) is shown in Figure 1.



typedef struct _REPARSE_DATA_BUFFER {

    ULONG  ReparseTag;

    USHORT ReparseDataLength;

    USHORT Reserved;

    union {

        struct {

            USHORT SubstituteNameOffset;

            USHORT SubstituteNameLength;

            USHORT PrintNameOffset;

            USHORT PrintNameLength;

            WCHAR PathBuffer[1];

        } SymbolicLinkReparseBuffer;

        struct {

            USHORT SubstituteNameOffset;

            USHORT SubstituteNameLength;

            USHORT PrintNameOffset;

            USHORT PrintNameLength;

            WCHAR PathBuffer[1];

        } MountPointReparseBuffer;

        struct {

            UCHAR  DataBuffer[1];

        } GenericReparseBuffer;




Figure 1 — MS-Defined Reparse Point Format

For non-Microsoft reparse point drivers, a fixed header must be used, with the remainder of the reparse point tag belonging to the driver itself.  The format for this information is shown in Figure 2.


typedef struct _REPARSE_GUID_DATA_BUFFER {

    ULONG  ReparseTag;

    USHORT ReparseDataLength;

    USHORT Reserved;

    GUID   ReparseGuid;

    struct {

        UCHAR  DataBuffer[1];

    } GenericReparseBuffer;




Figure 2 — Non MS Reparse Point Format


The use of a GUID provides a simple mechanism for distributed creation of these reparse points, although reparse point tags are assigned by Microsoft.  At present there are only four third-party reparse point tags defined in the latest version of ntifs.h:



#define IO_REPARSE_TAG_IFSTEST_CONGRUENT        (0x00000009L)

#define IO_REPARSE_TAG_ARKIVIO                  (0x0000000CL)

#define IO_REPARSE_TAG_SOLUTIONSOFT             (0x2000000DL)

#define IO_REPARSE_TAG_COMMVAULT                (0x0000000EL)


Presumably, there will be additional tags defined in ntifs.h as they are assigned by Microsoft.  Note that several other tag values are defined by Microsoft for use by their own reparse point filter drivers.


The format for the reparse point buffer is actually defined by the creator of the reparse point tag, although the first three fields must be present , as they define the “tag” for this reparse point, the data size of the reparse point data, and a reserved value that may be used by the file system as it deems fit.


Reparse Point Uses

A filter driver might use reparse point tags to store information about the file (or directory) so that the actual contents or location can be processed appropriately.  For example, SIS uses reparse point tags to point to the actual file, rather than the “instance”.  If someone tries to modify the file, however, SIS will copy the file from its original location and the changes will apply to the private instance, not to the common (shared) original file.


Another example would be a Hierarchical Storage Manager (HSM) that migrated some (or all) of the contents of individual files to a backing store.  When the individual file is accessed, the actual information about its location on backing media would be stored within the reparse point tag.  In this manner, if the HSM driver is not running, the file is inaccessible (it will return STATUS_IO_REPARSE_TAG_ NOT_HANDLED) and thus just a portion of the file’s data contents might be present (e.g., the file could have a sparse local representation).  This is useful in HSM applications (for example) because some portions of the file are used, such as the resources, while the file itself is not actually used in its entirety.


To open a file that contains a reparse point, the caller must specify they wish to open it directly, rather than to trigger the reparse operation by specifying FILE_OPEN_REPARSE_ POINT when they open the file.  Thus, a filter driver attempting to open its reparse point file would use IoCreateFileSpecifyDeviceObjectHint and specify this as part of its create operations.  The filter can then access the data of the file directly – if there is any data within the file.


Should the filter wish to change the contents of the reparse point, it must use the FSCTL operations.  Again, from ntifs.h:


FSCTL_SET_REPARSE_POINT – this operation is used to set the value of the reparse point on the given file or directory.

FSCTL_GET_REPARSE_POINT – this operation is used to retrieve the value of the reparse point data for the given file or directory

FSCTL_DELETE_REPARSE_POINT  - this operation is used to delete an existing reparse point on the given file or directory.


Note that NTFS actually enforces stronger security on these operations than can be expressed in the CTL_CODE macro.  Thus, the definition would appear to allow any access, but NTFS (and presumably other file systems) validates that the access is actually allowed.  For example, FSCTL_SET_ REPARSE_POINT requires that the caller have either FILE_WRITE_DATA or SeRestorePrivilege.  An access error would be reported as a result of this FSCTL call if the appropriate access has not been granted to the caller for the given file.


Naturally, There Are Restrictions

Reparse points, as implemented within NTFS have a few restrictions that anyone using them needs to be aware:


  •          A file that is using a reparse point may not also have extended attributes; the two features are incompatible with one another
  •         NTFS does not support more than one reparse point per file or directory.  An attempt to create a second reparse point tag on the file will generate a STATUS_IO_REPARSE_TAG_MISMATCH error to be returned to the caller.
  •          A directory must be empty for it to contain a reparse point; if the directory is not empty, an attempt to set a reparse point will generate a STATUS_ DIRECTORY_NOT_EMPTY error.
  •         The size of the entire reparse point tag must not be larger than MAXIMUM_REPARSE_DATA_ BUFFER_SIZE, which is 16KB in the latest version of ntifs.h


Note that some of these restrictions may be lifted in future versions of NTFS.


The tag information about the reparse point can be obtained from the file by querying the FileReparsePointInformation using the IRP_MJ_DIRECTORY_CONTROL  with IRP_ MN_QUERY_DIRECTORY.  This operation returns the reparse point information about individual entries within the directory, specifically it returns:


1.              The reparse point tag of the file

2.              The file ID of the file.


This provides a quick way for a filter driver (for example) to find all its reparse points within a given directory.  Iterating this would allow a full search of the tree to find all reparse points.


In Elaborate Summation

Reparse points are integrated in with the other NTFS features, such as the USN Journal, directory change notifications, etc.  It is used by several Windows features and is present in Windows 2000, Windows XP and Windows Server 2003, making it generally useful for those developing products for those environments.  While conceptually simple, the mechanism provided by reparse points is quite powerful.


User Comments
Rate this article and give us feedback. Do you find anything missing? Share your opinion with the community!
Post Your Comment

"Reparse points"
Are there any tools that can be used to get rid of "Reparse points"?

10-Oct-11, Wayne Wymore

good job

07-Feb-10, hu qingsong

Useful article. what I can't find however is any samples of filters using reparse points. Are they just vanilla file filter drivers? mini-filters? something else? what do they have to implement? How are they registered? etc etc... without giving away the shop, a few pointers or a description or two would make for a great article. Cheers.

25-Oct-06, Ati Rosselet

Post Your Comments.
Print this article.
Email this article.
bottom nav links