2.1.5.15.11.1 Algorithm for Performing Stream Rename

The inputs for a stream rename are:

  • Open: an Open for the stream being renamed.

  • ReplaceIfExists: A Boolean value. If TRUE and the target stream exists and the operation is successful, the target stream MUST be replaced. If FALSE and the target stream exists, the operation MUST fail.

  • NewStreamName: A Unicode string indicating the new name for the stream. This string MUST begin with the Unicode character ":".

The stream rename algorithm uses the following local variables:

  • Unicode strings: StreamName, StreamTypeName

  • Streams: TargetStream, NewDefaultStream

Pseudocode for the algorithm is as follows:

  • Split NewStreamName into a stream name component StreamName and attribute type component StreamTypeName, using the character ":" as a delimiter.

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

    • The last character of NewStreamName is ":".

    • The character ":" occurs more than three times in NewStreamName.

    • If StreamName contains any characters invalid for a streamname as specified in [MS-FSCC] section 2.1.5.3.

    • If StreamTypeName contains any characters invalid for a streamtype as specified in [MS-FSCC] section 2.1.5.4.

    • Both StreamName and StreamTypeName are zero-length.

    • StreamName is more than 255 Unicode characters in length.

    • If StreamName is zero-length and Open.File.FileType is DirectoryFile, because a DirectoryFile cannot have an unnamed data stream.

  • The operation MUST be failed with STATUS_OBJECT_TYPE_MISMATCH if either of the following conditions are true:

    • Open.Stream.StreamType is DataStream and StreamTypeName is not the Unicode string "$DATA".

    • Open.Stream.StreamType is DirectoryStream and StreamTypeName is not the Unicode string "$INDEX_ALLOCATION".

  • If Open.Stream.StreamType is DirectoryStream, the operation MUST be failed with STATUS_INVALID_PARAMETER.

  • If StreamName is a case-insensitive match with Open.Stream.Name, the operation MUST return STATUS_SUCCESS at this point.

  • If the length of StreamName is not 0, the object store MUST search Open.File.StreamList for a Stream with Stream.Name matching StreamName, ignoring case, setting TargetStream to the result.

  • If TargetStream is found:

    • If ReplaceIfExists is FALSE, the operation MUST be failed with STATUS_OBJECT_NAME_COLLISION.

    • If TargetStream.File.OpenList contains any Opens to TargetStream, the operation MUST be failed with STATUS_INVALID_PARAMETER.

    • If TargetStream.Size is not 0, the operation MUST be failed with STATUS_INVALID_PARAMETER.

    • If TargetStream.AllocationSize is not 0, the object store SHOULD release any associated allocation and MUST set TargetStream.AllocationSize to 0.

  • Else // TargetStream is not found:

    • The object store MUST build a new Stream object TargetStream with all fields initially set to zero.

    • Set TargetStream.File to Open.File.

    • Add TargetStream to Open.File.StreamList.

  • EndIf

  • Set TargetStream.Name to StreamName.

  • Set TargetStream.Size to Open.Stream.Size.

  • If Open.Stream.IsSparse is TRUE, set TargetStream.IsSparse to TRUE.

  • Move Open.Stream.ExtentList to TargetStream.

  • Set TargetStream.AllocationSize to Open.Stream.AllocationSize.

  • If Open.Stream.Name is empty, the object store MUST create a new default unnamed stream for the file as follows:

    • The object store MUST build a new Stream object NewDefaultStream with all fields initially set to zero.

    • Set NewDefaultStream.File to Open.File.

    • Add NewDefaultStream to Open.File.StreamList.

  • EndIf

  • Remove Open.Stream from Open.File.StreamList.

  • Set Open.Stream to TargetStream.

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

  • The object store MUST note that the file has been modified as specified in section 2.1.4.17 with Open equal to Open.

  • Return STATUS_SUCCESS.