2.1.5.10.37 FSCTL_SET_REPARSE_POINT

The server provides:

  • Open: An Open of a DataFile or DirectoryFile.

  • InputBufferSize: The byte count of the InputBuffer.

  • InputBuffer: An array of bytes containing a REPARSE_DATA_BUFFER or REPARSE_GUID_DATA_BUFFER structure as defined in [MS-FSCC] sections 2.1.2.2 and 2.1.2.3, respectively.

On completion, the object store MUST return:

  • Status: An NTSTATUS code that specifies the result.

Support for this operation is optional. If the object store does not implement this functionality, the operation MUST be failed with STATUS_INVALID_DEVICE_REQUEST.<136>

Pseudocode for the operation is as follows:

  • Phase 1 -- Verify the parameters

  • If (Open.GrantedAccess & (FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES)) == 0, the operation MUST be failed with STATUS_ACCESS_DENIED.

  • If Open.File.Volume.IsReadOnly is TRUE, the operation MUST be failed with STATUS_MEDIA_WRITE_PROTECTED.

  • If Open.File.Volume.IsReparsePointsSupported is FALSE, the operation MUST be failed with STATUS_VOLUME_NOT_UPGRADED.

  • If InputBufferSize is smaller than 8 bytes, the operation MUST be failed with STATUS_IO_REPARSE_DATA_INVALID.

  • If InputBufferSize is larger than 16384 bytes, the operation MUST be failed with STATUS_IO_REPARSE_DATA_INVALID.

  • If (InputBufferSize != InputBuffer.ReparseDataLength + 8) && (InputBufferSize != InputBuffer.ReparseDataLength + 24), the operation MUST be failed with STATUS_IO_REPARSE_DATA_INVALID.

  • If InputBuffer.ReparseTag == IO_REPARSE_TAG_MOUNT_POINT and Open.File.FileType != DirectoryFile, the operation MUST be failed with STATUS_NOT_A_DIRECTORY.

  • If InputBuffer.ReparseTag == IO_REPARSE_TAG_SYMLINK and Open.HasCreateSymbolicLinkAccess is FALSE, the operation MUST be failed with STATUS_ACCESS_DENIED.

  • If Open.File.FileType == DirectoryFile and Open.File.DirectoryList is not empty, the operation MUST be failed with STATUS_DIRECTORY_NOT_EMPTY.

  • If Open.File.FileType == DataFile and InputBuffer.ReparseTag == IO_REPARSE_TAG_SYMLINK and Open.Stream.Size is nonzero, the operation MUST be failed with STATUS_IO_REPARSE_DATA_INVALID.

  • If Open.File.FileAttributes.FILE_ATTRIBUTE_REPARSE_POINT is not set and Open.File.ExtendedAttributesLength is nonzero, the operation MUST be failed with STATUS_EAS_NOT_SUPPORTED.

  • Phase 2 -- Update the File

  • If Open.File.ReparseTag is not empty (indicating that a reparse point is already assigned):

    • If Open.File.ReparseTag != InputBuffer.ReparseTag, the operation MUST be failed with STATUS_IO_REPARSE_TAG_MISMATCH.

    • If Open.File.ReparseTag is a non-Microsoft tag and Open.File.ReparseGUID is not equal to InputBuffer.ReparseGUID, the operation MUST be failed with STATUS_REPARSE_ATTRIBUTE_CONFLICT.

    • Copy InputBuffer.DataBuffer to Open.File.ReparseData.

  • Else

    • Set Open.File.ReparseTag to InputBuffer.ReparseTag.

    • If InputBuffer.ReparseTag is a non-Microsoft Tag, then set Open.File.ReparseGUID to InputBuffer.ReparseGUID.

    • Set Open.File.ReparseData to InputBuffer.ReparseData.

    • Set Open.File.FileAttributes.FILE_ATTRIBUTE_REPARSE_POINT to TRUE.

  • EndIf

  • If Open.File.FileType == DataFile, set Open.File.FileAttributes.FILE_ATTRIBUTE_ARCHIVE to TRUE.

  • Update Open.File.LastChangeTime to the current system time.<137>

Upon successful completion of the operation, the object store MUST return:

  • Status set to STATUS_SUCCESS.