/// <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> /// 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 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 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> /// 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> /// 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);