Exemplo n.º 1
0
 public ModelReplayFileOperationRequest(ModelReplayChannel channel,
                                        ReplayModelSwitchChannelType switchChannelType,
                                        ModelDialectRevision maxSmbVersionClientSupported,
                                        ReplayModelRequestCommand requestCommand,
                                        ReplayModelChannelSequenceType channelSequence,
                                        ReplayModelSetReplayFlag isSetReplayFlag,
                                        ReplayModelRequestCommandParameters requestCommandParameters
                                        )
     : base(0)
 {
     this.channel                  = channel;
     this.switchChannelType        = switchChannelType;
     this.requestCommand           = requestCommand;
     this.channelSequence          = channelSequence;
     this.isSetReplayFlag          = isSetReplayFlag;
     this.requestCommandParameters = requestCommandParameters;
 }
 public ModelReplayFileOperationRequest(ModelReplayChannel channel,
     ReplayModelSwitchChannelType switchChannelType,
     ModelDialectRevision maxSmbVersionClientSupported,
     ReplayModelRequestCommand requestCommand,
     ReplayModelChannelSequenceType channelSequence,
     ReplayModelSetReplayFlag isSetReplayFlag,
     ReplayModelRequestCommandParameters requestCommandParameters
     )
     : base(0)
 {
     this.channel = channel;
     this.switchChannelType = switchChannelType;
     this.requestCommand = requestCommand;
     this.channelSequence = channelSequence;
     this.isSetReplayFlag = isSetReplayFlag;
     this.requestCommandParameters = requestCommandParameters;
 }
        public void FileOperationRequest(
            ReplayModelSwitchChannelType switchChannelType,
            ModelDialectRevision maxSmbVersionClientSupported,
            ReplayModelRequestCommand requestCommand,
            ReplayModelChannelSequenceType channelSequence,
            ReplayModelSetReplayFlag isReplay,
            ReplayModelRequestCommandParameters requestCommandParameters)
        {
            if (requestCommand == ReplayModelRequestCommand.IoCtl)
            {
                testConfig.CheckIOCTL(CtlCode_Values.FSCTL_LMR_REQUEST_RESILIENCY);
            }

            uint status = Smb2Status.STATUS_SUCCESS;
            Smb2FunctionalClient client = null;

            #region Switch channel
            switch (switchChannelType)
            {
            case ReplayModelSwitchChannelType.MainChannel:
                if (smb2ClientMainChannel == null)
                {
                    InitializeMainChannel(
                        maxSmbVersionClientSupported,
                        clientGuidMainChannel,
                        ReplayModelShareType.NonCAShare,
                        out treeIdMainChannel);

                    #region Create
                    Smb2CreateContextResponse[] serverCreateContexts = null;

                    status = smb2ClientMainChannel.Create(
                        treeIdMainChannel,
                        fileNameMainChannel,
                        CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                        out fileIdMainChannel,
                        out serverCreateContexts,
                        RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                        null,
                        shareAccess: ShareAccess_Values.NONE);
                    #endregion
                }
                client = smb2ClientMainChannel;
                break;

            case ReplayModelSwitchChannelType.AlternativeChannelWithMainChannel:
                InitializeAlternativeChannel(
                    clientGuidMainChannel,
                    treeIdMainChannel);
                client = smb2ClientAlternativeChannel;
                break;

            case ReplayModelSwitchChannelType.AlternativeChannelWithDisconnectMainChannel:
                InitializeAlternativeChannel(
                    clientGuidMainChannel,
                    treeIdMainChannel);
                smb2ClientMainChannel.Disconnect();
                smb2ClientMainChannel = null;
                client = smb2ClientAlternativeChannel;
                break;

            case ReplayModelSwitchChannelType.MainChannelWithAlternativeChannel:
                InitializeAlternativeChannel(
                    clientGuidMainChannel,
                    treeIdMainChannel);
                client = smb2ClientMainChannel;
                break;

            default:
                Site.Assume.Fail("Unknown ReplayModelSwitchChannelType {0}.", switchChannelType);
                break;
            }
            #endregion

            #region Prepare data for read
            if (switchChannelType == ReplayModelSwitchChannelType.MainChannel && !prepared && requestCommand == ReplayModelRequestCommand.Read)
            {
                status = smb2ClientMainChannel.Write(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    writeContent);
            }
            #endregion

            FillChannelSequence(client, channelSequence);

            if (requestCommand == ReplayModelRequestCommand.Write)
            {
                #region Write
                status = client.Write(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    requestCommandParameters == ReplayModelRequestCommandParameters.DefaultParameters ? writeContent : Smb2Utility.CreateRandomString(testConfig.WriteBufferLengthInKb),
                    checker: (header, response) =>
                {
                },
                    isReplay: isReplay == ReplayModelSetReplayFlag.WithReplayFlag);
                #endregion
            }
            else if (requestCommand == ReplayModelRequestCommand.SetInfo)
            {
                #region SetInfo
                if (requestCommandParameters == ReplayModelRequestCommandParameters.AlternativeParameters)
                {
                    endOfFileInformation.EndOfFile = 512;
                }
                byte[] buffer = TypeMarshal.ToBytes <FileEndOfFileInformation>(endOfFileInformation);

                status = client.SetFileAttributes(
                    treeIdMainChannel,
                    (byte)FileInformationClasses.FileEndOfFileInformation,
                    fileIdMainChannel,
                    buffer,
                    checker: (header, response) =>
                {
                },
                    isReplay: isReplay == ReplayModelSetReplayFlag.WithReplayFlag);
                #endregion
            }
            else if (requestCommand == ReplayModelRequestCommand.IoCtl)
            {
                #region IOCtl
                Packet_Header  ioCtlHeader;
                IOCTL_Response ioCtlResponse;
                byte[]         inputInResponse;
                byte[]         outputInResponse;
                status = client.ResiliencyRequest(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    (uint)(requestCommandParameters == ReplayModelRequestCommandParameters.DefaultParameters ? 0 : 2000),
                    (uint)Marshal.SizeOf(typeof(NETWORK_RESILIENCY_Request)),
                    out ioCtlHeader,
                    out ioCtlResponse,
                    out inputInResponse,
                    out outputInResponse,
                    checker: (header, response) =>
                {
                    // do nothing, skip the exception
                }
                    );
                #endregion
            }
            else if (requestCommand == ReplayModelRequestCommand.Read)
            {
                #region Read
                string data;
                status = client.Read(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    0,
                    requestCommandParameters == ReplayModelRequestCommandParameters.DefaultParameters ? (uint)testConfig.WriteBufferLengthInKb * 1024 : 512,
                    out data,
                    isReplay: isReplay == ReplayModelSetReplayFlag.WithReplayFlag);
                #endregion
            }

            FileOperationResponse((ModelSmb2Status)status, replayConfig);
        }
        public void PrepareFileOperation(
            ModelDialectRevision maxSmbVersionClientSupported,
            ReplayModelRequestCommand requestCommand)
        {
            if (requestCommand == ReplayModelRequestCommand.IoCtl)
            {
                testConfig.CheckIOCTL(CtlCode_Values.FSCTL_LMR_REQUEST_RESILIENCY);
            }

            InitializeMainChannel(
                maxSmbVersionClientSupported,
                clientGuidMainChannel,
                ReplayModelShareType.NonCAShare,
                out treeIdMainChannel);

            uint status = 0;

            #region Create
            Smb2CreateContextResponse[] serverCreateContexts = null;

            status = smb2ClientMainChannel.Create(
                treeIdMainChannel,
                fileNameMainChannel,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileIdMainChannel,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                null);
            #endregion

            if (requestCommand == ReplayModelRequestCommand.Write)
            {
                #region Write
                status = smb2ClientMainChannel.Write(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    writeContent);
                #endregion
            }
            else if (requestCommand == ReplayModelRequestCommand.SetInfo)
            {
                #region SetInfo
                byte[] buffer = TypeMarshal.ToBytes <FileEndOfFileInformation>(endOfFileInformation);

                status = smb2ClientMainChannel.SetFileAttributes(
                    treeIdMainChannel,
                    (byte)FileInformationClasses.FileEndOfFileInformation,
                    fileIdMainChannel,
                    buffer);
                #endregion
            }
            else if (requestCommand == ReplayModelRequestCommand.IoCtl)
            {
                #region IOCtl
                Packet_Header  ioCtlHeader;
                IOCTL_Response ioCtlResponse;
                byte[]         inputInResponse;
                byte[]         outputInResponse;
                status = smb2ClientMainChannel.ResiliencyRequest(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    0,
                    (uint)Marshal.SizeOf(typeof(NETWORK_RESILIENCY_Request)),
                    out ioCtlHeader,
                    out ioCtlResponse,
                    out inputInResponse,
                    out outputInResponse,
                    checker: (header, response) =>
                {
                    // do nothing, skip the exception
                }
                    );
                #endregion
            }
            else if (requestCommand == ReplayModelRequestCommand.Read)
            {
                #region Read
                #region Prepare data for read
                status = smb2ClientMainChannel.Write(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    writeContent);
                #endregion

                string data;
                status = smb2ClientMainChannel.Read(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    0,
                    (uint)testConfig.WriteBufferLengthInKb * 1024,
                    out data);
                #endregion
            }

            prepared = true;
        }
        public static void ReadConfigReturn(ReplayServerConfig c)
        {
            Condition.IsTrue(State == ModelState.Uninitialized);
            Condition.IsNotNull(c);

            Config = c;

            Open = null;
            LastOpen = null;
            MainChannel = null;
            AlternativeChannel = null;
            ModelRequestCommand = ReplayModelRequestCommand.NoRequest;

            State = ModelState.Initialized;
        }
        /// <summary>
        /// 3.3.4.1 Sending Any Outgoing Message
        /// </summary>
        /// <param name="requestCommand">Request command.</param>
        /// <param name="negotiateDialect">Negotiated dialect.</param>
        /// <param name="channelSequence">Session channel sequence.</param>
        private static void PostCheckChannelSequence(
            ReplayModelRequestCommand requestCommand,
            DialectRevision negotiateDialect,
            ReplayModelChannelSequenceType channelSequence)
        {
            //TODO: TD does not mention this
            if (requestCommand == ReplayModelRequestCommand.Create)
            {
                ModelHelper.Log(
                    LogType.TestInfo,
                    "If the command request does not include FileId, this section MUST be skipped");
                ModelHelper.Log(
                    LogType.TestInfo,
                    "Connection.Dialect is {0}, request command is {1}", negotiateDialect, requestCommand);

                return;
            }

            if (channelSequence == ReplayModelChannelSequenceType.DefaultChannelSequence)
            {
                ModelHelper.Log(
                    LogType.Requirement,
                    "3.3.4.1: For the command requests which include FileId, if Connection.Dialect belongs to the SMB 3.x dialect family and ChannelSequence is equal to Open.ChannelSequence," +
                    " the server MUST decrement Open.OutstandingRequestCount by 1. ");

                Open.OutstandingRequestCount -= 1;

                ModelHelper.Log(
                    LogType.TestInfo,
                    "Open.OutstandingRequestCount is {0} after decrement", Open.OutstandingRequestCount);
            }
            else
            {
                ModelHelper.Log(
                    LogType.Requirement,
                    "3.3.4.1: Otherwise, the server MUST decrement Open.OutstandingPreRequestCount by 1. ");

                Open.OutstandingPreRequestCount -= 1;

                ModelHelper.Log(
                    LogType.TestInfo,
                    "Open.OutstandingPreRequestCount is {0} after decrement", Open.OutstandingPreRequestCount);
            }
        }
        /// <summary>
        /// Handle session channel sequence after receiving request.
        /// 3.3.5.2.10   Verifying the Channel Sequence Number
        /// </summary>
        /// <param name="requestCommand">Request command.</param>
        /// <param name="negotiateDialect">Negotiated dialect.</param>
        /// <param name="channelSequence">Session channel sequence.</param>
        /// <param name="isSetReplayFlag">Indicates whether a replay flag is set or not.</param>
        /// <param name="status">The status that server returns.</param>
        /// <returns></returns>
        private static bool PreCheckChannelSequence(
            ReplayModelRequestCommand requestCommand,
            DialectRevision negotiateDialect,
            ref ReplayModelChannelSequenceType channelSequence,
            bool isSetReplayFlag,
            ModelSmb2Status status)
        {
            if (negotiateDialect == DialectRevision.Smb2002 || negotiateDialect == DialectRevision.Smb21 ||
                requestCommand == ReplayModelRequestCommand.Create)
            {
                ModelHelper.Log(
                    LogType.Requirement,
                    "3.3.5.2.10: If Connection.Dialect is equal to \"2.002\" or \"2.100\", or the command request does not include FileId," +
                    " this section MUST be skipped");
                ModelHelper.Log(
                    LogType.TestInfo,
                    "Connection.Dialect is {0}. The request command is {1}", negotiateDialect, requestCommand);
                ModelHelper.Log(LogType.TestTag, TestTag.Compatibility);
                return true;
            }

            if (!isSetReplayFlag)
            {
                ModelHelper.Log(
                    LogType.Requirement,
                    "3.3.5.2.10: If the SMB2_FLAGS_REPLAY_OPERATION bit is not set in the Flags field of the SMB2 Header:");
                ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedFields);

                if (channelSequence == ReplayModelChannelSequenceType.DefaultChannelSequence)
                {
                    ModelHelper.Log(
                        LogType.Requirement,
                        "If ChannelSequence in the SMB2 Header is equal to Open.ChannelSequence, the server MUST increment Open.OutstandingRequestCount by 1.");

                    Open.OutstandingRequestCount += 1;

                    ModelHelper.Log(
                        LogType.TestInfo,
                        "Open.OutstandingRequestCount is {0} after increment", Open.OutstandingRequestCount);
                }
                else if (channelSequence == ReplayModelChannelSequenceType.ChannelSequenceIncrementOne ||
                          channelSequence == ReplayModelChannelSequenceType.ChannelSequenceBoundaryValid)
                {
                    ModelHelper.Log(
                        LogType.Requirement,
                        "Otherwise, if the unsigned difference using 16-bit arithmetic between ChannelSequence and Open.ChannelSequence is less than or equal to 0x7FFF," +
                        " the server MUST increment Open.OutstandingPreRequestCount by Open.OutstandingRequestCount, and MUST set Open.OutstandingRequestCount to 1." +
                        " The server MUST set Open.ChannelSequence to ChannelSequence in the SMB2 Header");
                    ModelHelper.Log(
                        LogType.TestInfo,
                        "ChannelSequence is {0}", channelSequence);

                    Open.OutstandingPreRequestCount += Open.OutstandingRequestCount;
                    Open.OutstandingRequestCount = 1;
                    channelSequence = ReplayModelChannelSequenceType.DefaultChannelSequence;

                    ModelHelper.Log(
                        LogType.TestInfo,
                        "Open.OutstandingPreRequestCount is {0} after increment by Open.OutstandingRequestCount with value {1}",
                        Open.OutstandingPreRequestCount, Open.OutstandingRequestCount);
                }
                else
                {
                    if (requestCommand == ReplayModelRequestCommand.Write ||
                        requestCommand == ReplayModelRequestCommand.SetInfo ||
                        requestCommand == ReplayModelRequestCommand.IoCtl)
                    {
                        ModelHelper.Log(
                            LogType.Requirement,
                            "Otherwise, the server MUST fail SMB2 WRITE, SET_INFO, and IOCTL requests with STATUS_FILE_NOT_AVAILABLE");
                        ModelHelper.Log(
                            LogType.TestInfo,
                            "requestCommand is {0}", requestCommand);

                        Condition.IsTrue(status == ModelSmb2Status.STATUS_FILE_NOT_AVAILABLE);
                        return false;
                    }
                }
            }
            else
            {
                ModelHelper.Log(
                    LogType.Requirement,
                    "3.3.5.2.10: If the SMB2_FLAGS_REPLAY_OPERATION bit is set in the Flags field of the SMB2 Header:");

                if (channelSequence == ReplayModelChannelSequenceType.DefaultChannelSequence)
                {
                    ModelHelper.Log(
                        LogType.Requirement,
                        "If ChannelSequence in the SMB2 Header is equal to Open.ChannelSequence and the following:");

                    if (Open.OutstandingPreRequestCount == 0)
                    {
                        ModelHelper.Log(
                            LogType.Requirement,
                            "If ChannelSequence in the SMB2 Header is equal to Open.ChannelSequence and Open.OutstandingPreRequestCount is equal to zero, the server MUST increment Open.OutstandingRequestCount by 1");

                        Open.OutstandingRequestCount += 1;

                        ModelHelper.Log(
                            LogType.TestInfo,
                            "Open.OutstandingRequestCount is {0} after increment", Open.OutstandingRequestCount);
                    }
                }
                else if ((channelSequence == ReplayModelChannelSequenceType.ChannelSequenceIncrementOne ||
                          channelSequence == ReplayModelChannelSequenceType.ChannelSequenceBoundaryValid) &&
                         Open.OutstandingPreRequestCount == 0)
                {
                    ModelHelper.Log(
                        LogType.Requirement,
                        "Otherwise, if the unsigned difference using 16-bit arithmetic between ChannelSequence and Open.ChannelSequence is less than or equal to 0x7FFF and Open.OutstandingPreRequestCount is equal to zero," +
                        " the server MUST increment Open.OutstandingPreRequestCount by Open.OutstandingRequestCount and MUST set Open.OutstandingRequestCount to 1." +
                        " The server MUST set Open.ChannelSequence to ChannelSequence in the SMB2 Header.");

                    Open.OutstandingPreRequestCount += Open.OutstandingRequestCount;
                    Open.OutstandingRequestCount = 1;
                    channelSequence = ReplayModelChannelSequenceType.DefaultChannelSequence;

                    ModelHelper.Log(
                        LogType.TestInfo,
                        "Open.OutstandingPreRequestCount is {0} after increment by Open.OutstandingRequestCount with value {1}",
                        Open.OutstandingPreRequestCount, Open.OutstandingRequestCount);
                }
                else
                {
                    if (requestCommand == ReplayModelRequestCommand.Write ||
                        requestCommand == ReplayModelRequestCommand.SetInfo ||
                        requestCommand == ReplayModelRequestCommand.IoCtl)
                    {
                        ModelHelper.Log(
                            LogType.Requirement,
                            "Otherwise, the server MUST fail SMB2 WRITE, SET_INFO, and IOCTL requests with STATUS_FILE_NOT_AVAILABLE");
                        ModelHelper.Log(
                            LogType.TestInfo,
                            "requestCommand is {0}", requestCommand);
                        ModelHelper.Log(LogType.TestTag, TestTag.Compatibility);
                        Condition.IsTrue(status == ModelSmb2Status.STATUS_FILE_NOT_AVAILABLE);
                        return false;
                    }
                }
            }

            return true;
        }
        public static void FileOperationRequest(
            ReplayModelSwitchChannelType switchChannelType,
            ModelDialectRevision maxSmbVersionClientSupported,
            ReplayModelRequestCommand requestCommand,
            ReplayModelChannelSequenceType channelSequence,
            ReplayModelSetReplayFlag isSetReplayFlag,
            ReplayModelRequestCommandParameters requestCommandParameters)
        {
            Condition.IsNull(Request);
            Condition.IfThen(ModelRequestCommand != ReplayModelRequestCommand.NoRequest, ModelRequestCommand == requestCommand);
            Condition.IsTrue(requestCommand != ReplayModelRequestCommand.Create && requestCommand != ReplayModelRequestCommand.NoRequest);
            Condition.IsTrue(switchChannelType != ReplayModelSwitchChannelType.ReconnectMainChannel);

            Combination.NWise(2, switchChannelType, maxSmbVersionClientSupported, requestCommand, channelSequence, isSetReplayFlag, 
                requestCommandParameters);
            
            ModelReplayChannel channel = null;
            if (State == ModelState.Initialized)
            {
                Condition.IsTrue(switchChannelType == ReplayModelSwitchChannelType.MainChannel);
                Condition.IsTrue(requestCommandParameters == ReplayModelRequestCommandParameters.DefaultParameters);

                MainChannel =
                    new ModelReplayChannel(ModelHelper.DetermineNegotiateDialect(maxSmbVersionClientSupported,
                        Config.MaxSmbVersionSupported));

                Open = new ReplayOpen();
                channel = MainChannel;
            }
            else
            {
                Condition.IsNotNull(MainChannel);
                Condition.IsNotNull(Open);
                Condition.IsTrue(maxSmbVersionClientSupported == ModelUtility.GetModelDialectRevision(MainChannel.Connection_NegotiateDialect));

                if (switchChannelType == ReplayModelSwitchChannelType.MainChannel)
                {
                    channel = MainChannel;
                }
                else
                {
                    AlternativeChannel = new ModelReplayChannel(MainChannel.Connection_NegotiateDialect);
                    channel = AlternativeChannel;
                }
            }

            ModelReplayFileOperationRequest operationRequest = new ModelReplayFileOperationRequest(channel, switchChannelType, 
                maxSmbVersionClientSupported, requestCommand, channelSequence, isSetReplayFlag, requestCommandParameters);

            Request = operationRequest;

            State = ModelState.Connected;
        }
        public static void PrepareFileOperation(
            ModelDialectRevision maxSmbVersionClientSupported,
            ReplayModelRequestCommand requestCommand)
        {
            // Condition.IsTrue(maxSmbVersionClientSupported != ModelDialectRevision.Smb302);
            Condition.IsTrue(State == ModelState.Initialized);
            Condition.IsNull(MainChannel);
            Condition.IsNull(Open);
            Condition.IsTrue(ModelRequestCommand == ReplayModelRequestCommand.NoRequest);
            Condition.IsTrue(requestCommand != ReplayModelRequestCommand.Create && requestCommand != ReplayModelRequestCommand.NoRequest);

            MainChannel =
                new ModelReplayChannel(ModelHelper.DetermineNegotiateDialect(maxSmbVersionClientSupported,
                    Config.MaxSmbVersionSupported));

            Open = new ReplayOpen();
            ModelRequestCommand = requestCommand;

            State = ModelState.Connected;
        }
        public void PrepareFileOperation(
            ModelDialectRevision maxSmbVersionClientSupported,
            ReplayModelRequestCommand requestCommand)
        {
            if (requestCommand == ReplayModelRequestCommand.IoCtl)
            {
                testConfig.CheckIOCTL(CtlCode_Values.FSCTL_LMR_REQUEST_RESILIENCY);
            }

            InitializeMainChannel(
                maxSmbVersionClientSupported,
                clientGuidMainChannel,
                ReplayModelShareType.NonCAShare,
                out treeIdMainChannel);

            uint status = 0;

            #region Create
            Smb2CreateContextResponse[] serverCreateContexts = null;

            status = smb2ClientMainChannel.Create(
                treeIdMainChannel,
                fileNameMainChannel,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileIdMainChannel,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                null);
            #endregion

            if (requestCommand == ReplayModelRequestCommand.Write)
            {
                #region Write
                status = smb2ClientMainChannel.Write(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    writeContent);
                #endregion
            }
            else if (requestCommand == ReplayModelRequestCommand.SetInfo)
            {
                #region SetInfo
                byte[] buffer = TypeMarshal.ToBytes<FileEndOfFileInformation>(endOfFileInformation);

                status = smb2ClientMainChannel.SetFileAttributes(
                    treeIdMainChannel,
                    (byte)FileInformationClasses.FileEndOfFileInformation,
                    fileIdMainChannel,
                    buffer);
                #endregion
            }
            else if (requestCommand == ReplayModelRequestCommand.IoCtl)
            {
                #region IOCtl
                Packet_Header ioCtlHeader;
                IOCTL_Response ioCtlResponse;
                byte[] inputInResponse;
                byte[] outputInResponse;
                status = smb2ClientMainChannel.ResiliencyRequest(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    0,
                    (uint)Marshal.SizeOf(typeof(NETWORK_RESILIENCY_Request)),
                    out ioCtlHeader,
                    out ioCtlResponse,
                    out inputInResponse,
                    out outputInResponse,
                    checker: (header, response) =>
                    {
                        // do nothing, skip the exception
                    }
                    );
                #endregion
            }
            else if (requestCommand == ReplayModelRequestCommand.Read)
            {
                #region Read
                #region Prepare data for read
                status = smb2ClientMainChannel.Write(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    writeContent);
                #endregion

                string data;
                status = smb2ClientMainChannel.Read(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    0,
                    (uint)testConfig.WriteBufferLengthInKb * 1024,
                    out data);
                #endregion
            }

            prepared = true;
        }
        public void FileOperationRequest(
            ReplayModelSwitchChannelType switchChannelType,
            ModelDialectRevision maxSmbVersionClientSupported,
            ReplayModelRequestCommand requestCommand,
            ReplayModelChannelSequenceType channelSequence,
            ReplayModelSetReplayFlag isReplay,
            ReplayModelRequestCommandParameters requestCommandParameters)
        {
            if (requestCommand == ReplayModelRequestCommand.IoCtl)
            {
                testConfig.CheckIOCTL(CtlCode_Values.FSCTL_LMR_REQUEST_RESILIENCY);
            }

            uint status = Smb2Status.STATUS_SUCCESS;
            Smb2FunctionalClient client = null;

            #region Switch channel
            switch (switchChannelType)
            {
                case ReplayModelSwitchChannelType.MainChannel:
                    if (smb2ClientMainChannel == null)
                    {
                        InitializeMainChannel(
                            maxSmbVersionClientSupported,
                            clientGuidMainChannel,
                            ReplayModelShareType.NonCAShare,
                            out treeIdMainChannel);

                        #region Create
                        Smb2CreateContextResponse[] serverCreateContexts = null;

                        status = smb2ClientMainChannel.Create(
                            treeIdMainChannel,
                            fileNameMainChannel,
                            CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                            out fileIdMainChannel,
                            out serverCreateContexts,
                            RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                            null,
                            shareAccess: ShareAccess_Values.NONE);
                        #endregion
                    }
                    client = smb2ClientMainChannel;
                    break;
                case ReplayModelSwitchChannelType.AlternativeChannelWithMainChannel:
                    InitializeAlternativeChannel(
                        clientGuidMainChannel,
                        treeIdMainChannel);
                    client = smb2ClientAlternativeChannel;
                    break;
                case ReplayModelSwitchChannelType.AlternativeChannelWithDisconnectMainChannel:
                    InitializeAlternativeChannel(
                        clientGuidMainChannel,
                        treeIdMainChannel);
                    smb2ClientMainChannel.Disconnect();
                    smb2ClientMainChannel = null;
                    client = smb2ClientAlternativeChannel;
                    break;
                case ReplayModelSwitchChannelType.MainChannelWithAlternativeChannel:
                    InitializeAlternativeChannel(
                        clientGuidMainChannel,
                        treeIdMainChannel);
                    client = smb2ClientMainChannel;
                    break;
                default:
                    Site.Assume.Fail("Unknown ReplayModelSwitchChannelType {0}.", switchChannelType);
                    break;
            }
            #endregion

            #region Prepare data for read
            if (switchChannelType == ReplayModelSwitchChannelType.MainChannel && !prepared && requestCommand == ReplayModelRequestCommand.Read)
            {
                status = smb2ClientMainChannel.Write(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    writeContent);
            }
            #endregion

            FillChannelSequence(client, channelSequence);

            if (requestCommand == ReplayModelRequestCommand.Write)
            {
                #region Write
                status = client.Write(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    requestCommandParameters == ReplayModelRequestCommandParameters.DefaultParameters ? writeContent : Smb2Utility.CreateRandomString(testConfig.WriteBufferLengthInKb),
                    checker: (header, response) =>
                    {
                    },
                    isReplay: isReplay == ReplayModelSetReplayFlag.WithReplayFlag);
                #endregion
            }
            else if (requestCommand == ReplayModelRequestCommand.SetInfo)
            {
                #region SetInfo
                if (requestCommandParameters == ReplayModelRequestCommandParameters.AlternativeParameters)
                {
                    endOfFileInformation.EndOfFile = 512;
                }
                byte[] buffer = TypeMarshal.ToBytes<FileEndOfFileInformation>(endOfFileInformation);

                status = client.SetFileAttributes(
                    treeIdMainChannel,
                    (byte)FileInformationClasses.FileEndOfFileInformation,
                    fileIdMainChannel,
                    buffer,
                    checker: (header, response) =>
                    {
                    },
                    isReplay: isReplay == ReplayModelSetReplayFlag.WithReplayFlag);
                #endregion
            }
            else if (requestCommand == ReplayModelRequestCommand.IoCtl)
            {
                #region IOCtl
                Packet_Header ioCtlHeader;
                IOCTL_Response ioCtlResponse;
                byte[] inputInResponse;
                byte[] outputInResponse;
                status = client.ResiliencyRequest(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    (uint)(requestCommandParameters == ReplayModelRequestCommandParameters.DefaultParameters ? 0 : 2000),
                    (uint)Marshal.SizeOf(typeof(NETWORK_RESILIENCY_Request)),
                    out ioCtlHeader,
                    out ioCtlResponse,
                    out inputInResponse,
                    out outputInResponse,
                    checker: (header, response) =>
                    {
                        // do nothing, skip the exception
                    }
                    );
                #endregion
            }
            else if (requestCommand == ReplayModelRequestCommand.Read)
            {
                #region Read
                string data;
                status = client.Read(
                    treeIdMainChannel,
                    fileIdMainChannel,
                    0,
                    requestCommandParameters == ReplayModelRequestCommandParameters.DefaultParameters ? (uint)testConfig.WriteBufferLengthInKb * 1024 : 512,
                    out data,
                    isReplay: isReplay == ReplayModelSetReplayFlag.WithReplayFlag);
                #endregion
            }

            FileOperationResponse((ModelSmb2Status)status, replayConfig);
        }