3.3.5.15.6 Handling a Server-Side Data Copy Request

When the server receives a request with an SMB2 header with a Command value equal to SMB2 IOCTL, and a CtlCode of FSCTL_SRV_COPYCHUNK or FSCTL_SRV_COPYCHUNK_WRITE, message handling proceeds as follows:

The server MUST locate the source open from where data will be read by locating the open where Open.ResumeKey matches the SourceKey that was received in the SRV_COPYCHUNK_COPY structure, which was received in the buffer described by the InputCount and InputOffset fields of the SMB2 IOCTL Request. If the open is not found, the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND.

If the MaxOutputResponse value in the SMB2 IOCTL Request is less than the size of the SRV_COPYCHUNK_RESPONSE structure, the server MUST fail the SMB2 IOCTL Request with STATUS_INVALID_PARAMETER.

If the MaxOutputResponse value in the SMB2 IOCTL Request is greater than or equal to the size of the SRV_COPYCHUNK_RESPONSE structure and any of the following are true, the server MUST send an SMB2 IOCTL Response as specified in section 3.3.5.15.6.2:

  • The InputCount value in the SMB2 IOCTL Request is less than the size of the Buffer field containing the SRV_COPYCHUNK_COPY structure.

  • The ChunkCount value is greater than ServerSideCopyMaxNumberofChunks.

  • The Length value in a single chunk is greater than ServerSideCopyMaxChunkSize or equal to zero.

  • Sum of Lengths in all chunks is greater than ServerSideCopyMaxDataSize.

  • The TargetOffset value in any chunk is less than zero but not equal to 0xFFFFFFFFFFFFFFFF.

  • The Open.TreeConnect value of the source or destination file is on a named pipe file system.

The server MUST fail the request with STATUS_ACCESS_DENIED if any of the following are true:

  • The Open.GrantedAccess of the source file does not include FILE_READ_DATA access.

  • The Open.GrantedAccess of the destination file does not include FILE_WRITE_DATA or FILE_APPEND_DATA.

  • The Open.GrantedAccess of the destination file does not include FILE_READ_DATA, and the CtlCode is FSCTL_SRV_COPYCHUNK.

If the Open.GrantedAccess value of the destination file does not include FILE_WRITE_DATA or FILE_APPEND_DATA, then the request MUST be failed with STATUS_ACCESS_DENIED. If the Open.GrantedAccess value of the source file does not include FILE_READ_DATA access, then the request MUST be failed with STATUS_ACCESS_DENIED.

If Open.TreeConnect.Session of the destination file is not equal to Open.TreeConnect.Session of the source file, the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND.

The server SHOULD<381> verify that no byte-range locks conflicting with read access to the source file region starting from SourceOffset and extending Length bytes, and with write access to the destination file region starting from TargetOffset and extending Length bytes, are held. If any such locks are found, the server MUST not perform the copy and MUST fail the request as specified in section 3.3.5.15.6.1. If no such locks are found, starting with the first chunk received in the Chunks field, the server MUST copy each chunk from the source file to the destination file in an implementation-specific manner. If the copy operation fails, the server MUST fail the request as specified in section 3.3.5.15.6.1.

If all ranges are copied successfully, the server MUST construct an SMB2 IOCTL Response following the syntax specified in the section 2.2.32, with the following values:

  • CtlCode MUST be set to FSCTL_SRV_COPYCHUNK or FSCTL_SRV_COPYCHUNK_WRITE.

  • FileId.Persistent MUST be set to Open.DurableFileId. FileId.Volatile MUST be set to Open.FileId.

  • InputOffset SHOULD be set to the offset, in bytes, from the beginning of the SMB2 header to the Buffer[] field of the response.

  • InputCount SHOULD be set to zero.

  • OutputOffset MUST be set to InputOffset + InputCount, rounded up to a multiple of 8.

  • OutputCount MUST be set to 12.

  • Flags MUST be set to zero.

  • The server MUST copy a SRV_COPYCHUNK_RESPONSE following the syntax specified in section 2.2.32.1 into the Buffer field at the OutputOffset computed above. ChunksWritten MUST be set to the number of chunks processed. ChunkBytesWritten MUST be set to zero. TotalBytesWritten MUST be set to the total number of bytes written to the destination file across all chunk writes.

The response MUST be sent to the client.