2.1.5.15.6 FileLinkInformation

InputBuffer is of type FILE_LINK_INFORMATION_TYPE_1, as described in [MS-FSCC] section 2.4.27.1, for 32-bit local clients; or of type FILE_LINK_INFORMATION_TYPE_2, as described in [MS-FSCC] section 2.4.27.2, for remote clients or 64-bit local clients. Open represents the pre-existing file to which a new link named in InputBuffer.FileName will be created.

Pseudocode for the operation is as follows:

  • If InputBufferSize is less than the size, in bytes, of the FILE_LINK_INFORMATION_TYPE_1 structure (for 32-bit local clients) or the FILE_LINK_INFORMATION_TYPE_2 structure (for remote clients or 64-bit local clients), the operation MUST be failed with STATUS_INFO_LENGTH_MISMATCH.

  • If Open.Stream.StreamType is DataStream and Open.Stream.Name is not empty, the operation MUST be failed with STATUS_INVALID_PARAMETER.

  • If Open.File.FileType is DirectoryFile, the operation MUST be failed with STATUS_FILE_IS_A_DIRECTORY.

  • If Open.File.Volume.IsHardLinksSupported is FALSE, the operation MUST be failed with STATUS_NOT_SUPPORTED.

  • If Open.Link.IsDeleted is TRUE, 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 Open.File.LinkList has 1024 or more entries, the operation SHOULD be failed with STATUS_TOO_MANY_LINKS.

  • Split InputBuffer.FileName into PathName and FileName, as specified in section 2.1.5.1.

  • If the first character of InputBuffer.FileName is '\' or InputBuffer.RootDirectory is nonzero or this operation is from a remote client:

    • Open DestinationDirectory as specified in 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.

      • ShareAccess equal to FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE.<183>

      • 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

    • If InputBuffer.FileName contains the character '\', the object store MUST fail the operation with STATUS_OBJECT_NAME_INVALID.

    • Set DestinationDirectory equal to Open.Link.ParentFile.

  • EndIf

  • Search DestinationDirectory.File.DirectoryList for an ExistingLink where ExistingLink.Name or ExistingLink.ShortName matches FileName using case-sensitivity according to Open.IsCaseInsensitive. If such a link is found:

    • If InputBuffer.ReplaceIfExists is TRUE:

      • Set ReplacedLinkName = DestinationDirectory.FileName + FileName.

      • Remove ExistingLink from ExistingLink.File.LinkList.

      • Remove ExistingLink from DestinationDirectory.File.DirectoryList.

      • Set DeletedLink to TRUE.

    • Else:

      • The operation MUST be failed with STATUS_OBJECT_NAME_COLLISION.

    • EndIf

  • EndIf

  • The object store MUST build a new Link object NewLink with fields initialized as follows:

    • NewLink.Name set to FileName.

    • NewLink.File set to Open.File.

    • NewLink.ParentFile set to DestinationDirectory.File.

    • All other fields set to zero.

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

  • The object store MUST insert NewLink into Open.File.LinkList

  • The object store MUST insert NewLink into DestinationDirectory.File.DirectoryList.

  • The object store MUST update DestinationDirectory.File.LastModificationTime, DestinationDirectory.File.LastAccessTime, and DestinationDirectory.File.LastChangeTime.

  • If the Oplock member of the DirectoryStream in DestinationDirectory.File.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 "SET_INFORMATION"

    • OpParams containing a member FileInformationClass containing FileLinkInformation

    • Flags equal to "PARENT_OBJECT"

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

  • The object store MUST set Open.File.FileAttributes.FILE_ATTRIBUTE_ARCHIVE.

  • If DeletedLink is TRUE:

    • If ReplacedLinkName equals InputBuffer.FileName in a case-sensitive comparison:

      • // In this case, the link name has not changed, but the file it refers to has changed.

      • Action = FILE_ACTION_MODIFIED

      • 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

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

    • Else

      • // In this case, the implementer replaced a link, but the new link created differs only in case.

      • Action = FILE_ACTION_REMOVED

      • FilterMatch = FILE_NOTIFY_CHANGE_FILE_NAME

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

      • Action = FILE_ACTION_ADDED

      • FilterMatch = FILE_NOTIFY_CHANGE_FILE_NAME

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

    • EndIf

  • Else

    • // If the implementer did not delete a link, all that needs to be done is to notify that a new link was created.

    • Action = FILE_ACTION_ADDED

    • FilterMatch = FILE_NOTIFY_CHANGE_FILE_NAME

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

  • EndIf

  • The operation returns STATUS_SUCCESS.