internal static SMB1Command GetFlushResponse(SMB1Header header, FlushRequest request, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); if (request.FID == 0xFFFF) { // [MS-CIFS] If the FID is 0xFFFF, the Server.Connection.FileOpenTable MUST be scanned for // all files that were opened by the PID listed in the request header. // The server MUST attempt to flush each Server.Open so listed. return(new FlushResponse()); } OpenFileObject openFile = session.GetOpenFileObject(request.FID); if (openFile == null) { state.LogToServer(Severity.Verbose, "Flush failed. Invalid FID. (UID: {0}, TID: {1}, FID: {2})", header.UID, header.TID, request.FID); header.Status = NTStatus.STATUS_INVALID_HANDLE; return(new ErrorResponse(request.CommandName)); } header.Status = share.FileStore.FlushFileBuffers(openFile.Handle); if (header.Status != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "Flush '{0}{1}' failed. NTStatus: {2}. (FID: {3})", share.Name, openFile.Path, header.Status, request.FID); return(new ErrorResponse(request.CommandName)); } return(new FlushResponse()); }
public FlushRequestTests() { var request = new FlushRequest() { AllowNoIndices = false }; var response = this._client.Flush(request); this._status = response.ConnectionStatus; }
public NTStatus FlushFileBuffers(object handle) { FlushRequest request = new FlushRequest(); request.FileId = (FileID)handle; TrySendCommand(request); SMB2Command response = m_client.WaitForCommand(request.MessageID); if (response != null) { if (response.Header.Status == NTStatus.STATUS_SUCCESS && response is FlushResponse) { return(response.Header.Status); } } return(NTStatus.STATUS_INVALID_SMB); }
internal static SMB2Command GetFlushResponse(FlushRequest request, ISMBShare share, SMB2ConnectionState state) { SMB2Session session = state.GetSession(request.Header.SessionID); OpenFileObject openFile = session.GetOpenFileObject(request.FileId); if (openFile == null) { state.LogToServer(Severity.Verbose, "Flush failed. Invalid FileId. (SessionID: {0}, TreeID: {1}, FileId: {2})", request.Header.SessionID, request.Header.TreeID, request.FileId.Volatile); return(new ErrorResponse(request.CommandName, NTStatus.STATUS_FILE_CLOSED)); } NTStatus status = share.FileStore.FlushFileBuffers(openFile.Handle); if (status != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "Flush '{0}{1}' failed. NTStatus: {2}. (FileId: {3})", share.Name, openFile.Path, status, request.FileId.Volatile); return(new ErrorResponse(request.CommandName, status)); } return(new FlushResponse()); }
private SMB2Command ProcessSMB2Command(SMB2Command command, SMB2ConnectionState state) { if (command is SessionSetupRequest) { return(SessionSetupHelper.GetSessionSetupResponse((SessionSetupRequest)command, m_securityProvider, state)); } else if (command is EchoRequest) { return(new EchoResponse()); } else { SMB2Session session = state.GetSession(command.Header.SessionID); if (session == null) { return(new ErrorResponse(command.CommandName, NTStatus.STATUS_USER_SESSION_DELETED)); } if (command is TreeConnectRequest) { return(TreeConnectHelper.GetTreeConnectResponse((TreeConnectRequest)command, state, m_services, m_shares)); } else if (command is LogoffRequest) { state.LogToServer(Severity.Information, "Logoff: User '{0}' logged off.", session.UserName); m_securityProvider.DeleteSecurityContext(ref session.SecurityContext.AuthenticationContext); state.RemoveSession(command.Header.SessionID); return(new LogoffResponse()); } else { // Cancel requests can have an ASYNC header (TreeID will not be present) if (command is CancelRequest) { if (command.Header.IsAsync && command.Header.AsyncID == 0) { ErrorResponse response = new ErrorResponse(command.CommandName, NTStatus.STATUS_CANCELLED); response.Header.IsAsync = true; return(response); } // [MS-SMB2] If a request is not found, the server MUST stop processing for this cancel request. No response is sent. return(null); } ISMBShare share = session.GetConnectedTree(command.Header.TreeID); if (share == null) { return(new ErrorResponse(command.CommandName, NTStatus.STATUS_NETWORK_NAME_DELETED)); } if (command is TreeDisconnectRequest) { return(TreeConnectHelper.GetTreeDisconnectResponse((TreeDisconnectRequest)command, share, state)); } else if (command is CreateRequest) { return(CreateHelper.GetCreateResponse((CreateRequest)command, share, state)); } else if (command is QueryInfoRequest) { return(QueryInfoHelper.GetQueryInfoResponse((QueryInfoRequest)command, share, state)); } else if (command is SetInfoRequest) { return(SetInfoHelper.GetSetInfoResponse((SetInfoRequest)command, share, state)); } else if (command is QueryDirectoryRequest) { return(QueryDirectoryHelper.GetQueryDirectoryResponse((QueryDirectoryRequest)command, share, state)); } else if (command is ReadRequest) { return(ReadWriteResponseHelper.GetReadResponse((ReadRequest)command, share, state)); } else if (command is WriteRequest) { return(ReadWriteResponseHelper.GetWriteResponse((WriteRequest)command, share, state)); } else if (command is FlushRequest) { FlushRequest request = (FlushRequest)command; OpenFileObject openFile = session.GetOpenFileObject(request.FileId); if (openFile == null) { return(new ErrorResponse(request.CommandName, NTStatus.STATUS_FILE_CLOSED)); } NTStatus status = share.FileStore.FlushFileBuffers(openFile.Handle); if (status != NTStatus.STATUS_SUCCESS) { return(new ErrorResponse(request.CommandName, status)); } return(new FlushResponse()); } else if (command is CloseRequest) { return(CloseHelper.GetCloseResponse((CloseRequest)command, share, state)); } else if (command is IOCtlRequest) { return(IOCtlHelper.GetIOCtlResponse((IOCtlRequest)command, share, state)); } else if (command is ChangeNotifyRequest) { // [MS-SMB2] If the underlying object store does not support change notifications, the server MUST fail this request with STATUS_NOT_SUPPORTED ErrorResponse response = new ErrorResponse(command.CommandName, NTStatus.STATUS_NOT_SUPPORTED); // Windows 7 / 8 / 10 will infinitely retry sending ChangeNotify requests if the response does not have SMB2_FLAGS_ASYNC_COMMAND set. // Note: NoRemoteChangeNotify can be set in the registry to prevent the client from sending ChangeNotify requests altogether. response.Header.IsAsync = true; return(response); } } } return(new ErrorResponse(command.CommandName, NTStatus.STATUS_NOT_SUPPORTED)); }