Export (0) Print
Expand All

3.3.5.13 Receiving an SMB2 WRITE Request

When the server receives a request with an SMB2 header with a Command value equal to SMB2 WRITE, message handling proceeds as follows:

The server MUST locate the session, as specified in section 3.3.5.2.9.

The server MUST locate the tree connection, as specified in section 3.3.5.2.11.

Next the server MUST locate the open being written to by performing a lookup in the Session.OpenTable, using FileId.Volatile of the request as the lookup key. If no open is found, or if Open.DurableFileId is not equal to FileId.Persistent, the server MUST fail the request with STATUS_FILE_CLOSED. Otherwise, the server MUST locate the Request in Connection.RequestList for which Request.MessageId matches the MessageId value in the SMB2 Header, and set Request.Open to the Open.

If the range being written to is within the existing file size and Open.GrantedAccess does not include FILE_WRITE_DATA, or if the range being written to extends the file size and Open.GrantedAccess does not include FILE_APPEND_DATA, the server SHOULD<286> fail the request with STATUS_ACCESS_DENIED.

The server SHOULD<287> fail the request with STATUS_INVALID_PARAMETER if the Length field is greater than Connection.MaxWriteSize.

If Connection.Dialect belongs to the SMB 3.x dialect family and if any of the following conditions are TRUE, the server MUST fail the request with STATUS_INVALID_PARAMETER:

  • Channel is not equal to SMB2_CHANNEL_RDMA_V1_INVALIDATE, SMB2_CHANNEL_RDMA_V1, or SMB2_CHANNEL_NONE.

  • Connection.Dialect is "3.000" and Channel is equal to SMB2_CHANNEL_RDMA_V1_INVALIDATE.

  • Channel is equal to SMB2_CHANNEL_RDMA_V1 or SMB2_CHANNEL_RDMA_V1_INVALIDATE and the underlying Connection is not RDMA.

  • Channel is equal to SMB2_CHANNEL_RDMA_V1 or SMB2_CHANNEL_RDMA_V1_INVALIDATE and Length or DataOffset are not equal to 0.

  • Channel is equal to SMB2_CHANNEL_RDMA_V1 or SMB2_CHANNEL_RDMA_V1_INVALIDATE and RemainingBytes or WriteChannelInfoOffset or WriteChannelInfoLength are equal to 0.

If Channel is equal to 0 and DataOffset is greater than 0x100, the server MUST fail the request with STATUS_INVALID_PARAMETER.

If Channel is equal to 0 and the number of bytes received in Buffer is less than (DataOffset + Length), the server MUST fail the request with STATUS_INVALID_PARAMETER.

If Connection.SupportsMultiCredit is TRUE, the server MUST validate CreditCharge based on Length, as specified in section 3.3.5.2.5. If the validation fails, it MUST fail the write request with STATUS_INVALID_PARAMETER.

If the server implements the SMB 3.x dialect family, and if a write is being executed on a named pipe and the Flags field is set to SMB2_WRITEFLAG_WRITE_UNBUFFERED or SMB2_WRITEFLAG_WRITE_THROUGH, the server MUST fail the request with STATUS_INVALID_PARAMETER.

The server SHOULD<288> ignore undefined bits in the Flags field.

If the server implements the SMB 3.02 dialect, Connection.Dialect is not "3.002", and the SMB2_WRITEFLAG_WRITE_UNBUFFERED bit is set in the Flags field, the server MUST ignore the bit.

If Channel is not equal to one of the values specified in section 2.2.19, the server SHOULD<289> consider the Channel field value as SMB2_CHANNEL_NONE and MUST continue processing the request.

If Connection.Dialect belongs to the SMB 3.x dialect family and Channel is equal to SMB2_CHANNEL_RDMA_V1 and any of the following conditions is TRUE, the server MUST fail the request with STATUS_INVALID_PARAMETER.

  • Underlying Connection is not RDMA.

  • RemainingBytes is equal to 0.

  • Length or DataOffset is not equal to 0.

  • WriteChannelInfoOffset or WriteChannelInfoLength is equal to 0.

If the request Channel field contains the value SMB2_CHANNEL_RDMA_V1 or SMB2_CHANNEL_RDMA_V1_INVALIDATE, then the data MUST be first obtained via the processing specified in [MS-SMBD] section 3.1.4.6 RDMA Read from Peer Buffer, providing the Connection, a newly allocated buffer to receive the data, and the array of SMB_DIRECT_BUFFER_DESCRIPTOR_V1 structures passed in the request at offset WriteChannelInfoOffset and of length WriteChannelInfoLength fields.

If the server implements the SMB 3.02 dialect, SMB2_WRITEFLAG_WRITE_THROUGH is set in the Flags field of the request, SMB2_WRITEFLAG_WRITE_UNBUFFERED is not set in the Flags field of the request, and Open.CreateOptions doesn't include the FILE_NO_INTERMEDIATE_BUFFERING bit, the server MUST fail the request with STATUS_INVALID_PARAMETER.

If the server implements the SMB 2.1 or the SMB 3.x dialect family, SMB2_WRITEFLAG_WRITE_THROUGH is set in the Flags field of the request, and Open.CreateOptions doesn't include the FILE_NO_INTERMEDIATE_BUFFERING bit, the server MUST fail the request with STATUS_INVALID_PARAMETER.

If Open.IsSharedVHDX is TRUE, the server MUST issue a write to Remote Shared Virtual Disk, as specified in [MS-RSVD] section 3.2.5.4, by providing Open.LocalOpen for the length, in bytes, given by Length, at the offset, in bytes, from the beginning of the file, provided in Offset.

If Open.IsSharedVHDX is FALSE, the server MUST issue a write to the underlying object store represented by Open.LocalOpen for the length, in bytes, given by Length, at the offset, in bytes, from the beginning of the file, provided in Offset. If Connection.Dialect is not "2.002", and SMB2_WRITEFLAG_WRITE_THROUGH is set in the Flags field of the SMB2 WRITE Request, the server SHOULD<290> indicate to the underlying object store that the write is to be written to persistent storage before completion is returned. If the server implements the SMB 3.02 dialect, and if the SMB2_WRITEFLAG_WRITE_UNBUFFERED bit is set in the Flags field of the request, the server SHOULD indicate to the underlying object store that the write data is not to be buffered.

If the write is being executed on a named pipe, and the pipe is in blocking mode (the default), the operation could block for a long time, so the server MAY<291> choose to handle it asynchronously, as specified in section 3.3.4.2. To query a pipe's blocking mode, use the FilePipeInformation file information class, as specified in [MS-FSCC] section 2.4.29. To change a pipe's blocking mode, use an SMB2 SET_INFO Request with the FilePipeInformation file information class, as specified in [MS-FSCC] section 2.4.29.

If the write fails, the server MUST fail the request with the error code received from the write.

If the write succeeds, the server MUST construct a write response following the syntax specified in section 2.2.22 with the following values:

  • Count MUST be set to the number of bytes written.

  • Remaining MUST be set to zero.

  • WriteChannelInfoOffset MUST be set to zero.

  • WriteChannelInfoLength MUST be set to zero.

The response MUST then be sent to the client. If the request Channel field contains the value SMB2_CHANNEL_RDMA_V1_INVALIDATE, then the Token in the first element of the array of SMB_DIRECT_BUFFER_DESCRIPTOR_V1 structures passed in the request MUST additionally be supplied, as specified in [MS-SMBD] section 3.1.4.2.

The status code returned by this operation MUST be one of those defined in [MS-ERREF]. Common status codes returned by this operation include:

  • STATUS_SUCCESS

  • STATUS_INSUFFICIENT_RESOURCES

  • STATUS_ACCESS_DENIED

  • STATUS_FILE_CLOSED

  • STATUS_NETWORK_NAME_DELETED

  • STATUS_USER_SESSION_DELETED

  • STATUS_NETWORK_SESSION_EXPIRED

  • STATUS_INVALID_PARAMETER

  • STATUS_PIPE_BROKEN

  • STATUS_DISK_FULL

  • STATUS_CANCELLED

  • STATUS_FILE_LOCK_CONFLICT

 
Show:
© 2014 Microsoft