Export (0) Print
Expand All
This topic has not yet been rated - Rate this topic

2.1.5.14.11 FileRenameInformation

InputBuffer is of type FILE_RENAME_INFORMATION, as described in [MS-FSCC] section 2.4.34.Open.FileName is the pre-existing file name that will be changed by this operation.

This routine uses the following local variables:

  • Unicode strings: PathName, NewLinkName, PrevFullLinkName, SourceFullLinkName

  • Files: SourceDirectory, DestinationDirectory

  • Links: TargetLink, NewLink

  • Boolean values (initialized to FALSE): TargetExistsSameFile, ExactCaseMatch, MoveToNewDir, OverwriteSourceLink, RemoveTargetLink, FoundLink, MatchedShortName

  • Boolean values (initialized to TRUE): ActivelyRemoveSourceLink, RemoveSourceLink, AddTargetLink

  • 32-bit unsigned integers: FilterMatch, Action

Pseudocode for the operation is as follows:

  • If Open.GrantedAccess does not contain DELETE, as defined in [MS-SMB2] section 2.2.13.1, the operation MUST be failed with STATUS_ACCESS_DENIED.

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

    • If InputBuffer.FileNameLength is equal to zero.

    • If InputBuffer.FileNameLength is an odd number.

    • If InputBuffer.FileNameLength is greater than InputBufferLength minus the byte offset into the FILE_RENAME_INFORMATION InputBuffer of the InputBuffer.FileName field (that is, the total length of InputBuffer as given in InputBufferLength is insufficient to contain the fixed-size fields of InputBuffer plus the length of InputBuffer.FileName).

  • Split InputBuffer.FileName into PathName and NewLinkName per section 2.1.5.1.

  • If the first character of InputBuffer.FileName is '\':

    • Open DestinationDirectory per section 2.1.5.1, setting the open file operation's parameters as follows:

      • PathName equal to PathName.

      • DesiredAccess equal to FILE_ADD_FILE|SYNCHRONIZE, additionally specifying FILE_ADD_SUBDIRECTORY if Open.File.FileType is DirectoryFile.

      • ShareAccess equal to FILE_SHARE_READ|FILE_SHARE_WRITE.

      • CreateOptions equal to FILE_OPEN_FOR_BACKUP_INTENT.

      • CreateDisposition equal to FILE_OPEN.

    • If open of DestinationDirectory fails:

      • The operation MUST fail with the error returned by the open of DestinationDirectory.

    • Else if DestinationDirectory.Volume is not equal to Open.File.Volume:

      • The operation MUST be failed with STATUS_NOT_SAME_DEVICE.

    • EndIf

  • Else

    • Set DestinationDirectory equal to Open.Link.ParentFile.

  • EndIf

  • If Open.Stream.Oplock is not empty, the object store MUST check for an oplock break 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 Open.Stream.Oplock.

    • Operation equal to "SET_INFORMATION".

    • OpParams containing a member FileInformationClass containing FileRenameInformation.

  • If the first character of InputBuffer.FileName is ':':

    • Perform a stream rename according to the algorithm in section 2.1.5.14.11.1, setting the stream rename algorithm's parameters as follows:

      • Pass in the current Open.

      • ReplaceIfExists equal to InputBuffer.ReplaceIfExists.

      • NewStreamName equal to InputBuffer.FileName.

    • If the stream rename algorithm fails, the operation MUST fail with the same status code.

    • The operation returns STATUS_SUCCESS at this point.

  • EndIf

  • If Open.Link.IsDeleted is TRUE, the operation MUST be failed with STATUS_ACCESS_DENIED.

  • If Open.File.FileType is DirectoryFile, determine whether Open.File contains open files per section 2.1.4.2, with input values as follows:

    • File equal to Open.File.

    • Open equal to this operation's Open.

    • Operation equal to "SET_INFORMATION".

    • OpParams containing a member FileInformationClass containing FileRenameInformation.

  • If Open.File contains open files, the operation MUST be failed with STATUS_ACCESS_DENIED.

  • If InputBuffer.FileName is not valid as specified in [MS-FSCC] section 2.1.5, the operation MUST be failed with STATUS_OBJECT_NAME_INVALID.

  • If DestinationDirectory is the same as Open.Link.ParentFile:

    • If NewLinkName is a case-sensitive exact match with Open.Link.Name, the operation MUST return STATUS_SUCCESS at this point.

  • Else

    • Set MoveToNewDir to TRUE.

  • EndIf

  • If NewLinkName matches the Name or ShortName of any Link in DestinationDirectory.DirectoryList using case-sensitivity according to Open.IsCaseInsensitive:

    • Set FoundLink to TRUE.

    • Set TargetLink to the existing Link found in DestinationDirectory.DirectoryList. Because the name may have been found using a case-insensitive search (if Open.IsCaseInsensitive is TRUE), this preserves the case of the found name.

    • If NewLinkName matched TargetLink.ShortName, set MatchedShortName to TRUE.

    • Set RemoveTargetLink to TRUE.

    • If TargetLink.File.FileId128 equals Open.File.FileId128, set TargetExistsSameFile to TRUE. This detects a rename to another existing link to the same file.

    • If (TargetLink.Name is a case-sensitive exact match with NewLinkName) or

      (MatchedShortName is TRUE and

      TargetLink.ShortName is a case-sensitive exact match with NewLinkName):

      • Set ExactCaseMatch to TRUE.

    • EndIf

    • If TargetExistsSameFile is TRUE:

      • If MoveToNewDir is FALSE:

        • If Open.Link.ShortName is not empty and TargetLink.ShortName is not empty (this is the case where both the source link and the (existing) requested target are part of the primary link to the same file; this case occurs, for example, in a rename that only changes the case of the name):

          • Set ActivelyRemoveSourceLink to FALSE.

          • Set OverwriteSourceLink to TRUE.

          • If ExactCaseMatch is TRUE, set RemoveSourceLink to FALSE (because this algorithm earlier succeeded upon detecting an exact match between the name by which the file was opened and the new requested name, this case only occurs when the file was opened by one half of its primary link, and the requested rename target is the other half; for example, opening a file by its short name and renaming it to its long name).

        • Else If (Open.Link.Name is a case-sensitive exact match with TargetLink.Name) or

          (MatchedShortName is TRUE and

          Open.Link.Name is a case-sensitive exact match with TargetLink.ShortName) (this detects the case where the implementer is just changing the case of a single link; for example, given a file with links "primary", "link1", "link2", all in the same directory, the implementer is doing "ren link1 LINK1", and not "ren link1 link2"):

          • Set ActivelyRemoveSourceLink to FALSE.

          • Set OverwriteSourceLink to TRUE.

        • EndIf

      • EndIf

      • If ExactCaseMatch is TRUE and

        (OverwriteSourceLink is FALSE or

        Open.IsCaseInsensitive is TRUE or

        Open.Link.ShortName is empty)

        • Set RemoveTargetLink and AddTargetLink to FALSE.

      • EndIf

    • EndIf

    • If RemoveTargetLink is TRUE:

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

      • Set PrevFullLinkName to the full pathname from Open.File.Volume.RootDirectory to TargetLink.

      • If TargetExistsSameFile is FALSE:

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

          • If TargetLink.File.FileType is DirectoryFile.

          • If TargetLink.File.FileAttributes.FILE_ATTRIBUTE_READONLY is TRUE.

        • If TargetLink.IsDeleted is TRUE, the operation MUST be failed with STATUS_DELETE_PENDING.

        • If the caller does not have DELETE access to TargetLink.File:

          • If the caller does not have FILE_DELETE_CHILD access to DestinationDirectory:

            • The operation MUST be failed with STATUS_ACCESS_DENIED.

          • EndIf

        • EndIf

        • For each Stream on TargetLink.File:

          • If TargetLink.File.OpenList contains an Open with a Stream matching the current Stream, and that Stream's Oplock is not empty, the object store MUST check for an oplock break 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 the found Stream's Oplock.

            • Operation equal to SET_INFORMATION.

            • OpParams containing a member FileInformationClass containing FileEndOfFileInformation.

          • If there was not an oplock to be broken and TargetLink.File.OpenList contains an Open with a Stream matching the current Stream, the operation MUST be failed with STATUS_ACCESS_DENIED.

        • EndFor

        • If TargetLink.File.LinkList contains exactly one element:

          • The object store MUST delete TargetLink.File per section 2.1.5.4; if this fails, the operation MUST be failed with the same status.

        • Else

          • The object store MUST delete TargetLink per section 2.1.5.4; if this fails, the operation MUST be failed with the same status.

          • The object store MUST post a USN change as per section 2.1.4.11 with File equal to File, Reason equal to (USN_REASON_HARD_LINK_CHANGE | USN_REASON_CLOSE), and FileName equal to TargetLink.Name.

        • EndIf

      • Else

        • The object store MUST post a USN change as per section 2.1.4.11 with File equal to File, Reason equal to USN_REASON_RENAME_OLD_NAME, and FileName equal to TargetLink.Name.

        • The object store MUST delete TargetLink per section 2.1.5.4; if this fails, the operation MUST be failed with the same status.

      • EndIf

    • EndIf

  • EndIf

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

  • If RemoveSourceLink is TRUE:

    • Set SourceDirectory to Open.Link.ParentFile.

    • If ActivelyRemoveSourceLink is TRUE:

      • Remove Open.Link from Open.File.LinkList.

      • Remove Open.Link from Open.Link.ParentFile.DirectoryList.

      • A new TunnelCacheEntry object TunnelCacheEntry MUST be constructed and added to the Open.File.Volume.TunnelCacheList as follows:

        • TunnelCacheEntry .EntryTime MUST be set to the current time.

        • TunnelCacheEntry .ParentFile MUST be set to Open.Link.ParentFile.

        • TunnelCacheEntry .FileName MUST be set to Open.Link.Name.

        • TunnelCacheEntry .FileShortName MUST be set to Open.Link.ShortName.

        • If Open.FileName matches Open.Link.ShortName, then TunnelCacheEntry.KeyByShortName MUST be set to TRUE, else TunnelCacheEntry.KeyByShortName MUST be set to FALSE.

        • TunnelCacheEntry .FileCreationTime MUST be set to Open.File.CreationTime.

        • TunnelCacheEntry .FileObjectId MUST be set to Open.File.ObjectId.

      • EndIf

      • If Open.File.FileType is DirectoryFile, then Open.File MUST have every TunnelCacheEntry associated with it invalidated:

        • For every ExistingTunnelCacheEntry in Open.File.Volume.TunnelCacheList:

          • If ExistingTunnelCacheEntry.ParentFile matches Open.File, then ExistingTunnelCacheEntry MUST be removed from Open.File.Volume.TunnelCacheList.

        • EndFor

      • EndIf

    • EndIf

    • Set SourceFullLinkName to Open.FileName.

  • EndIf

  • If AddTargetLink is TRUE:

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

      • Open.File.FileType is DirectoryFile and the caller does not have FILE_ADD_SUBDIRECTORY access on DestinationDirectory.

      • Open.File.FileType is DataFile and the caller does not have FILE_ADD_FILE access on DestinationDirectory.

    • The object store MUST create a new Link object NewLink, initialized as follows:

      • NewLink.File equal to Open.File.

      • NewLink.ParentFile equal to DestinationDirectory.

      • All other fields set to zero.

    • If Open.File.FileType is DataFile and Open.IsCaseInsensitive is TRUE, and tunnel caching is implemented, the object store MUST search Open.File.Volume.TunnelCacheList for a TunnelCacheEntry where TunnelCacheEntry.ParentFile equals DestinationDirectory and either (TunnelCacheEntry.KeyByShortName is FALSE and TunnelCacheEntry.FileName matches NewLinkName) or (TunnelCacheEntry.KeyByShortName is TRUE and TunnelCacheEntry.FileShortName matches NewLinkName). If such an entry is found:

      • Set NewLink.File.CreationTime to TunnelCacheEntry.FileCreationTime.

      • Set NewLink.File.PendingNotifications. FILE_NOTIFY_CHANGE_CREATION to TRUE.

      • Set NewLink.File.ObjectId to TunnelCacheEntry.FileObjectId.

      • Set NewLink.Name to TunnelCacheEntry.FileName.

      • Set NewLink.ShortName to TunnelCacheEntry.FileShortName if that name is not already in use among all names and short names in NewLink.ParentFile.DirectoryList.

      • Remove TunnelCacheEntry from NewLink.File.Volume.TunnelCacheList.

    • Else:

      • Set NewLink.Name to NewLinkName.

    • EndIf

    • If Open.Link.ShortName is not empty and Open.IsCaseInsensitive is TRUE and NewLink.ShortName is empty, then if short names are enabled, the object store MUST create a short name as follows:

      • If NewLink.Name is 8.3-compliant as described in [MS-FSCC] section 2.1.5.2.1:

        • Set NewLink.ShortName to NewLink.Name.

      • Else:

        • Generate a NewLink.ShortName that is 8.3-compliant as described in [MS-FSCC] section 2.1.5.2.1. The string chosen is implementation-specific, but MUST be unique among all names and short names present in DestinationDirectory.DirectoryList.

      • EndIf

    • EndIf

    • The object store MUST add NewLink to DestinationDirectory.DirectoryList.

    • The object store MUST replace Open.Link with NewLink.

    • If MoveToNewDir is TRUE:

      • DestinationDirectory .LastModifiedTime MUST be updated.

      • DestinationDirectory .LastAccessedTime MUST be updated.

      • DestinationDirectory .LastChangeTime MUST be updated.

    • EndIf

  • EndIf

  • The object store MUST change the compname component (as specified in [MS-FSCC] section 2.1.5) of Open.FileName to NewLinkName.

  • If RemoveSourceLink is TRUE:

    • SourceDirectory .LastModifiedTime MUST be updated.

    • SourceDirectory .LastAccessedTime MUST be updated.

    • SourceDirectory .LastChangeTime MUST be updated.

  • EndIf

  • The object store MUST update Open.File.LastChangeTime.<127>

  • If Open.File.FileType is DataFile, the object store MUST set Open.File.FileAttributes.FILE_ATTRIBUTE_ARCHIVE.

  • FilterMatch = 0

  • If RemoveTargetLink is TRUE and OverwriteSourceLink is FALSE and ExactCaseMatch is FALSE:

    • If TargetLink.File.FileType is DirectoryFile

      • FilterMatch = FILE_NOTIFY_CHANGE_DIR_NAME

    • Else

      • FilterMatch = FILE_NOTIFY_CHANGE_FILE_NAME

    • EndIf

    • The object store MUST report a directory change notification per section 2.1.4.1 with Volume equal to Open.File.Volume, Action equal to FILE_ACTION_REMOVED, and FileName set to PrevFullLinkName with a FilterMatch of FilterMatch.

  • EndIf

  • If RemoveSourceLink is TRUE:

    • If Open.File.FileType is DirectoryFile

      • FilterMatch = FILE_NOTIFY_CHANGE_DIR_NAME

    • Else

      • FilterMatch = FILE_NOTIFY_CHANGE_FILE_NAME

    • EndIf

    • If MoveToNewDir is TRUE or AddTargetLink is FALSE or RemoveTargetLink and ExactCaseMatch are TRUE: Action = FILE_ACTION_REMOVED

    • Else

      • Action = FILE_ACTION_REMOVED_OLD_NAME

    • EndIf

    • The object store MUST report a directory change notification per section 2.1.4.1 with Volume equal to Open.File.Volume, Action equal to Action, and FileName set to SourceFullLinkName with a FilterMatch of FilterMatch.

  • EndIf

  • If FoundLink is FALSE or (OverwriteSourceLink is TRUE and ExactCaseMatch is FALSE) or (RemoveTargetLink is TRUE and ExactCaseMatch is FALSE):

    • If MoveToNewDir is TRUE, set Action to FILE_ACTION_ADDED; otherwise set Action to FILE_ACTION_RENAMED_NEW_NAME.

  • Else If RemoveTargetLink is TRUE and TargetExistsSameFile is FALSE:

    • FilterMatch = FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_LAST_ACCESS | FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_SECURITY | FILE_NOTIFY_CHANGE_EA

    • Action = FILE_ACTION_MODIFIED

  • EndIf

  • If FilterMatch != 0:

    • The object store MUST report a directory change notification per section 2.1.4.1 with Volume equal to Open.File.Volume, Action equal to Action, and FileName set to Open.FileName with a FilterMatch of FilterMatch.

  • EndIf

  • If MoveToNewDir is TRUE:

    • If the Oplock member of the DirectoryStream in DestinationDirectory.StreamList (hereinafter referred to as DestinationParentOplock) 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 DestinationParentOplock

      • Operation equal to "SET_INFORMATION"

      • OpParams containing a member FileInformationClass containing FileRenameInformation

      • Flags equal to "PARENT_OBJECT"

  • EndIf

  • If the Oplock member of the DirectoryStream in Open.Link.ParentFile.StreamList (hereinafter referred to as SourceParentOplock) 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 SourceParentOplock

    • Operation equal to "SET_INFORMATION"

    • OpParams containing a member FileInformationClass containing FileRenameInformation

    • Flags equal to "PARENT_OBJECT"

  • The operation returns STATUS_SUCCESS.

 
Did you find this helpful?
(1500 characters remaining)
Thank you for your feedback
Show:
© 2014 Microsoft. All rights reserved.