WRITE_MPX: Write Block Multiplex

Client Request
==================================
Description
=================================
UCHAR WordCount; Count of parameter words = 12
USHORT Fid; File handle
USHORT Count; Total bytes, including this buffer
USHORT Reserved;
ULONG Offset; Offset in file to begin write
ULONG Timeout; milliseconds to wait for completion
USHORT WriteMode; Write mode:
bit 0 - complete write to disk and send final result response
bit 1 - return Remaining
bit 7 - Connectionless mode
ULONG RequestMask; Connectionless mode mask
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 (# = DataLength)

Server Response
==================================
Description
=================================
UCHAR WordCount; Count of parameter words = 1
ULONG ResponseMask; OR of all masks received
USHORT ByteCount; Count of data bytes = 0

SMB_COM_WRITE_MPX is used to maximize the performance of writing a large block of data from the client to the server. The NT server supports SMB_COM_WRITE_MPX only over connectionless transports, consequently bit7 of writemode in the request must be set.

fid in the request must refer to either a file or a spooled printer.

mask contains a bit mask indicating where in the transfer that the SMB belongs. The response which contains the logical OR of all of the mask values received and is always generated. All in this exchange use the same SMB header mid value but only final message is a connectionless sequenced request (sequencenumber is non-zero).

The server keeps a responsemask which is the logical or-ing of the requestmask value contained in each SMB_COM_WRITE_MPX received since the last sequenced SMB_COM_WRITE_MPX. The server only responds to the final (sequenced) command, and this response contains the accumulated responsemask. The client uses the responsemask received to determine which packets, if any, must be retransmitted. The server imposes no restrictions on the values in the mask nor upon the order or contiguity of the data being sent. The client uses this behavior to only send the missing parts in the next write sequence when retransmitting. The next SMB_COM_WRITE_MPX sequence sent must use a new sequencenumber value or the server will incorrectly respond with the mask from the previous SMB_COM_WRITE_MPX command.

The flow is:

Client

=================
Sequence
Number
=========
<->

====
Server

=====================
SMB_COM_WRITE_MPX 0 ->
SMB_COM_WRITE_MPX 0 ->
...
SMB_COM_WRITE_MPX S ->
S <- SMB_COM_WRITE_MPX OK
SMB_COM_WRITE_MPX 0 ->
SMB_COM_WRITE_MPX 0 ->
....
SMB_COM_WRITE_MPX S+1 ->
S+1 <- SMB_COM_WRITE_MPX OK

Other SMB requests can intervene during this protocol exchange.

A server response will be generated only after the sequenced SMB_COM_WRITE_MPX has been received unless this SMB is received over a connection oriented transport (in which case the error response is immediately sent).

At the time of the request, the client knows the number of data bytes expected to be sent and passes this information to the server in count. The server can use this information to reserve buffer space, if possible.

If bit0 of writemode is clear, the request assumed to be a form of write behind on the part of the client. If an error occurs while writing data to disk such as disk full, the next access of the file handle (another write, close, read, etc.) will return the fact that the error occurred. If bit0 of writemode is set, the server will collect all the data, write it to disk and then send a final response indicating the result of the write . The total number of bytes written is also returned in this response.