2.1.5.10.32 FSCTL_SET_ENCRYPTION

The server provides:

  • Open: An Open of a DataFile or DirectoryFile.

  • InputBuffer: An array of bytes containing an ENCRYPTION_BUFFER structure indicating the requested encryption state of the stream or file, as specified in [MS-FSCC] section 2.3.71.

  • InputBufferSize: The number of bytes in InputBuffer.

On completion, the object store MUST return:

  • Status: An NTSTATUS code that specifies the result.

This operation uses the following local variables:

  • Boolean value (initialized to FALSE): ChangedFileEncryption

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.<133>

Pseudocode for the operation is as follows:

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

  • If InputBufferSize is smaller than BlockAlign(sizeof(ENCRYPTION_BUFFER), 4), the operation MUST be failed with STATUS_BUFFER_TOO_SMALL.

  • The operation MUST be failed with STATUS_INVALID_PARAMETER under any of the following conditions:

    • If InputBuffer.EncryptionOperation is not one of the predefined values in [MS-FSCC] section 2.3.71.

    • If InputBuffer.EncryptionOperation == STREAM_SET_ENCRYPTION and Open.Stream.IsCompressed is TRUE.

  • If InputBuffer.EncryptionOperation == FILE_SET_ENCRYPTION:

    • If Open.File.Attributes.FILE_ATTRIBUTE_ENCRYPTED is FALSE:

      • The object store MUST set Open.File.FileAttributes.FILE_ATTRIBUTE_ENCRYPTED to TRUE.

      • The object store MUST set Open.File.PendingNotifications.FILE_NOTIFY_CHANGE_ATTRIBUTES to TRUE.

      • The object store MUST set ChangedFileEncryption to TRUE.

    • EndIf

  • ElseIf InputBuffer.EncryptionOperation == FILE_CLEAR_ENCRYPTION:

    • If Open.File.Attributes.FILE_ATTRIBUTE_ENCRYPTED is TRUE:

      • If there exists an ExistingStream in Open.File.StreamList such that ExistingStream.IsEncrypted is TRUE, the operation MUST be failed with STATUS_INVALID_DEVICE_REQUEST.

      • The object store MUST set Open.File.FileAttributes.FILE_ATTRIBUTE_ENCRYPTED to FALSE.

      • The object store MUST set Open.File.PendingNotifications.FILE_NOTIFY_CHANGE_ATTRIBUTES to TRUE.

      • The object store MUST set ChangedFileEncryption to TRUE.

    • EndIf

  • ElseIf InputBuffer.EncryptionOperation == STREAM_SET_ENCRYPTION:

    • If Open.Stream.IsEncrypted is FALSE:

      • The object store MUST set Open.Stream.IsEncrypted to TRUE.

      • If Open.File.Attributes.FILE_ATTRIBUTE_ENCRYPTED is FALSE:

        • The object store MUST set Open.File.FileAttributes.FILE_ATTRIBUTE_ENCRYPTED to TRUE.

        • The object store MUST set Open.File.PendingNotifications.FILE_NOTIFY_CHANGE_ATTRIBUTES to TRUE.

      • EndIf

    • EndIf

  • Else: // InputBuffer.EncryptionOperation == STREAM_CLEAR_ENCRYPTION

    • If Open.Stream.IsEncrypted is TRUE:

      • The object store MUST set Open.Stream.IsEncrypted to FALSE.

      • If there does not exist an ExistingStream in Open.File.StreamList such that ExistingStream.IsEncrypted is TRUE:

        • The object store MUST set Open.File.FileAttributes.FILE_ATTRIBUTE_ENCRYPTED to FALSE.

        • The object store MUST set Open.File.PendingNotifications.FILE_NOTIFY_CHANGE_ATTRIBUTES to TRUE.

      • EndIf

    • EndIf

  • EndIf

  • The object store MUST update the duplicated information as specified in section 2.1.4.18 with Link equal to Open.Link.

  • If Open.File.PendingNotifications is nonzero:

    • Set FilterMatch = (Open.File.PendingNotifications | Open.Link.PendingNotifications).

    • Send directory change notification as specified in section 2.1.4.1, with Volume equal to Open.File.Volume, Action equal to FILE_ACTION_MODIFIED, FilterMatch equal to FilterMatch, and FileName equal to Open.FileName.

    • For each ExistingLink in Open.Link.ParentFile.DirectoryList:

      • If ExistingLink is not equal to Open.Link:

        • ExistingLink.PendingNotifications |= Open.File.PendingNotifications

      • EndIf

    • EndFor

    • Set Open.Link.PendingNotifications to zero.

    • Set Open.File.PendingNotifications to zero.

  • EndIf

  • If the Oplock member of the DirectoryStream in Open.Link.ParentFile.StreamList (hereinafter referred to as ParentOplock) is not empty, the object store MUST check for an oplock break on the parent according to the algorithm in section 2.1.4.12, with input values as follows:

    • Open equal to this operation's Open

    • Oplock equal to ParentOplock

    • Operation equal to "FS_CONTROL"

    • OpParams containing a member ControlCode containing "FSCTL_SET_ENCRYPTION"

    • Flags equal to "PARENT_OBJECT"

  • The object store MUST post a USN change as specified in section 2.1.4.11 with File equal to File, Reason equal to USN_REASON_ENCRYPTION_CHANGE, and FileName equal to Open.Link.Name.

  • If ChangedFileEncryption is TRUE:

    • If Open.UserSetChangeTime is FALSE, update Open.File.LastChangeTime to the current time.

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

  • EndIf

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

    • Status set to STATUS_SUCCESS.