/// <summary>
        /// Add an open into the GlobalOpenTable, and to its own TreeConnect's OpenTable.
        /// </summary>
        /// <param name="open">The open to be added or updated.</param>
        /// <exception cref="System.ArgumentNullException">The open or open.TreeConnectis null</exception>
        /// <exception cref="System.ArgumentException">The open already exists</exception>
        public void AddOpenFile(CifsServerPerOpenFile open)
        {
            if (open == null || open.TreeConnect == null)
            {
                throw new ArgumentException("The open or open.TreeConnect is null.");
            }

            lock (this.globalTables)
            {
                (open.TreeConnect as CifsServerPerTreeConnect).AddOpen(open);
                this.globalTables.GlobalOpenTable.Add(open.FileGlobalId, open);
            }
        }
        protected virtual void UpdateResponseRoleContext(
            CifsServerPerConnection connection,
            SmbPacket requestPacket,
            SmbPacket responsePacket)
        {
            if (requestPacket == null || responsePacket == null || responsePacket.SmbHeader.Status != 0)
            {
                return;
            }

            SmbHeader smbHeader = responsePacket.SmbHeader;

            switch (responsePacket.SmbHeader.Command)
            {
                #region Negotiate
                case SmbCommand.SMB_COM_NEGOTIATE:
                    {
                        SmbNegotiateRequestPacket request = requestPacket as SmbNegotiateRequestPacket;
                        SmbNegotiateResponsePacket response = responsePacket as SmbNegotiateResponsePacket;
                        if (request != null && response != null && request.SmbData.Dialects != null)
                        {
                            int dialectIndex = (int)(response.SmbParameters.DialectIndex);
                            byte[] dialectBytes = request.SmbData.Dialects;
                            int startIndex = 0;
                            for (int i = 0; i < dialectIndex; i++)
                            {
                                startIndex = Array.IndexOf<byte>(dialectBytes, 0, startIndex,
                                    dialectBytes.Length - startIndex) + 1;
                            }
                            connection.SelectedDialect = CifsMessageUtils.ToSmbString(dialectBytes, startIndex, true);
                            connection.NTLMChallenge = response.SmbData.Challenge;
                            connection.OpLockSupport = this.opLockSupport;
                            connection.NegotiateTime = response.SmbParameters.SystemTime;

                            if (this.ntlmAuthenticationPolicy != NTLMAuthenticationPolicyValues.Disabled)
                            {
                                //Prepare security context for the coming ntlm authentication.
                                foreach (AccountCredential accountCredential in this.accountCredentials)
                                {
                                    NlmpServerSecurityContext serverSecurityContext = new NlmpServerSecurityContext(
                                        NegotiateTypes.NTLM_NEGOTIATE_OEM | NegotiateTypes.NTLMSSP_NEGOTIATE_NTLM,
                                        new NlmpClientCredential(string.Empty, accountCredential.DomainName,
                                            accountCredential.AccountName, accountCredential.Password),
                                        !string.IsNullOrEmpty(this.domainName),
                                        this.domainName,
                                        this.serverName);
                                    serverSecurityContext.UpdateServerChallenge(
                                        BitConverter.ToUInt64(response.SmbData.Challenge, 0));
                                    this.nlmpServerSecurityContexts.Add(serverSecurityContext);
                                }
                            }

                            if ((response.SmbParameters.SecurityMode & SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_REQUIRED)
                                == SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_REQUIRED)
                            {
                                connection.IsSigningActive = true;
                            }
                        }
                    }
                    break;
                #endregion

                #region Session

                case SmbCommand.SMB_COM_SESSION_SETUP_ANDX:
                    #region SMB_COM_SESSION_SETUP_ANDX
                    {
                        SmbSessionSetupAndxRequestPacket request = requestPacket as SmbSessionSetupAndxRequestPacket;
                        SmbSessionSetupAndxResponsePacket response = responsePacket as SmbSessionSetupAndxResponsePacket;

                        if (request != null && response != null)
                        {
                            NlmpServerSecurityContext securityContext = null;
                            if (response.SmbParameters.Action != ActionValues.GuestAccess)
                            {
                                this.ActiveAccount = CifsMessageUtils.PlainTextAuthenticate(request, this.accountCredentials);

                                if (string.IsNullOrEmpty(this.ActiveAccount))
                                {
                                    securityContext = CifsMessageUtils.NTLMAuthenticate(request,
                                        this.nlmpServerSecurityContexts, connection.NegotiateTime.Time);

                                    if (securityContext != null)
                                    {
                                        connection.IsSigningActive = true;
                                        connection.SigningChallengeResponse = request.SmbData.UnicodePassword;
                                        this.ActiveAccount = securityContext.Context.ClientCredential.AccountName;
                                        connection.SigningSessionKey = NlmpUtility.GetResponseKeyNt(
                                            NlmpVersion.v1,
                                            securityContext.Context.ClientCredential.DomainName,
                                            securityContext.Context.ClientCredential.AccountName,
                                            securityContext.Context.ClientCredential.Password);
                                    }
                                }
                            }

                            CifsServerPerSession session = new CifsServerPerSession(
                                connection,
                                smbHeader.Uid,
                                securityContext,
                                DateTime.Now,
                                DateTime.Now,
                                CifsMessageUtils.ToSmbString(request.SmbData.AccountName, 0, false),
                                GenerateSessionGlobalId());
                            this.AddSession(session);
                        }
                    }
                    #endregion
                    break;
                case SmbCommand.SMB_COM_LOGOFF_ANDX:
                    #region SMB_COM_LOGOFF_ANDX
                    {
                        SmbLogoffAndxRequestPacket request = requestPacket as SmbLogoffAndxRequestPacket;
                        SmbLogoffAndxResponsePacket response = responsePacket as SmbLogoffAndxResponsePacket;
                        CifsServerPerSession session = connection.GetSession(smbHeader.Uid);

                        if (request != null && response != null && session != null)
                        {
                            this.RemoveSession(session.SessionGlobalId);
                        }
                    }
                    #endregion
                    break;

                #endregion

                #region Tree Connect

                case SmbCommand.SMB_COM_TREE_CONNECT:
                    #region SMB_COM_TREE_CONNECT
                    {
                        SmbTreeConnectRequestPacket request = requestPacket as SmbTreeConnectRequestPacket;
                        SmbTreeConnectResponsePacket response = responsePacket as SmbTreeConnectResponsePacket;
                        CifsServerPerSession session = connection.GetSession(smbHeader.Uid);

                        //If Core Protocol, No sessions setup, make a default session
                        if (session == null
                            && (connection.SelectedDialect == CifsMessageUtils.DIALECT_PCNETWORK_PROGRAM
                                || connection.SelectedDialect == CifsMessageUtils.DIALECT_NTLANMAN))
                        {
                            session = new CifsServerPerSession(
                                    connection,
                                    smbHeader.Uid, //should be unique, windows always be zero
                                    null,
                                    DateTime.Now,
                                    DateTime.Now,
                                    string.Empty,
                                    GenerateSessionGlobalId());
                            this.AddSession(session);
                        }

                        if (request != null && response != null && session != null)
                        {
                            CifsServerPerTreeConnect treeConnect = new CifsServerPerTreeConnect(
                                session,
                                CifsMessageUtils.ToSmbString(request.SmbData.Path, 0, false),
                                response.SmbParameters.TID,
                                this.GenerateTreeGlobalId(),
                                DateTime.Now);
                            this.AddTreeConnect(treeConnect);
                        }
                    }
                    #endregion
                    break;
                case SmbCommand.SMB_COM_TREE_CONNECT_ANDX:
                    #region SMB_COM_TREE_CONNECT_ANDX
                    {
                        SmbTreeConnectAndxRequestPacket request = requestPacket as SmbTreeConnectAndxRequestPacket;

                        SmbTreeConnectAndxResponsePacket response = responsePacket as SmbTreeConnectAndxResponsePacket;
                        CifsServerPerSession session = connection.GetSession(smbHeader.Uid);

                        if (request != null && response != null && session != null)
                        {
                            CifsServerPerTreeConnect treeConnect = new CifsServerPerTreeConnect(
                                session,
                                CifsMessageUtils.ToString(request.SmbData.Path, request.SmbHeader.Flags2),
                                smbHeader.Tid,
                                this.GenerateTreeGlobalId(),
                                DateTime.Now);
                            this.AddTreeConnect(treeConnect);
                        }
                    }
                    #endregion
                    break;
                case SmbCommand.SMB_COM_TREE_DISCONNECT:
                    #region SMB_COM_TREE_DISCONNECT
                    {
                        SmbTreeDisconnectRequestPacket request = requestPacket as SmbTreeDisconnectRequestPacket;
                        SmbTreeDisconnectResponsePacket response = responsePacket as SmbTreeDisconnectResponsePacket;
                        CifsServerPerSession session = connection.GetSession(smbHeader.Uid);

                        if (request != null && response != null && session != null)
                        {
                            //If core protocol, no logoff any more, we have to remove the session if there is
                            // no treeconnects in it except this.
                            if (session.TreeConnectTable.Count == 1
                                && (connection.SelectedDialect == CifsMessageUtils.DIALECT_PCNETWORK_PROGRAM
                                    || connection.SelectedDialect == CifsMessageUtils.DIALECT_NTLANMAN))
                            {
                                this.RemoveSession(session.SessionGlobalId);
                            }
                            else
                            {
                                CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid);
                                if (treeConnect != null)
                                {
                                    this.RemoveTreeConnect(treeConnect.TreeGlobalId);
                                }
                            }
                        }
                    }
                    #endregion
                    break;

                #endregion

                #region Open File/Search

                case SmbCommand.SMB_COM_OPEN:
                    #region SMB_COM_OPEN
                    {
                        SmbOpenRequestPacket request = requestPacket as SmbOpenRequestPacket;
                        SmbOpenResponsePacket response = responsePacket as SmbOpenResponsePacket;
                        CifsServerPerSession session = connection.GetSession(smbHeader.Uid);

                        if (request != null && response != null && session != null)
                        {
                            CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid);
                            if (treeConnect != null)
                            {
                                OplockLevelValue opLock = OplockLevelValue.None;
                                if ((smbHeader.Flags & SmbFlags.SMB_FLAGS_OPLOCK) == SmbFlags.SMB_FLAGS_OPLOCK)
                                {
                                    opLock = OplockLevelValue.Exclusive;
                                }
                                if ((smbHeader.Flags & SmbFlags.SMB_FLAGS_OPBATCH) == SmbFlags.SMB_FLAGS_OPBATCH)
                                {
                                    opLock = OplockLevelValue.Batch;
                                }
                                CifsServerPerOpenFile open = new CifsServerPerOpenFile(
                                    treeConnect,
                                    CifsMessageUtils.ToSmbString(request.SmbData.FileName, 0, false),
                                    response.SmbParameters.FID,
                                    response.SmbParameters.AccessMode,
                                    opLock,
                                    this.GenerateFileGlobalId(),
                                    request.SmbHeader.Pid);
                                this.AddOpenFile(open);
                            }
                        }
                    }
                    #endregion
                    break;

                case SmbCommand.SMB_COM_CREATE:
                    #region SMB_COM_CREATE
                    {
                        SmbCreateRequestPacket request = requestPacket as SmbCreateRequestPacket;
                        SmbCreateResponsePacket response = responsePacket as SmbCreateResponsePacket;
                        CifsServerPerSession session = connection.GetSession(smbHeader.Uid);

                        if (request != null && response != null && session != null)
                        {
                            CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid);
                            if (treeConnect != null)
                            {
                                OplockLevelValue opLock = OplockLevelValue.None;
                                if ((smbHeader.Flags & SmbFlags.SMB_FLAGS_OPLOCK) == SmbFlags.SMB_FLAGS_OPLOCK)
                                {
                                    opLock = OplockLevelValue.Exclusive;
                                }
                                if ((smbHeader.Flags & SmbFlags.SMB_FLAGS_OPBATCH) == SmbFlags.SMB_FLAGS_OPBATCH)
                                {
                                    opLock = OplockLevelValue.Batch;
                                }
                                CifsServerPerOpenFile open = new CifsServerPerOpenFile(
                                    treeConnect,
                                    CifsMessageUtils.ToSmbString(request.SmbData.FileName, 0, false),
                                    response.SmbParameters.FID,
                                    (ushort)request.SmbParameters.FileAttributes,
                                    opLock,
                                    this.GenerateFileGlobalId(),
                                    request.SmbHeader.Pid);
                                this.AddOpenFile(open);
                            }
                        }
                    }
                    #endregion
                    break;
                case SmbCommand.SMB_COM_CREATE_TEMPORARY:
                    #region SMB_COM_CREATE_TEMPORARY
                    {
                        SmbCreateTemporaryRequestPacket request = requestPacket as SmbCreateTemporaryRequestPacket;
                        SmbCreateTemporaryResponsePacket response = responsePacket as SmbCreateTemporaryResponsePacket;
                        CifsServerPerSession session = connection.GetSession(smbHeader.Uid);

                        if (request != null && response != null && session != null)
                        {
                            CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid);
                            if (treeConnect != null)
                            {
                                OplockLevelValue opLock = OplockLevelValue.None;
                                if ((smbHeader.Flags & SmbFlags.SMB_FLAGS_OPLOCK) == SmbFlags.SMB_FLAGS_OPLOCK)
                                {
                                    opLock = OplockLevelValue.Exclusive;
                                }
                                if ((smbHeader.Flags & SmbFlags.SMB_FLAGS_OPBATCH) == SmbFlags.SMB_FLAGS_OPBATCH)
                                {
                                    opLock = OplockLevelValue.Batch;
                                }
                                CifsServerPerOpenFile open = new CifsServerPerOpenFile(
                                    treeConnect,
                                    CifsMessageUtils.ToSmbString(response.SmbData.TemporaryFileName, 0, false),
                                    response.SmbParameters.FID,
                                    (uint)request.SmbParameters.FileAttributes,
                                    opLock,
                                    this.GenerateFileGlobalId(),
                                    request.SmbHeader.Pid);
                                this.AddOpenFile(open);
                            }
                        }
                    }
                    #endregion
                    break;
                case SmbCommand.SMB_COM_CREATE_NEW:
                    #region SMB_COM_CREATE_NEW
                    {
                        SmbCreateNewRequestPacket request = requestPacket as SmbCreateNewRequestPacket;
                        SmbCreateNewResponsePacket response = responsePacket as SmbCreateNewResponsePacket;
                        CifsServerPerSession session = connection.GetSession(smbHeader.Uid);

                        if (request != null && response != null && session != null)
                        {
                            CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid);
                            if (treeConnect != null)
                            {
                                OplockLevelValue opLock = OplockLevelValue.None;
                                if ((smbHeader.Flags & SmbFlags.SMB_FLAGS_OPLOCK) == SmbFlags.SMB_FLAGS_OPLOCK)
                                {
                                    opLock = OplockLevelValue.Exclusive;
                                }
                                if ((smbHeader.Flags & SmbFlags.SMB_FLAGS_OPBATCH) == SmbFlags.SMB_FLAGS_OPBATCH)
                                {
                                    opLock |= OplockLevelValue.Batch;
                                }
                                CifsServerPerOpenFile open = new CifsServerPerOpenFile(
                                    treeConnect,
                                    CifsMessageUtils.ToSmbString(request.SmbData.FileName, 0, false),
                                    response.SmbParameters.FID,
                                    (uint)request.SmbParameters.FileAttributes,
                                    opLock,
                                    this.GenerateFileGlobalId(),
                                    request.SmbHeader.Pid);
                                this.AddOpenFile(open);
                            }
                        }
                    }
                    #endregion
                    break;
                case SmbCommand.SMB_COM_OPEN_ANDX:
                    #region SMB_COM_OPEN_ANDX
                    {
                        SmbOpenAndxRequestPacket request = requestPacket as SmbOpenAndxRequestPacket;
                        SmbOpenAndxResponsePacket response = responsePacket as SmbOpenAndxResponsePacket;
                        CifsServerPerSession session = connection.GetSession(smbHeader.Uid);

                        if (request != null && response != null && session != null)
                        {
                            CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid);
                            if (treeConnect != null)
                            {
                                OplockLevelValue opLock = OplockLevelValue.None;
                                if ((smbHeader.Flags & SmbFlags.SMB_FLAGS_OPLOCK) == SmbFlags.SMB_FLAGS_OPLOCK)
                                {
                                    opLock = OplockLevelValue.Exclusive;
                                }
                                if ((smbHeader.Flags & SmbFlags.SMB_FLAGS_OPBATCH) == SmbFlags.SMB_FLAGS_OPBATCH)
                                {
                                    opLock |= OplockLevelValue.Batch;
                                }
                                string fileName;
                                if ((request.SmbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE)
                                {
                                    fileName = Encoding.Unicode.GetString(request.SmbData.FileName);
                                }
                                else
                                {
                                    fileName = Encoding.ASCII.GetString(request.SmbData.FileName);
                                }
                                CifsServerPerOpenFile open = new CifsServerPerOpenFile(
                                    treeConnect,
                                    fileName,
                                    response.SmbParameters.FID,
                                    (uint)response.SmbParameters.FileAttrs,
                                    opLock,
                                    this.GenerateFileGlobalId(),
                                    request.SmbHeader.Pid);
                                this.AddOpenFile(open);

                                //save FID for chained response like:
                                //treeConnect->openAndx->readAndx->close
                                //when "close", FID is need to close the open opened in openAndx.
                                if (response.AndxPacket != null)
                                {
                                    //borrow smbHeader.Protocol to save FID for later process.
                                    //smbHeader.Protocol also use a flag to differentiate a single packet from a
                                    //batched andx packet.
                                    //FID is ushort, impossible to impact smbHeader.Protocol's usage as
                                    //a real packet header 0x424D53FF(0xFF, 'S', 'M', 'B')
                                    SmbHeader andxHeader = response.AndxPacket.SmbHeader;
                                    andxHeader.Protocol = response.SmbParameters.FID;
                                    response.AndxPacket.SmbHeader = andxHeader;
                                }
                            }
                        }
                    }
                    #endregion
                    break;
                case SmbCommand.SMB_COM_NT_CREATE_ANDX:
                    #region SMB_COM_NT_CREATE_ANDX
                    {
                        SmbNtCreateAndxRequestPacket request = requestPacket as SmbNtCreateAndxRequestPacket;
                        SmbNtCreateAndxResponsePacket response = responsePacket as SmbNtCreateAndxResponsePacket;
                        CifsServerPerSession session = connection.GetSession(smbHeader.Uid);

                        if (request != null && response != null && session != null)
                        {
                            CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid);
                            if (treeConnect != null)
                            {
                                string fileName;
                                if ((request.SmbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE)
                                {
                                    fileName = Encoding.Unicode.GetString(request.SmbData.FileName);
                                }
                                else
                                {
                                    fileName = Encoding.ASCII.GetString(request.SmbData.FileName);
                                }
                                CifsServerPerOpenFile open = new CifsServerPerOpenFile(
                                    treeConnect,
                                    fileName,
                                    response.SmbParameters.FID,
                                    (uint)response.SmbParameters.ExtFileAttributes,
                                    response.SmbParameters.OplockLevel,
                                    this.GenerateFileGlobalId(),
                                    request.SmbHeader.Pid);
                                this.AddOpenFile(open);
                            }
                        }
                    }
                    #endregion
                    break;
                case SmbCommand.SMB_COM_OPEN_PRINT_FILE:
                    #region SMB_COM_OPEN_PRINT_FILE
                    {
                        SmbOpenPrintFileRequestPacket request = requestPacket as SmbOpenPrintFileRequestPacket;
                        SmbOpenPrintFileResponsePacket response = responsePacket as SmbOpenPrintFileResponsePacket;
                        CifsServerPerSession session = connection.GetSession(smbHeader.Uid);

                        if (request != null && response != null && session != null)
                        {
                            CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid);
                            if (treeConnect != null)
                            {
                                CifsServerPerOpenFile open = new CifsServerPerOpenFile(
                                    treeConnect,
                                    CifsMessageUtils.ToSmbString(request.SmbData.Identifier, 0, false),
                                    response.SmbParameters.FID,
                                    request.SmbParameters.Mode,
                                    OplockLevelValue.None,
                                    this.GenerateFileGlobalId(),
                                    request.SmbHeader.Pid);
                                this.AddOpenFile(open);
                            }
                        }
                    }
                    #endregion
                    break;
                case SmbCommand.SMB_COM_TRANSACTION2:
                    #region Trans2Open2
                    {
                        SmbTrans2Open2RequestPacket request = requestPacket as SmbTrans2Open2RequestPacket;
                        SmbTrans2Open2FinalResponsePacket response = responsePacket as SmbTrans2Open2FinalResponsePacket;
                        CifsServerPerSession session = connection.GetSession(smbHeader.Uid);

                        if (request != null && response != null && session != null)
                        {
                            CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid);
                            if (treeConnect != null)
                            {
                                string fileName;
                                if ((request.SmbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) ==
                                    SmbFlags2.SMB_FLAGS2_UNICODE)
                                {
                                    fileName = Encoding.Unicode.GetString(request.Trans2Parameters.FileName);
                                }
                                else
                                {
                                    fileName = Encoding.ASCII.GetString(request.Trans2Parameters.FileName);
                                }
                                CifsServerPerOpenFile open = new CifsServerPerOpenFile(
                                    treeConnect,
                                    fileName,
                                    response.Trans2Parameters.Fid,
                                    (uint)response.Trans2Parameters.FileAttributes,
                                    OplockLevelValue.None,
                                    this.GenerateFileGlobalId(),
                                    request.SmbHeader.Pid);
                                this.AddOpenFile(open);
                            }
                        }
                    }
                    #endregion

                    #region Trans2FindFirst2
                    {
                        SmbTrans2FindFirst2RequestPacket request = requestPacket as SmbTrans2FindFirst2RequestPacket;
                        SmbTrans2FindFirst2FinalResponsePacket response = responsePacket as SmbTrans2FindFirst2FinalResponsePacket;
                        CifsServerPerSession session = connection.GetSession(smbHeader.Uid);
                        if (request != null && response != null && session != null)
                        {
                            CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid);
                            if (treeConnect != null)
                            {
                                string fileName;
                                if ((request.SmbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) ==
                                    SmbFlags2.SMB_FLAGS2_UNICODE)
                                {
                                    fileName = Encoding.Unicode.GetString(request.Trans2Parameters.FileName);
                                }
                                else
                                {
                                    fileName = Encoding.ASCII.GetString(request.Trans2Parameters.FileName);
                                }
                                CifsServerPerOpenSearch openSearch = new CifsServerPerOpenSearch(
                                    treeConnect,
                                    response.Trans2Parameters.SID,
                                    smbHeader.Mid,
                                    smbHeader.Pid,
                                    this.GenerateSearchGlobalId());
                                this.AddOpenSearch(openSearch);
                            }
                        }
                    }
                    #endregion
                    break;
                case SmbCommand.SMB_COM_WRITE_AND_CLOSE:
                    #region SMB_COM_WRITE_AND_CLOSE
                    {
                        SmbWriteAndCloseRequestPacket request = requestPacket as SmbWriteAndCloseRequestPacket;
                        SmbWriteAndCloseResponsePacket response = responsePacket as SmbWriteAndCloseResponsePacket;
                        CifsServerPerSession session = connection.GetSession(smbHeader.Uid);

                        if (request != null && response != null && session != null)
                        {
                            CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid);
                            if (treeConnect != null)
                            {
                                CifsServerPerOpenFile open = treeConnect.GetOpen(request.SmbParameters.FID);
                                if (open != null)
                                {
                                    this.RemoveOpenFile(open.FileGlobalId);
                                }
                            }
                        }
                    }
                    #endregion
                    break;
                case SmbCommand.SMB_COM_CLOSE:
                    #region SMB_COM_CLOSE
                    {
                        SmbCloseRequestPacket request = requestPacket as SmbCloseRequestPacket;
                        SmbCloseResponsePacket response = responsePacket as SmbCloseResponsePacket;
                        CifsServerPerSession session = connection.GetSession(smbHeader.Uid);

                        if (request != null && response != null && session != null)
                        {
                            CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid);
                            if (treeConnect != null)
                            {
                                CifsServerPerOpenFile open = treeConnect.GetOpen(request.SmbParameters.FID);
                                if (open == null)
                                {
                                    open = treeConnect.GetOpen((ushort)smbHeader.Protocol);
                                }
                                if (open != null)
                                {
                                    this.RemoveOpenFile(open.FileGlobalId);
                                }
                            }
                        }
                    }
                    #endregion
                    break;
                case SmbCommand.SMB_COM_FIND_CLOSE2:
                    #region SMB_COM_FIND_CLOSE2
                    {
                        SmbFindClose2RequestPacket request = requestPacket as SmbFindClose2RequestPacket;
                        SmbFindClose2ResponsePacket response = responsePacket as SmbFindClose2ResponsePacket;
                        CifsServerPerSession session = connection.GetSession(smbHeader.Uid);

                        if (request != null && response != null && session != null)
                        {
                            CifsServerPerTreeConnect treeConnect = session.GetTreeConnect(smbHeader.Tid);
                            if (treeConnect != null)
                            {
                                CifsServerPerOpenSearch openSearch = treeConnect.GetOpenSearch(
                                    request.SmbParameters.SearchHandle); ;
                                if (openSearch != null)
                                {
                                    this.RemoveOpenSearch(openSearch.SearchGlobalId);
                                }
                            }
                        }
                    }
                    #endregion
                    break;

                #endregion

                default:
                    // No Connection/Session/Tree/Open will be updated if other types of response.
                    break;
            }

            SmbBatchedRequestPacket batchedRequest = requestPacket as SmbBatchedRequestPacket;
            SmbBatchedResponsePacket batchedResponse = responsePacket as SmbBatchedResponsePacket;

            if (batchedRequest != null && batchedResponse != null)
            {

                //pass the FID stored in the andxHeader.Protocol into response.AndxPacket
                if (batchedRequest.AndxPacket != null && batchedResponse.AndxPacket != null
                    && batchedResponse.SmbHeader.Protocol != CifsMessageUtils.SMB_PROTOCOL_ANDXPACKET
                    && batchedResponse.SmbHeader.Protocol != CifsMessageUtils.SMB_PROTOCOL_IDENTIFIER)
                {
                    SmbHeader andxHeader = batchedResponse.AndxPacket.SmbHeader;
                    andxHeader.Protocol = smbHeader.Protocol;
                    batchedResponse.AndxPacket.SmbHeader = andxHeader;
                }
                this.UpdateResponseRoleContext(connection, batchedRequest.AndxPacket, batchedResponse.AndxPacket);
            }
        }
        public SmbLockingAndxRequestPacket CreateLockingAndxRequest(
            CifsServerPerOpenFile open,
            NewOplockLevelValue newOplockLevel)
        {
            SmbLockingAndxRequestPacket request = new SmbLockingAndxRequestPacket();
            SmbHeader smbHeader = new SmbHeader();
            smbHeader.Protocol = CifsMessageUtils.SMB_PROTOCOL_IDENTIFIER;
            smbHeader.Command = SmbCommand.SMB_COM_LOCKING_ANDX;
            smbHeader.Uid = (ushort)open.Session.SessionId;
            smbHeader.Tid = (ushort)open.TreeConnect.TreeConnectId;
            smbHeader.Mid = CifsMessageUtils.INVALID_MID;

            request.SmbHeader = smbHeader;

            SMB_COM_LOCKING_ANDX_Request_SMB_Parameters smbParameters = request.SmbParameters;
            smbParameters.FID = (ushort)open.FileId;
            smbParameters.NewOplockLevel = newOplockLevel;
            smbParameters.TypeOfLock = LockingAndxTypeOfLock.OPLOCK_RELEASE;
            smbParameters.WordCount = (byte)(TypeMarshal.GetBlockMemorySize(smbParameters) / 2);
            request.SmbParameters = smbParameters;

            request.AndxPacket = null;

            return request;
        }