/// <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 actively close the connection.
 /// </summary>
 /// <param name="connection">the connection between server and client</param>
 /// <exception cref="ArgumentNullException">connection is null</exception>
 public override void Disconnect(IFileServiceServerConnection connection)
 {
     if (connection == null)
     {
         throw new ArgumentNullException("connection");
     }
     this.cifsServer.Disconnect(connection as CifsServerPerConnection);
     this.fsEndpoints.Remove(connection.Identity);
 }
        /// <summary>
        /// server response the negotiate request from client.
        /// </summary>
        /// <param name="connection">the connection between server and client</param>
        /// <param name="requestPacket">the request</param>
        public override void SendNegotiateResponse(
            IFileServiceServerConnection connection,
            SmbFamilyPacket requestPacket)
        {
            CifsServerPerConnection cifsConnection = connection as CifsServerPerConnection;
            SmbPacket response = this.cifsServer.CreateDefaultResponse(cifsConnection,
                                                                       requestPacket as SmbNegotiateRequestPacket);

            this.cifsServer.SendPacket(response, cifsConnection);
        }
        /// <summary>
        /// server response the session request from client.
        /// </summary>
        /// <param name="connection">the connection between server and client</param>
        /// <param name="requestPacket">the request</param>
        /// <returns>The session object.</returns>
        public override IFileServiceServerSession SendSessionSetupResponse(
            IFileServiceServerConnection connection,
            SmbFamilyPacket requestPacket)
        {
            CifsServerPerConnection cifsConnection = connection as CifsServerPerConnection;
            SmbPacket response = this.cifsServer.CreateDefaultResponse(cifsConnection,
                                                                       requestPacket as SmbPacket);

            this.cifsServer.SendPacket(response, cifsConnection);
            return(cifsConnection.GetSession(response.SmbHeader.Uid));
        }
        /// <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 an error packet
        /// </summary>
        /// <param name="connection">the connection between server and client</param>
        /// <param name="status">error code</param>
        /// <param name="requestPacket">the request packet to send the error response</param>
        public override void SendErrorResponse(
            IFileServiceServerConnection connection,
            uint status,
            SmbFamilyPacket requestPacket)
        {
            CifsServerPerConnection cifsConnection = connection as CifsServerPerConnection;
            SmbPacket response = this.cifsServer.CreateDefaultResponse(cifsConnection,
                                                                       requestPacket as SmbPacket);

            SmbHeader smbHeader = response.SmbHeader;

            smbHeader.Status   = status;
            response.SmbHeader = smbHeader;
            this.cifsServer.SendPacket(response, cifsConnection);
        }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="connection">The SMB connection associated with this session.</param>
 /// <param name="sessionId">Session Id of the Session</param>
 /// <param name="securityContext">The security context of the user that established the session, as obtained
 /// from the authentication subsystem after successful authentication.</param>
 /// <param name="creationTime">The time that the session was established.</param>
 /// <param name="idleTime">The time that the session processed its most recent request.</param>
 /// <param name="userName">The name of the user who established the session.</param>
 /// <param name="sessionGlobalId">A numeric 32-bit value obtained by registration with the Server Service Remote
 /// Protocol.</param>
 public CifsServerPerSession(
     IFileServiceServerConnection connection,
     long sessionId,
     ServerSecurityContext securityContext,
     DateTime creationTime,
     DateTime idleTime,
     string userName,
     int sessionGlobalId)
 {
     this.connection = connection;
     this.sessionId = sessionId;
     this.securityContext = securityContext;
     this.creationTime = creationTime;
     this.idleTime = idleTime;
     this.userName = userName;
     this.sessionGlobalId = sessionGlobalId;
     this.treeConnectTable = new Dictionary<ushort, IFileServiceServerTreeConnect>();
 }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="connection">The SMB connection associated with this session.</param>
 /// <param name="sessionId">Session Id of the Session</param>
 /// <param name="securityContext">The security context of the user that established the session, as obtained
 /// from the authentication subsystem after successful authentication.</param>
 /// <param name="creationTime">The time that the session was established.</param>
 /// <param name="idleTime">The time that the session processed its most recent request.</param>
 /// <param name="userName">The name of the user who established the session.</param>
 /// <param name="sessionGlobalId">A numeric 32-bit value obtained by registration with the Server Service Remote
 /// Protocol.</param>
 public CifsServerPerSession(
     IFileServiceServerConnection connection,
     long sessionId,
     ServerSecurityContext securityContext,
     DateTime creationTime,
     DateTime idleTime,
     string userName,
     int sessionGlobalId)
 {
     this.connection       = connection;
     this.sessionId        = sessionId;
     this.securityContext  = securityContext;
     this.creationTime     = creationTime;
     this.idleTime         = idleTime;
     this.userName         = userName;
     this.sessionGlobalId  = sessionGlobalId;
     this.treeConnectTable = new Dictionary <ushort, IFileServiceServerTreeConnect>();
 }
        /// <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 actively close the connection.
 /// </summary>
 /// <param name="connection">the connection between server and client</param>
 /// <exception cref="ArgumentNullException">connection is null</exception>
 public override void Disconnect(IFileServiceServerConnection connection)
 {
     if (connection == null)
     {
         throw new ArgumentNullException("connection");
     }
     this.cifsServer.Disconnect(connection as CifsServerPerConnection);
     this.fsEndpoints.Remove(connection.Identity);
 }
 /// <summary>
 /// server actively close the connection.
 /// </summary>
 /// <param name="connection">the connection between server and client</param>
 public abstract void Disconnect(IFileServiceServerConnection connection);
 /// <summary>
 /// server response an error packet
 /// </summary>
 /// <param name="connection">the connection between server and client</param>
 /// <param name="status">error code</param>
 /// <param name="requestPacket">the request packet to send the error response</param>
 public abstract void SendErrorResponse(
     IFileServiceServerConnection connection,
     uint status,
     SmbFamilyPacket requestPacket);
 /// <summary>
 /// server response the session request from client.
 /// The method will complete 2nd session setup request automatically.
 /// </summary>
 /// <param name="connection">the connection between server and client</param>
 /// <param name="requestPacket">the request</param>
 /// <returns>The session object.</returns>
 public abstract IFileServiceServerSession SendSessionSetupResponse(
     IFileServiceServerConnection connection,
     SmbFamilyPacket requestPacket);
 /// <summary>
 /// server response the negotiate request from client.
 /// </summary>
 /// <param name="connection">the connection between server and client</param>
 /// <param name="requestPacket">the request</param>
 public abstract void SendNegotiateResponse(
     IFileServiceServerConnection connection,
     SmbFamilyPacket requestPacket);
 /// <summary>
 /// server response the session request from client.
 /// The method will complete 2nd session setup request automatically.
 /// </summary>
 /// <param name="connection">the connection between server and client</param>
 /// <param name="requestPacket">the request</param>
 /// <returns>The session object.</returns>
 public abstract IFileServiceServerSession SendSessionSetupResponse(
     IFileServiceServerConnection connection,
     SmbFamilyPacket requestPacket);
 /// <summary>
 /// server response the negotiate request from client.
 /// </summary>
 /// <param name="connection">the connection between server and client</param>
 /// <param name="requestPacket">the request</param>
 public abstract void SendNegotiateResponse(
     IFileServiceServerConnection connection,
     SmbFamilyPacket requestPacket);
 /// <summary>
 /// server response the session request from client.
 /// </summary>
 /// <param name="connection">the connection between server and client</param>
 /// <param name="requestPacket">the request</param>
 /// <returns>The session object.</returns>
 public override IFileServiceServerSession SendSessionSetupResponse(
     IFileServiceServerConnection connection,
     SmbFamilyPacket requestPacket)
 {
     CifsServerPerConnection cifsConnection = connection as CifsServerPerConnection;
     SmbPacket response = this.cifsServer.CreateDefaultResponse(cifsConnection,
         requestPacket as SmbPacket);
     this.cifsServer.SendPacket(response, cifsConnection);
     return cifsConnection.GetSession(response.SmbHeader.Uid);
 }
 /// <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 actively close the connection.
 /// </summary>
 /// <param name="connection">the connection between server and client</param>
 public abstract void Disconnect(IFileServiceServerConnection connection);
        /// <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>
 /// 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 an error packet
        /// </summary>
        /// <param name="connection">the connection between server and client</param>
        /// <param name="status">error code</param>
        /// <param name="requestPacket">the request packet to send the error response</param>
        public override void SendErrorResponse(
            IFileServiceServerConnection connection,
            uint status,
            SmbFamilyPacket requestPacket)
        {
            CifsServerPerConnection cifsConnection = connection as CifsServerPerConnection;
            SmbPacket response = this.cifsServer.CreateDefaultResponse(cifsConnection,
                requestPacket as SmbPacket);

            SmbHeader smbHeader = response.SmbHeader;
            smbHeader.Status = status;
            response.SmbHeader = smbHeader;
            this.cifsServer.SendPacket(response, cifsConnection);
        }
 /// <summary>
 /// server response the negotiate request from client.
 /// </summary>
 /// <param name="connection">the connection between server and client</param>
 /// <param name="requestPacket">the request</param>
 public override void SendNegotiateResponse(
     IFileServiceServerConnection connection,
     SmbFamilyPacket requestPacket)
 {
     CifsServerPerConnection cifsConnection = connection as CifsServerPerConnection;
     SmbPacket response = this.cifsServer.CreateDefaultResponse(cifsConnection,
         requestPacket as SmbNegotiateRequestPacket);
     this.cifsServer.SendPacket(response, cifsConnection);
 }
 /// <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>
 /// 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 an error packet
 /// </summary>
 /// <param name="connection">the connection between server and client</param>
 /// <param name="status">error code</param>
 /// <param name="requestPacket">the request packet to send the error response</param>
 public abstract void SendErrorResponse(
     IFileServiceServerConnection connection,
     uint status,
     SmbFamilyPacket requestPacket);