Batching Requests ("AndX" Messages)
LANMAN1.0
and later dialects of the CIFS protocol allow multiple SMB requests to be sent in one message to the server. Messages of this type are called AndX SMBs, and they obey the following rules:
-
The embedded command does not repeat the SMB header information. Rather the next SMB starts at the WordCount field.
-
All multiple (chained) requests must fit within the negotiated transmit size. For example, if SMB_COM_TREE_CONNECT_ANDX included OPENandX SMB_COM_OPEN_ANDX which included SMB_COM_WRITE were sent, they would all have to fit within the negotiated buffer size. This would limit the size of the write.
-
There is one message sent containing the chained requests and there is one response message to the chained requests. The server may NOT elect to send separate responses to each of the chained requests.
-
All chained responses must fit within the negotiated transmit size. This limits the maximum value on an embedded SMB_COM_READ for example. It is the client's responsibility to not request more bytes than will fit within the multiple response.
-
The server will implicitly use the result of the first command in the "X" command. For example the tid obtained via SMB_COM_TREE_CONNECT_ANDX would be used in the embedded SMB_COM_OPEN_ANDX and the fid obtained in the SMB_COM_OPEN_ANDX would be used in the embedded SMB_COM_READ.
-
Each chained request can only reference the same fid and tid as the other commands in the combined request. The chained requests can be thought of as performing a single (multi-part) operation on the same resource.
-
The first command to encounter an error will stop all further processing of embedded commands. The server will not back out commands that succeeded. Thus if a chained request contained SMB_COM_OPEN_ANDX and SMB_COM_READ and the server was able to open the file successfully but the read encountered an error, the file would remain open. This is exactly the same as if the requests had been sent separately.
-
If an error occurs while processing chained requests, the last response (of the chained responses in the buffer) will be the one which encountered the error. Other unprocessed chained requests will have been ignored when the server encountered the error and will not be represented in the chained response. Actually the last valid andxcommand (if any) will represent the SMB on which the error occurred. If no valid andxcommand is present, then the error occurred on the first request/response and command contains the command which failed. In all cases the error information are returned in the SMB header at the start of the response buffer.
-
Each chained request and response contains the offset (from the start of the SMB header) to the next chained request/response (in the AndXOffset field in the various "and X" protocols defined later e.g. SMB_COM_OPEN_ANDX). This allows building the requests unpacked. There may be space between the end of the previous request (as defined by WordCount and ByteCount) and the start of the next chained request. This simplifies the building of chained protocol requests. Note that because the client must know the size of the data being returned in order to post the correct number of receives (e.g. SMB_COM_TRANSACTION, SMB_COM_READ_MPX), the data in each response SMB is expected to be truncated to the maximum number of 512 byte blocks (sectors) which will fit (starting at a 32 bit boundary) in the negotiated buffer size with the odd bytes remaining (if any) in the final buffer.