internal static SMB2Command GetCancelResponse(CancelRequest request, SMB2ConnectionState state) { SMB2Session session = state.GetSession(request.Header.SessionID); if (request.Header.IsAsync) { SMB2AsyncContext context = state.GetAsyncContext(request.Header.AsyncID); if (context != null) { ISMBShare share = session.GetConnectedTree(context.TreeID); OpenFileObject openFile = session.GetOpenFileObject(context.FileID); NTStatus status = share.FileStore.Cancel(context.IORequest); if (openFile != null) { state.LogToServer(Severity.Information, "Cancel: Requested cancel on '{0}{1}'. NTStatus: {2}, AsyncID: {3}.", share.Name, openFile.Path, status, context.AsyncID); } if (status == NTStatus.STATUS_SUCCESS || status == NTStatus.STATUS_CANCELLED || status == NTStatus.STATUS_NOT_SUPPORTED) // See ChangeNotifyHelper.cs { state.RemoveAsyncContext(context); // [MS-SMB2] If the target request is successfully canceled, the target request MUST be failed by sending // an ERROR response packet [..] with the status field of the SMB2 header set to STATUS_CANCELLED. ErrorResponse response = new ErrorResponse(request.CommandName, NTStatus.STATUS_CANCELLED); response.Header.IsAsync = true; response.Header.AsyncID = context.AsyncID; return(response); } // [MS-SMB2] If the target request is not successfully canceled [..] no response is sent. // Note: Failing to respond might cause the client to disconnect the connection as per [MS-SMB2] 3.2.6.1 Request Expiration Timer Event return(null); } else { // [MS-SMB2] If a request is not found [..] no response is sent. return(null); } } else { // [MS-SMB2] the SMB2 CANCEL Request MUST use an ASYNC header for canceling requests that have received an interim response. // [MS-SMB2] If the target request is not successfully canceled [..] no response is sent. return(null); } }