internal static MessageStatus WorkAroundFsCtlDeleteReparsePoint(ReparseTag reparseTag, bool reparseGuidEqualOpenGuid, MessageStatus returnedStatus, ITestSite site)
 {
     if (returnedStatus == MessageStatus.INVALID_PARAMETER)
     {
         if ((reparseTag == ReparseTag.NON_MICROSOFT_RANGE_TAG) && (!reparseGuidEqualOpenGuid))
         {
             returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(990, MessageStatus.REPARSE_ATTRIBUTE_CONFLICT, returnedStatus, site);
         }
         else if ((reparseTag == ReparseTag.IO_REPARSE_TAG_RESERVED_ZERO) || (reparseTag == ReparseTag.IO_REPARSE_TAG_RESERVED_ONE))
         {
             returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(984, MessageStatus.IO_REPARSE_TAG_INVALID, returnedStatus, site);
         }
         else if (reparseTag == ReparseTag.NotEqualOpenFileReparseTag)
         {
             returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(989, MessageStatus.IO_REPARSE_TAG_MISMATCH, returnedStatus, site);
         }
         else if (reparseTag == ReparseTag.NON_MICROSOFT_RANGE_TAG && reparseGuidEqualOpenGuid)
         {
             returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(1257, MessageStatus.IO_REPARSE_DATA_INVALID, returnedStatus, site);
         }
         else
         {
             returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(5001, MessageStatus.SUCCESS, returnedStatus, site);
         }
     }
     return(returnedStatus);
 }
        internal static MessageStatus WorkaroundFsCtlSetReparsePoint(ReparseTag inputReparseTag, BufferSize bufferSize, bool isReparseGUIDNotEqual, bool isFileReparseTagNotEqualInputBufferReparseTag, MessageStatus returnedStatus, ITestSite site)
        {
            if ((inputReparseTag == ReparseTag.SYMLINK))
            {
                returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(1231, MessageStatus.ACCESS_DENIED, returnedStatus, site);
            }
            else if (returnedStatus == MessageStatus.INVALID_PARAMETER)
            {
                if (inputReparseTag != ReparseTag.EMPTY)
                {
                    if (isFileReparseTagNotEqualInputBufferReparseTag)
                    {
                        returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(1237, MessageStatus.IO_REPARSE_TAG_MISMATCH, returnedStatus, site);
                    }
                    else if ((inputReparseTag == ReparseTag.NON_MICROSOFT_RANGE_TAG) && (!isReparseGUIDNotEqual))
                    {
                        returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(1238, MessageStatus.REPARSE_ATTRIBUTE_CONFLICT, returnedStatus, site);
                    }
                }
                else
                {
                    returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(1246, MessageStatus.SUCCESS, returnedStatus, site);
                }
            }

            return(returnedStatus);
        }
 internal static bool WorkaroundFsCtlGetReparsePoint(BufferSize bufferSize, ReparseTag openFileReparseTag, bool isBytesReturnedSet, ref MessageStatus returnedStatus, ITestSite site)
 {
     if ((bufferSize == BufferSize.BufferSizeSuccess && openFileReparseTag == ReparseTag.NON_MICROSOFT_RANGE_TAG) ||
         (bufferSize == BufferSize.LessThanREPARSE_DATA_BUFFER && openFileReparseTag == ReparseTag.NON_MICROSOFT_RANGE_TAG) || (bufferSize == BufferSize.BufferSizeSuccess && openFileReparseTag == ReparseTag.IO_REPARSE_TAG_RESERVED_ZERO))
     {
         isBytesReturnedSet = FsaUtility.TransferExpectedResult <bool>(1091, true, isBytesReturnedSet, site);
         if (returnedStatus == MessageStatus.NOT_A_REPARSE_POINT)
         {
             // If the open file is not a reparse point, SMB2 server will return STATUS_NOT_A_REPARSE_POINT
             // This is acceptable in model and expect as STATUS_SUCCESS.
             returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(2853, MessageStatus.SUCCESS, returnedStatus, site);
         }
     }
     else if (openFileReparseTag == ReparseTag.EMPTY)
     {
         return(isBytesReturnedSet);
     }
     else if (((openFileReparseTag != ReparseTag.NON_MICROSOFT_RANGE_TAG) && (BufferSize.LessThanREPARSE_DATA_BUFFER == bufferSize)) ||
              ((openFileReparseTag == ReparseTag.NON_MICROSOFT_RANGE_TAG) && (BufferSize.LessThanREPARSE_GUID_DATA_BUFFER == bufferSize)))
     {
         returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(1083, MessageStatus.BUFFER_TOO_SMALL, returnedStatus, site);
     }
     else if (bufferSize == BufferSize.LessThanREPARSE_GUID_DATA_BUFFER && openFileReparseTag == ReparseTag.IO_REPARSE_TAG_RESERVED_ZERO)
     {
         isBytesReturnedSet = FsaUtility.TransferExpectedResult <bool>(1091, true, isBytesReturnedSet, site);
     }
     return(isBytesReturnedSet);
 }
示例#4
0
        /// <summary>
        /// Get a reparse buffer from a byte array.
        /// </summary>
        /// <param name="ba">The byte array to parse</param>
        /// <returns>The reparse buffer.</returns>
        public static ReparseBuffer FromByteArray(byte[] ba)
        {
            BinaryReader reader      = new BinaryReader(new MemoryStream(ba), Encoding.Unicode);
            ReparseTag   tag         = (ReparseTag)reader.ReadUInt32();
            int          data_length = reader.ReadUInt16();

            // Reserved
            reader.ReadUInt16();

            ReparseBuffer buffer = null;

            long remaining_length = reader.RemainingLength();
            long expected_length  = data_length;

            if (!NtFileUtils.IsReparseTagMicrosoft(tag))
            {
                expected_length += 16;
            }

            if (remaining_length != expected_length)
            {
                // Corrupted buffer. Return an opaque buffer with all the data until the end.
                return(new OpaqueReparseBuffer(tag, reader.ReadToEnd()));
            }

            switch (tag)
            {
            case ReparseTag.MOUNT_POINT:
                buffer = new MountPointReparseBuffer();
                break;

            case ReparseTag.SYMLINK:
                buffer = new SymlinkReparseBuffer(false);
                break;

            case ReparseTag.GLOBAL_REPARSE:
                buffer = new SymlinkReparseBuffer(true);
                break;

            case ReparseTag.APPEXECLINK:
                buffer = new ExecutionAliasReparseBuffer();
                break;

            default:
                if (NtFileUtils.IsReparseTagMicrosoft(tag))
                {
                    buffer = new OpaqueReparseBuffer(tag);
                }
                else
                {
                    buffer = new GenericReparseBuffer(tag);
                }
                break;
            }

            buffer.ParseBuffer(data_length, reader);
            return(buffer);
        }
 internal static bool WorkAroundFsCtlGetReparsePoint(BufferSize bufferSize, ReparseTag openFileReparseTag, bool isBytesReturnedSet, ITestSite site)
 {
     if (!((openFileReparseTag == ReparseTag.EMPTY) ||
           ((openFileReparseTag != ReparseTag.NON_MICROSOFT_RANGE_TAG) && (BufferSize.LessThanREPARSE_DATA_BUFFER == bufferSize)) ||
           ((openFileReparseTag == ReparseTag.NON_MICROSOFT_RANGE_TAG) && (BufferSize.LessThanREPARSE_GUID_DATA_BUFFER == bufferSize))))
     {
         isBytesReturnedSet = FsaUtility.TransferExpectedResult <bool>(1091, true, isBytesReturnedSet, site);
     }
     return(isBytesReturnedSet);
 }
示例#6
0
        public static ReparseBuffer FromByteArray(byte[] ba, bool opaque_buffer)
        {
            BinaryReader reader      = new BinaryReader(new MemoryStream(ba), Encoding.Unicode);
            ReparseTag   tag         = (ReparseTag)reader.ReadUInt32();
            int          data_length = reader.ReadUInt16();

            // Reserved
            reader.ReadUInt16();

            ReparseBuffer buffer = null;

            if (data_length != reader.RemainingLength())
            {
                // Possibly corrupted. Return an opaque buffer with all the data until the end.
                return(new OpaqueReparseBuffer(tag, reader.ReadToEnd()));
            }

            switch (tag)
            {
            case ReparseTag.MOUNT_POINT:
                buffer = new MountPointReparseBuffer();
                break;

            case ReparseTag.SYMLINK:
                buffer = new SymlinkReparseBuffer(false);
                break;

            case ReparseTag.GLOBAL_REPARSE:
                buffer = new SymlinkReparseBuffer(true);
                break;

            case ReparseTag.APPEXECLINK:
                buffer = new ExecutionAliasReparseBuffer();
                break;

            case ReparseTag.AF_UNIX:
                buffer = new OpaqueReparseBuffer(ReparseTag.AF_UNIX);
                break;

            default:
                if (opaque_buffer || reader.RemainingLength() < 16)
                {
                    buffer = new OpaqueReparseBuffer(tag);
                }
                else
                {
                    buffer = new GenericReparseBuffer(tag);
                }
                break;
            }

            buffer.ParseBuffer(data_length, reader);
            return(buffer);
        }
示例#7
0
        /// <summary>
        /// Gets reparse point names for symbolic links and mount points.
        /// </summary>
        /// <param name="fileHandle">Handle for the reparse point, must be opened with <see cref="FileAccessRights.ReadExtendedAttributes"/>.</param>
        public unsafe static (string printName, string substituteName, ReparseTag tag) GetReparsePointNames(SafeFileHandle fileHandle)
        {
            return(BufferHelper.BufferInvoke((HeapBuffer buffer) =>
            {
                ControlCode controlCode = ControlCodes.FileSystem.GetReparsePoint;
                buffer.EnsureByteCapacity(1024);

                while (!Imports.DeviceIoControl(
                           hDevice: fileHandle,
                           dwIoControlCode: controlCode,
                           lpInBuffer: null,
                           nInBufferSize: 0,
                           lpOutBuffer: buffer.VoidPointer,
                           nOutBufferSize: checked ((uint)buffer.ByteCapacity),
                           lpBytesReturned: out _,
                           lpOverlapped: null))
                {
                    WindowsError error = Errors.GetLastError();
                    switch (error)
                    {
                    case WindowsError.ERROR_SUCCESS:
                        // This can happen if the handle isn't a reparse point.
                        break;

                    case WindowsError.ERROR_MORE_DATA:
                        buffer.EnsureByteCapacity(buffer.ByteCapacity + 1024);
                        break;

                    default:
                        throw Errors.GetIoExceptionForError(error);
                    }
                }

                ReparseTag reparseTag = ((REPARSE_DATA_BUFFER *)buffer.VoidPointer)->ReparseTag;

                string printName = null;
                string substitutename = null;

                if (reparseTag == ReparseTag.MountPoint)
                {
                    printName = ((REPARSE_DATA_BUFFER *)buffer.VoidPointer)->MountPointData.PrintName.CreateString();
                    substitutename = ((REPARSE_DATA_BUFFER *)buffer.VoidPointer)->MountPointData.SubstituteName.CreateString();
                }
                else if (reparseTag == ReparseTag.SymbolicLink)
                {
                    printName = ((REPARSE_DATA_BUFFER *)buffer.VoidPointer)->SymbolicLinkData.PrintName.CreateString();
                    substitutename = ((REPARSE_DATA_BUFFER *)buffer.VoidPointer)->SymbolicLinkData.SubstituteName.CreateString();
                }

                return (printName, substitutename, reparseTag);
            }));
        }
示例#8
0
        /// <summary>
        /// Get a reparse buffer from a byte array.
        /// </summary>
        /// <param name="ba">The byte array to parse</param>
        /// <param name="opaque_buffer">True to return an opaque buffer if
        /// the tag isn't known, otherwise try and parse as a generic buffer</param>
        /// <returns>The reparse buffer.</returns>
        public static ReparseBuffer FromByteArray(byte[] ba, bool opaque_buffer)
        {
            BinaryReader reader      = new BinaryReader(new MemoryStream(ba), Encoding.Unicode);
            ReparseTag   tag         = (ReparseTag)reader.ReadUInt32();
            int          data_length = reader.ReadUInt16();

            // Reserved
            reader.ReadUInt16();

            ReparseBuffer buffer = null;

            switch (tag)
            {
            case ReparseTag.MOUNT_POINT:
                buffer = new MountPointReparseBuffer();
                break;

            case ReparseTag.SYMLINK:
                buffer = new SymlinkReparseBuffer(false);
                break;

            case ReparseTag.GLOBAL_REPARSE:
                buffer = new SymlinkReparseBuffer(true);
                break;

            case ReparseTag.APPEXECLINK:
                buffer = new ExecutionAliasReparseBuffer();
                break;

            case ReparseTag.AFUNIX:
                buffer = new OpaqueReparseBuffer(ReparseTag.AFUNIX);
                break;

            default:
                if (opaque_buffer)
                {
                    buffer = new OpaqueReparseBuffer(tag);
                }
                else
                {
                    buffer = new GenericReparseBuffer(tag);
                }
                break;
            }

            buffer.ParseBuffer(data_length, reader);
            return(buffer);
        }
示例#9
0
        /// <summary>
        /// Convert reparse buffer to a byte array in the REPARSE_DATA_BUFFER_EX format.
        /// </summary>
        /// <param name="flags">Flags for the buffer.</param>
        /// <param name="existing_guid">Existing GUID to match against.</param>
        /// <param name="existing_tag">Existing tag to matcha against.</param>
        /// <returns>The reparse buffer as a byte array.</returns>
        public byte[] ToByteArray(ReparseBufferExFlags flags, ReparseTag existing_tag, Guid existing_guid)
        {
            MemoryStream stm    = new MemoryStream();
            BinaryWriter writer = new BinaryWriter(stm);

            // Flags.
            writer.Write((int)flags);
            // Existing tag.
            writer.Write((uint)existing_tag);
            // Existing GUID for non-Microsoft tags.
            writer.Write(existing_guid.ToByteArray());
            // Reserved (64 bit)
            writer.Write(0L);
            // The original reparse buffer.
            writer.Write(ToByteArray());
            return(stm.ToArray());
        }
示例#10
0
 static FileData GetFileData(NtFile volume, ReparseTag tag, long fileid)
 {
     using (var file = NtFile.OpenFileById(volume, fileid, FileAccessRights.ReadAttributes | FileAccessRights.Synchronize,
                                           FileShareMode.None, FileOpenOptions.OpenReparsePoint | FileOpenOptions.SynchronousIoNonAlert | FileOpenOptions.OpenForBackupIntent))
     {
         var           filename = file.GetWin32PathName(NtApiDotNet.Win32.Win32PathNameFlags.None, false).GetResultOrDefault(fileid.ToString());
         ReparseBuffer reparse  = new OpaqueReparseBuffer(tag, new byte[0]);
         try
         {
             reparse = file.GetReparsePoint();
         }
         catch (NtException)
         {
         }
         return(new FileData()
         {
             FileName = filename,
             Reparse = reparse
         });
     }
 }
 internal static MessageStatus WorkaroundFsCtlDeleteReparsePoint(ReparseTag reparseTag, bool reparseGuidEqualOpenGuid, MessageStatus returnedStatus, ITestSite site)
 {
     if (reparseTag == ReparseTag.EMPTY && reparseGuidEqualOpenGuid)
     {
         returnedStatus = FsaUtility.TransferExpectedResult<MessageStatus>(5001, MessageStatus.SUCCESS, returnedStatus, site);
     }
     else if (reparseTag == ReparseTag.IO_REPARSE_TAG_RESERVED_ONE || reparseTag == ReparseTag.IO_REPARSE_TAG_RESERVED_ZERO)
     {
         returnedStatus = FsaUtility.TransferExpectedResult<MessageStatus>(2437, MessageStatus.IO_REPARSE_TAG_INVALID, returnedStatus, site);
     }
     else if ((reparseTag == ReparseTag.NON_MICROSOFT_RANGE_TAG) && (!reparseGuidEqualOpenGuid))
     {
         returnedStatus = FsaUtility.TransferExpectedResult<MessageStatus>(990, MessageStatus.REPARSE_ATTRIBUTE_CONFLICT, returnedStatus, site);
     }
     else if (reparseTag == ReparseTag.NON_MICROSOFT_RANGE_TAG && reparseGuidEqualOpenGuid)
     {
         returnedStatus = FsaUtility.TransferExpectedResult<MessageStatus>(1257, MessageStatus.IO_REPARSE_DATA_INVALID, returnedStatus, site);
     }
     else if (reparseTag == ReparseTag.NotEqualOpenFileReparseTag)
     {
         returnedStatus = FsaUtility.TransferExpectedResult<MessageStatus>(989, MessageStatus.IO_REPARSE_TAG_MISMATCH, returnedStatus, site);
     }
     return returnedStatus;
 }
示例#12
0
 /// <summary>
 /// Get if a reparse tag is a Microsoft defined one.
 /// </summary>
 /// <param name="tag">The reparse tag.</param>
 /// <returns>True if it's a Microsoft reparse tag.</returns>
 public static bool IsReparseTagMicrosoft(ReparseTag tag)
 {
     return(((uint)tag & 0x80000000) != 0);
 }
示例#13
0
 internal OpaqueReparseBuffer(ReparseTag tag) : base(tag)
 {
 }
示例#14
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="tag">The reparse tag.</param>
 /// <param name="data">The opaque data blob.</param>
 public OpaqueReparseBuffer(ReparseTag tag, byte[] data) : base(tag)
 {
     Data = (byte[])data.Clone();
 }
示例#15
0
 internal GenericReparseBuffer(ReparseTag tag) : base(tag)
 {
 }
示例#16
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="tag">The reparse tag.</param>
 /// <param name="guid">The reparse GUID</param>
 /// <param name="data">Additional reparse data.</param>
 public GenericReparseBuffer(ReparseTag tag, Guid guid, byte[] data) : base(tag)
 {
     Data = (byte[])data.Clone();
     Guid = guid;
 }
示例#17
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="tag">The reparse tag to assign.</param>
 protected ReparseBuffer(ReparseTag tag)
 {
     Tag = tag;
 }
示例#18
0
 /// <summary>
 /// Returns true if the given tag is a name surrogate.
 /// </summary>
 public static bool IsReparseTagNameSurrogate(ReparseTag reparseTag)
 {
     // https://msdn.microsoft.com/en-us/library/windows/hardware/ff549462.aspx
     return(((uint)reparseTag & 0x20000000) != 0);
 }
 internal static MessageStatus WorkAroundFsCtlGetReparsePointStatus(BufferSize bufferSize, ReparseTag openFileReparseTag, MessageStatus returnedStatus, ITestSite site)
 {
     if (openFileReparseTag == ReparseTag.EMPTY)
     {
         return(returnedStatus);
     }
     else if ((openFileReparseTag != ReparseTag.NON_MICROSOFT_RANGE_TAG) && (BufferSize.LessThanREPARSE_DATA_BUFFER == bufferSize))
     {
         returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(1080, MessageStatus.BUFFER_TOO_SMALL, returnedStatus, site);
     }
     else if ((openFileReparseTag == ReparseTag.NON_MICROSOFT_RANGE_TAG) && (BufferSize.LessThanREPARSE_GUID_DATA_BUFFER == bufferSize))
     {
         returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(1083, MessageStatus.BUFFER_TOO_SMALL, returnedStatus, site);
     }
     else if (returnedStatus == MessageStatus.NOT_A_REPARSE_POINT &&
              (bufferSize == BufferSize.BufferSizeSuccess || (bufferSize == BufferSize.LessThanREPARSE_DATA_BUFFER && openFileReparseTag == ReparseTag.NON_MICROSOFT_RANGE_TAG)))
     {
         // If the open file is not a reparse point, SMB server will return STATUS_NOT_A_REPARSE_POINT
         // This is acceptable in model and expect as STATUS_SUCCESS.
         returnedStatus = FsaUtility.TransferExpectedResult <MessageStatus>(2853, MessageStatus.SUCCESS, returnedStatus, site);
     }
     return(returnedStatus);
 }
        public static MessageStatus FsCtlSetReparsePoint(
            ReparseTag inputReparseTag,
            BufferSize bufferSize,
            bool isReparseGUIDNotEqual,
            bool isFileReparseTagNotEqualInputBufferReparseTag
            )
        {
            Condition.IsTrue(bufferSize == BufferSize.LessThan8Bytes ||
                               bufferSize == BufferSize.NotEqualReparseDataLengthPlus24 ||
                               bufferSize == BufferSize.NotEqualReparseDataLengthPlus8 ||
                               bufferSize == BufferSize.BufferSizeSuccess);

            Condition.IsTrue(inputReparseTag == ReparseTag.MOUNT_POINT ||
                               inputReparseTag == ReparseTag.SYMLINK ||
                               inputReparseTag == ReparseTag.IO_REPARSE_TAG_RESERVED_ZERO ||
                               inputReparseTag == ReparseTag.NON_MICROSOFT_RANGE_TAG ||
                               inputReparseTag == ReparseTag.EMPTY);

            if (!isObjectImplementedFunctionality)
            {
                Helper.CaptureRequirement(4331, @"[ In FSCTL_SET_REPARSE_POINT] If the object store does not implement this functionality,
                    the operation MUST be failed with STATUS_INVALID_DEVICE_REQUEST.<46>");
                return MessageStatus.INVALID_DEVICE_REQUEST;
            }

            if (!isReparsePointsSupportedTrue)
            {
                Helper.CaptureRequirement(4332, @"[ In FSCTL_SET_REPARSE_POINT,Pseudocode for the operation is as follows:]
                    If Open.File.Volume.IsReparsePointsSupported is FALSE, the operation MUST be failed with STATUS_VOLUME_NOT_UPGRADED.");
                return MessageStatus.STATUS_VOLUME_NOT_UPGRADED;
            }

            if (bufferSize == BufferSize.LessThan8Bytes)
            {
                Helper.CaptureRequirement(1226, @"[ In FSCTL_SET_REPARSE_POINT,Pseudocode for the operation is as follows:]
                    If InputBufferSize is smaller than 8 bytes, the operation MUST be failed with STATUS_IO_REPARSE_DATA_INVALID.");
                return MessageStatus.IO_REPARSE_DATA_INVALID;
            }

            if (bufferSize == BufferSize.NotEqualReparseDataLengthPlus8 && bufferSize == BufferSize.NotEqualReparseDataLengthPlus24)
            {
                Helper.CaptureRequirement(1229, @"[ In FSCTL_SET_REPARSE_POINT,Pseudocode for the operation is as follows:]
                    If (InputBufferSize != InputBuffer.ReparseDataLength + 8) && (InputBufferSize != InputBuffer.ReparseDataLength + 24),
                    the operation MUST be failed with STATUS_IO_REPARSE_DATA_INVALID.");
                return MessageStatus.IO_REPARSE_DATA_INVALID;
            }

            //If InputBuffer.ReparseTag == IO_REPARSE_TAG_SYMLINK and Open.HasCreateSymLinkPrivilege
            //is FALSE
            if ((inputReparseTag == ReparseTag.SYMLINK) && (!isHasCreateSymbolicLinkAccessTrue))
            {
                Helper.CaptureRequirement(1231, @"[ In FSCTL_SET_REPARSE_POINT,Pseudocode for the operation is as follows:]
                    If InputBuffer.ReparseTag == IO_REPARSE_TAG_SYMLINK and Open.HasCreateSymbolicLinkAccess is FALSE,
                    the operation MUST be failed with STATUS_ACCESS_DENIED.");
                return MessageStatus.ACCESS_DENIED;
            }

            //If Open.File.ReparseTag is not empty (indicating that a reparse point is already assigned)
            if (inputReparseTag != ReparseTag.EMPTY)
            {
                //If Open.File.ReparseTag != InputBuffer.ReparseTag
                if (isFileReparseTagNotEqualInputBufferReparseTag)
                {
                    Helper.CaptureRequirement(1237, @"[ In FSCTL_SET_REPARSE_POINT,Pseudocode for the operation is as follows:
                        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.");
                    return MessageStatus.IO_REPARSE_TAG_MISMATCH;
                }

                //If Open.File.ReparseTag is a non-Microsoft tag && Open.File.ReparseGUID is not equal
                //to InputBuffer.ReparseGUID
                if ((inputReparseTag == ReparseTag.NON_MICROSOFT_RANGE_TAG) && (!isReparseGUIDNotEqual))
                {
                    Helper.CaptureRequirement(1238, @"[ In FSCTL_SET_REPARSE_POINT,Pseudocode for the operation is as follows:
                        Phase 2 -- Update the File]If Open.File.ReparseTag is not empty (indicating that a reparse point is already assigned)
                        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.");
                    return MessageStatus.REPARSE_ATTRIBUTE_CONFLICT;
                }
            }

            Helper.CaptureRequirement(1222, @"[ In FSCTL_SET_REPARSE_POINT]On completion, the object store MUST return:Status:
                 An NTSTATUS code that specifies the result.");
            Helper.CaptureRequirement(1246, @"[In FSCTL_SET_SHORT_NAME_BEHAVIOR]the object store MUST return STATUS_INVALID_DEVICE_REQUEST.");
            return MessageStatus.SUCCESS;
        }
        internal static MessageStatus WorkaroundFsCtlSetReparsePoint(ReparseTag inputReparseTag, BufferSize bufferSize, bool isReparseGUIDNotEqual, bool isFileReparseTagNotEqualInputBufferReparseTag, MessageStatus returnedStatus, ITestSite site)
        {
            if ((inputReparseTag == ReparseTag.SYMLINK))
            {
                returnedStatus = FsaUtility.TransferExpectedResult<MessageStatus>(1231, MessageStatus.ACCESS_DENIED, returnedStatus, site);
            }
            else if (returnedStatus == MessageStatus.INVALID_PARAMETER)
            {
                if (inputReparseTag != ReparseTag.EMPTY)
                {
                    if (isFileReparseTagNotEqualInputBufferReparseTag)
                    {
                        returnedStatus = FsaUtility.TransferExpectedResult<MessageStatus>(1237, MessageStatus.IO_REPARSE_TAG_MISMATCH, returnedStatus, site);
                    }
                    else if ((inputReparseTag == ReparseTag.NON_MICROSOFT_RANGE_TAG) && (!isReparseGUIDNotEqual))
                    {
                        returnedStatus = FsaUtility.TransferExpectedResult<MessageStatus>(1238, MessageStatus.REPARSE_ATTRIBUTE_CONFLICT, returnedStatus, site);
                    }
                }
                else
                {
                    returnedStatus = FsaUtility.TransferExpectedResult<MessageStatus>(1246, MessageStatus.SUCCESS, returnedStatus, site);
                }
            }

            return returnedStatus;
        }
示例#22
0
 /// <summary>
 /// Get if a reparse tag is a name surrogate.
 /// </summary>
 /// <param name="tag">The reparse tag.</param>
 /// <returns>True if it's a surrogate reparse tag.</returns>
 public static bool IsReparseTagNameSurrogate(ReparseTag tag)
 {
     return(((uint)tag & 0x20000000) != 0);
 }
        public static MessageStatus FsCtlDeleteReparsePoint(
            ReparseTag reparseTag,
            bool reparseGuidEqualOpenGuid
            )
        {
            Condition.IsTrue(reparseTag == ReparseTag.IO_REPARSE_TAG_RESERVED_ONE || reparseTag == ReparseTag.IO_REPARSE_TAG_RESERVED_ZERO || reparseTag == ReparseTag.EMPTY || reparseTag == ReparseTag.NON_MICROSOFT_RANGE_TAG || reparseTag == ReparseTag.NotEqualOpenFileReparseTag);

            if (!isReparsePointsSupportedTrue)
            {
                Helper.CaptureRequirement(5000, @"[In FSCTL_DELETE_REPARSE_POINT,Pseudocode for the operation is as follows:
                    Phase 1 -- Verify the parameters.]
                    If Open.File.Volume.IsReparsePointsSupported is FALSE, the operation MUST be failed with STATUS_VOLUME_NOT_UPGRADED.");
                return MessageStatus.STATUS_VOLUME_NOT_UPGRADED;
            }

            if (!isObjectImplementedFunctionality)
            {
                Helper.CaptureRequirement(4999, @"[In FSCTL_DELETE_REPARSE_POINT] If the object store does not implement this functionality,
                    the operation MUST be failed with STATUS_INVALID_DEVICE_REQUEST.<21>");
                return MessageStatus.INVALID_DEVICE_REQUEST;
            }

            //If the ReparseTag is IO_REPARSE_TAG_RESERVED_ZERO,
            if (reparseTag == ReparseTag.IO_REPARSE_TAG_RESERVED_ONE)
            {
                Helper.CaptureRequirement(984, @"[In FSCTL_DELETE_REPARSE_POINT,Phase 1 - Verify the parameters.]
                    If the ReparseTag is IO_REPARSE_TAG_RESERVED_ZERO , the operation MUST be failed with STATUS_IO_REPARSE_TAG_INVALID.");
                return MessageStatus.IO_REPARSE_TAG_INVALID;
            }

            //If the ReparseTag is IO_REPARSE_TAG_RESERVED_ONE,
            if (reparseTag == ReparseTag.IO_REPARSE_TAG_RESERVED_ZERO)
            {
                Helper.CaptureRequirement(2437, @"[In FSCTL_DELETE_REPARSE_POINT,
                    Phase 1 -- Verify the parameters.]If the ReparseTag is IO_REPARSE_TAG_RESERVED_ONE,
                    the operation MUST be failed with STATUS_IO_REPARSE_TAG_INVALID.");
                return MessageStatus.IO_REPARSE_TAG_INVALID;
            }
            //If ReparseTag is a non-Microsoft Reparse Tag, then the ReparseGUID must be a valid GUID;
            //otherwise the operation MUST be failed with STATUS_IO_REPARSE_DATA_INVALID.
            if (reparseTag == ReparseTag.NON_MICROSOFT_RANGE_TAG && reparseGuidEqualOpenGuid)
            {
                Helper.CaptureRequirement(1257, @"[In FSCTL_DELETE_REPARSE_POINT,Pseudocode for the operation is as follows:
                    Phase 1 -- Verify the parameters.]otherwise[If ReparseTag is not a non-Microsoft Reparse Tag]
                    the operation MUST be failed with STATUS_IO_REPARSE_DATA_INVALID.");
                return MessageStatus.IO_REPARSE_DATA_INVALID;
            }
            if (reparseTag == ReparseTag.NotEqualOpenFileReparseTag)
            {
                Helper.CaptureRequirement(989, @"[In FSCTL_DELETE_REPARSE_POINT,Pseudocode for the operation is as follows:
                    Phase 2 -- Validate that the requested tag deletion type matches with the stored tag type.]
                    If (ReparseTag != Open.File.ReparseTag), the operation MUST be failed with STATUS_IO_REPARSE_TAG_MISMATCH.");
                return MessageStatus.IO_REPARSE_TAG_MISMATCH;
            }
            if ((reparseTag == ReparseTag.NON_MICROSOFT_RANGE_TAG) && (!reparseGuidEqualOpenGuid))
            {
                Helper.CaptureRequirement(990, @"[In FSCTL_DELETE_REPARSE_POINT,Pseudocode for the operation is as follows:
                    Phase 2 -- Validate that the requested tag deletion type matches with the stored tag type.]
                    If (ReparseTag is a non-Microsoft Reparse Tag && Open.File.ReparseGUID != ReparseGUID),
                    the operation MUST be failed with STATUS_REPARSE_ATTRIBUTE_CONFLICT.");
                return MessageStatus.REPARSE_ATTRIBUTE_CONFLICT;
            }
            Helper.CaptureRequirement(1254, @"[In FSCTL_DELETE_REPARSE_POINT]On completion, the object store MUST return:[Status].");
            Helper.CaptureRequirement(5001, @"[In FSCTL_DELETE_REPARSE_POINT,Pseudocode for the operation is as follows:]
                Upon successful completion of the operation, the object store MUST return:status set to STATUS_SUCCESS.");
            return MessageStatus.SUCCESS;
        }
        public static MessageStatus FsCtlGetReparsePoint(
            BufferSize bufferSize,
            ReparseTag openFileReparseTag,
            out bool isBytesReturnedSet
            )
        {
            Condition.IsTrue(bufferSize == BufferSize.LessThanREPARSE_DATA_BUFFER || bufferSize == BufferSize.LessThanREPARSE_GUID_DATA_BUFFER || bufferSize == BufferSize.BufferSizeSuccess);
            Condition.IsTrue(openFileReparseTag == ReparseTag.EMPTY ||
                               openFileReparseTag == ReparseTag.NON_MICROSOFT_RANGE_TAG ||
                               openFileReparseTag == ReparseTag.Initialize);
            isBytesReturnedSet = false;

            if (!isObjectImplementedFunctionality)
            {
                Helper.CaptureRequirement(5039, @"[In FSCTL_GET_REPARSE_POINT] If the object store does not implement this functionality,
                    the operation MUST be failed with STATUS_INVALID_DEVICE_REQUEST.<30>");
                return MessageStatus.INVALID_DEVICE_REQUEST;
            }

            if (!isReparsePointsSupportedTrue)
            {
                Helper.CaptureRequirement(5040, @"[In FSCTL_GET_REPARSE_POINT] Pseudocode for the operation is as follows:
                    If Open.File.Volume.IsReparsePointsSupported is FALSE, the operation MUST be failed with STATUS_VOLUME_NOT_UPGRADED.");
                return MessageStatus.STATUS_VOLUME_NOT_UPGRADED;
            }
            //    If Open.File.ReparseTag is empty
            if (openFileReparseTag == ReparseTag.EMPTY)
            {
                Helper.CaptureRequirement(1077, @"[In FSCTL_GET_REPARSE_POINT,Pseudocode for the operation is as follows:
                    Phase 1 : Check whether there is a reparse point on the File]If Open.File.ReparseTag is empty,
                    the operation MUST be failed with STATUS_NOT_A_REPARSE_POINT.");
                return MessageStatus.NOT_A_REPARSE_POINT;
            }

            //Verify that OutputBufferSize is large enough to contain the reparse point data header
            //If Open.File.ReparseTag is a Microsoft reparse tag as defined in [MS-FSCC] section 2.1.2.1
            //If OutputBufferSize is small than the size of REPARSE_DATA_BUFFER
            if ((openFileReparseTag != ReparseTag.NON_MICROSOFT_RANGE_TAG) && (BufferSize.LessThanREPARSE_DATA_BUFFER == bufferSize))
            {
                Helper.CaptureRequirement(1080, @"[In FSCTL_GET_REPARSE_POINT,Pseudocode for the operation is as follows:
                Phase 2 - Verify that OutputBufferSize is large enough to contain the reparse point data header.]
                If it[ Open.File.ReparseTag] is not, the operation MUST be failed with STATUS_BUFFER_TOO_SMALL.");
                return MessageStatus.BUFFER_TOO_SMALL;
            }

            //If Open.File.ReparseTag is a non-Microsoft reparse tag
            //If OutputBufferSize is small than the size of REPARSE_GUID_DATA_BUFFER
            if ((openFileReparseTag == ReparseTag.NON_MICROSOFT_RANGE_TAG) && (BufferSize.LessThanREPARSE_GUID_DATA_BUFFER == bufferSize))
            {
                Helper.CaptureRequirement(1083, @"[In FSCTL_GET_REPARSE_POINT,Pseudocode for the operation is as follows:
                    Phase 2 : Verify that OutputBufferSize is large enough to contain the reparse point data header.]
                    If it[Open.File.ReparseTag] is not, the operation MUST be failed with STATUS_BUFFER TOO_SMALL.");
                return MessageStatus.BUFFER_TOO_SMALL;
            }

            isBytesReturnedSet = true;
            Helper.CaptureRequirement(1090, @"[In FSCTL_GET_REPARSE_POINT,Pseudocode for the operation is as follows:
                Phase 3 : Return the reparse data]Upon successful completion of the operation, the object store MUST return:BytesReturned set to the number of bytes written to OutputBuffer.");
            Helper.CaptureRequirement(1073, @"[In FSCTL_GET_REPARSE_POINT]On completion, the object store MUST return:[OutputBuffer ,BytesCopied,Status ].");
            Helper.CaptureRequirement(1091, @"[In FSCTL_GET_REPARSE_POINT,Pseudocode for the operation is as follows:Phase 3 : Return the reparse data]Upon successful completion of the operation, the object store MUST return:Status set to STATUS_SUCCESS.");
            return MessageStatus.SUCCESS;
        }
示例#25
0
 /// <summary>
 /// Get if a reparse tag is a directory which can have children.
 /// </summary>
 /// <param name="tag">The reparse tag.</param>
 /// <returns>True if it's a directory reparse tag which can have children.</returns>
 public static bool IsReparseTagDirectory(ReparseTag tag)
 {
     return(((uint)tag & 0x10000000) != 0);
 }
 internal static bool WorkaroundFsCtlGetReparsePoint(BufferSize bufferSize, ReparseTag openFileReparseTag, bool isBytesReturnedSet, ref MessageStatus returnedStatus, ITestSite site)
 {
     if ((bufferSize == BufferSize.BufferSizeSuccess && openFileReparseTag == ReparseTag.NON_MICROSOFT_RANGE_TAG) ||
         (bufferSize == BufferSize.LessThanREPARSE_DATA_BUFFER && openFileReparseTag == ReparseTag.NON_MICROSOFT_RANGE_TAG) || (bufferSize == BufferSize.BufferSizeSuccess && openFileReparseTag == ReparseTag.IO_REPARSE_TAG_RESERVED_ZERO))
     {
         isBytesReturnedSet = FsaUtility.TransferExpectedResult<bool>(1091, true, isBytesReturnedSet, site);
         if (returnedStatus == MessageStatus.NOT_A_REPARSE_POINT)
         {
             // If the open file is not a reparse point, SMB2 server will return STATUS_NOT_A_REPARSE_POINT
             // This is acceptable in model and expect as STATUS_SUCCESS.
             returnedStatus = FsaUtility.TransferExpectedResult<MessageStatus>(2853, MessageStatus.SUCCESS, returnedStatus, site);
         }
     }
     else if (openFileReparseTag == ReparseTag.EMPTY)
     {
         return isBytesReturnedSet;
     }
     else if (((openFileReparseTag != ReparseTag.NON_MICROSOFT_RANGE_TAG) && (BufferSize.LessThanREPARSE_DATA_BUFFER == bufferSize)) ||
         ((openFileReparseTag == ReparseTag.NON_MICROSOFT_RANGE_TAG) && (BufferSize.LessThanREPARSE_GUID_DATA_BUFFER == bufferSize)))
     {
         returnedStatus = FsaUtility.TransferExpectedResult<MessageStatus>(1083, MessageStatus.BUFFER_TOO_SMALL, returnedStatus, site);
     }
     else if (bufferSize == BufferSize.LessThanREPARSE_GUID_DATA_BUFFER && openFileReparseTag == ReparseTag.IO_REPARSE_TAG_RESERVED_ZERO)
     {
         isBytesReturnedSet = FsaUtility.TransferExpectedResult<bool>(1091, true, isBytesReturnedSet, site);
     }
     return isBytesReturnedSet;
 }