/// <summary>
 /// Add an open file into this OpenTable.
 /// </summary>
 /// <param name="open">The open to add.</param>
 /// <exception cref="System.ArgumentNullException">the open is null</exception>
 /// <exception cref="System.ArgumentException">the open already exists</exception>
 public void AddOpen(IFileServiceServerOpen open)
 {
     lock (this.openTable)
     {
         this.openTable.Add((ushort)open.FileId, open);
     }
 }
 /// <summary>
 /// Expect a request. If user is not interested in the packet, please call DefaultSendResponse().
 /// </summary>
 /// <param name="timeout">timeout</param>
 /// <param name="connection">the connection between server and client</param>
 /// <param name="session">the session between server and client</param>
 /// <param name="treeConnect">the tree connect between server and client</param>
 /// <param name="open">the file open between server and client</param>
 /// <param name="requestPacket">the request</param>
 public abstract void ExpectRequest(
     TimeSpan timeout,
     out IFileServiceServerConnection connection,
     out IFileServiceServerSession session,
     out IFileServiceServerTreeConnect treeConnect,
     out IFileServiceServerOpen open,
     out SmbFamilyPacket requestPacket);
        /// <summary>
        /// Automatically response latest request.
        /// </summary>
        /// <param name="connection">the connection between server and client</param>
        /// <param name="session">the session between server and client</param>
        /// <param name="treeConnect">the tree connect between server and client</param>
        /// <param name="open">the file open between server and client</param>
        /// <param name="requestPacket">the request</param>
        public override void DefaultSendResponse(
            IFileServiceServerConnection connection,
            IFileServiceServerSession session,
            IFileServiceServerTreeConnect treeConnect,
            IFileServiceServerOpen open,
            SmbFamilyPacket requestPacket)
        {
            CifsServerPerConnection cifsConnection = connection as CifsServerPerConnection;
            SmbPacket response = this.cifsServer.CreateDefaultResponse(cifsConnection,
                                                                       requestPacket as SmbPacket);

            this.cifsServer.SendPacket(response, cifsConnection);
        }
        /// <summary>
        /// server response the create request from client.
        /// </summary>
        /// <param name="treeConnect">the tree connect between server and client</param>
        /// <param name="requestPacket">the request</param>
        /// <returns>The file open object</returns>
        public override IFileServiceServerOpen SendCreateResponse(
            IFileServiceServerTreeConnect treeConnect,
            SmbFamilyPacket requestPacket)
        {
            CifsServerPerConnection cifsConnection = treeConnect.Session.Connection as CifsServerPerConnection;
            IFileServiceServerOpen  open           = null;
            SmbCreateResponsePacket response       = this.cifsServer.CreateDefaultResponse(cifsConnection, requestPacket
                                                                                           as SmbPacket) as SmbCreateResponsePacket;

            if (response != null)
            {
                this.cifsServer.SendPacket(response, cifsConnection);
                open = (treeConnect as CifsServerPerTreeConnect).GetOpen(response.SmbParameters.FID);
            }
            return(open);
        }
        /// <summary>
        /// server response the IO control request from client.
        /// </summary>
        /// <param name="open">the file open between server and client</param>
        /// <param name="controlCode">The file system control code</param>
        /// <param name="data">The information about this IO control</param>
        public override void SendIoControlResponse(IFileServiceServerOpen open, FsCtlCode controlCode, byte[] data)
        {
            CifsServerPerConnection connection = open.TreeConnect.Session.Connection as CifsServerPerConnection;

            foreach (SmbIoctlRequestPacket request in connection.PendingRequestTable)
            {
                if (request != null &&
                    request.SmbHeader.Uid == open.TreeConnect.Session.SessionId &&
                    request.SmbHeader.Tid == open.TreeConnect.TreeConnectId &&
                    request.SmbParameters.FID == open.FileId)
                {
                    SmbIoctlResponsePacket response = this.cifsServer.CreateIoctlResponse(connection,
                                                                                          request, null, data);
                    this.cifsServer.SendPacket(response, connection);
                    return;
                }
            }
        }
        /// <summary>
        /// server response the close request from client.
        /// </summary>
        /// <param name="open">the file open between server and client</param>
        public override void SendCloseResponse(IFileServiceServerOpen open)
        {
            CifsServerPerConnection connection = open.TreeConnect.Session.Connection as CifsServerPerConnection;

            foreach (SmbCloseRequestPacket request in connection.PendingRequestTable)
            {
                if (request != null &&
                    request.SmbHeader.Uid == open.TreeConnect.Session.SessionId &&
                    request.SmbHeader.Tid == open.TreeConnect.TreeConnectId &&
                    request.SmbParameters.FID == open.FileId)
                {
                    SmbCloseResponsePacket response = this.cifsServer.CreateCloseResponse(connection, request);

                    this.cifsServer.SendPacket(response, connection);
                    return;
                }
            }
        }
        /// <summary>
        /// server response Trans2QueryFileInformation request from client.
        /// </summary>
        /// <param name="open">the file open between server and client</param>
        /// <param name="data">The transaction2 data to send</param>
        public override void SendTrans2QueryFileInformationResponse(IFileServiceServerOpen open, object data)
        {
            CifsServerPerConnection connection = open.TreeConnect.Session.Connection as CifsServerPerConnection;

            foreach (SmbTrans2QueryFileInformationRequestPacket request in connection.PendingRequestTable)
            {
                if (request != null &&
                    request.SmbHeader.Uid == open.TreeConnect.Session.SessionId &&
                    request.SmbHeader.Tid == open.TreeConnect.TreeConnectId &&
                    request.Trans2Parameters.FID == open.FileId)
                {
                    SmbPacket response = this.cifsServer.CreateTrans2QueryFileInformationFinalResponse(
                        connection, request, data);
                    this.cifsServer.SendPacket(response, connection);
                    return;
                }
            }
        }
        /// <summary>
        /// server response the read request from client.
        /// The method will automatically reply multiple READ response if data is too large.
        /// </summary>
        /// <param name="open">the file open between server and client</param>
        /// <param name="data">The actual bytes</param>
        /// <param name = "available">
        /// This field is valid when reading from named pipes or I/O devices. This field indicates the number of bytes
        /// remaining to be read after the requested read was completed.
        /// </param>
        public override void SendReadResponse(IFileServiceServerOpen open, byte[] data, int available)
        {
            CifsServerPerConnection connection = open.TreeConnect.Session.Connection as CifsServerPerConnection;

            foreach (SmbReadAndxRequestPacket request in connection.PendingRequestTable)
            {
                if (request != null &&
                    request.SmbHeader.Uid == open.TreeConnect.Session.SessionId &&
                    request.SmbHeader.Tid == open.TreeConnect.TreeConnectId &&
                    request.SmbParameters.FID == open.FileId)
                {
                    SmbPacket response = this.cifsServer.CreateReadAndxResponse(connection, request, (ushort)available,
                                                                                data, null);
                    this.cifsServer.SendPacket(response, connection);
                    return;
                }
            }
        }
        /// <summary>
        /// server response the write request from client.
        /// </summary>
        /// <param name="open">the file open between server and client</param>
        /// <param name="writtenCount">number of bytes in Write request</param>
        public override void SendWriteResponse(IFileServiceServerOpen open, int writtenCount)
        {
            CifsServerPerConnection connection = open.TreeConnect.Session.Connection as CifsServerPerConnection;

            foreach (SmbWriteAndxRequestPacket request in connection.PendingRequestTable)
            {
                if (request != null &&
                    request.SmbHeader.Uid == open.TreeConnect.Session.SessionId &&
                    request.SmbHeader.Tid == open.TreeConnect.TreeConnectId &&
                    request.SmbParameters.FID == open.FileId)
                {
                    SmbWriteAndxResponsePacket response = this.cifsServer.CreateWriteAndxResponse(
                        connection, request, 0, null);
                    SMB_COM_WRITE_ANDX_Response_SMB_Parameters smbParameters = response.SmbParameters;
                    smbParameters.Count    = (ushort)writtenCount;
                    response.SmbParameters = smbParameters;
                    this.cifsServer.SendPacket(response, connection);
                    return;
                }
            }
        }
        /// <summary>
        /// server response the trans transact nmpipe request from client.
        /// </summary>
        /// <param name="open">the file open between server and client</param>
        /// <param name="data">The actual bytes</param>
        /// <param name = "available">indicates the number of bytes remaining to be read</param>
        public override void SendTransTransactNmpipeResponse(IFileServiceServerOpen open, byte[] data, int available)
        {
            CifsServerPerConnection connection = open.TreeConnect.Session.Connection as CifsServerPerConnection;

            foreach (SmbTransTransactNmpipeRequestPacket request in connection.PendingRequestTable)
            {
                if (request != null &&
                    request.SmbHeader.Uid == open.TreeConnect.Session.SessionId &&
                    request.SmbHeader.Tid == open.TreeConnect.TreeConnectId)
                {
                    SmbTransTransactNmpipeSuccessResponsePacket response =
                        this.cifsServer.CreateTransTransactNmpipeSuccessResponse(
                            connection, request, data);
                    if (available > 0)
                    {
                        Cifs.SmbHeader header = response.SmbHeader;
                        header.Status      = (uint)NtStatus.STATUS_BUFFER_OVERFLOW;
                        response.SmbHeader = header;
                    }
                    this.cifsServer.SendPacket(response, connection);
                    return;
                }
            }
        }
 /// <summary>
 /// server response the read request from client.
 /// The method will automatically reply multiple READ response if data is too large.
 /// </summary>
 /// <param name="open">the file open between server and client</param>
 /// <param name="data">The actual bytes</param>
 /// <param name = "available">
 /// This field is valid when reading from named pipes or I/O devices. This field indicates the number of bytes
 /// remaining to be read after the requested read was completed.
 /// </param>
 public abstract void SendReadResponse(IFileServiceServerOpen open, byte[] data, int available);
 /// <summary>
 /// server response the write request from client.
 /// </summary>
 /// <param name="open">the file open between server and client</param>
 /// <param name="writtenCount">number of bytes in Write request</param>
 public abstract void SendWriteResponse(IFileServiceServerOpen open, int writtenCount);
 /// <summary>
 /// Expect a request. If user is not interested in the packet, please call DefaultSendResponse().
 /// </summary>
 /// <param name="timeout">timeout</param>
 /// <param name="connection">the connection between server and client</param>
 /// <param name="session">the session between server and client</param>
 /// <param name="treeConnect">the tree connect between server and client</param>
 /// <param name="open">the file open between server and client</param>
 /// <param name="requestPacket">the request</param>
 public abstract void ExpectRequest(
     TimeSpan timeout,
     out IFileServiceServerConnection connection,
     out IFileServiceServerSession session,
     out IFileServiceServerTreeConnect treeConnect,
     out IFileServiceServerOpen open,
     out SmbFamilyPacket requestPacket);
 /// <summary>
 /// server response Trans2QueryFileInformation request from client.
 /// </summary>
 /// <param name="open">the file open between server and client</param>
 /// <param name="data">The transaction2 data to send</param>
 public abstract void SendTrans2QueryFileInformationResponse(IFileServiceServerOpen open, object data);
        /// <summary>
        /// server response the read request from client.
        /// The method will automatically reply multiple READ response if data is too large.
        /// </summary>
        /// <param name="open">the file open between server and client</param>
        /// <param name="data">The actual bytes</param>
        /// <param name = "available">
        /// This field is valid when reading from named pipes or I/O devices. This field indicates the number of bytes 
        /// remaining to be read after the requested read was completed.
        /// </param>
        public override void SendReadResponse(IFileServiceServerOpen open, byte[] data, int available)
        {
            CifsServerPerConnection connection = open.TreeConnect.Session.Connection as CifsServerPerConnection;

            foreach (SmbReadAndxRequestPacket request in connection.PendingRequestTable)
            {
                if (request != null
                    && request.SmbHeader.Uid == open.TreeConnect.Session.SessionId
                    && request.SmbHeader.Tid == open.TreeConnect.TreeConnectId
                    && request.SmbParameters.FID == open.FileId)
                {
                    SmbPacket response = this.cifsServer.CreateReadAndxResponse(connection, request, (ushort)available,
                        data, null);
                    this.cifsServer.SendPacket(response, connection);
                    return;
                }
            }
        }
        /// <summary>
        /// server response the trans transact nmpipe request from client.
        /// </summary>
        /// <param name="open">the file open between server and client</param>
        /// <param name="data">The actual bytes</param>
        /// <param name = "available">indicates the number of bytes remaining to be read</param>
        public override void SendTransTransactNmpipeResponse(IFileServiceServerOpen open, byte[] data, int available)
        {
            CifsServerPerConnection connection = open.TreeConnect.Session.Connection as CifsServerPerConnection;

            foreach (SmbTransTransactNmpipeRequestPacket request in connection.PendingRequestTable)
            {
                if (request != null
                    && request.SmbHeader.Uid == open.TreeConnect.Session.SessionId
                    && request.SmbHeader.Tid == open.TreeConnect.TreeConnectId)
                {
                    SmbTransTransactNmpipeSuccessResponsePacket response =
                        this.cifsServer.CreateTransTransactNmpipeSuccessResponse(
                        connection, request, data);
                    if (available > 0)
                    {
                        Cifs.SmbHeader header = response.SmbHeader;
                        header.Status = (uint)NtStatus.STATUS_BUFFER_OVERFLOW;
                        response.SmbHeader = header;
                    }
                    this.cifsServer.SendPacket(response, connection);
                    return;
                }
            }
        }
 /// <summary>
 /// server response the close request from client.
 /// </summary>
 /// <param name="open">the file open between server and client</param>
 public abstract void SendCloseResponse(IFileServiceServerOpen open);
        /// <summary>
        /// server response the close request from client.
        /// </summary>
        /// <param name="open">the file open between server and client</param>
        public override void SendCloseResponse(IFileServiceServerOpen open)
        {
            CifsServerPerConnection connection = open.TreeConnect.Session.Connection as CifsServerPerConnection;

            foreach (SmbCloseRequestPacket request in connection.PendingRequestTable)
            {
                if (request != null
                    && request.SmbHeader.Uid == open.TreeConnect.Session.SessionId
                    && request.SmbHeader.Tid == open.TreeConnect.TreeConnectId
                    && request.SmbParameters.FID == open.FileId)
                {
                    SmbCloseResponsePacket response = this.cifsServer.CreateCloseResponse(connection, request);

                    this.cifsServer.SendPacket(response, connection);
                    return;
                }
            }
        }
 /// <summary>
 /// server response the trans transact nmpipe request from client.
 /// </summary>
 /// <param name="open">the file open between server and client</param>
 /// <param name="data">The actual bytes</param>
 /// <param name = "available">indicates the number of bytes remaining to be read</param>
 public abstract void SendTransTransactNmpipeResponse(IFileServiceServerOpen open, byte[] data, int available);
 /// <summary>
 /// server response the write request from client.
 /// </summary>
 /// <param name="open">the file open between server and client</param>
 /// <param name="writtenCount">number of bytes in Write request</param>
 public abstract void SendWriteResponse(IFileServiceServerOpen open, int writtenCount);
        /// <summary>
        /// Expect a request. If user is not interested in the packet, please call DefaultSendResponse().
        /// </summary>
        /// <param name="timeout">timeout</param>
        /// <param name="connection">the connection between server and client</param>
        /// <param name="session">the session between server and client</param>
        /// <param name="treeConnect">the tree connect between server and client</param>
        /// <param name="open">the file open between server and client</param>
        /// <param name="requestPacket">the request</param>
        public override void ExpectRequest(
            TimeSpan timeout,
            out IFileServiceServerConnection connection,
            out IFileServiceServerSession session,
            out IFileServiceServerTreeConnect treeConnect,
            out IFileServiceServerOpen open,
            out SmbFamilyPacket requestPacket)
        {
            CifsServerPerConnection cifsConnection;
            SmbPacket request = this.cifsServer.ExpectPacket(timeout, out cifsConnection);

            connection    = cifsConnection;
            requestPacket = request;
            session       = null;
            treeConnect   = null;
            open          = null;

            if (request != null)
            {
                session = cifsConnection.GetSession(request.SmbHeader.Uid);
                if (session != null)
                {
                    treeConnect = (session as CifsServerPerSession).GetTreeConnect(request.SmbHeader.Tid);
                    if (treeConnect != null)
                    {
                        ushort fid = 0;
                        SmbTransactionRequestPacket            transactionRequest = request as SmbTransactionRequestPacket;
                        SmbNtTransactIoctlRequestPacket        ioctlRequest       = request as SmbNtTransactIoctlRequestPacket;
                        SmbNtTransactNotifyChangeRequestPacket notifyChange       = request as SmbNtTransactNotifyChangeRequestPacket;

                        if (transactionRequest != null)
                        {
                            //SubCommand(2bytes), FID(2bytes)
                            fid = transactionRequest.SmbParameters.Setup[1];
                        }

                        else if (ioctlRequest != null)
                        {
                            //FunctionCode(4bytes), FID(2bytes), IsFctl(1bytes), IsFlags(1bytes)
                            fid = ioctlRequest.SmbParameters.Setup[2];
                        }
                        else if (notifyChange != null)
                        {
                            //CompletionFilter(4bytes), FID(2bytes), WatchTree(1bytes), Reserved(1bytes)
                            fid = notifyChange.SmbParameters.Setup[2];
                        }
                        else
                        {
                            Type         packetType = request.GetType();
                            PropertyInfo pi         = packetType.GetProperty(
                                "Trans2Parameters", BindingFlags.Instance | BindingFlags.Public);

                            if (pi == null)
                            {
                                pi = packetType.GetProperty(
                                    "NtTransParameters", BindingFlags.Instance | BindingFlags.Public);
                            }
                            if (pi == null)
                            {
                                pi = packetType.GetProperty(
                                    "SmbParameters", BindingFlags.Instance | BindingFlags.Public);
                            }
                            if (pi != null)
                            {
                                object    smbParameters = pi.GetValue(request, null);
                                FieldInfo fi            = smbParameters.GetType().GetField(
                                    "FID",
                                    BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase);
                                if (fi != null)
                                {
                                    fid = (ushort)fi.GetValue(smbParameters);
                                }
                            }
                        }

                        if (fid > 0)
                        {
                            open = (treeConnect as CifsServerPerTreeConnect).GetOpen(fid);
                        }
                    }
                }
            }
        }
 /// <summary>
 /// server response Trans2QueryFileInformation request from client.
 /// </summary>
 /// <param name="open">the file open between server and client</param>
 /// <param name="data">The transaction2 data to send</param>
 public abstract void SendTrans2QueryFileInformationResponse(IFileServiceServerOpen open, object data);
 /// <summary>
 /// server response the trans transact nmpipe request from client.
 /// </summary>
 /// <param name="open">the file open between server and client</param>
 /// <param name="data">The actual bytes</param>
 /// <param name = "available">indicates the number of bytes remaining to be read</param>
 public abstract void SendTransTransactNmpipeResponse(IFileServiceServerOpen open, byte[] data, int available);
 /// <summary>
 /// server response the IO control request from client.
 /// </summary>
 /// <param name="open">the file open between server and client</param>
 /// <param name="controlCode">The file system control code</param>
 /// <param name="data">The information about this IO control</param>
 public abstract void SendIoControlResponse(IFileServiceServerOpen open, FsCtlCode controlCode, byte[] data);
 /// <summary>
 /// Automatically response latest request.
 /// </summary>
 /// <param name="connection">the connection between server and client</param>
 /// <param name="session">the session between server and client</param>
 /// <param name="treeConnect">the tree connect between server and client</param>
 /// <param name="open">the file open between server and client</param>
 /// <param name="requestPacket">the request</param>
 public override void DefaultSendResponse(
     IFileServiceServerConnection connection,
     IFileServiceServerSession session,
     IFileServiceServerTreeConnect treeConnect,
     IFileServiceServerOpen open,
     SmbFamilyPacket requestPacket)
 {
     CifsServerPerConnection cifsConnection = connection as CifsServerPerConnection;
     SmbPacket response = this.cifsServer.CreateDefaultResponse(cifsConnection,
         requestPacket as SmbPacket);
     this.cifsServer.SendPacket(response, cifsConnection);
 }
        /// <summary>
        /// Expect a request. If user is not interested in the packet, please call DefaultSendResponse().
        /// </summary>
        /// <param name="timeout">timeout</param>
        /// <param name="connection">the connection between server and client</param>
        /// <param name="session">the session between server and client</param>
        /// <param name="treeConnect">the tree connect between server and client</param>
        /// <param name="open">the file open between server and client</param>
        /// <param name="requestPacket">the request</param>
        public override void ExpectRequest(
            TimeSpan timeout,
            out IFileServiceServerConnection connection,
            out IFileServiceServerSession session,
            out IFileServiceServerTreeConnect treeConnect,
            out IFileServiceServerOpen open,
            out SmbFamilyPacket requestPacket)
        {
            CifsServerPerConnection cifsConnection;
            SmbPacket request = this.cifsServer.ExpectPacket(timeout, out cifsConnection);
            connection = cifsConnection;
            requestPacket = request;
            session = null;
            treeConnect = null;
            open = null;

            if (request != null)
            {
                session = cifsConnection.GetSession(request.SmbHeader.Uid);
                if (session != null)
                {
                    treeConnect = (session as CifsServerPerSession).GetTreeConnect(request.SmbHeader.Tid);
                    if (treeConnect != null)
                    {
                        ushort fid = 0;
                        SmbTransactionRequestPacket transactionRequest = request as SmbTransactionRequestPacket;
                        SmbNtTransactIoctlRequestPacket ioctlRequest = request as SmbNtTransactIoctlRequestPacket;
                        SmbNtTransactNotifyChangeRequestPacket notifyChange = request as SmbNtTransactNotifyChangeRequestPacket;

                        if (transactionRequest != null)
                        {
                            //SubCommand(2bytes), FID(2bytes)
                            fid = transactionRequest.SmbParameters.Setup[1];
                        }

                        else if (ioctlRequest != null)
                        {
                            //FunctionCode(4bytes), FID(2bytes), IsFctl(1bytes), IsFlags(1bytes)
                            fid = ioctlRequest.SmbParameters.Setup[2];
                        }
                        else if (notifyChange != null)
                        {
                            //CompletionFilter(4bytes), FID(2bytes), WatchTree(1bytes), Reserved(1bytes)
                            fid = notifyChange.SmbParameters.Setup[2];
                        }
                        else
                        {
                            Type packetType = request.GetType();
                            PropertyInfo pi = packetType.GetProperty(
                                "Trans2Parameters", BindingFlags.Instance | BindingFlags.Public);

                            if (pi == null)
                            {
                                pi = packetType.GetProperty(
                                    "NtTransParameters", BindingFlags.Instance | BindingFlags.Public);
                            }
                            if (pi == null)
                            {
                                pi = packetType.GetProperty(
                                    "SmbParameters", BindingFlags.Instance | BindingFlags.Public);
                            }
                            if (pi != null)
                            {
                                object smbParameters = pi.GetValue(request, null);
                                FieldInfo fi = smbParameters.GetType().GetField(
                                    "FID",
                                    BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase);
                                if (fi != null)
                                {
                                    fid = (ushort)fi.GetValue(smbParameters);
                                }
                            }
                        }

                        if (fid > 0)
                        {
                            open = (treeConnect as CifsServerPerTreeConnect).GetOpen(fid);
                        }
                    }
                }
            }
        }
 /// <summary>
 /// server response the IO control request from client.
 /// </summary>
 /// <param name="open">the file open between server and client</param>
 /// <param name="controlCode">The file system control code</param>
 /// <param name="data">The information about this IO control</param>
 public abstract void SendIoControlResponse(IFileServiceServerOpen open, FsCtlCode controlCode, byte[] data);
        /// <summary>
        /// server response the IO control request from client.
        /// </summary>
        /// <param name="open">the file open between server and client</param>
        /// <param name="controlCode">The file system control code</param>
        /// <param name="data">The information about this IO control</param>
        public override void SendIoControlResponse(IFileServiceServerOpen open, FsCtlCode controlCode, byte[] data)
        {
            CifsServerPerConnection connection = open.TreeConnect.Session.Connection as CifsServerPerConnection;

            foreach (SmbIoctlRequestPacket request in connection.PendingRequestTable)
            {
                if (request != null
                    && request.SmbHeader.Uid == open.TreeConnect.Session.SessionId
                    && request.SmbHeader.Tid == open.TreeConnect.TreeConnectId
                    && request.SmbParameters.FID == open.FileId)
                {
                    SmbIoctlResponsePacket response = this.cifsServer.CreateIoctlResponse(connection,
                        request, null, data);
                    this.cifsServer.SendPacket(response, connection);
                    return;
                }
            }
        }
 /// <summary>
 /// server response the read request from client.
 /// The method will automatically reply multiple READ response if data is too large.
 /// </summary>
 /// <param name="open">the file open between server and client</param>
 /// <param name="data">The actual bytes</param>
 /// <param name = "available">
 /// This field is valid when reading from named pipes or I/O devices. This field indicates the number of bytes 
 /// remaining to be read after the requested read was completed.
 /// </param>
 public abstract void SendReadResponse(IFileServiceServerOpen open, byte[] data, int available);
        /// <summary>
        /// server response Trans2QueryFileInformation request from client.
        /// </summary>
        /// <param name="open">the file open between server and client</param>
        /// <param name="data">The transaction2 data to send</param>
        public override void SendTrans2QueryFileInformationResponse(IFileServiceServerOpen open, object data)
        {
            CifsServerPerConnection connection = open.TreeConnect.Session.Connection as CifsServerPerConnection;

            foreach (SmbTrans2QueryFileInformationRequestPacket request in connection.PendingRequestTable)
            {
                if (request != null
                    && request.SmbHeader.Uid == open.TreeConnect.Session.SessionId
                    && request.SmbHeader.Tid == open.TreeConnect.TreeConnectId
                    && request.Trans2Parameters.FID == open.FileId)
                {
                    SmbPacket response = this.cifsServer.CreateTrans2QueryFileInformationFinalResponse(
                        connection, request, data);
                    this.cifsServer.SendPacket(response, connection);
                    return;
                }
            }
        }
 /// <summary>
 /// Automatically response latest request.
 /// </summary>
 /// <param name="connection">the connection between server and client</param>
 /// <param name="session">the session between server and client</param>
 /// <param name="treeConnect">the tree connect between server and client</param>
 /// <param name="open">the file open between server and client</param>
 /// <param name="requestPacket">the request</param>
 public abstract void DefaultSendResponse(
     IFileServiceServerConnection connection,
     IFileServiceServerSession session,
     IFileServiceServerTreeConnect treeConnect,
     IFileServiceServerOpen open,
     SmbFamilyPacket requestPacket);
        /// <summary>
        /// server response the write request from client.
        /// </summary>
        /// <param name="open">the file open between server and client</param>
        /// <param name="writtenCount">number of bytes in Write request</param>
        public override void SendWriteResponse(IFileServiceServerOpen open, int writtenCount)
        {
            CifsServerPerConnection connection = open.TreeConnect.Session.Connection as CifsServerPerConnection;

            foreach (SmbWriteAndxRequestPacket request in connection.PendingRequestTable)
            {
                if (request != null
                    && request.SmbHeader.Uid == open.TreeConnect.Session.SessionId
                    && request.SmbHeader.Tid == open.TreeConnect.TreeConnectId
                    && request.SmbParameters.FID == open.FileId)
                {
                    SmbWriteAndxResponsePacket response = this.cifsServer.CreateWriteAndxResponse(
                        connection, request, 0, null);
                    SMB_COM_WRITE_ANDX_Response_SMB_Parameters smbParameters = response.SmbParameters;
                    smbParameters.Count = (ushort)writtenCount;
                    response.SmbParameters = smbParameters;
                    this.cifsServer.SendPacket(response, connection);
                    return;
                }
            }
        }
 /// <summary>
 /// Automatically response latest request.
 /// </summary>
 /// <param name="connection">the connection between server and client</param>
 /// <param name="session">the session between server and client</param>
 /// <param name="treeConnect">the tree connect between server and client</param>
 /// <param name="open">the file open between server and client</param>
 /// <param name="requestPacket">the request</param>
 public abstract void DefaultSendResponse(
     IFileServiceServerConnection connection,
     IFileServiceServerSession session,
     IFileServiceServerTreeConnect treeConnect,
     IFileServiceServerOpen open,
     SmbFamilyPacket requestPacket);
 /// <summary>
 /// Add an open file into this OpenTable.
 /// </summary>
 /// <param name="open">The open to add.</param>
 /// <exception cref="System.ArgumentNullException">the open is null</exception>
 /// <exception cref="System.ArgumentException">the open already exists</exception>
 public void AddOpen(IFileServiceServerOpen open)
 {
     lock (this.openTable)
     {
         this.openTable.Add((ushort)open.FileId, open);
     }
 }
 /// <summary>
 /// server response the close request from client.
 /// </summary>
 /// <param name="open">the file open between server and client</param>
 public abstract void SendCloseResponse(IFileServiceServerOpen open);