public static void RequestOplock(OplockLevel_Values oplockType)
        {
            // OPLOCK_LEVEL_NONE is only initial state, it's meaningless when requesting an Oplock
            Condition.IsFalse(oplockType == OplockLevel_Values.OPLOCK_LEVEL_NONE);
            // OPLOCK_LEVEL_LEASE is used when requesting Lease, so it's not applicable for requesting Oplock
            Condition.IsFalse(oplockType == OplockLevel_Values.OPLOCK_LEVEL_LEASE);

            if (OplockState == OplockLevel_Values.OPLOCK_LEVEL_NONE && LeaseState == ModelLeaseStateType.Lease_None)
            {
                OplockState = oplockType;
            }
        }
        public static void OplockBreakAcknowledgementRequest(OplockVolatilePortion volatilePortion, OplockPersistentPortion persistentPortion, OplockLevel_Values oplockLevel)
        {
            Combination.Isolated(volatilePortion == OplockVolatilePortion.VolatilePortionNotFound);
            Combination.Isolated(persistentPortion == OplockPersistentPortion.PersistentNotMatchesDurableFileId);

            // Isolate the values that are not allowed
            Combination.Isolated(oplockLevel == OplockLevel_Values.OPLOCK_LEVEL_BATCH);
            Combination.Isolated(oplockLevel == OplockLevel_Values.OPLOCK_LEVEL_EXCLUSIVE);
            Combination.Isolated(oplockLevel == OplockLevel_Values.OPLOCK_LEVEL_LEASE);

            Condition.IsTrue(State == ModelState.Connected);
            Condition.IsNull(Request);

            bool volatilePortionFound = volatilePortion == OplockVolatilePortion.VolatilePortionFound;
            bool persistentMatchesDurableFileId = persistentPortion == OplockPersistentPortion.PersistentMatchesDurableFileId;

            Request = new ModelOplockBreakAcknowledgementRequest(volatilePortionFound, persistentMatchesDurableFileId, oplockLevel);
        }
        public void OplockBreakAcknowledgementRequest(OplockVolatilePortion volatilePortion, OplockPersistentPortion persistentPortion, OplockLevel_Values oplockLevel)
        {
            bool volatilePortionFound = volatilePortion == OplockVolatilePortion.VolatilePortionFound;
            bool persistentMatchesDurableFileId = persistentPortion == OplockPersistentPortion.PersistentMatchesDurableFileId;
            FILEID fileIdRequest = fileId;

            if(!volatilePortionFound)
            {
                fileIdRequest.Volatile = FILEID.Invalid.Volatile;
            }

            if(!persistentMatchesDurableFileId)
            {
                fileIdRequest.Persistent = FILEID.Invalid.Persistent;
            }

            OPLOCK_BREAK_Response? oplockBreakResponse = null;
            uint status = testClient.OplockAcknowledgement(treeId, fileIdRequest, (OPLOCK_BREAK_Acknowledgment_OplockLevel_Values)oplockLevel, (header, response) => { oplockBreakResponse = response; });

            OplockBreakResponse((ModelSmb2Status)status, oplockBreakResponse.Value.OplockLevel, oplockLevelOnOpen);
        }
 public ModelOplockBreakAcknowledgementRequest(bool volatilePortionFound, bool persistentMatchesDurableFileId, OplockLevel_Values oplockLevel)
     : base(0)
 {
     this.VolatilePortionFound = volatilePortionFound;
     this.PersistentMatchesDurableFileId = persistentMatchesDurableFileId;
     this.OplockLevel = oplockLevel;
 }
        /// <summary>
        /// Reset all member variables before running next test case
        /// </summary>
        public override void Reset()
        {
            if (oplockClient != null)
            {
                oplockClient.Disconnect();
                oplockClient = null;
            }

            if (leaseClient != null)
            {
                leaseClient.Disconnect();
                leaseClient = null;
            }

            fileName = null;
            breakType = ModelBreakType.NoBreak;
            treeIdOplock = 0;
            treeIdLease = 0;
            alreadyRequested = false;
            grantedLeaseState = LeaseStateValues.SMB2_LEASE_NONE;
            grantedOplockLevel = OplockLevel_Values.OPLOCK_LEVEL_NONE;

            base.Reset();
        }
        /// <summary>
        /// One client requests an Oplock.
        /// </summary>
        /// <param name="oplockLevel">Type of the oplock level</param>
        public void RequestOplock(OplockLevel_Values oplockLevel)
        {
            FILEID fileId;
            Smb2CreateContextResponse[] responses;

            oplockClient.Create(
                treeIdOplock,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out responses,
                (RequestedOplockLevel_Values)oplockLevel,
                checker: (header, response) =>
                {
                    grantedOplockLevel = response.OplockLevel;
                });
            HandleResult();
        }
        public void RequestOplockAndOperateFileRequest(
            RequestedOplockLevel_Values requestedOplockLevel,
            OplockFileOperation fileOperation,
            out OplockLevel_Values grantedOplockLevel,
            out OplockConfig c)
        {
            Smb2CreateContextResponse[] serverCreateContexts;
            string fileName = "OplockMBT_"+ Guid.NewGuid().ToString();

            OplockLevel_Values grantedTmp = OplockLevel_Values.OPLOCK_LEVEL_NONE;
            testClient.Create(
                    treeId,
                    fileName,
                    CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                    out fileId,
                    out serverCreateContexts,
                    requestedOplockLevel_Values: requestedOplockLevel,
                    checker: (header, response) =>
                    {
                        grantedTmp = response.OplockLevel;
                    });

            Site.Log.Add(LogEntryKind.Debug, "OplockLevel granted by server: {0}", grantedTmp);
            grantedOplockLevel = grantedTmp;
            c = oplockConfig;

            oplockLevelOnOpen = grantedTmp;

            fileOperationInvoker = new FileOperationDelegate(FileOperation);
            fileOperationInvoker.BeginInvoke(fileOperation, fileName, null, null);

            // Assume that notification will arrive in .5 sec if there's any
            // Without such sleep, OplockBreakNotification would not be expected by SE
            Thread.Sleep(500);
        }
        public static void OplockBreakResponse(ModelSmb2Status status, OPLOCK_BREAK_Response_OplockLevel_Values oplockLevel, OplockLevel_Values oplockLevelOnOpen)
        {
            Condition.IsTrue(State == ModelState.Connected);
            Condition.IsNotNull(Request);

            ModelOplockBreakAcknowledgementRequest oplockBreakAckRequest = ModelHelper.RetrieveOutstandingRequest<ModelOplockBreakAcknowledgementRequest>(ref Request);

            ModelHelper.Log(LogType.Requirement,
                "3.3.5.22.1   Processing an Oplock Acknowledgment");

            if (!oplockBreakAckRequest.VolatilePortionFound
                || !oplockBreakAckRequest.PersistentMatchesDurableFileId)
            {
                ModelHelper.Log(LogType.Requirement,
                    "Next, the server MUST locate the open on which the client is acknowledging an oplock break by performing a lookup in Session.OpenTable " +
                    "using FileId.Volatile of the request as the lookup key. If no open is found, or if Open.DurableFileId is not equal to FileId.Persistent, " +
                    "the server MUST fail the request with STATUS_FILE_CLOSED. ");
                ModelHelper.Log(LogType.TestTag, TestTag.InvalidIdentifier);

                if (!oplockBreakAckRequest.VolatilePortionFound)
                {
                    ModelHelper.Log(LogType.TestInfo, "Open is not found.");
                }
                if (!oplockBreakAckRequest.PersistentMatchesDurableFileId)
                {
                    ModelHelper.Log(LogType.TestInfo, "Open.DurableFileId is not equal to FileId.Persistent.");
                }
                Condition.IsTrue(status == ModelSmb2Status.STATUS_FILE_CLOSED);
                return;
            }

            // We need this to avoid Open.OplockLevel being symbolic which will result case exploration failure
            Condition.IsTrue(Open.OplockLevel == oplockLevelOnOpen);
            Condition.IsTrue(oplockLevelOnOpen == OplockLevel_Values.OPLOCK_LEVEL_NONE
                || oplockLevelOnOpen == OplockLevel_Values.OPLOCK_LEVEL_II
                || oplockLevelOnOpen == OplockLevel_Values.OPLOCK_LEVEL_BATCH);

            if (oplockBreakAckRequest.OplockLevel == OplockLevel_Values.OPLOCK_LEVEL_LEASE)
            {
                ModelHelper.Log(LogType.Requirement,
                    "If the OplockLevel in the acknowledgment is SMB2_OPLOCK_LEVEL_LEASE, the server MUST do the following:");
                ModelHelper.Log(LogType.TestInfo, "Open.OplockState is {0}.", Open.OplockState);

                if (Open.OplockState != OplockState.Breaking)
                {
                    ModelHelper.Log(LogType.Requirement,
                        "If Open.OplockState is not Breaking, stop processing the acknowledgment, " +
                        "and send an error response with STATUS_INVALID_PARAMETER.");
                    ModelHelper.Log(LogType.TestTag, TestTag.Compatibility);
                    Condition.IsTrue(status == ModelSmb2Status.STATUS_INVALID_PARAMETER);
                    return;
                }
                else
                {
                    ModelHelper.Log(LogType.Requirement,
                        "If Open.OplockState is Breaking, complete the oplock break request received from the object store as described in section 3.3.4.6, " +
                        "with a new level SMB2_OPLOCK_LEVEL_NONE in an implementation-specific manner,<350> and set Open.OplockLevel to SMB2_OPLOCK_LEVEL_NONE, " +
                        "and Open.OplockState to None.");
                    ModelHelper.Log(LogType.TestInfo, "Open.OplockLevel is set to SMB2_OPLOCK_LEVEL_NONE, and Open.OplockState is set to None");
                    Open.OplockLevel = OplockLevel_Values.OPLOCK_LEVEL_NONE;
                    Open.OplockState = OplockState.None;

                    // Do not assert implementation-specific manner
                    return;
                }
            }

            if ((Open.OplockLevel == OplockLevel_Values.OPLOCK_LEVEL_EXCLUSIVE
                || Open.OplockLevel == OplockLevel_Values.OPLOCK_LEVEL_BATCH)
                && (oplockBreakAckRequest.OplockLevel != OplockLevel_Values.OPLOCK_LEVEL_II && oplockBreakAckRequest.OplockLevel != OplockLevel_Values.OPLOCK_LEVEL_NONE))
            {
                ModelHelper.Log(LogType.Requirement,
                    "If Open.OplockLevel is SMB2_OPLOCK_LEVEL_EXCLUSIVE or SMB2_OPLOCK_LEVEL_BATCH, " +
                    "and if OplockLevel is not SMB2_OPLOCK_LEVEL_II or SMB2_OPLOCK_LEVEL_NONE, the server MUST do the following:");
                ModelHelper.Log(LogType.TestInfo, "Open.OplockState is {0}.", Open.OplockState);

                if (Open.OplockState != OplockState.Breaking)
                {
                    ModelHelper.Log(LogType.Requirement,
                        "If Open.OplockState is not Breaking, stop processing the acknowledgment, " +
                        "and send an error response with STATUS_INVALID_OPLOCK_PROTOCOL.");
                    ModelHelper.Log(LogType.TestTag, TestTag.Compatibility);
                    Condition.IsTrue(status == ModelSmb2Status.STATUS_INVALID_OPLOCK_PROTOCOL);
                    return;
                }
                else
                {
                    ModelHelper.Log(LogType.Requirement,
                        "If Open.OplockState is Breaking, complete the oplock break request received from the object store, " +
                        "as described in section 3.3.4.6, with a new level SMB2_OPLOCK_LEVEL_NONE in an implementation-specific manner," +
                        "<351> and set Open.OplockLevel to SMB2_OPLOCK_LEVEL_NONE and Open.OplockState to None.");
                    ModelHelper.Log(LogType.TestInfo, "Open.OplockLevel is set to SMB2_OPLOCK_LEVEL_NONE, and Open.OplockState is set to None");
                    Open.OplockLevel = OplockLevel_Values.OPLOCK_LEVEL_NONE;
                    Open.OplockState = OplockState.None;

                    // Do not assert implementation-specific manner
                    return;
                }
            }

            if (Open.OplockLevel == OplockLevel_Values.OPLOCK_LEVEL_II
                && oplockBreakAckRequest.OplockLevel != OplockLevel_Values.OPLOCK_LEVEL_NONE)
            {
                ModelHelper.Log(LogType.Requirement,
                    "If Open.OplockLevel is SMB2_OPLOCK_LEVEL_II, and if OplockLevel is not SMB2_OPLOCK_LEVEL_NONE, " +
                    "the server MUST do the following:");
                ModelHelper.Log(LogType.TestInfo, "Open.OplockState is {0}.", Open.OplockState);

                if (Open.OplockState != OplockState.Breaking)
                {
                    ModelHelper.Log(LogType.Requirement,
                        "If Open.OplockState is not Breaking, stop processing the acknowledgment, and send an error response with STATUS_INVALID_OPLOCK_PROTOCOL.");
                    ModelHelper.Log(LogType.TestTag, TestTag.Compatibility);
                    Condition.IsTrue(status == ModelSmb2Status.STATUS_INVALID_OPLOCK_PROTOCOL);
                    return;
                }
                else
                {
                    ModelHelper.Log(LogType.Requirement,
                        "If Open.OplockState is Breaking, complete the oplock break request received from the object store, " +
                        "as described in section 3.3.4.6, with a new level SMB2_OPLOCK_LEVEL_NONE in an implementation-specific manner," +
                        "<352> and set Open.OplockLevel to SMB2_OPLOCK_LEVEL_NONE and Open.OplockState to None.");
                    ModelHelper.Log(LogType.TestInfo, "Open.OplockLevel is set to SMB2_OPLOCK_LEVEL_NONE, and Open.OplockState is set to None");
                    Open.OplockLevel = OplockLevel_Values.OPLOCK_LEVEL_NONE;
                    Open.OplockState = OplockState.None;

                    // Do not assert implementation-specific manner
                    return;
                }
            }

            if (oplockBreakAckRequest.OplockLevel == OplockLevel_Values.OPLOCK_LEVEL_II
                || oplockBreakAckRequest.OplockLevel == OplockLevel_Values.OPLOCK_LEVEL_NONE)
            {
                ModelHelper.Log(LogType.Requirement,
                    "If OplockLevel is SMB2_OPLOCK_LEVEL_II or SMB2_OPLOCK_LEVEL_NONE, the server MUST do the following:");
                ModelHelper.Log(LogType.TestInfo, "Open.OplockState is {0}.", Open.OplockState);

                if (Open.OplockState != OplockState.Breaking)
                {
                    ModelHelper.Log(LogType.Requirement,
                        "If Open.OplockState is not Breaking, stop processing the acknowledgment, " +
                        "and send an error response with STATUS_INVALID_DEVICE_STATE.");
                    ModelHelper.Log(LogType.TestTag, TestTag.Compatibility);
                    Condition.IsTrue(status == ModelSmb2Status.STATUS_INVALID_DEVICE_STATE);
                    return;
                }
                else
                {
                    ModelHelper.Log(LogType.Requirement,
                        "If Open.OplockState is Breaking, " +
                        "complete the oplock break request received from the object store as described in section 3.3.4.6, " +
                        "with a new level received in OplockLevel in an implementation-specific manner.<353>");

                    if (status != ModelSmb2Status.STATUS_SUCCESS)
                    {
                        ModelHelper.Log(LogType.Requirement,
                            "If the object store indicates an error, set the Open.OplockLevel to SMB2_OPLOCK_LEVEL_NONE, " +
                            "the Open.OplockState to None, and send the error response with the error code received.");
                        ModelHelper.Log(LogType.TestInfo, "Open.OplockLevel is set to SMB2_OPLOCK_LEVEL_NONE, and Open.OplockState is set to None");
                        Open.OplockLevel = OplockLevel_Values.OPLOCK_LEVEL_NONE;
                        Open.OplockState = OplockState.None;
                        return;
                    }
                    else
                    {
                        ModelHelper.Log(LogType.Requirement,
                            "If the object store indicates success, update Open.OplockLevel and Open.OplockState as follows:");
                        if (oplockBreakAckRequest.OplockLevel == OplockLevel_Values.OPLOCK_LEVEL_II)
                        {
                            ModelHelper.Log(LogType.Requirement,
                                "If OplockLevel is SMB2_OPLOCK_LEVEL_II, " +
                                "set Open.OplockLevel to SMB2_OPLOCK_LEVEL_II and Open.OplockState to Held.");
                            ModelHelper.Log(LogType.TestInfo, "Open.OplockLevel is set to OPLOCK_LEVEL_II, and Open.OplockState is set to None");
                            Open.OplockLevel = OplockLevel_Values.OPLOCK_LEVEL_II;
                            Open.OplockState = OplockState.Held;
                        }
                        if (oplockBreakAckRequest.OplockLevel == OplockLevel_Values.OPLOCK_LEVEL_NONE)
                        {
                            ModelHelper.Log(LogType.Requirement,
                                "If OplockLevel is SMB2_OPLOCK_LEVEL_NONE, " +
                                "set Open.OplockLevel to SMB2_OPLOCK_LEVEL_NONE and the Open.OplockState to None.");
                            ModelHelper.Log(LogType.TestInfo, "Open.OplockLevel is set to SMB2_OPLOCK_LEVEL_NONE, and Open.OplockState is set to None");
                            Open.OplockLevel = OplockLevel_Values.OPLOCK_LEVEL_NONE;
                            Open.OplockState = OplockState.None;
                        }
                    }
                }
            }

            ModelHelper.Log(LogType.Requirement,
                "The server then MUST construct an oplock break response using the syntax specified in section 2.2.25 with the following value:");
            ModelHelper.Log(LogType.Requirement,
                "OplockLevel MUST be set to Open.OplockLevel.");
            ModelHelper.Log(LogType.TestInfo,
                "Open.OplockLevel is {0}.", Open.OplockLevel);

            Condition.IsTrue(Open.OplockLevel == (OplockLevel_Values)oplockLevel);

            Condition.IsTrue(status == ModelSmb2Status.STATUS_SUCCESS);
        }
        public static void RequestOplockAndOperateFileReturn(OplockLevel_Values grantedOplockLevel, OplockConfig c)
        {
            Condition.IsTrue(State == ModelState.Connected);
            Condition.IsNotNull(Request);

            ModelRequestOplockAndTriggerBreakRequest requestOplockAndTriggerBreakRequest = ModelHelper.RetrieveOutstandingRequest<ModelRequestOplockAndTriggerBreakRequest>(ref Request);

            Condition.IsTrue(Config.Platform == c.Platform);

            if (Share_ForceLevel2Oplock
                && (requestOplockAndTriggerBreakRequest.RequestedOplockLevel == RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH
                     || requestOplockAndTriggerBreakRequest.RequestedOplockLevel == RequestedOplockLevel_Values.OPLOCK_LEVEL_EXCLUSIVE))
            {
                ModelHelper.Log(LogType.Requirement,
                    "3.3.5.9: If TreeConnect.Share.ForceLevel2Oplock is TRUE, " +
                    "and RequestedOplockLevel is SMB2_OPLOCK_LEVEL_BATCH or SMB2_OPLOCK_LEVEL_EXCLUSIVE, " +
                    "the server SHOULD<245> set RequestedOplockLevel to SMB2_OPLOCK_LEVEL_II.");
                if (Config.Platform != Platform.NonWindows)
                {
                    ModelHelper.Log(LogType.TestInfo, "The SUT platform is Windows.");
                    Condition.IsTrue(grantedOplockLevel == OplockLevel_Values.OPLOCK_LEVEL_II);

                    // Skip following WBN which is for pre-Win8
                    // <226> Section 3.3.5.9: Windows Vista and Windows Server 2008 do not support the SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK flag
                    // and ignore  the TreeConnect.Share.ForceLevel2Oplock value.
                }
            }

            if (ModelUtility.IsSmb3xFamily(Connection_Dialect)
                && Share_Type_Include_STYPE_CLUSTER_SOFS
                && requestOplockAndTriggerBreakRequest.RequestedOplockLevel == RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH)
            {
                ModelHelper.Log(LogType.Requirement,
                    "3.3.5.9: If Connection.Dialect belongs to the SMB 3.x dialect family TreeConnect.Share.Type includes STYPE_CLUSTER_SOFS " +
                    "and the RequestedOplockLevel is SMB2_OPLOCK_LEVEL_BATCH, the server MUST set RequestedOplockLevel to SMB2_OPLOCK_LEVEL_II.");
                // The Oplock acquisition depends on underlying object store implemention specific
                // we may not garantee level2 would be always granted
                // Only assert it's not batch
                ModelHelper.Log(LogType.TestInfo, "All the above conditions are met.");
                Condition.IsTrue(grantedOplockLevel != OplockLevel_Values.OPLOCK_LEVEL_BATCH);
            }

            Open = new ModelOplockOpen();

            ModelHelper.Log(LogType.TestInfo, "Open.OplockLevel is set to SMB2_OPLOCK_LEVEL_NONE.");
            Open.OplockLevel = OplockLevel_Values.OPLOCK_LEVEL_NONE;

            ModelHelper.Log(LogType.TestInfo, "Open.OplockState is set to None.");
            Open.OplockState = OplockState.None;

            // Acquire Oplock from underlying object

            // If the underlying object store grants the oplock,
            // then Open.OplockState is set to Held and Open.OplockLevel is set to the level of the oplock acquired.
            if (grantedOplockLevel != OplockLevel_Values.OPLOCK_LEVEL_NONE)
            {
                ModelHelper.Log(LogType.TestInfo, "Open.OplockState is set to Held.");
                Open.OplockState = OplockState.Held;
                Open.OplockLevel = grantedOplockLevel;
            }
        }
        public Smb2CreateResponsePacket CreateCreateResponseAsync(
            Smb2Endpoint endpoint,
            ulong asyncId,
            ulong messageId,
            OplockLevel_Values oplockLevel,
            CreateAction_Values createAction,
            _FILETIME creationTime,
            _FILETIME lastAccessTime,
            _FILETIME lastWriteTime,
            _FILETIME changeTime,
            ulong allocationSize,
            ulong endofFile,
            File_Attributes fileAttributes,
            FILEID fileId,
            params CREATE_CONTEXT_Values[] contexts
            )
        {
            Smb2CreateResponsePacket packet = CreateCreateResponse(endpoint, messageId, oplockLevel,
                createAction, creationTime, lastAccessTime, lastWriteTime, changeTime, allocationSize,
                endofFile, fileAttributes, fileId, contexts);

            ModifyAsyncHeader(packet, endpoint, asyncId);

            packet.Sign();

            return packet;
        }
        public Smb2CreateResponsePacket CreateCreateResponse(
            Smb2Endpoint endpoint,
            ulong messageId,
            OplockLevel_Values oplockLevel,
            CreateAction_Values createAction,
            _FILETIME creationTime,
            _FILETIME lastAccessTime,
            _FILETIME lastWriteTime,
            _FILETIME changeTime,
            ulong allocationSize,
            ulong endofFile,
            File_Attributes fileAttributes,
            FILEID fileId,
            params CREATE_CONTEXT_Values[] createContexts
            )
        {
            Smb2CreateResponsePacket packet = new Smb2CreateResponsePacket();

            SetHeader(packet, endpoint, messageId);

            packet.PayLoad.StructureSize = CREATE_Response_StructureSize_Values.V1;
            packet.PayLoad.OplockLevel = oplockLevel;
            packet.PayLoad.Reserved = 0;
            packet.PayLoad.CreateAction = createAction;
            packet.PayLoad.CreationTime = creationTime;
            packet.PayLoad.LastAccessTime = lastAccessTime;
            packet.PayLoad.LastWriteTime = lastWriteTime;
            packet.PayLoad.ChangeTime = changeTime;
            packet.PayLoad.AllocationSize = allocationSize;
            packet.PayLoad.EndofFile = endofFile;
            packet.PayLoad.FileAttributes = fileAttributes;
            packet.PayLoad.Reserved2 = 0;
            packet.PayLoad.FileId = fileId;

            if (createContexts == null)
            {
                packet.PayLoad.CreateContextsOffset = 0;
                packet.PayLoad.CreateContextsLength = 0;
                packet.PayLoad.Buffer = new byte[0];
            }
            else
            {
                packet.PayLoad.CreateContextsOffset = Smb2Consts.CreateContextOffsetInCreateResponse;

                using (MemoryStream ms = new MemoryStream())
                {
                    for (int i = 0; i < createContexts.Length; i++)
                    {
                        byte[] createContext = TypeMarshal.ToBytes(createContexts[i]);

                        if (i != (createContexts.Length - 1))
                        {
                            int alignedLen = Smb2Utility.AlignBy8Bytes(createContext.Length);

                            byte[] nextValue = BitConverter.GetBytes(alignedLen);
                            Array.Copy(nextValue, createContext, nextValue.Length);

                            ms.Write(createContext, 0, createContext.Length);

                            //write the padding 0;
                            for (int j = 0; j < (alignedLen - createContext.Length); j++)
                            {
                                ms.WriteByte(0);
                            }
                        }
                        else
                        {
                            ms.Write(createContext, 0, createContext.Length);
                        }
                    }

                    packet.PayLoad.Buffer = ms.ToArray();
                    packet.PayLoad.CreateContextsLength = (uint)packet.PayLoad.Buffer.Length;
                }
            }

            packet.Sign();

            return packet;
        }
        public static void Verification(ModelBreakType breakType, OplockLevel_Values grantedOplockType, ModelLeaseStateType grantedLeaseType)
        {
            PrintMatrixAndState();
            // 1st Client(Oplock)      2nd Client(Lease)   OplockBreakExist   GrantedLeaseState
            // ================================================================================
            // OPLOCK_LEVEL_II         Any Lease           No                 Lease_R
            // OPLOCK_LEVEL_EXCLUSIVE  Any Lease           Yes                Lease_R
            // OPLOCK_LEVEL_BATCH      Any Lease           Yes                Lease_R
            switch (OplockState)
            {
                // The first request is not for Oplock
                case OplockLevel_Values.OPLOCK_LEVEL_NONE:
                    break;
                case OplockLevel_Values.OPLOCK_LEVEL_II:
                    Condition.IsTrue(breakType == ModelBreakType.NoBreak);
                    Condition.IsTrue(grantedLeaseType == ModelLeaseStateType.Lease_R);
                    break;
                case OplockLevel_Values.OPLOCK_LEVEL_EXCLUSIVE:
                case OplockLevel_Values.OPLOCK_LEVEL_BATCH:
                    Condition.IsTrue(breakType == ModelBreakType.OplockBreak);
                    Condition.IsTrue(grantedLeaseType == ModelLeaseStateType.Lease_R);
                    break;
                default:
                    break;
            }

            // 1st Client(Lease)      2nd Client(Oplock)   LeaseBreakExist   GrantedOplockLevel
            // ================================================================================
            // Lease_R                Any Oplock           No                OPLOCK_LEVEL_II
            // Lease_RH               Any Oplock           No                OPLOCK_LEVEL_NONE
            // Lease_RW               Any Oplock           Yes               OPLOCK_LEVEL_II
            // Lease_RWH              Any Oplock           Yes               OPLOCK_LEVEL_NONE
            switch (LeaseState)
            {
                // The first request is not for Lease
                case ModelLeaseStateType.Lease_None:
                    break;
                case ModelLeaseStateType.Lease_R:
                    Condition.IsTrue(breakType == ModelBreakType.NoBreak);
                    Condition.IsTrue(grantedOplockType == OplockLevel_Values.OPLOCK_LEVEL_II);
                    break;
                case ModelLeaseStateType.Lease_RH:
                    Condition.IsTrue(breakType == ModelBreakType.NoBreak);
                    Condition.IsTrue(grantedOplockType == OplockLevel_Values.OPLOCK_LEVEL_NONE);
                    break;
                case ModelLeaseStateType.Lease_RW:
                    Condition.IsTrue(breakType == ModelBreakType.LeaseBreak);
                    Condition.IsTrue(grantedOplockType == OplockLevel_Values.OPLOCK_LEVEL_II);
                    break;
                case ModelLeaseStateType.Lease_RWH:
                    Condition.IsTrue(breakType == ModelBreakType.LeaseBreak);
                    Condition.IsTrue(grantedOplockType == OplockLevel_Values.OPLOCK_LEVEL_NONE);
                    break;
                default:
                    break;
            }
        }
        public static void RequestOplockAndOperateFileReturn(OplockLevel_Values grantedOplockLevel, OplockConfig c)
        {
            Condition.IsTrue(State == ModelState.Connected);
            Condition.IsNotNull(Request);

            ModelRequestOplockAndTriggerBreakRequest requestOplockAndTriggerBreakRequest = ModelHelper.RetrieveOutstandingRequest <ModelRequestOplockAndTriggerBreakRequest>(ref Request);

            Condition.IsTrue(Config.Platform == c.Platform);

            if (Share_ForceLevel2Oplock &&
                (requestOplockAndTriggerBreakRequest.RequestedOplockLevel == RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH ||
                 requestOplockAndTriggerBreakRequest.RequestedOplockLevel == RequestedOplockLevel_Values.OPLOCK_LEVEL_EXCLUSIVE))
            {
                ModelHelper.Log(LogType.Requirement,
                                "3.3.5.9: If TreeConnect.Share.ForceLevel2Oplock is TRUE, " +
                                "and RequestedOplockLevel is SMB2_OPLOCK_LEVEL_BATCH or SMB2_OPLOCK_LEVEL_EXCLUSIVE, " +
                                "the server SHOULD<245> set RequestedOplockLevel to SMB2_OPLOCK_LEVEL_II.");
                if (Config.Platform != Platform.NonWindows)
                {
                    ModelHelper.Log(LogType.TestInfo, "The SUT platform is Windows.");
                    Condition.IsTrue(grantedOplockLevel == OplockLevel_Values.OPLOCK_LEVEL_II);

                    // Skip following WBN which is for pre-Win8
                    // <226> Section 3.3.5.9: Windows Vista and Windows Server 2008 do not support the SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK flag
                    // and ignore  the TreeConnect.Share.ForceLevel2Oplock value.
                }
            }

            if (ModelUtility.IsSmb3xFamily(Connection_Dialect) &&
                Share_Type_Include_STYPE_CLUSTER_SOFS &&
                requestOplockAndTriggerBreakRequest.RequestedOplockLevel == RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH)
            {
                ModelHelper.Log(LogType.Requirement,
                                "3.3.5.9: If Connection.Dialect belongs to the SMB 3.x dialect family TreeConnect.Share.Type includes STYPE_CLUSTER_SOFS " +
                                "and the RequestedOplockLevel is SMB2_OPLOCK_LEVEL_BATCH, the server MUST set RequestedOplockLevel to SMB2_OPLOCK_LEVEL_II.");
                // The Oplock acquisition depends on underlying object store implemention specific
                // we may not garantee level2 would be always granted
                // Only assert it's not batch
                ModelHelper.Log(LogType.TestInfo, "All the above conditions are met.");
                Condition.IsTrue(grantedOplockLevel != OplockLevel_Values.OPLOCK_LEVEL_BATCH);
            }

            Open = new ModelOplockOpen();

            ModelHelper.Log(LogType.TestInfo, "Open.OplockLevel is set to SMB2_OPLOCK_LEVEL_NONE.");
            Open.OplockLevel = OplockLevel_Values.OPLOCK_LEVEL_NONE;

            ModelHelper.Log(LogType.TestInfo, "Open.OplockState is set to None.");
            Open.OplockState = OplockState.None;

            // Acquire Oplock from underlying object

            // If the underlying object store grants the oplock,
            // then Open.OplockState is set to Held and Open.OplockLevel is set to the level of the oplock acquired.
            if (grantedOplockLevel != OplockLevel_Values.OPLOCK_LEVEL_NONE)
            {
                ModelHelper.Log(LogType.TestInfo, "Open.OplockState is set to Held.");
                Open.OplockState = OplockState.Held;
                Open.OplockLevel = grantedOplockLevel;
            }
        }
示例#14
0
        public static void Verification(ModelBreakType breakType, OplockLevel_Values grantedOplockType, ModelLeaseStateType grantedLeaseType)
        {
            PrintMatrixAndState();
            // 1st Client(Oplock)      2nd Client(Lease)   OplockBreakExist   GrantedLeaseState
            // ================================================================================
            // OPLOCK_LEVEL_II         Any Lease           No                 Lease_R
            // OPLOCK_LEVEL_EXCLUSIVE  Any Lease           Yes                Lease_R
            // OPLOCK_LEVEL_BATCH      Any Lease           Yes                Lease_R
            switch (OplockState)
            {
            // The first request is not for Oplock
            case OplockLevel_Values.OPLOCK_LEVEL_NONE:
                break;

            case OplockLevel_Values.OPLOCK_LEVEL_II:
                Condition.IsTrue(breakType == ModelBreakType.NoBreak);
                Condition.IsTrue(grantedLeaseType == ModelLeaseStateType.Lease_R);
                break;

            case OplockLevel_Values.OPLOCK_LEVEL_EXCLUSIVE:
            case OplockLevel_Values.OPLOCK_LEVEL_BATCH:
                Condition.IsTrue(breakType == ModelBreakType.OplockBreak);
                Condition.IsTrue(grantedLeaseType == ModelLeaseStateType.Lease_R);
                break;

            default:
                break;
            }

            // 1st Client(Lease)      2nd Client(Oplock)   LeaseBreakExist   GrantedOplockLevel
            // ================================================================================
            // Lease_R                Any Oplock           No                OPLOCK_LEVEL_II
            // Lease_RH               Any Oplock           No                OPLOCK_LEVEL_NONE
            // Lease_RW               Any Oplock           Yes               OPLOCK_LEVEL_II
            // Lease_RWH              Any Oplock           Yes               OPLOCK_LEVEL_NONE
            switch (LeaseState)
            {
            // The first request is not for Lease
            case ModelLeaseStateType.Lease_None:
                break;

            case ModelLeaseStateType.Lease_R:
                Condition.IsTrue(breakType == ModelBreakType.NoBreak);
                Condition.IsTrue(grantedOplockType == OplockLevel_Values.OPLOCK_LEVEL_II);
                break;

            case ModelLeaseStateType.Lease_RH:
                Condition.IsTrue(breakType == ModelBreakType.NoBreak);
                Condition.IsTrue(grantedOplockType == OplockLevel_Values.OPLOCK_LEVEL_NONE);
                break;

            case ModelLeaseStateType.Lease_RW:
                Condition.IsTrue(breakType == ModelBreakType.LeaseBreak);
                Condition.IsTrue(grantedOplockType == OplockLevel_Values.OPLOCK_LEVEL_II);
                break;

            case ModelLeaseStateType.Lease_RWH:
                Condition.IsTrue(breakType == ModelBreakType.LeaseBreak);
                Condition.IsTrue(grantedOplockType == OplockLevel_Values.OPLOCK_LEVEL_NONE);
                break;

            default:
                break;
            }
        }