コード例 #1
0
 public static void IndicateOplockBreak(
     ref NewOplockLevel newOplockLevel,
     ref bool AcknowledgeRequired,
     ref MessageStatus returnStatus)
 {
     Helper.CaptureRequirement(6437, @"[In Indicating an Oplock Break to the Server]The object store MUST return ReturnStatus, 
         AcknowledgeRequired, and NewOplockLevel to the server.");
 }
コード例 #2
0
        public static MessageStatus OplockBreakAcknowledge(
            bool OpenStreamOplockEmpty,
            OpType opType,
            RequestedOplockLevel level,
            bool ExclusiveOpenEqual,
            OplockState oplockState,
            bool RHBreakQueueIsEmpty,
            bool ThisContextOpenEqual,
            bool ThisContextBreakingToRead,
            bool OplockWaitListEmpty,
            bool StreamIsDeleted,
            bool GrantingInAck,
            bool keyEqualOnRHOplocks,
            bool keyEqualOnRHBreakQueue,
            bool keyEqualOnROplocks,
            RequestedOplock requestOplock
            )
        {
            bool        NewOplockGranted = false;
            bool        ReturnBreakToNone = false;
            bool        FoundMatchingRHOplock = false;
            OplockState BREAK_LEVEL_MASK, R_AND_RH_GRANTED, RH_GRANTED;

            //If Open.Stream.Oplock is empty, the operation MUST be failed
            //with STATUS_INVALID_OPLOCK_PROTOCOL.
            if (OpenStreamOplockEmpty)
            {
                Helper.CaptureRequirement(6450, @"[In Server Acknowledges an Oplock Break]Pseudocode for the operation is as follows:
                    If Open.Stream.Oplock is empty, the operation MUST be failed with STATUS_INVALID_OPLOCK_PROTOCOL.");
                return(MessageStatus.INVALID_OPLOCK_PROTOCOL);
            }

            if (opType == OpType.LEVEL_ONE || opType == OpType.LEVEL_TWO)
            {
                //If Open.Stream.Oplock.ExclusiveOpen is not equal to Open,
                //the operation MUST be failed with STATUS_INVALID_OPLOCK_PROTOCOL.
                if (!ExclusiveOpenEqual)
                {
                    Helper.CaptureRequirement(6451, @"[In Server Acknowledges an Oplock Break,Pseudocode for the operation is as follows:]
                        If Type is LEVEL_NONE or LEVEL_TWO:If Open.Stream.Oplock.ExclusiveOpen is not equal to Open, 
                        the operation MUST be failed with STATUS_INVALID_OPLOCK_PROTOCOL.");
                    return(MessageStatus.INVALID_OPLOCK_PROTOCOL);
                }

                if (opType == OpType.LEVEL_TWO &&
                    (oplockState & OplockState.BREAK_TO_TWO) != 0)
                {
                    oplockState      = OplockState.LEVEL_TWO_OPLOCK;
                    NewOplockGranted = true;
                }
                else if ((oplockState & OplockState.BREAK_TO_TWO) != 0 ||
                         (oplockState & OplockState.BREAK_TO_TWO_TO_NONE) != 0)
                {
                    oplockState = OplockState.NO_OPLOCK;
                }
                else if ((oplockState & OplockState.BREAK_TO_TWO_TO_NONE) != 0)
                {
                    oplockState       = OplockState.NO_OPLOCK;
                    ReturnBreakToNone = true;
                }
                else
                {
                    Helper.CaptureRequirement(6457, @"[In Server Acknowledges an Oplock Break,Pseudocode for the operation is as follows:]
                        Else[If Type is not LEVEL_NONE and not LEVEL_TWO:The operation MUST be failed with STATUS_INVALID_OPLOCK_PROTOCOL.");
                    return(MessageStatus.INVALID_OPLOCK_PROTOCOL);
                }


                if (NewOplockGranted)
                {
                    //The operation waits until the newly-granted Level 2 oplock is broken
                }
                else if (ReturnBreakToNone)
                {
                    //call 3.1.5.17.3
                    NewOplockLevel newLevel = NewOplockLevel.LEVEL_NONE;
                    bool           b        = false;
                    MessageStatus  m        = MessageStatus.SUCCESS;
                    IndicateOplockBreak(ref newLevel, ref b, ref m);
                    Helper.CaptureRequirement(6465, @"[In Server Acknowledges an Oplock Break,Pseudocode for the operation is as follows:
                        Else If ReturnBreakToNone is TRUE:]In this case the server was expecting the oplock to break to Level 2, 
                        but because the oplock is actually breaking to None (that is, no oplock), 
                        the object store MUST indicate an oplock break to the server according to the algorithm in section 3.1.5.17.3, 
                        setting the algorithm's parameters as follows:ReturnStatus equal to STATUS_SUCCESS.");
                }
                else
                {
                    Helper.CaptureRequirement(6466, @"[In Server Acknowledges an Oplock Break,Pseudocode for the operation is as follows:]
                        Else[If ReturnBreakToNone is FALSE]The operation MUST immediately return STATUS_SUCCESS.");
                    return(MessageStatus.SUCCESS);
                }
            }
            else if (opType == OpType.LEVEL_GRANULAR)
            {
                //Let BREAK_LEVEL_MASK = (BREAK_TO_READ_CACHING | BREAK_TO_WRITE_CACHING |
                //BREAK_TO_HANDLE_CACHING | BREAK_TO_NO_CACHING)
                BREAK_LEVEL_MASK = OplockState.BREAK_TO_READ_CACHING |
                                   OplockState.BREAK_TO_WRITE_CACHING |
                                   OplockState.BREAK_TO_HANDLE_CACHING |
                                   OplockState.BREAK_TO_NO_CACHING;

                //Let R_AND_RH_GRANTED = (READ_CACHING|HANDLE_CACHING|MIXED_R_AND_RH)
                R_AND_RH_GRANTED = OplockState.READ_CACHING |
                                   OplockState.HANDLE_CACHING |
                                   OplockState.MIXED_R_AND_RH;

                //Let RH_GRANTED = (READ_CACHING|HANDLE_CACHING)
                RH_GRANTED = OplockState.READ_CACHING | OplockState.HANDLE_CACHING;

                if ((((oplockState & BREAK_LEVEL_MASK) == 0) &&
                     (oplockState != R_AND_RH_GRANTED) &&
                     (oplockState != RH_GRANTED)) ||
                    (((oplockState == R_AND_RH_GRANTED) ||
                      (oplockState == RH_GRANTED)) && RHBreakQueueIsEmpty))
                {
                    Helper.CaptureRequirement(6471, @"[In Server Acknowledges an Oplock Break,Pseudocode for the operation is as follows:
                        Else If Type is LEVEL_GRANULAR:]If (Open.Stream.Oplock.State does not contain any flag in BREAK_LEVEL_MASK 
                        and (Open.Stream.Oplock.State != R_AND_RH_GRANTED) and (Open.Stream.Oplock.State != RH_GRANTED)) 
                        or (((Open.Stream.Oplock.State == R_AND_RH_GRANTED) or (Open.Stream.Oplock.State == RH_GRANTED)) 
                        and Open.Stream.Oplock.RHBreakQueue is empty):The request MUST be failed with STATUS_INVALID_OPLOCK_PROTOCOL.");
                    return(MessageStatus.INVALID_OPLOCK_PROTOCOL);
                }

                switch (oplockState)
                {
                case OplockState.READ_CACHING | OplockState.HANDLE_CACHING | OplockState.MIXED_R_AND_RH:
                case OplockState.READ_CACHING | OplockState.HANDLE_CACHING:
                case OplockState.READ_CACHING | OplockState.HANDLE_CACHING | OplockState.BREAK_TO_READ_CACHING:
                case OplockState.READ_CACHING | OplockState.HANDLE_CACHING | OplockState.BREAK_TO_NO_CACHING:
                {
                    //begin first for lop
                    if (ThisContextOpenEqual)
                    {
                        FoundMatchingRHOplock = true;
                        //If ThisContext.BreakingToRead is FALSE:
                        if (!ThisContextBreakingToRead)
                        {
                            //If RequestedOplockLevel is not 0 and
                            //Open.Stream.Oplock.WaitList is not empty:
                            if (level != RequestedOplockLevel.ZERO &&
                                !OplockWaitListEmpty)
                            {
                                //call 3.1.5.17.3
                                NewOplockLevel newLevel = NewOplockLevel.LEVEL_NONE;
                                bool           b        = true;
                                MessageStatus  m        = MessageStatus.CANNOT_GRANT_REQUESTED_OPLOCK;
                                IndicateOplockBreak(ref newLevel, ref b, ref m);
                                Helper.CaptureRequirement(6476, @"[In Server Acknowledges an Oplock Break,Pseudocode for the operation is as follows:
                                            Else If Type is LEVEL_GRANULAR:Switch Open.Stream.Oplock.StateCase (READ_CACHING|HANDLE_CACHING|MIXED_R_AND_RH):
                                            Case (READ_CACHING|HANDLE_CACHING):Case (READ_CACHING|HANDLE_CACHING|BREAK_TO_READ_CACHING):
                                            Case (READ_CACHING|HANDLE_CACHING|BREAK_TO_NO_CACHING):
                                            For each RHOpContext ThisContext in Open.Stream.Oplock.RHBreakQueue:
                                            If ThisContext.Open equals Open:If ThisContext.BreakingToRead is FALSE:
                                            If RequestedOplockLevel is not 0 and Open.Stream.Oplock.WaitList is not empty:
                                            The object store MUST indicate an oplock break to the server according to the algorithm in section 3.1.5.17.3, 
                                            setting the algorithm's parameters as follows:]ReturnStatus equal to STATUS_CANNOT_GRANT_REQUESTED_OPLOCK.");
                            }
                        }
                        else
                        {
                            if (!OplockWaitListEmpty &&
                                ((level == (RequestedOplockLevel.READ_CACHING |
                                            RequestedOplockLevel.WRITE_CACHING)) ||
                                 (level == (RequestedOplockLevel.READ_CACHING |
                                            RequestedOplockLevel.WRITE_CACHING |
                                            RequestedOplockLevel.HANDLE_CACHING))))
                            {
                                //call 3.1.5.17.3
                                NewOplockLevel newLevel = NewOplockLevel.READ_CACHING;
                                bool           b        = true;
                                MessageStatus  m        = MessageStatus.CANNOT_GRANT_REQUESTED_OPLOCK;
                                IndicateOplockBreak(ref newLevel, ref b, ref m);
                                Helper.CaptureRequirement(6480, @"[In Server Acknowledges an Oplock Break,Pseudocode for the operation is as follows:
                                            Else If Type is LEVEL_GRANULAR:Switch Open.Stream.Oplock.StateCase (READ_CACHING|HANDLE_CACHING|MIXED_R_AND_RH):
                                            Case (READ_CACHING|HANDLE_CACHING):Case (READ_CACHING|HANDLE_CACHING|BREAK_TO_READ_CACHING):
                                            Case (READ_CACHING|HANDLE_CACHING|BREAK_TO_NO_CACHING):
                                            For each RHOpContext ThisContext in Open.Stream.Oplock.RHBreakQueue:
                                            If ThisContext.Open equals Open:Else // ThisContext.BreakingToRead is TRUE.
                                            If Open.Stream.Oplock.WaitList is not empty and( RequestedOplockLevel is (READ_CACHING|WRITE_CACHING) 
                                            or (READ_CACHING|WRITE_CACHING|HANDLE_CACHING)):
                                            The object store MUST indicate an oplock break to the server according to the algorithm in section 3.1.5.17.3, 
                                            setting the algorithm's parameters as follows:]ReturnStatus equal to STATUS_CANNOT_GRANT_REQUESTED_OPLOCK.");
                            }
                        }

                        if (level == RequestedOplockLevel.ZERO)
                        {
                            //Recompute Open.Stream.Oplock.State according to the algorithm
                            //in section 3.1.4.13, passing Open.Stream.Oplock as the
                            //ThisOplock parameter.
                            Helper.CaptureRequirement(6485, @"[In Server Acknowledges an Oplock Break,Pseudocode for the operation is as follows:
                                        Else If Type is LEVEL_GRANULAR:Switch Open.Stream.Oplock.StateCase (READ_CACHING|HANDLE_CACHING|MIXED_R_AND_RH):
                                        Case (READ_CACHING|HANDLE_CACHING):Case (READ_CACHING|HANDLE_CACHING|BREAK_TO_READ_CACHING):
                                        Case (READ_CACHING|HANDLE_CACHING|BREAK_TO_NO_CACHING):
                                        For each RHOpContext ThisContext in Open.Stream.Oplock.RHBreakQueue:If RequestedOplockLevel is 0 (that is, no flags):]
                                        The algorithm MUST immediately return STATUS_SUCCESS.");
                            return(MessageStatus.SUCCESS);
                        }
                        else if ((level & RequestedOplockLevel.WRITE_CACHING) == 0)
                        {
                            //call 3.1.5.17.2
                            return(SharedOplock(OpenStreamOplockEmpty, oplockState, GrantingInAck, keyEqualOnRHOplocks, keyEqualOnRHBreakQueue, keyEqualOnROplocks, StreamIsDeleted, requestOplock));
                        }
                        else
                        {
                        }
                    }

                    if (!FoundMatchingRHOplock)
                    {
                        Helper.CaptureRequirement(6494, @"[In Server Acknowledges an Oplock Break,Pseudocode for the operation is as follows:Else If Type is LEVEL_GRANULAR:Switch Open.Stream.Oplock.StateCase (READ_CACHING|HANDLE_CACHING|MIXED_R_AND_RH):Case (READ_CACHING|HANDLE_CACHING):Case (READ_CACHING|HANDLE_CACHING|BREAK_TO_READ_CACHING):Case (READ_CACHING|HANDLE_CACHING|BREAK_TO_NO_CACHING):]If FoundMatchingRHOplock is FALSE:The operation MUST be failed with STATUS_INVALID_OPLOCK_PROTOCOL.");
                        return(MessageStatus.INVALID_OPLOCK_PROTOCOL);
                    }

                    Helper.CaptureRequirement(6495, @"[In Server Acknowledges an Oplock Break,Pseudocode for the operation is as follows:
                                Else If Type is LEVEL_GRANULAR:Switch Open.Stream.Oplock.StateCase (READ_CACHING|HANDLE_CACHING|MIXED_R_AND_RH):
                                Case (READ_CACHING|HANDLE_CACHING):Case (READ_CACHING|HANDLE_CACHING|BREAK_TO_READ_CACHING):Case (READ_CACHING|HANDLE_CACHING|BREAK_TO_NO_CACHING):]The operation immediately returns STATUS_SUCCESS.");
                    return(MessageStatus.SUCCESS);
                }

                case OplockState.READ_CACHING | OplockState.WRITE_CACHING | OplockState.EXCLUSIVE | OplockState.BREAK_TO_READ_CACHING:
                case OplockState.READ_CACHING | OplockState.WRITE_CACHING | OplockState.EXCLUSIVE | OplockState.BREAK_TO_NO_CACHING:
                case OplockState.READ_CACHING | OplockState.WRITE_CACHING | OplockState.HANDLE_CACHING | OplockState.EXCLUSIVE | OplockState.BREAK_TO_READ_CACHING | OplockState.BREAK_TO_WRITE_CACHING:
                case OplockState.READ_CACHING | OplockState.WRITE_CACHING | OplockState.HANDLE_CACHING | OplockState.EXCLUSIVE | OplockState.BREAK_TO_READ_CACHING | OplockState.BREAK_TO_HANDLE_CACHING:
                case OplockState.READ_CACHING | OplockState.WRITE_CACHING | OplockState.HANDLE_CACHING | OplockState.EXCLUSIVE | OplockState.BREAK_TO_READ_CACHING:
                case OplockState.READ_CACHING | OplockState.WRITE_CACHING | OplockState.HANDLE_CACHING | OplockState.EXCLUSIVE | OplockState.BREAK_TO_NO_CACHING:
                {
                    //If Open.Stream.Oplock.ExclusiveOpen != Open
                    if (!ExclusiveOpenEqual)
                    {
                        Helper.CaptureRequirement(6496, @"[In Server Acknowledges an Oplock Break,Pseudocode for the operation is as follows:
                                    Else If Type is LEVEL_GRANULAR:Switch Open.Stream.Oplock.State]Case 
                                   (READ_CACHING|WRITE_CACHING|EXCLUSIVE|BREAK_TO_READ_CACHING):
                                    Case (READ_CACHING|WRITE_CACHING|EXCLUSIVE|BREAK_TO_NO_CACHING):
                                    Case (READ_CACHING|WRITE_CACHING|HANDLE_CACHING|EXCLUSIVE|BREAK_TO_READ_CACHING|BREAK_TO_WRITE_CACHING):
                                    Case (READ_CACHING|WRITE_CACHING|HANDLE_CACHING|EXCLUSIVE|BREAK_TO_READ_CACHING|BREAK_TO_HANDLE_CACHING):
                                    Case (READ_CACHING|WRITE_CACHING|HANDLE_CACHING|EXCLUSIVE|BREAK_TO_READ_CACHING):
                                    Case (READ_CACHING|WRITE_CACHING|HANDLE_CACHING|EXCLUSIVE|BREAK_TO_NO_CACHING):
                                    If Open.Stream.Oplock.ExclusiveOpen != Open:The operation MUST be failed with STATUS_INVALID_OPLOCK_PROTOCOL.");
                        return(MessageStatus.INVALID_OPLOCK_PROTOCOL);
                    }

                    //If Open.Stream.Oplock.WaitList is not empty and
                    //Open.Stream.Oplock.State does not contain HANDLE_CACHING and
                    //RequestedOplockLevel is (READ_CACHING|WRITE_CACHING|HANDLE_CACHING):
                    if (!OplockWaitListEmpty &&
                        ((oplockState & OplockState.HANDLE_CACHING) == 0) &&
                        (level == (RequestedOplockLevel.READ_CACHING |
                                   RequestedOplockLevel.WRITE_CACHING |
                                   RequestedOplockLevel.HANDLE_CACHING)))
                    {
                        //call 3.1.5.17.3
                        NewOplockLevel newLevel = NewOplockLevel.READ_CACHING;
                        bool           b        = true;
                        MessageStatus  m        = MessageStatus.CANNOT_GRANT_REQUESTED_OPLOCK;
                        IndicateOplockBreak(ref newLevel, ref b, ref m);
                        Helper.CaptureRequirement(6503, @"[In Server Acknowledges an Oplock Break,Pseudocode for the operation is as follows:
                                    Else If Type is LEVEL_GRANULAR:Switch Open.Stream.Oplock.State,
                                    Case (READ_CACHING|WRITE_CACHING|EXCLUSIVE|BREAK_TO_READ_CACHING):
                                    Case (READ_CACHING|WRITE_CACHING|EXCLUSIVE|BREAK_TO_NO_CACHING):
                                    Case (READ_CACHING|WRITE_CACHING|HANDLE_CACHING|EXCLUSIVE|BREAK_TO_READ_CACHING|BREAK_TO_WRITE_CACHING):
                                    Case (READ_CACHING|WRITE_CACHING|HANDLE_CACHING|EXCLUSIVE|BREAK_TO_READ_CACHING|BREAK_TO_HANDLE_CACHING):
                                    Case (READ_CACHING|WRITE_CACHING|HANDLE_CACHING|EXCLUSIVE|BREAK_TO_READ_CACHING):
                                    Case (READ_CACHING|WRITE_CACHING|HANDLE_CACHING|EXCLUSIVE|BREAK_TO_NO_CACHING):]
                                    If Open.Stream.Oplock.WaitList is not empty and Open.Stream.Oplock.
                                    State does not contain HANDLE_CACHING and RequestedOplockLevel is (READ_CACHING|WRITE_CACHING|HANDLE_CACHING):]
                                    ReturnStatus equal to STATUS_CANNOT_GRANT_REQUESTED_OPLOCK.");
                    }
                    else
                    {
                        if (StreamIsDeleted && ((level & RequestedOplockLevel.HANDLE_CACHING) != 0))
                        {
                            //call 3.1.5.17.3
                            NewOplockLevel newLevel = NewOplockLevel.READ_CACHING | NewOplockLevel.HANDLE_CACHING;
                            bool           b        = true;
                            MessageStatus  m        = MessageStatus.CANNOT_GRANT_REQUESTED_OPLOCK;
                            IndicateOplockBreak(ref newLevel, ref b, ref m);
                            Helper.CaptureRequirement(6507, @"[In Server Acknowledges an Oplock Break,Pseudocode for the operation is as follows:
                                        Else If Type is LEVEL_GRANULAR:Switch Open.Stream.Oplock.State,
                                        Case (READ_CACHING|WRITE_CACHING|EXCLUSIVE|BREAK_TO_READ_CACHING):
                                        Case (READ_CACHING|WRITE_CACHING|EXCLUSIVE|BREAK_TO_NO_CACHING):
                                        Case (READ_CACHING|WRITE_CACHING|HANDLE_CACHING|EXCLUSIVE|BREAK_TO_READ_CACHING|BREAK_TO_WRITE_CACHING):
                                        Case (READ_CACHING|WRITE_CACHING|HANDLE_CACHING|EXCLUSIVE|BREAK_TO_READ_CACHING|BREAK_TO_HANDLE_CACHING):
                                        Case (READ_CACHING|WRITE_CACHING|HANDLE_CACHING|EXCLUSIVE|BREAK_TO_READ_CACHING):
                                        Case (READ_CACHING|WRITE_CACHING|HANDLE_CACHING|EXCLUSIVE|BREAK_TO_NO_CACHING):
                                        ElseIf Open.Stream.IsDeleted is TRUE and RequestedOplockLevel contains HANDLE_CACHING:]
                                        The object store MUST indicate an oplock break to the server according to the algorithm in section 3.1.5.17.3, 
                                        setting the algorithm's parameters as follows:ReturnStatus equal to STATUS_CANNOT_GRANT_REQUESTED_OPLOCK.");
                        }

                        if (level == RequestedOplockLevel.ZERO)
                        {
                            oplockState = OplockState.NO_OPLOCK;
                            Helper.CaptureRequirement(6512, @"[In Server Acknowledges an Oplock Break,Pseudocode for the operation is as follows:
                                        Else If Type is LEVEL_GRANULAR:Switch Open.Stream.Oplock.State,Case (READ_CACHING|WRITE_CACHING|EXCLUSIVE|BREAK_TO_READ_CACHING):
                                        Case (READ_CACHING|WRITE_CACHING|EXCLUSIVE|BREAK_TO_NO_CACHING):
                                        Case (READ_CACHING|WRITE_CACHING|HANDLE_CACHING|EXCLUSIVE|BREAK_TO_READ_CACHING|BREAK_TO_WRITE_CACHING):
                                        Case (READ_CACHING|WRITE_CACHING|HANDLE_CACHING|EXCLUSIVE|BREAK_TO_READ_CACHING|BREAK_TO_HANDLE_CACHING):
                                        Case (READ_CACHING|WRITE_CACHING|HANDLE_CACHING|EXCLUSIVE|BREAK_TO_READ_CACHING):
                                        Case (READ_CACHING|WRITE_CACHING|HANDLE_CACHING|EXCLUSIVE|BREAK_TO_NO_CACHING):
                                        If RequestedOplockLevel is 0 (that is, no flags):]The operation immediately returns STATUS_SUCCESS.");
                            return(MessageStatus.SUCCESS);
                        }
                        else if ((level & RequestedOplockLevel.WRITE_CACHING) == 0)
                        {
                            //The object store MUST request a shared oplock according to the
                            //algorithm in section 3.1.5.17.2, setting the algorithm's
                            //parameters as follows:
                        }
                        else
                        {
                            oplockState = (OplockState)level | OplockState.EXCLUSIVE;
                        }
                    }
                    break;
                }

                default:
                    Helper.CaptureRequirement(6442, @"[In Server Acknowledges an Oplock Break]Whether the new oplock is granted or not, the object store MUST return:[Status].");
                    Helper.CaptureRequirement(6519, @"[In Server Acknowledges an Oplock Break,Pseudocode for the operation is as follows:
                            Else If Type is LEVEL_GRANULAR:Switch Open.Stream.Oplock.State]The operation MUST be failed with STATUS_INVALID_OPLOCK_PROTOCOL.");
                    return(MessageStatus.INVALID_OPLOCK_PROTOCOL);
                }
            }
            return(MessageStatus.SUCCESS);
        }
コード例 #3
0
 public static void IndicateOplockBreak(
     ref NewOplockLevel newOplockLevel,
     ref bool AcknowledgeRequired,
     ref MessageStatus returnStatus)
 {
     Helper.CaptureRequirement(6437, @"[In Indicating an Oplock Break to the Server]The object store MUST return ReturnStatus,
         AcknowledgeRequired, and NewOplockLevel to the server.");
 }
コード例 #4
0
        public static MessageStatus ExclusiveOplock(
            bool isOpenStreamOplockEmpty,
            OplockState oplockState,
            bool isOpenListContains,
            bool streamIsDeleted,
            bool isRHBreakQueueEmpty,
            bool isOplockKeyEqual,
            bool isOplockKeyEqualExclusive,
            RequestedOplock requestOplock)
        {
            //If Open.Stream.Oplock is empty
            if (isOpenStreamOplockEmpty)
            {
                gOplockState = OplockState.NO_OPLOCK;
            }

            //If Open.Stream.Oplock.State contains LEVEL_TWO_OPLOCK or NO_OPLOCK:
            if ((oplockState & OplockState.LEVEL_TWO_OPLOCK) != 0 ||
                (oplockState & OplockState.NO_OPLOCK) != 0)
            {
                //If Open.Stream.Oplock.State contains LEVEL_TWO_OPLOCK and RequestedOplock
                //contains one or more of READ_CACHING, HANDLE_CACHING, or WRITE_CACHING,
                //the operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED.
                if ((oplockState & OplockState.LEVEL_TWO_OPLOCK) != 0 &&
                    (requestOplock == RequestedOplock.READ_CACHING ||
                     requestOplock == RequestedOplock.HANDLE_CACHING ||
                     requestOplock == RequestedOplock.WRITE_CACHING ||
                     requestOplock == RequestedOplock.READ_HANDLE ||
                     requestOplock == RequestedOplock.READ_WRITE ||
                     requestOplock == RequestedOplock.READ_WRITE_HANDLE))
                {
                    Helper.CaptureRequirement(6344, @"[In Algorithm to Request an Exclusive Oplock,Pseudocode for the algorithm is as follows:]
                        If Open.Stream.Oplock.State contains LEVEL_TWO_OPLOCK or NO_OPLOCK:If Open.Stream.Oplock.State contains LEVEL_TWO_OPLOCK 
                        and RequestedOplock contains one or more of READ_CACHING, HANDLE_CACHING, or WRITE_CACHING, 
                        the operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED.");
                    return(MessageStatus.OPLOCK_NOT_GRANTED);
                }

                if (oplockState == OplockState.LEVEL_TWO_OPLOCK)
                {
                    NewOplockLevel newLevel = NewOplockLevel.LEVEL_NONE;
                    bool           b        = false;
                    MessageStatus  m        = MessageStatus.SUCCESS;
                    IndicateOplockBreak(ref newLevel, ref b, ref m);
                    Helper.CaptureRequirement(6348, @"[In Algorithm to Request an Exclusive Oplock,Pseudocode for the algorithm is as follows:
                        If Open.Stream.Oplock.State contains LEVEL_TWO_OPLOCK or NO_OPLOCK:
                        Remove the first Open ThisOpen from Open.Stream.Oplock.IIOplocks (there should be exactly one present), 
                        and notify the server of an oplock break according to the algorithm in section 3.1.5.17.3, 
                        setting the algorithm's parameters as follows:]ReturnStatus equal to STATUS_SUCCESS.");
                }

                //If Open.File.OpenList contains more than one Open whose Stream is the same
                //as Open.Stream, and NO_OPLOCK is present in Open.Stream.Oplock.State
                if (isOpenListContains && (oplockState & OplockState.NO_OPLOCK) != 0)
                {
                    Helper.CaptureRequirement(6349, @"[In Algorithm to Request an Exclusive Oplock,Pseudocode for the algorithm is as follows:]
                        If Open.File.OpenList contains more than one Open whose Stream is the same as Open.Stream, 
                        and NO_OPLOCK is present in Open.Stream.Oplock.State, the operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED.");
                    return(MessageStatus.OPLOCK_NOT_GRANTED);
                }

                //If Open.Stream.IsDeleted is true and RequestedOplock contains HANDLE_CACHING,
                //the operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED.
                if (streamIsDeleted &&
                    (requestOplock == RequestedOplock.HANDLE_CACHING ||
                     requestOplock == RequestedOplock.READ_HANDLE ||
                     requestOplock == RequestedOplock.READ_WRITE_HANDLE))
                {
                    Helper.CaptureRequirement(6350, @"[In Algorithm to Request an Exclusive Oplock,Pseudocode for the algorithm is as follows:]
                        If Open.Stream.IsDeleted is TRUE and RequestedOplock contains HANDLE_CACHING, 
                        the operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED.");
                    return(MessageStatus.OPLOCK_NOT_GRANTED);
                }
            }
            else if (((oplockState & (OplockState.READ_CACHING |
                                      OplockState.WRITE_CACHING |
                                      OplockState.HANDLE_CACHING)) != 0) &&
                     ((oplockState & (OplockState.BREAK_TO_TWO |
                                      OplockState.BREAK_TO_NONE |
                                      OplockState.BREAK_TO_TWO_TO_NONE |
                                      OplockState.BREAK_TO_READ_CACHING |
                                      OplockState.BREAK_TO_WRITE_CACHING |
                                      OplockState.BREAK_TO_HANDLE_CACHING |
                                      OplockState.BREAK_TO_NO_CACHING)) == 0) &&
                     isRHBreakQueueEmpty)
            {
                if (requestOplock != RequestedOplock.READ_CACHING &&
                    requestOplock != RequestedOplock.WRITE_CACHING &&
                    requestOplock != RequestedOplock.HANDLE_CACHING &&
                    requestOplock != RequestedOplock.READ_HANDLE &&
                    requestOplock != RequestedOplock.READ_WRITE &&
                    requestOplock != RequestedOplock.READ_WRITE_HANDLE)
                {
                    Helper.CaptureRequirement(6353, @"[In Algorithm to Request an Exclusive Oplock,Pseudocode for the algorithm is as follows:]
                        If RequestedOplock contains none of READ_CACHING, WRITE_CACHING, or HANDLE_CACHING, 
                         the operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED.");
                    return(MessageStatus.OPLOCK_NOT_GRANTED);
                }

                //If Open.Stream.IsDeleted is true and RequestedOplock contains HANDLE_CACHING,
                //the operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED.
                if (streamIsDeleted &&
                    (requestOplock == RequestedOplock.HANDLE_CACHING ||
                     requestOplock == RequestedOplock.READ_HANDLE ||
                     requestOplock == RequestedOplock.READ_WRITE_HANDLE))
                {
                    Helper.CaptureRequirement(6354, @"[In Algorithm to Request an Exclusive Oplock,Pseudocode for the algorithm is as follows:]
                        If Open.Stream.IsDeleted is TRUE and RequestedOplock contains HANDLE_CACHING, 
                        the operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED.");
                    return(MessageStatus.OPLOCK_NOT_GRANTED);
                }

                switch (oplockState)
                {
                case OplockState.READ_CACHING:
                {
                    if (requestOplock != RequestedOplock.READ_WRITE &&
                        requestOplock != RequestedOplock.READ_WRITE_HANDLE)
                    {
                        Helper.CaptureRequirement(6355, @"[In Algorithm to Request an Exclusive Oplock,Pseudocode for the algorithm is as follows:
                                    Else If (Open.Stream.Oplock.State contains one or more of READ_CACHING, WRITE_CACHING, or HANDLE_CACHING) 
                                    and(Open.Stream.Oplock.State contains none of BREAK_TO_TWO, BREAK_TO_NONE, BREAK_TO_TWO_TO_NONE, BREAK_TO_READ_CACHING, 
                                    BREAK_TO_WRITE_CACHING, BREAK_TO_HANDLE_CACHING, or BREAK_TO_NO_CACHING) and           
                                    (Open.Stream.Oplock.State.RHBreakQueue is empty):]Switch (Open.Stream.Oplock.State):
                                    Case READ_CACHING:If RequestedOplock is neither (READ_CACHING|WRITE_CACHING) nor (READ_CACHING|WRITE_CACHING|HANDLE_CACHING), 
                                    the operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED.");
                        return(MessageStatus.OPLOCK_NOT_GRANTED);
                    }

                    //If ThisOpen.OplockKey != Open.OplockKey, the operation
                    //MUST be failed with STATUS_OPLOCK_NOT_GRANTED.
                    if (!isOplockKeyEqual)
                    {
                        Helper.CaptureRequirement(6356, @"[In Algorithm to Request an Exclusive Oplock,Pseudocode for the algorithm is as follows:
                                    Else If (Open.Stream.Oplock.State contains one or more of READ_CACHING, WRITE_CACHING, or HANDLE_CACHING) 
                                    and (Open.Stream.Oplock.State contains none of BREAK_TO_TWO, BREAK_TO_NONE, BREAK_TO_TWO_TO_NONE, BREAK_TO_READ_CACHING, 
                                    BREAK_TO_WRITE_CACHING, BREAK_TO_HANDLE_CACHING, or BREAK_TO_NO_CACHING) and           
                                    (Open.Stream.Oplock.State.RHBreakQueue is empty):Switch (Open.Stream.Oplock.State):Case READ_CACHING:]
                                    For each Open ThisOpen in Open.Stream.Oplock.ROplocks:If ThisOpen.OplockKey != Open.OplockKey, 
                                    the operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED.");
                        return(MessageStatus.OPLOCK_NOT_GRANTED);
                    }

                    NewOplockLevel newLevel = NewOplockLevel.LEVEL_NONE;
                    bool           b        = false;
                    MessageStatus  m        = MessageStatus.OPLOCK_SWITCHED_TO_NEW_HANDLE;
                    IndicateOplockBreak(ref newLevel, ref b, ref m);
                    Helper.CaptureRequirement(6361, @"[In Algorithm to Request an Exclusive Oplock,Pseudocode for the algorithm is as follows:
                                Else If (Open.Stream.Oplock.State contains one or more of READ_CACHING, WRITE_CACHING, or HANDLE_CACHING) 
                                and (Open.Stream.Oplock.State contains none of BREAK_TO_TWO, BREAK_TO_NONE, BREAK_TO_TWO_TO_NONE, BREAK_TO_READ_CACHING, 
                                BREAK_TO_WRITE_CACHING, BREAK_TO_HANDLE_CACHING, or BREAK_TO_NO_CACHING) and           
                                (Open.Stream.Oplock.State.RHBreakQueue is empty):Switch (Open.Stream.Oplock.State):
                                Case READ_CACHING:For each Open ThisOpen in Open.Stream.Oplock.ROplocks:Notify the server of an oplock break 
                                according to the algorithm in section 3.1.5.17.3, setting the algorithm's parameters as follows:]
                                ReturnStatus equal to STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE.");

                    break;
                }

                case OplockState.READ_CACHING | OplockState.HANDLE_CACHING:
                {
                    if (requestOplock != RequestedOplock.READ_WRITE_HANDLE ||
                        !isRHBreakQueueEmpty)
                    {
                        Helper.CaptureRequirement(6363, @"[In Algorithm to Request an Exclusive Oplock,Pseudocode for the algorithm is as follows:
                                    Else If (Open.Stream.Oplock.State contains one or more of READ_CACHING, WRITE_CACHING, or HANDLE_CACHING) 
                                    and(Open.Stream.Oplock.State contains none of BREAK_TO_TWO, BREAK_TO_NONE, BREAK_TO_TWO_TO_NONE, BREAK_TO_READ_CACHING,
                                    BREAK_TO_WRITE_CACHING, BREAK_TO_HANDLE_CACHING, or BREAK_TO_NO_CACHING) and           
                                    (Open.Stream.Oplock.State.RHBreakQueue is empty):Switch (Open.Stream.Oplock.State):]
                                    Case (READ_CACHING|HANDLE_CACHING):If RequestedOplock is not (READ_CACHING|WRITE_CACHING|HANDLE_CACHING) 
                                    or Open.Stream.Oplock.RHBreakQueue is not empty, the operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED.");
                        return(MessageStatus.OPLOCK_NOT_GRANTED);
                    }

                    //If ThisOpen.OplockKey != Open.OplockKey, the operation MUST
                    //be failed with STATUS_OPLOCK_NOT_GRANTED
                    if (!isOplockKeyEqual)
                    {
                        Helper.CaptureRequirement(6364, @"[In Algorithm to Request an Exclusive Oplock,Pseudocode for the algorithm is as follows:
                                    Else If (Open.Stream.Oplock.State contains one or more of READ_CACHING, WRITE_CACHING, 
                                    or HANDLE_CACHING) and(Open.Stream.Oplock.State contains none of BREAK_TO_TWO, BREAK_TO_NONE, BREAK_TO_TWO_TO_NONE, 
                                    BREAK_TO_READ_CACHING, BREAK_TO_WRITE_CACHING, BREAK_TO_HANDLE_CACHING, or BREAK_TO_NO_CACHING) and           
                                   (Open.Stream.Oplock.State.RHBreakQueue is empty):Switch (Open.Stream.Oplock.State):Case (READ_CACHING|HANDLE_CACHING):]
                                    For each Open ThisOpen in Open.Stream.Oplock.RHOplocks:If ThisOpen.OplockKey != Open.OplockKey,
                                    the operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED.");
                        return(MessageStatus.OPLOCK_NOT_GRANTED);
                    }

                    NewOplockLevel newLevel = NewOplockLevel.LEVEL_NONE;
                    bool           b        = false;
                    MessageStatus  m        = MessageStatus.OPLOCK_SWITCHED_TO_NEW_HANDLE;
                    IndicateOplockBreak(ref newLevel, ref b, ref m);
                    Helper.CaptureRequirement(6369, @"[In Algorithm to Request an Exclusive Oplock,Pseudocode for the algorithm is as follows:
                                Else If (Open.Stream.Oplock.State contains one or more of READ_CACHING, WRITE_CACHING, or HANDLE_CACHING) 
                                and(Open.Stream.Oplock.State contains none of BREAK_TO_TWO, BREAK_TO_NONE, BREAK_TO_TWO_TO_NONE, BREAK_TO_READ_CACHING, 
                                BREAK_TO_WRITE_CACHING, BREAK_TO_HANDLE_CACHING, or BREAK_TO_NO_CACHING) and           
                               (Open.Stream.Oplock.State.RHBreakQueue is empty):Switch (Open.Stream.Oplock.State):Case (READ_CACHING|HANDLE_CACHING):
                                For each Open ThisOpen in Open.Stream.Oplock.RHOplocks:Notify the server of an oplock break according to the algorithm in section 3.1.5.17.3, 
                                setting the algorithm's parameters as follows:]ReturnStatus equal to STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE.");

                    break;
                }

                case OplockState.READ_CACHING | OplockState.WRITE_CACHING |
                    OplockState.HANDLE_CACHING | OplockState.EXCLUSIVE:
                {
                    if (requestOplock != RequestedOplock.READ_WRITE_HANDLE)
                    {
                        Helper.CaptureRequirement(6371, @"[In Algorithm to Request an Exclusive Oplock,
                                    Pseudocode for the algorithm is as follows:Else If (Open.Stream.Oplock.State contains one or more of READ_CACHING, 
                                    WRITE_CACHING, or HANDLE_CACHING) and(Open.Stream.Oplock.State contains none of BREAK_TO_TWO, BREAK_TO_NONE, 
                                    BREAK_TO_TWO_TO_NONE, BREAK_TO_READ_CACHING, BREAK_TO_WRITE_CACHING, BREAK_TO_HANDLE_CACHING, or BREAK_TO_NO_CACHING) and           
                                   (Open.Stream.Oplock.State.RHBreakQueue is empty):Switch (Open.Stream.Oplock.State):]
                                    Case (READ_CACHING|WRITE_CACHING|HANDLE_CACHING|EXCLUSIVE):If RequestedOplock is not (READ_CACHING|WRITE_CACHING|HANDLE_CACHING),
                                    the operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED.");
                        return(MessageStatus.OPLOCK_NOT_GRANTED);
                    }
                    break;
                }

                case OplockState.READ_CACHING | OplockState.WRITE_CACHING |
                    OplockState.EXCLUSIVE:
                {
                    if (requestOplock != RequestedOplock.READ_WRITE_HANDLE &&
                        requestOplock != RequestedOplock.READ_WRITE)
                    {
                        Helper.CaptureRequirement(6372, @"[In Algorithm to Request an Exclusive Oplock,
                                    Pseudocode for the algorithm is as follows:Else If (Open.Stream.Oplock.State contains one or more of READ_CACHING, 
                                    WRITE_CACHING, or HANDLE_CACHING) and(Open.Stream.Oplock.State contains none of BREAK_TO_TWO, BREAK_TO_NONE, 
                                    BREAK_TO_TWO_TO_NONE, BREAK_TO_READ_CACHING, BREAK_TO_WRITE_CACHING, BREAK_TO_HANDLE_CACHING, or BREAK_TO_NO_CACHING) and
                                    (Open.Stream.Oplock.State.RHBreakQueue is empty):Switch (Open.Stream.Oplock.State):]
                                    Case (READ_CACHING|WRITE_CACHING|EXCLUSIVE):If RequstedOplock is neither (READ_CACHING|WRITE_CACHING|HANDLE_CACHING) 
                                    nor (READ_CACHING|WRITE_CACHING), the operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED.");
                        return(MessageStatus.OPLOCK_NOT_GRANTED);
                    }

                    //If Open.OplockKey != Open.Stream.Oplock.ExclusiveOpen.OplockKey,
                    //the operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED.
                    if (!isOplockKeyEqualExclusive)
                    {
                        Helper.CaptureRequirement(6373, @"[In Algorithm to Request an Exclusive Oplock,
                                    Pseudocode for the algorithm is as follows:Else If (Open.Stream.Oplock.State contains one or more of READ_CACHING, 
                                    WRITE_CACHING, or HANDLE_CACHING) and(Open.Stream.Oplock.State contains none of BREAK_TO_TWO, BREAK_TO_NONE, 
                                    BREAK_TO_TWO_TO_NONE, BREAK_TO_READ_CACHING, BREAK_TO_WRITE_CACHING, BREAK_TO_HANDLE_CACHING, or BREAK_TO_NO_CACHING) and           
                                    (Open.Stream.Oplock.State.RHBreakQueue is empty):Switch (Open.Stream.Oplock.State):
                                    Case (READ_CACHING|WRITE_CACHING|EXCLUSIVE):]If Open.OplockKey != Open.Stream.Oplock.ExclusiveOpen.OplockKey,
                                    the operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED.");
                        return(MessageStatus.OPLOCK_NOT_GRANTED);
                    }

                    NewOplockLevel newLevel = NewOplockLevel.LEVEL_NONE;
                    bool           b        = false;
                    MessageStatus  m        = MessageStatus.OPLOCK_SWITCHED_TO_NEW_HANDLE;
                    IndicateOplockBreak(ref newLevel, ref b, ref m);
                    Helper.CaptureRequirement(6377, @"[In Algorithm to Request an Exclusive Oplock,
                                Pseudocode for the algorithm is as follows:
                                Else If (Open.Stream.Oplock.State contains one or more of READ_CACHING, WRITE_CACHING, or HANDLE_CACHING) 
                                and(Open.Stream.Oplock.State contains none of BREAK_TO_TWO, BREAK_TO_NONE, BREAK_TO_TWO_TO_NONE, BREAK_TO_READ_CACHING, 
                                BREAK_TO_WRITE_CACHING, BREAK_TO_HANDLE_CACHING, or BREAK_TO_NO_CACHING) and           
                               (Open.Stream.Oplock.State.RHBreakQueue is empty):Switch (Open.Stream.Oplock.State):
                                Case (READ_CACHING|WRITE_CACHING|EXCLUSIVE):Notify the server of an oplock break 
                                according to the algorithm in section 3.1.5.17.3, 
                                setting the algorithm's parameters as follows:]ReturnStatus equal to STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE.");

                    break;
                }

                default:
                {
                    Helper.CaptureRequirement(6380, @"[In Algorithm to Request an Exclusive Oplock,
                                Pseudocode for the algorithm is as follows:
                                Else If (Open.Stream.Oplock.State contains one or more of READ_CACHING, WRITE_CACHING, or HANDLE_CACHING) 
                                and (Open.Stream.Oplock.State contains none of BREAK_TO_TWO, BREAK_TO_NONE, BREAK_TO_TWO_TO_NONE, BREAK_TO_READ_CACHING, 
                                BREAK_TO_WRITE_CACHING, BREAK_TO_HANDLE_CACHING, or BREAK_TO_NO_CACHING) and           
                               (Open.Stream.Oplock.State.RHBreakQueue is empty):Switch (Open.Stream.Oplock.State):]
                                The operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED.");
                    return(MessageStatus.OPLOCK_NOT_GRANTED);
                }
                }
            }
            else
            {
                Helper.CaptureRequirement(6381, @"[In Algorithm to Request an Exclusive Oplock,
                    Pseudocode for the algorithm is as follows:]
                    Else[If (Open.Stream.Oplock.State does not contains one or more of READ_CACHING, WRITE_CACHING, and HANDLE_CACHING) 
                    or (Open.Stream.Oplock.State does not contain none of BREAK_TO_TWO, BREAK_TO_NONE, BREAK_TO_TWO_TO_NONE, 
                    BREAK_TO_READ_CACHING, BREAK_TO_WRITE_CACHING, BREAK_TO_HANDLE_CACHING, or BREAK_TO_NO_CACHING) and
                    (Open.Stream.Oplock.State.RHBreakQueue is empty):]The operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED.");
                return(MessageStatus.OPLOCK_NOT_GRANTED);
            }

            return(MessageStatus.SUCCESS);
        }
コード例 #5
0
        /// <summary>
        /// Algorithm to request a shared oplock
        /// </summary>
        /// <param name="isOpenStreamOplockEmpty">true if Open.Stream.Oplock is empty</param>
        /// <param name="oplockState">Oplock state</param>
        /// <param name="GrantingInAck"> A boolean value.
        /// True: if this oplock is being requested as part of an oplock break acknowledgement, false if not</param>
        /// <param name="keyEqualOnRHOplocks">True if there is an Open on
        /// Open.Stream.Oplock.RHOplocks whose OplockKey is equal to Open.OplockKey</param>
        /// <param name="keyEqualOnRHBreakQueue">True if there is an Open on
        /// Open.Stream.Oplock.RHBreakQueue whose OplockKey is equal to Open.OplockKey</param>
        /// <param name="keyEqualOnROplocks">True if there is an Open ThisOpen on
        /// Open.Stream.Oplock.ROplocks whose OplockKey is equal to Open.OplockKey (there should be at most one present)</param>
        /// <param name="StreamIsDeleted">True if Open.Stream.IsDeleted is true</param>
        /// <param name="requestOplock">The oplock type being requested</param>
        /// <returns> An NTSTATUS code indicating the result of the operation</returns>
        public static MessageStatus SharedOplock(
            bool isOpenStreamOplockEmpty,
            OplockState oplockState,
            bool GrantingInAck,
            bool keyEqualOnRHOplocks,
            bool keyEqualOnRHBreakQueue,
            bool keyEqualOnROplocks,
            bool StreamIsDeleted,
            RequestedOplock requestOplock)
        {
            //If Open.Stream.Oplock is empty
            if (isOpenStreamOplockEmpty)
            {
                gOplockState = OplockState.NO_OPLOCK;
            }

            if (!GrantingInAck &&
                (oplockState & (OplockState.BREAK_TO_TWO |
                                OplockState.BREAK_TO_NONE |
                                OplockState.BREAK_TO_TWO_TO_NONE |
                                OplockState.BREAK_TO_READ_CACHING |
                                OplockState.BREAK_TO_WRITE_CACHING |
                                OplockState.BREAK_TO_HANDLE_CACHING |
                                OplockState.BREAK_TO_NO_CACHING |
                                OplockState.EXCLUSIVE)) != 0)
            {
                Helper.CaptureRequirement(6396, @"[In Algorithm to Request a Shared Oplock,Pseudocode for the algorithm is as follows:]
                    If (GrantingInAck is FALSE) and (Open.Stream.Oplock.State contains one or more of BREAK_TO_TWO, 
                    BREAK_TO_NONE, BREAK_TO_TWO_TO_NONE, BREAK_TO_READ_CACHING, BREAK_TO_WRITE_CACHING, BREAK_TO_HANDLE_CACHING, 
                    BREAK_TO_NO_CACHING, or EXCLUSIVE), then:The operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED.");
                return(MessageStatus.OPLOCK_NOT_GRANTED);
            }

            switch (requestOplock)
            {
            case RequestedOplock.LEVEL_TWO:
            {
                if ((oplockState & (OplockState.NO_OPLOCK |
                                    OplockState.LEVEL_TWO_OPLOCK |
                                    OplockState.READ_CACHING |
                                    (OplockState.LEVEL_TWO_OPLOCK | OplockState.READ_CACHING))) == 0)
                {
                    Helper.CaptureRequirement(6397, @"[In Algorithm to Request a Shared Oplock,Pseudocode for the algorithm is as follows:]
                                Switch (RequestedOplock):Case LEVEL_TWO:
                                The operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED if Open.Stream.Oplock.
                                State is anything other than the following:NO_OPLOCK,LEVEL_TWO_OPLOCK,READ_CACHING,(LEVEL_TWO_OPLOCK|READ_CACHING).");
                    return(MessageStatus.OPLOCK_NOT_GRANTED);
                }
                break;
            }

            case RequestedOplock.READ_CACHING:
            {
                if (!GrantingInAck &&
                    (oplockState & (OplockState.NO_OPLOCK |
                                    OplockState.LEVEL_TWO_OPLOCK |
                                    OplockState.READ_CACHING |
                                    (OplockState.LEVEL_TWO_OPLOCK | OplockState.READ_CACHING) |
                                    (OplockState.READ_CACHING | OplockState.HANDLE_CACHING) |
                                    (OplockState.READ_CACHING | OplockState.HANDLE_CACHING |
                                     OplockState.MIXED_R_AND_RH) |
                                    (OplockState.READ_CACHING | OplockState.HANDLE_CACHING |
                                     OplockState.BREAK_TO_READ_CACHING) |
                                    (OplockState.READ_CACHING | OplockState.HANDLE_CACHING |
                                     OplockState.BREAK_TO_NO_CACHING))) == 0)
                {
                    Helper.CaptureRequirement(6398, @"[In Algorithm to Request a Shared Oplock,Pseudocode for the algorithm is as follows:
                                Switch (RequestedOplock):]Case READ_CACHING:The operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED 
                                if GrantingInAck is FALSE and Open.Stream.Oplock.State is anything other than the following:NO_OPLOCK,LEVEL_TWO_OPLOCK,
                                READ_CACHING,(LEVEL_TWO_OPLOCK|READ_CACHING),(READ_CACHING|HANDLE_CACHING),(READ_CACHING|HANDLE_CACHING|MIXED_R_AND_RH),
                                (READ_CACHING|HANDLE_CACHING|BREAK_TO_READ_CACHING),(READ_CACHING|HANDLE_CACHING|BREAK_TO_NO_CACHING).");
                    return(MessageStatus.OPLOCK_NOT_GRANTED);
                }

                if (!GrantingInAck)
                {
                    //If there is an Open on Open.Stream.Oplock.RHOplocks whose OplockKey
                    //is equal to Open.OplockKey, the operation MUST be failed with
                    //STATUS_OPLOCK_NOT_GRANTED.
                    if (keyEqualOnRHOplocks)
                    {
                        Helper.CaptureRequirement(6399, @"[In Algorithm to Request a Shared Oplock,Pseudocode for the algorithm is as follows:
                                    Switch (RequestedOplock):Case READ_CACHING:]If GrantingInAck is FALSE:
                                    If there is an Open on Open.Stream.Oplock.RHOplocks whose OplockKey is equal to Open.OplockKey, 
                                    the operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED.");
                        return(MessageStatus.OPLOCK_NOT_GRANTED);
                    }

                    //If there is an Open on Open.Stream.Oplock.RHBreakQueue whose OplockKey
                    //is equal to Open.OplockKey, the operation MUST be failed with
                    //STATUS_OPLOCK_NOT_GRANTED.
                    if (keyEqualOnRHBreakQueue)
                    {
                        Helper.CaptureRequirement(6400, @"[In Algorithm to Request a Shared Oplock,Pseudocode for the algorithm is as follows:
                                    Switch (RequestedOplock):Case READ_CACHING:If GrantingInAck is FALSE:]
                                    If there is an Open on Open.Stream.Oplock.RHBreakQueue whose OplockKey is equal to Open.OplockKey, 
                                    the operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED.");
                        return(MessageStatus.OPLOCK_NOT_GRANTED);
                    }

                    //If there is an Open ThisOpen on Open.Stream.Oplock.ROplocks whose
                    //OplockKey is equal to Open.OplockKey (there should be at most one
                    //present):
                    if (keyEqualOnROplocks)
                    {
                        NewOplockLevel newLevel = NewOplockLevel.READ_CACHING;
                        bool           b        = false;
                        MessageStatus  m        = MessageStatus.OPLOCK_SWITCHED_TO_NEW_HANDLE;
                        IndicateOplockBreak(ref newLevel, ref b, ref m);
                        Helper.CaptureRequirement(6405, @"[In Algorithm to Request a Shared Oplock,Pseudocode for the algorithm is as follows:
                                    Switch (RequestedOplock):Case READ_CACHING:If GrantingInAck is FALSE:
                                    If there is an Open ThisOpen on Open.Stream.Oplock.ROplocks whose OplockKey is equal to Open.OplockKey 
                                    (there should be at most one present):Notify the server of an oplock break according to the algorithm in section 3.1.5.17.3,
                                    setting the algorithm's parameters as follows:]ReturnStatus equal to STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE.");
                    }
                }
                break;
            }

            case RequestedOplock.READ_HANDLE:
            {
                if (!GrantingInAck && (oplockState & (OplockState.NO_OPLOCK |
                                                      OplockState.READ_CACHING |
                                                      (OplockState.READ_CACHING | OplockState.HANDLE_CACHING) |
                                                      (OplockState.READ_CACHING | OplockState.HANDLE_CACHING |
                                                       OplockState.MIXED_R_AND_RH))) == 0)
                {
                    Helper.CaptureRequirement(6410, @"[In Algorithm to Request a Shared Oplock,Pseudocode for the algorithm is as follows:
                                Switch (RequestedOplock):]Case (READ_CACHING|HANDLE_CACHING):The operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED 
                                 if GrantingInAck is FALSE and Open.Stream.Oplock.State is anything other than the following:NO_OPLOCK,READ_CACHING,(READ_CACHING|HANDLE_CACHING),(READ_CACHING|HANDLE_CACHING|MIXED_R_AND_RH).");
                    return(MessageStatus.OPLOCK_NOT_GRANTED);
                }

                //If Open.Stream.IsDeleted is true
                if (StreamIsDeleted)
                {
                    Helper.CaptureRequirement(6411, @"[In Algorithm to Request a Shared Oplock,Pseudocode for the algorithm is as follows:
                                Switch (RequestedOplock):Case (READ_CACHING|HANDLE_CACHING):]If Open.Stream.IsDeleted is TRUE, 
                                the operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED.");
                    return(MessageStatus.OPLOCK_NOT_GRANTED);
                }

                if (!GrantingInAck)
                {
                    if (keyEqualOnROplocks)
                    {
                        NewOplockLevel newLevel = NewOplockLevel.READ_CACHING | NewOplockLevel.HANDLE_CACHING;
                        bool           b        = false;
                        MessageStatus  m        = MessageStatus.OPLOCK_SWITCHED_TO_NEW_HANDLE;
                        IndicateOplockBreak(ref newLevel, ref b, ref m);
                        Helper.CaptureRequirement(6416, @"[In Algorithm to Request a Shared Oplock,Pseudocode for the algorithm is as follows:
                                    Switch (RequestedOplock):Case (READ_CACHING|HANDLE_CACHING):If GrantingInAck is FALSE: 
                                    If there is an Open ThisOpen on Open.Stream.Oplock.ROplocks whose OplockKey is equal to Open.OplockKey 
                                    (there should be at most one present):Notify the server of an oplock break according to the algorithm in section 3.1.5.17.3, 
                                    setting the algorithm's parameters as follows:]ReturnStatus equal to STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE.");
                    }

                    if (keyEqualOnRHOplocks)
                    {
                        NewOplockLevel newLevel = NewOplockLevel.READ_CACHING | NewOplockLevel.HANDLE_CACHING;
                        bool           b        = false;
                        MessageStatus  m        = MessageStatus.OPLOCK_SWITCHED_TO_NEW_HANDLE;
                        IndicateOplockBreak(ref newLevel, ref b, ref m);
                        Helper.CaptureRequirement(6420, @"[In Algorithm to Request a Shared Oplock,Pseudocode for the algorithm is as follows:
                                    Switch (RequestedOplock):Case (READ_CACHING|HANDLE_CACHING):If GrantingInAck is FALSE:
                                    If there is an Open ThisOpen on Open.Stream.Oplock.RHOplocks whose OplockKey is equal to Open.OplockKey 
                                    (there should be at most one present):Notify the server of an oplock break according to the algorithm in section 3.1.5.17.3, 
                                    setting the algorithm's parameters as follows:]ReturnStatus equal to STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE.");
                    }
                }

                break;
            }

            default:
                break;
            }

            return(MessageStatus.SUCCESS);
        }