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); }
/// <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); }
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); }
/// <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); })); }
/// <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); }
/// <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()); }
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; }
/// <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); }
internal OpaqueReparseBuffer(ReparseTag tag) : base(tag) { }
/// <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(); }
internal GenericReparseBuffer(ReparseTag tag) : base(tag) { }
/// <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; }
/// <summary> /// Constructor. /// </summary> /// <param name="tag">The reparse tag to assign.</param> protected ReparseBuffer(ReparseTag tag) { Tag = tag; }
/// <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; }
/// <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; }
/// <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; }