Example #1
0
 public ModelReplayCreateRequest(ModelReplayChannel channel,
                                 ReplayModelSwitchChannelType switchChannelType,
                                 ReplayModelChannelSequenceType channelSequence,
                                 ReplayModelDurableHandle modelDurableHandle,
                                 ReplayModelRequestedOplockLevel requestedOplockLevel,
                                 ReplayModelFileName fileName,
                                 ReplayModelCreateGuid createGuid,
                                 ReplayModelFileAttributes fileAttributes,
                                 ReplayModelCreateDisposition createDisposition,
                                 ReplayModelLeaseState leaseState,
                                 ReplayModelSetReplayFlag isSetReplayFlag,
                                 ReplayModelLeaseKey leaseKey)
     : base(0)
 {
     this.channel              = channel;
     this.switchChannelType    = switchChannelType;
     this.channelSequence      = channelSequence;
     this.modelDurableHandle   = modelDurableHandle;
     this.requestedOplockLevel = requestedOplockLevel;
     this.fileName             = fileName;
     this.createGuid           = createGuid;
     this.fileAttributes       = fileAttributes;
     this.createDisposition    = createDisposition;
     this.leaseState           = leaseState;
     this.isSetReplayFlag      = isSetReplayFlag;
     this.leaseKey             = leaseKey;
 }
Example #2
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 ModelReplayCreateRequest(ModelReplayChannel channel,
     ReplayModelSwitchChannelType switchChannelType,
     ReplayModelChannelSequenceType channelSequence,
     ReplayModelDurableHandle modelDurableHandle,
     ReplayModelRequestedOplockLevel requestedOplockLevel,
     ReplayModelFileName fileName,
     ReplayModelCreateGuid createGuid,
     ReplayModelFileAttributes fileAttributes,
     ReplayModelCreateDisposition createDisposition,
     ReplayModelLeaseState leaseState,
     ReplayModelSetReplayFlag isSetReplayFlag,
     ReplayModelLeaseKey leaseKey)
     : base(0)
 {
     this.channel = channel;
     this.switchChannelType = switchChannelType;
     this.channelSequence = channelSequence;
     this.modelDurableHandle = modelDurableHandle;
     this.requestedOplockLevel = requestedOplockLevel;
     this.fileName = fileName;
     this.createGuid = createGuid;
     this.fileAttributes = fileAttributes;
     this.createDisposition = createDisposition;
     this.leaseState = leaseState;
     this.isSetReplayFlag = isSetReplayFlag;
     this.leaseKey = leaseKey;
 }
        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 CreateRequest(
            ModelDialectRevision maxSmbVersionClientSupported,
            ReplayModelShareType shareType,
            ReplayModelClientSupportPersistent isClientSupportPersistent,
            ReplayModelSwitchChannelType switchChannelType,
            ReplayModelChannelSequenceType channelSequence,
            ReplayModelSetReplayFlag isSetReplayFlag,
            ReplayModelDurableHandle modelDurableHandle,
            ReplayModelRequestedOplockLevel requestedOplockLevel,
            ReplayModelLeaseState leaseState,
            ReplayModelFileName fileName,
            ReplayModelCreateGuid createGuid,
            ReplayModelFileAttributes fileAttributes,
            ReplayModelCreateDisposition createDisposition,
            ReplayModelLeaseKey leaseKey)
        {
            Smb2FunctionalClient client = null;

            switch (switchChannelType)
            {
            case ReplayModelSwitchChannelType.MainChannel:
            {
                if (smb2ClientMainChannel == null)
                {
                    InitializeMainChannel(maxSmbVersionClientSupported, clientGuidMainChannel, shareType,
                                          out treeIdMainChannel, false,
                                          isClientSupportPersistent == ReplayModelClientSupportPersistent.ClientSupportPersistent);
                }
                break;
            }

            case ReplayModelSwitchChannelType.ReconnectMainChannel:
            {
                Site.Assume.IsNotNull(smb2ClientMainChannel, "Main channel is expected to exist.");
                smb2ClientMainChannel.Disconnect();
                smb2ClientMainChannel = null;
                InitializeMainChannel(maxSmbVersionClientSupported, clientGuidMainChannel, shareType,
                                      out treeIdMainChannel, true,
                                      isClientSupportPersistent == ReplayModelClientSupportPersistent.ClientSupportPersistent);
                break;
            }

            default:     //AlternativeChannelWithMainChannel, AlternativeChannelWithDisconnectMainChannel, MainChannelWithAlternativeChannel
            {
                InitializeAlternativeChannel(
                    clientGuidMainChannel,
                    treeIdMainChannel,
                    isClientSupportPersistent == ReplayModelClientSupportPersistent.ClientSupportPersistent);

                if (switchChannelType == ReplayModelSwitchChannelType.AlternativeChannelWithDisconnectMainChannel)
                {
                    smb2ClientMainChannel.Disconnect();
                    smb2ClientMainChannel = null;
                }
                break;
            }
            }

            if (switchChannelType == ReplayModelSwitchChannelType.AlternativeChannelWithDisconnectMainChannel ||
                switchChannelType == ReplayModelSwitchChannelType.AlternativeChannelWithMainChannel)
            {
                client = smb2ClientAlternativeChannel;
            }
            else
            {
                client = smb2ClientMainChannel;
            }

            Smb2CreateContextRequest[]  contexts;
            RequestedOplockLevel_Values oplockLevel;
            LeaseStateValues            requestLeaseState;

            FillParameters(leaseState,
                           requestedOplockLevel,
                           modelDurableHandle,
                           createGuid == ReplayModelCreateGuid.DefaultCreateGuid ? createGuidMainChannel : Guid.NewGuid(),
                           leaseKey == ReplayModelLeaseKey.DefaultLeaseKey ? leaseKeyMainChannel : Guid.NewGuid(),
                           out requestLeaseState,
                           out oplockLevel,
                           out contexts);

            FillChannelSequence(client, channelSequence);

            Smb2CreateContextResponse[] serverCreateContexts;
            ulong createRequestId;

            client.CreateRequest(
                treeIdMainChannel,
                fileName == ReplayModelFileName.DefaultFileName ? fileNameMainChannel : Guid.NewGuid().ToString(),
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                (isSetReplayFlag == ReplayModelSetReplayFlag.WithReplayFlag ? Packet_Header_Flags_Values.FLAGS_REPLAY_OPERATION : Packet_Header_Flags_Values.NONE) | (testConfig.SendSignedRequest ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE),
                out createRequestId,
                oplockLevel,
                contexts,
                createDisposition: createDisposition == ReplayModelCreateDisposition.DefaultCreateDisposition ? CreateDisposition_Values.FILE_OPEN_IF : CreateDisposition_Values.FILE_OVERWRITE_IF,
                fileAttributes: fileAttributes == ReplayModelFileAttributes.DefaultFileAttributes ? File_Attributes.NONE : File_Attributes.FILE_ATTRIBUTE_TEMPORARY
                );

            uint status = client.CreateResponse(
                createRequestId,
                out fileIdMainChannel,
                out serverCreateContexts,
                checker: (header, response) =>
            {
            }
                );

            CreateResponse(
                (ModelSmb2Status)status,
                ConvertHandle(serverCreateContexts),
                replayConfig);
        }
        public static void CreateRequest(
            ModelDialectRevision maxSmbVersionClientSupported,
            ReplayModelShareType shareType,
            ReplayModelClientSupportPersistent clientPersistentCapability,
            ReplayModelSwitchChannelType switchChannelType,
            ReplayModelChannelSequenceType channelSequence,
            ReplayModelSetReplayFlag isSetReplayFlag,
            ReplayModelDurableHandle modelDurableHandle,
            ReplayModelRequestedOplockLevel requestedOplockLevel,
            ReplayModelLeaseState leaseState,
            ReplayModelFileName fileName,
            ReplayModelCreateGuid createGuid,
            ReplayModelFileAttributes fileAttributes,
            ReplayModelCreateDisposition createDisposition,
            ReplayModelLeaseKey leaseKey)
        {
            Condition.IsTrue(State == ModelState.Connected || State == ModelState.Initialized);
            Condition.IsNull(Request);

            Combination.NWise(2, maxSmbVersionClientSupported, shareType, clientPersistentCapability, switchChannelType, channelSequence, isSetReplayFlag, modelDurableHandle,
                requestedOplockLevel, leaseState, fileName, createGuid, fileAttributes, createDisposition, leaseKey);

            Combination.Isolated(channelSequence == ReplayModelChannelSequenceType.InvalidChannelSequence);
            Combination.Isolated(channelSequence == ReplayModelChannelSequenceType.ChannelSequenceBoundaryValid);

            //No lease for non durable handle 
            Condition.IfThen(modelDurableHandle == ReplayModelDurableHandle.NormalHandle,
                requestedOplockLevel != ReplayModelRequestedOplockLevel.OplockLevelLeaseV1 &&
                requestedOplockLevel != ReplayModelRequestedOplockLevel.OplockLevelLeaseV2);

            //No lease state or lease key(default) if not requesting lease
            Condition.IfThen(
                requestedOplockLevel != ReplayModelRequestedOplockLevel.OplockLevelLeaseV1 &&
                requestedOplockLevel != ReplayModelRequestedOplockLevel.OplockLevelLeaseV2,
                leaseState == ReplayModelLeaseState.LeaseStateIsNone && leaseKey == ReplayModelLeaseKey.DefaultLeaseKey);

            //Ensure valid lease state if requesting lease
            Condition.IfThen(
                requestedOplockLevel == ReplayModelRequestedOplockLevel.OplockLevelLeaseV1 ||
                requestedOplockLevel == ReplayModelRequestedOplockLevel.OplockLevelLeaseV2,
                leaseState != ReplayModelLeaseState.LeaseStateIsNone);

            if (State == ModelState.Initialized)
            {
                Condition.IsTrue(switchChannelType == ReplayModelSwitchChannelType.MainChannel);

                DialectRevision negotiateDialect = ModelHelper.DetermineNegotiateDialect(maxSmbVersionClientSupported,
                    Config.MaxSmbVersionSupported);

                MainChannel = new ModelReplayChannel(negotiateDialect, shareType,
                    clientPersistentCapability == ReplayModelClientSupportPersistent.ClientSupportPersistent);
            }
            else // There's already an open exist
            {
                //Open eixsts
                Condition.IsTrue(Open != null);

                // Ensure same dialect
                Condition.IsTrue(ModelUtility.GetDialectRevision(maxSmbVersionClientSupported) == MainChannel.Connection_NegotiateDialect);

                // Ensure connect to same share
                Condition.IsTrue(shareType == MainChannel.Connection_Session_TreeConnect_Share_IsCA);

                switch (switchChannelType)
                {
                    case ReplayModelSwitchChannelType.MainChannel:
                    {
                        Condition.IsTrue((clientPersistentCapability ==
                                          ReplayModelClientSupportPersistent.ClientSupportPersistent) ==
                                         MainChannel.Connection_ClientCapabilities_SupportPersistent);
                        break;
                    }
                    case ReplayModelSwitchChannelType.ReconnectMainChannel:
                    {
                        MainChannel.Connection_ClientCapabilities_SupportPersistent =
                            (clientPersistentCapability == ReplayModelClientSupportPersistent.ClientSupportPersistent);
                        break;
                    }
                    case ReplayModelSwitchChannelType.AlternativeChannelWithDisconnectMainChannel:
                    case ReplayModelSwitchChannelType.AlternativeChannelWithMainChannel:
                    case ReplayModelSwitchChannelType.MainChannelWithAlternativeChannel:
                    {
                        AlternativeChannel = new ModelReplayChannel(MainChannel.Connection_NegotiateDialect, shareType,
                            clientPersistentCapability == ReplayModelClientSupportPersistent.ClientSupportPersistent);
                        break;
                    }
                }

                #region Handle state changes when there's connection lost or reconnection
                if (switchChannelType == ReplayModelSwitchChannelType.AlternativeChannelWithDisconnectMainChannel ||
                    switchChannelType == ReplayModelSwitchChannelType.ReconnectMainChannel)
                {
                    bool isPreserved = false;

                    ModelHelper.Log(
                        LogType.Requirement,
                        "3.3.7.1: The server MUST iterate over the Session.OpenTable and determine whether each Open is to be preserved for reconnect." +
                        " If any of the following conditions is satisfied, it indicates that the Open is to be preserved for reconnect");
                    ModelHelper.Log(
                        LogType.TestInfo,
                        "Open.OplockLevel is {0}, Open.OplockState is {1}, Open.IsDurable {2}", Open.OplockLevel,
                        Open.OplockStateIsHeld ? "Held" : "not Held", Open.IsDurable);
                    if (Open.Lease != null)
                    {
                        ModelHelper.Log(
                            LogType.TestInfo,
                            "LeaseState is {0}", Open.Lease.LeaseState);
                    }

                    if (switchChannelType == ReplayModelSwitchChannelType.AlternativeChannelWithDisconnectMainChannel)
                    {
                        ModelHelper.Log(
                            LogType.TestInfo,
                            "TD does not states the open is preserved when multi channels exist.");
                        isPreserved = true;
                    }
                    else if (Open.OplockLevel == ReplayModelRequestedOplockLevel.OplockLevelBatch &&
                             Open.OplockStateIsHeld &&
                             Open.IsDurable) // Open.OplockLevel is equal to SMB2_OPLOCK_LEVEL_BATCH
                    {
                        ModelHelper.Log(
                            LogType.Requirement,
                            "Open.OplockLevel is equal to SMB2_OPLOCK_LEVEL_BATCH and Open.OplockState is equal to Held, and Open.IsDurable is TRUE");

                        isPreserved = true;

                        ModelHelper.Log(
                            LogType.TestInfo,
                            "Open is to be preserved for reconnect");
                    }
                    else if (((Open.OplockLevel == ReplayModelRequestedOplockLevel.OplockLevelLeaseV1 ||
                               Open.OplockLevel == ReplayModelRequestedOplockLevel.OplockLevelLeaseV2) && 
                              Open.Lease != null &&
                              Open.Lease.LeaseState == ReplayModelLeaseState.LeaseStateIncludeH &&
                              Open.OplockStateIsHeld &&
                              Open.IsDurable)) // Open.OplockLevel is equal to SMB2_OPLOCK_LEVEL_LEASE and contains SMB2_LEASE_HANDLE_CACHING
                    {
                        ModelHelper.Log(
                            LogType.Requirement,
                            "Open.OplockLevel is equal to SMB2_OPLOCK_LEVEL_LEASE, Lease.LeaseState contains SMB2_LEASE_HANDLE_CACHING," +
                            " Open.OplockState is equal to Held, and Open.IsDurable is TRUE.");

                        isPreserved = true;

                        ModelHelper.Log(
                            LogType.TestInfo,
                            "Open is to be preserved for reconnect");
                    }
                    // "The server supports leasing and Open.IsResilient is TRUE" covered by resilient model

                    if (isPreserved)
                    {
                        ModelHelper.Log(
                            LogType.Requirement,
                            "If the Open is to be preserved for reconnect, perform the following actions:");
                        ModelHelper.Log(
                            LogType.Requirement,
                            "Set Open.Connection to NULL");
                        //Skip requirement for resilient handle which covered by resilient model

                        Open.ConnectionIsNotNull = false;
                    }
                    else
                    {
                        ModelHelper.Log(
                            LogType.Requirement,
                            "If the Open is not to be preserved for reconnect, the server MUST close the Open as specified in section 3.3.4.17");

                        LastOpen = Open;
                        Open = null;

                        ModelHelper.Log(
                            LogType.TestInfo,
                            "Open is set to NULL");
                    }
                }
                #endregion

            }

            ModelReplayChannel channel = GetChannel(switchChannelType);

            ModelReplayCreateRequest replayCreateRequest = 
                new ModelReplayCreateRequest(channel, switchChannelType, channelSequence, modelDurableHandle, requestedOplockLevel, fileName,
                    createGuid, fileAttributes, createDisposition, leaseState, isSetReplayFlag, leaseKey);

            Request = replayCreateRequest;
            State = ModelState.Connected;
        }
 /// <summary>
 /// Get channel by switchChannelType.
 /// </summary>
 /// <param name="switchChannelType">The type of switching channel.</param>
 /// <returns></returns>
 private static ModelReplayChannel GetChannel(ReplayModelSwitchChannelType switchChannelType)
 {
     ModelReplayChannel channel;
     switch (switchChannelType)
     {
         case ReplayModelSwitchChannelType.AlternativeChannelWithMainChannel:
             channel = AlternativeChannel;
             break;
         case ReplayModelSwitchChannelType.ReconnectMainChannel:
             channel = MainChannel;
             AlternativeChannel = null;
             break;
         case ReplayModelSwitchChannelType.AlternativeChannelWithDisconnectMainChannel:
             channel = AlternativeChannel;
             MainChannel = null;
             break;
         case ReplayModelSwitchChannelType.MainChannelWithAlternativeChannel:
             channel = MainChannel;
             break;
         default: // ReplayModelSwitchChannelType.MainChannel
             channel = MainChannel;
             break;
     }
     return channel;
 }
        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 void CreateRequest(
            ModelDialectRevision maxSmbVersionClientSupported,
            ReplayModelShareType shareType,
            ReplayModelClientSupportPersistent isClientSupportPersistent,
            ReplayModelSwitchChannelType switchChannelType,
            ReplayModelChannelSequenceType channelSequence,
            ReplayModelSetReplayFlag isSetReplayFlag,
            ReplayModelDurableHandle modelDurableHandle,
            ReplayModelRequestedOplockLevel requestedOplockLevel,
            ReplayModelLeaseState leaseState,
            ReplayModelFileName fileName,
            ReplayModelCreateGuid createGuid,
            ReplayModelFileAttributes fileAttributes,
            ReplayModelCreateDisposition createDisposition,
            ReplayModelLeaseKey leaseKey)
        {
            Smb2FunctionalClient client = null;

            switch (switchChannelType)
            {
                case ReplayModelSwitchChannelType.MainChannel:
                {
                    if (smb2ClientMainChannel == null)
                    {
                        InitializeMainChannel(maxSmbVersionClientSupported, clientGuidMainChannel, shareType,
                            out treeIdMainChannel, false,
                            isClientSupportPersistent == ReplayModelClientSupportPersistent.ClientSupportPersistent);
                    }
                    break;
                }
                case ReplayModelSwitchChannelType.ReconnectMainChannel:
                {
                    Site.Assume.IsNotNull(smb2ClientMainChannel, "Main channel is expected to exist.");
                    smb2ClientMainChannel.Disconnect();
                    smb2ClientMainChannel = null;
                    InitializeMainChannel(maxSmbVersionClientSupported, clientGuidMainChannel, shareType,
                        out treeIdMainChannel, true,
                        isClientSupportPersistent == ReplayModelClientSupportPersistent.ClientSupportPersistent);
                    break;
                }
                default: //AlternativeChannelWithMainChannel, AlternativeChannelWithDisconnectMainChannel, MainChannelWithAlternativeChannel
                {
                    InitializeAlternativeChannel(
                        clientGuidMainChannel,
                        treeIdMainChannel,
                        isClientSupportPersistent == ReplayModelClientSupportPersistent.ClientSupportPersistent);

                    if (switchChannelType == ReplayModelSwitchChannelType.AlternativeChannelWithDisconnectMainChannel)
                    {
                        smb2ClientMainChannel.Disconnect();
                        smb2ClientMainChannel = null;
                    }
                    break;
                }
            }

            if (switchChannelType == ReplayModelSwitchChannelType.AlternativeChannelWithDisconnectMainChannel ||
                switchChannelType == ReplayModelSwitchChannelType.AlternativeChannelWithMainChannel)
            {
                client = smb2ClientAlternativeChannel;
            }
            else
            {
                client = smb2ClientMainChannel;
            }

            Smb2CreateContextRequest[] contexts;
            RequestedOplockLevel_Values oplockLevel;
            LeaseStateValues requestLeaseState;

            FillParameters(leaseState,
                requestedOplockLevel,
                modelDurableHandle,
                createGuid == ReplayModelCreateGuid.DefaultCreateGuid ? createGuidMainChannel : Guid.NewGuid(),
                leaseKey == ReplayModelLeaseKey.DefaultLeaseKey ? leaseKeyMainChannel : Guid.NewGuid(),
                out requestLeaseState,
                out oplockLevel,
                out contexts);

            FillChannelSequence(client, channelSequence);

            Smb2CreateContextResponse[] serverCreateContexts;
            ulong createRequestId;
            client.CreateRequest(
                    treeIdMainChannel,
                    fileName == ReplayModelFileName.DefaultFileName ? fileNameMainChannel : Guid.NewGuid().ToString(),
                    CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                    (isSetReplayFlag == ReplayModelSetReplayFlag.WithReplayFlag ? Packet_Header_Flags_Values.FLAGS_REPLAY_OPERATION : Packet_Header_Flags_Values.NONE) | (testConfig.SendSignedRequest ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE),
                    out createRequestId,
                    oplockLevel,
                    contexts,
                    createDisposition: createDisposition == ReplayModelCreateDisposition.DefaultCreateDisposition ? CreateDisposition_Values.FILE_OPEN_IF : CreateDisposition_Values.FILE_OVERWRITE_IF,
                    fileAttributes: fileAttributes == ReplayModelFileAttributes.DefaultFileAttributes ? File_Attributes.NONE : File_Attributes.FILE_ATTRIBUTE_TEMPORARY
                 );

            uint status = client.CreateResponse(
                    createRequestId,
                    out fileIdMainChannel,
                    out serverCreateContexts,
                    checker: (header, response) =>
                    {
                    }
                 );

            CreateResponse(
                (ModelSmb2Status)status,
                ConvertHandle(serverCreateContexts),
                replayConfig);
        }
        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);
        }