READ_MPX: Read Block Multiplex

The Read Block Multiplexed protocol is used to maximize the performance of reading a large block of data from the server to the client while still allowing other operations to take place between the client and server in the meantime. The NT server supports SMB_COM_READ_MPX only over connectionless transports.

Client Request
================================
Description
===================================
UCHAR WordCount; Count of parameter words = 8
USHORT Fid; File handle
ULONG Offset; Offset in file to begin read
USHORT MaxCount; Max bytes to return (maximum 65535)
USHORT MinCount; Min bytes to return (normally 0)
ULONG Reserved1;
USHORT Reserved2;
USHORT ByteCount; Count of data bytes = 0

fid identifies the resource being read, and may refer to a disk file or a spooled printer.

timeout is the number of milliseconds to wait for completion fid refers to a named pipe.

Server Response
==================================
Description
=================================
UCHAR WordCount; Count of parameter words = 8
ULONG Offset; Offset in file where data read
USHORT Count; Total bytes being returned
USHORT Reserved;
USHORT DataCompactionMode;
USHORT Reserved;
USHORT DataLength; Number of data bytes this buffer
USHORT DataOffset; Offset (from header start) to data
USHORT ByteCount; Count of data bytes
UCHAR Pad[]; Pad to SHORT or LONG
UCHAR Data[]; Data (size = DataLength)

Other requests may be active between the client and server. The server responds with the one or more response messages as defined above until the requested data amount has been returned. Each response contains the pid and mid of the original request and the offset and count of describing the placement of the data within the file.

The client knows the maximum amount of data bytes which the server may return (from maxcount of the request). Thus the client initializes its bytes expected variable to this value. The server then informs the client of the actual amount being returned via each part of the response in count. The server may reduce the expected bytes by lowering the total number of bytes expected in count in any response.

When the amount of data bytes received (sum of the datalength fields) equals the total amount of data bytes expected (smallest count received), then the client has received all the data bytes. This allows the protocol to work even if the responses are received out of sequence.

Note that datalength being returned here can not be larger than the smaller of the client's buffer size (as specified in maxbuffersize on the COM_SESSION_SETUP_AND_X client request SMB) or the server's buffer size (as specified in maxbuffersize of the COM_NEGOTIATE server response SMB).

As is true in SMB_COM_READ, the total number of bytes returned may be less than the number requested only if a read specifies bytes beyond the current file size and fid refers to a disk file. In this case only the bytes that exist are returned. A read completely beyond the end of file will result in a single response with a zero value in count. If the total number of bytes returned is less than the number of bytes requested, this indicates end of file (if reading other than a standard blocked disk file, only ZERO bytes returned indicates end of file).

Once started, the Read Block Multiplexed operation is expected to go to completion. The client is expected to receive all the responses generated by the server. Conflicting commands (such as file close) must not be sent to the server while a multiplexed operation is in progress.

The flow for the SMB_COM_READ_MPX protocol is:

client ---------------> Read MPX. request >---------------------> server
client <--------------< Read MPX response 1 with data <---------- server
client <--------------< Read MPX response 2 with data <---------- server
...
client <--------------< Read MPX response n with data <---------- server