3.0 SMB Message Formats and Data Types

Clients exchange messages with a server to access resources on that server. These messages are called Server Message Blocks (SMBs), and every SMB message has a common format.

This section describes the entire set of SMB commands and responses exchanged between CIFS clients and servers. It also details which SMBs are introduced into the protocol as higher dialect levels are negotiated.

3.1 Notation

This specification makes use of "C"-like notation to describe the formats of messages. Unlike the "C" language, which allows implementation flexibility in laying out structures, this specification adopts the following rules. Multi-byte values are always transmitted least significant byte first. All fields, except "bit-fields," are aligned on the nearest byte boundary (even if longer than a byte), and there is no implicit padding. Fields using the "bit field" notation are defined to be laid out within the structure with the first-named field occupying the lowest order bits, the next named field the next lowest order bits, and so on.

3.2 SMB Header

Although each SMB command has specific encodings, some fields in the SMB header have meaning to all SMBs. These fields and considerations are described in the following sections:

typedef unsigned char UCHAR;          // 8 unsigned bits
typedef unsigned short USHORT;        // 16 unsigned bits
typedef unsigned long ULONG;          // 32 unsigned bits

typedef struct {
    ULONG LowPart;
    LONG HighPart;
} LARGE_INTEGER;                      // 64 bits of data

typedef struct  {
    UCHAR Protocol[4];                // Contains 0xFF,'SMB'
    UCHAR Command;                    // Command code
    union {
        struct {
            UCHAR ErrorClass;         // Error class
            UCHAR Reserved;           // Reserved for future use
            USHORT Error;             // Error code
        } DosError;
        ULONG Status;                 // 32-bit error code
    } Status;
    UCHAR Flags;                      // Flags
    USHORT Flags2;                    // More flags
    union {
        USHORT Pad[6];                // Ensure section is 12 bytes long
        struct {
            USHORT PidHigh;           // High part of PID
            UCHAR SecuritySignature[8];     // reserved for security
        } Extra;
    };
    USHORT Tid;                       // Tree identifier
    USHORT Pid;                       // Caller's process id
    USHORT Uid;                       // Unauthenticated user id
    USHORT Mid;                       // multiplex id
    UCHAR  WordCount;                 // Count of parameter words
    USHORT ParameterWords[ WordCount ];    // The parameter words
    USHORT ByteCount;                 // Count of bytes
    UCHAR  Buffer[ ByteCount ];       // The bytes
} SMB_HEADER;

All SMBs in this specification have identical format up to the ParameterWords fields. (Some obsolescent ones do not.) Different SMBs have a different number and interpretation of ParameterWords and Buffer. All reserved fields in the SMB header must be zero.

Note   Command is the operation code that this SMB is requesting or responding to.

3.2.1 Flags Field

This field contains eight individual flags, numbered from least significant to most significant, which have the following meanings:

Bit
==
Meaning
============================
Earliest Dialect
==============
0 Reserved for obsolescent requests. (LOCK_AND_READ, WRITE_AND_CLOSE) LANMAN1.0
1 Reserved (must be zero).
2 Reserved (must be zero).
3 When on, all pathnames in this SMB must be treated as case-less. When off, the pathnames are case-sensitive. LANMAN1.0
4 Reserved (clients must send as zero; servers must ignore).
5 Reserved for obsolescent requests. (SMB_COM_OPEN, SMB_COM_CREATE and SMB_COM_CREATE_NEW) LANMAN1.0
6 Reserved for obsolescent requests. (SMB_COM_OPEN, SMB_COM_CREATE and SMB_COM_CREATE_NEW) LANMAN1.0
7 SMB_FLAGS_SERVER_TO_REDIR. When on, this SMB is being sent from the server in response to a client request. The Command field usually contains the same value in a protocol request from the client to the server as in the matching response from the server to the client. This bit unambiguously distinguishes the command request from the command response. PC NETWORK PROGRAM 1.0

3.3.2 Flags2 Field

This field contains six individual flags that are defined below and numbered from least significant bit to most significant bit. Flags that are not defined must be set to zero.

Bit
==
Meaning
============================
Earliest Dialect
=============
0 If set in a request, the server may return long components in path names in the response.
1 If set, the client is aware of extended attributes.
11 If set, the client is aware of Extended Security NT LM 0.12
12 If set, any request pathnames in this SMB should be resolved in the Distributed File System. NT LM 0.12
13 If set, indicates that a read will be permitted if the client does not have read permission but does have execute permission. This flag is only useful on a read request.
14 If set, specifies that the returned error code is a 32-bit error code in Status.Status. Otherwise the Status.DosError.ErrorClass and Status.DosError.Error fields contain the DOS-style error information. When passing NT status codes is negotiated, this flag should be set for every SMB. NT LM 0.12
15 If set, any fields of datatype STRING in this SMB message are encoded as UNICODE. Otherwise, they are in ASCII. NT LM 0.12

3.2.3 Tid Field

Tid represents an instance of an authenticated connection to a server resource. The server returns Tid to the client when the client successfully connects to a resource, and the client uses Tid in subsequent requests referring to the resource.

In most SMB requests, Tid must contain a valid value. Exceptions include prior to getting a Tid established, including SMB_COM_NEGOTIATE, SMB_COM_TREE_CONNECT, SMB_COM_ECHO, and SMB_COM_SESSION_SETUP_ANDX. 0xFFFF should be used for Tid for these situations. The server is always responsible for enforcing use of a valid Tid where appropriate.

3.2.4 Pid Field

Pid is the caller's process id, and is generated by the client to uniquely identify a process within the client computer. Concurrency control is associated with Pid (and PidHigh)—sharing modes, and locks are arbitrated using the Pid. For example, if a file is successfully opened for exclusive access, subsequent opens from other clients or from the same client with a different Pid will be refused.

Clients inform servers of the creation of a new process by simply introducing a new Pid value into the dialogue for new processes. The client operating system must ensure that the appropriate close and cleanup SMBs will be sent when the last process referencing a file closes it. From the server's point of view, there is no concept of Fids "belonging to" processes. A Fid returned by the server to one process may be used by any other process using the same transport connection and Tid.

It is up to the client operating system to ensure that only authorized client processes gain access to Fids (and Tids). On SMB_COM_TREE_DISCONNECT (or when the client and server session is terminated) with a given Tid, the server will invalidate any files opened by any process on that client.

3.2.5 Uid Field

Uid is a user ID assigned by the server after a user authenticates to it, and that will be associated with that user until the client requests the association be broken. After authentication to the server, the client should make sure that the Uid is not used for a different user than the one who authenticated. (It is permitted that a single user have more than one Uid.) Requests that do authorization, such as open requests, will perform access checks using the identity associated with the Uid.

3.2.6 Mid Field

The multiplex ID (Mid) is used along with Pid to allow multiplexing the single client and server connection among the client's multiple processes, threads, and requests per thread. Clients may have many outstanding requests (up to the negotiated number) at one time. Servers may respond to requests in any order, but a response message must always contain the same Mid and Pid values as the corresponding request message. The client must not have multiple outstanding requests to a server with the same Mid and Pid.

3.2.7 Status Field

An SMB returns error information to the client in the Status field. Protocol dialects prior to NT LM 0.12 return status to the client using the combination of Status.DosError.ErrorClass and Status.DosError.Error. Beginning with NT LM 0.12, CIFS servers can return 32-bit error information to clients using Status.Status, if the incoming client SMB has bit 14 set in the Flags2 field of the SMB header. Contents of response parameters are not guaranteed in the case of an error return and must be ignored. For write-behind activity, a subsequent write or close of the file may return the fact that a previous write failed. Normally, write-behind failures are limited to hard disk errors and device out of space.

3.2.8 Timeouts

In general, SMBs are not expected to block at the server; they should return "immediately." But some SMB requests do indicate timeout periods for the completion of the request on the server. If a server implementation cannot support timeouts, an error can be returned just as if a timeout had occurred—if the resource is not available immediately upon request.

3.2.9 Data Buffer (BUFFER) and String Formats

The data portion of SMBs typically contains the data to be read or written, file paths, or directory paths. The format of the data portion depends on the message. All fields in the data portion have the same format, which in every case consists of an identifier byte followed by the data.

Identifier
=============
Description
=====================
Value
====
Data Block

Dialect

Pathname

ASCII

Variable block

See Below

Null terminated String

Null terminated String

Null terminated String

See Below

1

2

3

4

5


When the identifier indicates a data block or variable block then the format is a word indicating the length followed by the data.

In all dialects prior to NT LM 0.12, all strings are encoded in ASCII. If the agreed dialect is NT LM 0.12 or later, Unicode strings may be exchanged. Unicode strings include file names, resource names, and user names. This applies to null-terminated strings, length specified strings, and the type-prefixed strings. In all cases where a string is passed in Unicode format, the Unicode string must be word-aligned with respect to the beginning of the SMB. Should the string not naturally fall on a two-byte boundary, a null byte of padding will be inserted, and the Unicode string will begin at the next address. In the description of the SMBs, items that may be encoded in Unicode or ASCII are labeled as STRING. If the encoding is ASCII, even if the negotiated string is Unicode, the quantity is labeled as UCHAR.

For type-prefixed Unicode strings, the padding byte is found after the type byte. The type byte is 4 (indicating SMB_FORMAT_ASCII), independent of whether the string is ASCII or Unicode. For strings whose start addresses are found using offsets within the fixed part of the SMB (as opposed to simply being found at the byte following the preceding field), it is guaranteed that the offset will be properly aligned.

Strings that are never passed in Unicode are:

When Unicode is negotiated, bit 15 should be set in the Flags2 field of every SMB header.

Despite the flexible encoding scheme, no field of a data portion may be omitted or included out of order. In addition, neither a WordCount nor ByteCount of value 0 at the end of a message may be omitted.

3.3 File Names

File names in the CIFS protocol consist of components separated by a backslash ('\'). Early clients of the CIFS protocol required that the name components adhere to an 8.3 format name. These names consist of two parts: a basename of no more than 8 characters, and an extension of no more than 3 characters. The basename and extension are separated by a '.'. All characters are legal in the basename and extension except the space character (0x20) and:

" . / \[]:+|<>=;,*?

If the client has indicated long name support by setting bit2 in the Flags2 field of the SMB header, this indicates that the client is not bound by the 8.3 convention. Specifically, this indicates that any SMB that returns file names to the client may return names that do not adhere to the 8.3 convention, and have a total length of up to 255 characters. This capability was introduced with the LM1.2X002 protocol dialect.

3.4 Wildcards

Some SMB requests allow wildcards to be given for the filename. The wildcard allows a number of files to be operated on as a unit without having to separately enumerate the files and individually operate on each one from the client.

If the client is using 8.3 names, each part of the name ( base (8) or extension (3) ) is treated separately. For long filenames, the . in the name is significant even though there is no longer a restriction on the size of each of the components.

The ? character is a wild card for a single character. If a filename part commences with one or more "?"s, then exactly that number of characters will be matched by the wildcards, e.g., "??x" equals "abx" but not "abcx" or "ax." When a filename part has trailing "?"s, then it matches the specified number of characters or less, e.g., "x??" matches "xab," "xa" and "x," but not "xabc." If only "?"s are present in the filename part, then it is handled as for trailing "?"s.

The * character matches an entire part of the name, as does an empty specification for that part. A part consisting of * means that the rest of the component should be filled with ?, and the search should be performed with this wildcard character. For example, "*.abc" or ".abc" match any file with an extension of "abc". "*.*," "*" or "null" match all files in a directory.

If the negotiated dialect is "NT LM 0.12" or later, and the client requires MS-DOS wildcard matching semantics, UNICODE wildcards should be translated according to the following rules:

Translate the ? literal to >

Translate the . literal to " if it is followed by a ? or a *

Translate the * literal to < if it is followed by a .

The translation can be performed in-place.

3.5 Dfs Pathnames

A Dfs pathname adheres to the standard described in the FileNames section. A Dfs-enabled client accessing a Dfs share should set the Flags2 bit 12 in all name-based SMB requests indicating to the server that the enclosed pathname should be resolved in the Distributed File System namespace. The pathname should always have the full file name, including the server name and share name. If the server can resolve the Dfs name to a piece of local storage, the local storage will be accessed. If the server determines that the Dfs name actually maps to a different server share, the access to the name will fail with the 32-bit status STATUS_PATH_NOT_COVERED (0xC0000257), or DOS error ERRsrv/ERRbadpath.

On receiving this error, the Dfs-enabled client should ask the server for a referral (see TRANS2_GET_DFS_REFERRAL). The referral request should contain the full file name.

The response to the request will contain a list of server and share names to try, and the part of the request file name that junctions to the list of server shares. If the ServerType field of the referral is set to 1 (SMB server), then the client should resubmit the request with the original file name to one of the server shares in the list, once again setting the Flags2 bit 12 bit in the SMB. If the ServerType field is not 1, then the client should strip off the part of the file name that junctions to the server share before resubmitting the request to one of servers in the list.

A response to a referral request may elicit a response that does not have the StorageServers bit set. In that case, the client should resubmit the referral request to one of the servers in the list, until it finally obtains a referral response that has the StorageServers bit set, at which point the client can resubmit the request SMB to one of the listed server shares.

If, after getting a referral with the StorageServers bit set and resubmitting the request to one of the server shares in the list, the server fails the request with STATUS_PATH_NOT_COVERED, there must be an inconsistency between the view of the Dfs namespace held by the server granting the referral and the server listed in that referral. In this case, the client may inform the server granting the referral of this inconsistency via the TRANS2_REPORT_DFS_INCONSISTENCY SMB.

3.6 Time and Date Encoding

When SMB requests or responses encode time values, the following describes the various encodings used.

struct {
        USHORT Day : 5;
        USHORT Month : 4;
        USHORT Year : 7;
} SMB_DATE;

The Year field has a range of 0-119, which represents years 1980-2099. The Month is encoded as 1-12, and the day ranges from 1-31

struct {
        USHORT TwoSeconds : 5;
        USHORT Minutes : 6;
        USHORT Hours : 5;
} SMB_TIME;

Hours ranges from 0-23, Minutes range from 0-59, and TwoSeconds ranges from 0-29 representing two-second increments within the minute.

typedef struct {
    ULONG LowTime;
    LONG HighTime;
} TIME;

TIME indicates a signed 64-bit integer representing either an absolute time or a time interval. Times are specified in units of 100ns. A positive value expresses an absolute time, where the base time (the 64-bit integer with value 0) is the beginning of the year 1601 AD in the Gregorian calendar. A negative value expresses a time interval relative to some base time, usually the current time.

typedef unsigned long UTIME;

UTIME is the number of seconds since Jan 1, 1970, 00:00:00.0.

3.7 Access Mode Encoding

Various client requests and server responses, such as SMB_COM_OPEN, pass file access modes encoded into a USHORT. The encoding of these is as follows:

    1111 11
   5432 1098 7654 3210
   rWrC rLLL rSSS rAAA

where:

    W—Write through mode. No read ahead or write behind allowed on
       this file or device. When the response is returned, data is
       expected to be on the disk or device.

    S—Sharing mode:
       0—Compatibility mode
       1—Deny read/write/execute (exclusive)
       2—Deny write
       3—Deny read/execute
       4—Deny none

    A—Access mode
       0—Open for reading
       1—Open for writing
       2—Open for reading and writing
       3—Open for execute

    rSSSrAAA = 11111111 (hex FF) indicates file control block (FCB) open (???)

    C—Cache mode
       0—Normal file
       1—Do not cache this file

    L—Locality of reference
       0—Locality of reference is unknown
       1—Mainly sequential access
       2—Mainly random access
       3—Random access with some locality
       4 to 7—Currently undefined

3.8 Access Mask Encoding

The ACCESS_MASK structure is one 32-bit value containing standard, specific, and generic rights. These rights are used in access-control entries (ACEs) and are the primary means of specifying the requested or granted access to an object.

The bits in this value are allocated as follows:

Bits Meaning
0 -15 Specific rights. Contains the access mask specific to the object type associated with the mask.
16-23 Standard rights. Contains the object's standard access rights and can be a combination of the following predefined flags:

Bit Flag Meaning
16 DELETE Delete access
17 READ_CONTROL Read access to the owner, group, and discretionary access-control list (ACL) of the security descriptor
18 WRITE_DAC Write access to the discretionary access-control list (ACL)
19 WRITE_OWNER Write access to owner
20 SYNCHRONIZE Microsoft® Windows NT®: Synchronize access

 

Bits Meaning
24 Access system security (ACCESS_SYSTEM_SECURITY). This flag is not a typical access type. It is used to indicate access to a system ACL. This type of access requires the calling process to have a specific privilege.
25 Maximum allowed (MAXIMUM_ALLOWED)
26, 27 Reserved
28 Generic all (GENERIC_ALL)
29 Generic execute (GENERIC_EXECUTE)
30 Generic write (GENERIC_WRITE)
31 Generic read (GENERIC_READ)

3.9 Open Function Encoding

OpenFunction specifies the action to be taken depending on whether or not the file exists. This word has the following format:

bits:

    1111 11
   5432 1098 7654 3210
   rrrr rrrr rrrC rrOO

where:

    C—Create (action to be taken if file does not exist).
0—Fail.
1—Create file.

    r—reserved (must be zero).

    O—Open (action to be taken if file exists).
0—Fail.
1—Open file.
2—Truncate file.

3.10 Open Action Encoding

Action in the response to an open or create request describes the action taken as a result of the request. It has the following format:

bits:

    1111 11
   5432 1098 7654 3210
   Lrrr rrrr rrrr rrOO

where:

    L—Lock (single user total file lock status).
0—file opened by another user (or mode not supported by server).
1—file is opened only by this user at the present time.

    r—reserved (must be zero).

    O—Open (action taken on Open).
1—The file existed and was opened.
2—The file did not exist but was created.
3—The file existed and was truncated.

3.11 File Attribute Encoding

When SMB messages exchange file attribute information, it is encoded in 16 bits as:

Value
=====
Description
=================
0x01 Read only file
0x02 Hidden file
0x04 System file
0x08 Volume
0x10 Directory
0x20 Archive file
others Reserved—must be 0

3.12 Extended File Attribute Encoding

The extended file attributes is a 32-bit value composed of attributes and flags.

Any combination of the following attributes is acceptable, except all other file attributes override FILE_ATTR_NORMAL:

Name

===========

Value

===

Meaning

===============================

ATTR_ARCHIVE 0x020 The file has not been archived since it was last modified. Applications use this attribute to mark files for backup or removal.
ATTR_COMPRESSED 0x800 The file or directory is compressed. For a file, this means that all of the data in the file is compressed. For a directory, this means that compression is the default for newly created files and subdirectories.
ATTR_NORMAL 0x080 The file has no other attributes set. This attribute is valid only if used alone.
ATTR_HIDDEN 0x002 The file is hidden. It is not to be included in an ordinary directory listing.
ATTR_READONLY 0x001 The file is read only. Applications can read the file but cannot write to it or delete it.
ATTR_TEMPORARY 0x100 The file is temporary
ATTR_DIRECTORY 0x010 The file is a directory
ATTR_SYSTEM 0x004 The file is part of or is used exclusively by the operating system.

Any combination of the following flags is acceptable:

Name

============

Value

=======

Meaning

===========================

WRITE_THROUGH 0x80000000 Instructs the operating system to write through any intermediate cache and go directly to the file. The operating system can still cache write operations, but cannot lazily flush them.
NO_BUFFERING 0x20000000 Requests the server to open the file with no intermediate buffering or caching; the server is not obliged to honor the request. An application must meet certain requirements when working with files opened with FILE_FLAG_NO_BUFFERING. File access must begin at offsets within the file that are integer multiples of the volume's sector size, and must be for numbers of bytes that are integer multiples of the volume's sector size. For example, if the sector size is 512 bytes, an application can request reads and writes of 512, 1024, or 2048 bytes, but not of 335, 981, or 7171 bytes.
RANDOM_ACCESS 0x10000000 Indicates that the application intends to access the file randomly. The server may use this flag to optimize file caching.
SEQUENTIAL_SCAN 0x08000000 Indicates that the file is to be accessed sequentially from beginning to end. Windows uses this flag to optimize file caching. If an application moves the file pointer for random access, optimum caching may not occur; however, correct operation is still guaranteed. Specifying this flag can increase performance for applications that read large files using sequential access. Performance gains can be even more noticeable for applications that read large files mostly sequentially, but occasionally skip over small ranges of bytes.
DELETE_ON_CLOSE 0x04000000 Requests that the server delete the file immediately after all its handles have been closed.
BACKUP_SEMANTICS 0x02000000 Indicates that the file is being opened or created for a backup or restore operation. The server should allow the client to override normal file security checks, provided it has the necessary permission to do so.
POSIX_SEMANTICS 0x01000000 Indicates that the file is to be accessed according to POSIX rules. This includes allowing multiple files with names differing only in case, for file systems that support such naming. (Use care when using this option because files created with this flag may not be accessible by applications written for MS-DOS, Windows 3.x, or Windows NT.)

3.13 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:

3.14 "Transaction" Style Subprotocols

The "transaction" style subprotocols are used for commands that potentially need to transfer a large amount of data (greater than 64K bytes).

3.14.1 SMB_COM_TRANSACTION2 Format

Primary Client Request
=================
Description
=============================
Command SMB_COM_TRANSACTION2
UCHAR WordCount; Count of parameter words; value = (14 + SetupCount)
USHORT TotalParameterCount; Total parameter bytes being sent
USHORT TotalDataCount; Total data bytes being sent
USHORT MaxParameterCount; Max parameter bytes to return
USHORT MaxDataCount; Max data bytes to return
UCHAR MaxSetupCount; Max setup words to return
UCHAR Reserved;
USHORT Flags; Additional information:
bit 0—also disconnect TID in TID
ULONG Timeout;
USHORT Reserved2;
USHORT ParameterCount; Parameter bytes sent this buffer
USHORT ParameterOffset; Offset (from header start) to Parameters
USHORT DataCount; Data bytes sent this buffer
USHORT DataOffset; Offset (from header start) to data
UCHAR SetupCount; Count of setup words
UCHAR Reserved3; Reserved (pad above to word)
USHORT Setup[SetupCount]; Setup words (# = SetupWordCount)
USHORT ByteCount; Count of data bytes
STRING Name[]; Must be NULL
UCHAR Pad[]; Pad to SHORT or LONG
UCHAR Parameters[ ParameterCount]; Parameter bytes (# = ParameterCount)
UCHAR Pad1[]; Pad to SHORT or LONG
UCHAR Data[ DataCount ]; Data bytes (# = DataCount)

Interim Server Response
=================
Description
=============================
UCHAR WordCount; Count of parameter words = 0
USHORT ByteCount; Count of data bytes = 0

Secondary Client Request
=================
Description
=============================
Command SMB_COM_TRANSACTION_SECONDARY
UCHAR WordCount; Count of parameter words = 8
USHORT TotalParameterCount; Total parameter bytes being sent
USHORT TotalDataCount; Total data bytes being sent
USHORT ParameterCount; Parameter bytes sent this buffer
USHORT ParameterOffset; Offset (from header start) to Parameters
USHORT ParameterDisplacement; Displacement of these Parameter bytes
USHORT DataCount; Data bytes sent this buffer
USHORT DataOffset; Offset (from header start) to data
USHORT DataDisplacement; Displacement of these data bytes
USHORT Fid; FID for handle-based requests, else 0xFFFF. This field is present only if this is an SMB_COM_TRANSACTION2 request.
USHORT ByteCount; Count of data bytes
UCHAR Pad[]; Pad to SHORT or LONG
UCHAR Parameters[ParameterCount]; Parameter bytes (# = ParameterCount)
UCHAR Pad1[]; Pad to SHORT or LONG
UCHAR Data[DataCount]; Data bytes (# = DataCount)

Server Response
==================
Description
=============================
UCHAR WordCount; Count of data bytes; value = 10 + SetupCount
USHORT TotalParameterCount; Total parameter bytes being sent
USHORT TotalDataCount; Total data bytes being sent
USHORT Reserved;
USHORT ParameterCount; Parameter bytes sent this buffer
USHORT ParameterOffset; Offset (from header start) to Parameters
USHORT ParameterDisplacement; Displacement of these Parameter bytes
USHORT DataCount; Data bytes sent this buffer
USHORT DataOffset; Offset (from header start) to data
USHORT DataDisplacement; Displacement of these data bytes
UCHAR SetupCount; Count of setup words
UCHAR Reserved2; Reserved (pad above to word)
USHORT Setup[SetupWordCount]; Setup words (# = SetupWordCount)
USHORT ByteCount; Count of data bytes
UCHAR Pad[]; Pad to SHORT or LONG
UCHAR Parameters[ParameterCount]; Parameter bytes (# = ParameterCount)
UCHAR Pad1[]; Pad to SHORT or LONG
UCHAR Data[DataCount]; Data bytes (# = DataCount)

3.14.2 The 3.13.2 SMB_COM_NT_TRANSACTION Formats

Primary Client Request
==================
Description
=============================
UCHAR WordCount; Count of parameter words; value = (19 + SetupCount)
UCHAR MaxSetupCount; Max setup words to return
USHORT Reserved;
ULONG TotalParameterCount; Total parameter bytes being sent
ULONG TotalDataCount; Total data bytes being sent
ULONG MaxParameterCount; Max parameter bytes to return
ULONG MaxDataCount; Max data bytes to return
ULONG ParameterCount; Parameter bytes sent this buffer
ULONG ParameterOffset; Offset (from header start) to Parameters
ULONG DataCount; Data bytes sent this buffer
ULONG DataOffset; Offset (from header start) to data
UCHAR SetupCount; Count of setup words
USHORT Function; The transaction function code
UCHAR Buffer[1];
USHORT Setup[SetupWordCount]; Setup words
USHORT ByteCount; Count of data bytes
UCHAR Pad1[]; Pad to LONG
UCHAR Parameters[ParameterCount]; Parameter bytes
UCHAR Pad2[]; Pad to LONG
UCHAR Data[DataCount]; Data bytes

Interim Server Response
==================
Description
============================
UCHAR WordCount; Count of parameter words = 0
USHORT ByteCount; Count of data bytes = 0

Secondary Client Request
==================
Description
============================
UCHAR WordCount; Count of parameter words = 18
UCHAR Reserved[3]; MBZ
ULONG TotalParameterCount; Total parameter bytes being sent
ULONG TotalDataCount; Total data bytes being sent
ULONG ParameterCount; Parameter bytes sent this buffer
ULONG ParameterOffset; Offset (from header start) to Parameters
ULONG ParameterDisplacement; Specifies the offset from the start of the overall parameter block to the parameter bytes that are contained in this message
ULONG DataCount; Data bytes sent this buffer
ULONG DataOffset; Offset (from header start) to data
ULONG DataDisplacement; Specifies the offset from the start of the overall data block to the data bytes that are contained in this message.
UCHAR Reserved1;
USHORT ByteCount; Count of data bytes
UCHAR Pad1[]; Pad to LONG
UCHAR Parameters[ParameterCount]; Parameter bytes
UCHAR Pad2[]; Pad to LONG
UCHAR Data[DataCount]; Data bytes

Server Response
==================
Description
============================
UCHAR WordCount; Count of data bytes; value = 18 + SetupCount
UCHAR Reserved[3];
ULONG TotalParameterCount; Total parameter bytes being sent
ULONG TotalDataCount; Total data bytes being sent
ULONG ParameterCount; Parameter bytes sent this buffer
ULONG ParameterOffset; Offset (from header start) to Parameters
ULONG ParameterDisplacement; Specifies the offset from the start of the overall parameter block to the parameter bytes that are contained in this message
ULONG DataCount; Data bytes sent this buffer
ULONG DataOffset; Offset (from header start) to data
ULONG DataDisplacement; Specifies the offset from the start of the overall data block to the data bytes that are contained in this message.
UCHAR SetupCount; Count of setup words
USHORT Setup[SetupWordCount]; Setup words
USHORT ByteCount; Count of data bytes
UCHAR Pad1[]; Pad to LONG
UCHAR Parameters[ParameterCount]; Parameter bytes
UCHAR Pad2[]; Pad to SHORT or LONG
UCHAR Data[DataCount]; Data bytes

3.14.3 Functional Description

The transaction Setup information and/or Parameters define functions specific to a particular resource on a particular server. Therefore, the functions supported are not defined by the transaction subprotocol. The transaction protocol simply provides a means of delivering them and retrieving the results.

The number of bytes needed in order to perform the transaction request may be more than will fit in a single buffer.

At the time of the request, the client knows the number of parameter and data bytes expected to be sent and passes this information to the server via the primary request (TotalParameterCount and TotalDataCount). This may be reduced by lowering the total number of bytes expected (TotalParameterCount and TotalDataCount) in each (if any) secondary request.

When the amount of parameter bytes received (total of each ParameterCount) equals the total amount of parameter bytes expected (smallest TotalParameterCount) received, the server has then received all the parameter bytes.

Likewise, when the amount of data bytes received (total of each DataCount) equals the total amount of data bytes expected (smallest TotalDataCount) received, the server has then received all the data bytes.

The parameter bytes should normally be sent first followed by the data bytes. However, the server knows where each begins and ends in each buffer by the offset fields (ParameterOffset and DataOffset) and the length fields (ParameterCount and DataCount). The displacement of the bytes (relative to start of each) is also known (ParameterDisplacement and DataDisplacement). Thus, the server is able to reassemble the parameter and data bytes should the individual requests be received out of sequence.

If all parameter bytes and data bytes fit into a single buffer, no interim response is expected, and no secondary request is sent.

The client knows the maximum amount of data bytes and parameter bytes that the server may return (from MaxParameterCount and MaxDataCount of the request). Thus, the client initializes its bytes expected variables to these values. The server then informs the client of the actual amounts being returned via each message of the server response (TotalParameterCount and TotalDataCount). The server may reduce the expected bytes by lowering the total number of bytes expected (TotalParameterCount and/or TotalDataCount) in each (any) response.

When the amount of parameter bytes received (total of each ParameterCount) equals the total amount of parameter bytes expected (smallest TotalParameterCount) received, the client has then received all the parameter bytes.

Likewise, when the amount of data bytes received (total of each DataCount) equals the total amount of data bytes expected (smallest TotalDataCount) received, the client has then received all the data bytes.

The parameter bytes should normally be returned first, followed by the data bytes. However, the client knows where each begins and ends in each buffer by the offset fields (ParameterOffset and DataOffset) and the length fields (ParameterCount and DataCount). The displacement of the bytes (relative to start of each) is also known (ParameterDisplacement and DataDisplacement). The client is able to reassemble the parameter and data bytes should the server responses be received out of sequence.

The flow for these transactions over a connection-oriented transport is:

  1. The client sends the primary client request identifying the total bytes (both parameters and data) expected to be sent, and contains the set up words and as many of the parameter and data bytes as will fit in a negotiated size buffer. This request also identifies the maximum number of bytes (setup, parameters, and data) the server is to return on the transaction completion. If all the bytes fit in the single buffer, skip to step 4.

  2. The server responds with a single interim response meaning "OK, send the remainder of the bytes" or (if error response) terminate the transaction.

  3. The client then sends another buffer full of bytes to the server. This step is repeated until all of the bytes are sent and received.

  4. The Server sets up and performs the transaction with the information provided.

  5. Upon completion of the transaction, the server sends back (up to) the number of parameter and data bytes requested (or as many as will fit in the negotiated buffer size). This step is repeated until all result bytes have been returned.

The flow for the transaction protocol when the request parameters and data do not all fit in a single buffer is:

Client
=====================
<->
==
Server
======================
Primary TRANSACTION request ->
<- Interim Server Response
Secondary TRANSACTION request 1 ->
Secondary TRANSACTION request 2 ->
Secondary TRANSACTION request N ->
<- TRANSACTION response 1
<- TRANSACTION response 2
<- TRANSACTION response m

When the request parameters and data all fit in a single buffer, the flow for the transaction protocol is:

Client
=====================
<->
==
Server
======================
Primary TRANSACTION request ->
<- TRANSACTION response 1
<- TRANSACTION response 2
<- TRANSACTION response m

The primary transaction request through the final response makes up the complete transaction exchange; thus, the Tid, Pid, Uid and Mid must remain constant and can be used as appropriate by both the server and the client. Of course, other SMB requests may intervene as well.

There are (at least) three ways that actual server responses have been observed to differ from what might be expected. First, some servers will send Pad bytes to move the DataOffset to a 2- or 4-byte boundary, even if there are no data bytes. The point here is that the ByteCount must be used instead of ParameterOffset plus ParameterCount to infer the actual message length. Second, some servers always return MaxParameterCount bytes, even if the particular Transact2 has no parameter response. Finally, in case of an error, some servers send the "traditional WordCount==0/ByteCount==0" response while others generate a Transact response format.

3.15 Valid SMB Requests by Negotiated Dialect

CIFS clients and servers may exchange the following SMB messages if the "PC NETWORK PROGRAM 1.0" dialect is negotiated:

SMB_COM_CREATE_DIRECTORY SMB_COM_DELETE_DIRECTORY
SMB_COM_OPEN SMB_COM_CREATE
SMB_COM_CLOSE SMB_COM_FLUSH
SMB_COM_DELETE SMB_COM_RENAME
SMB_COM_QUERY_INFORMATION SMB_COM_SET_INFORMATION
SMB_COM_READ SMB_COM_WRITE
SMB_COM_LOCK_BYTE_RANGE SMB_COM_UNLOCK_BYTE_RANGE
SMB_COM_CREATE_TEMPORARY SMB_COM_CREATE_NEW
SMB_COM_CHECK_DIRECTORY SMB_COM_PROCESS_EXIT
SMB_COM_SEEK SMB_COM_TREE_CONNECT
SMB_COM_TREE_DISCONNECT SMB_COM_NEGOTIATE
SMB_COM_QUERY_INFORMATION_DISK SMB_COM_SEARCH
SMB_COM_OPEN_PRINT_FILE SMB_COM_WRITE_PRINT_FILE
SMB_COM_CLOSE_PRINT_FILE SMB_COM_GET_PRINT_QUEUE

If the "LANMAN 1.0" dialect is negotiated, all of the messages in the previous list must be supported. Clients negotiating LANMAN 1.0 and higher dialects will probably no longer send SMB_COM_PROCESS_EXIT, and the response format for SMB_COM_NEGOTIATE is modified as well. New messages introduced with the LANMAN 1.0 dialect are:

SMB_COM_LOCK_AND_READ SMB_COM_WRITE_AND_UNLOCK
SMB_COM_READ_RAW SMB_COM_READ_MPX
SMB_COM_WRITE_MPX SMB_COM_WRITE_RAW
SMB_COM_WRITE_COMPLETE SMB_COM_WRITE_MPX_SECONDARY
SMB_COM_SET_INFORMATION2 SMB_COM_QUERY_INFORMATION2
SMB_COM_LOCKING_ANDX SMB_COM_TRANSACTION
SMB_COM_TRANSACTION_SECONDARY SMB_COM_IOCTL
SMB_COM_IOCTL_SECONDARY SMB_COM_COPY
SMB_COM_MOVE SMB_COM_ECHO
SMB_COM_WRITE_AND_CLOSE SMB_COM_OPEN_ANDX
SMB_COM_READ_ANDX SMB_COM_WRITE_ANDX
SMB_COM_SESSION_SETUP_ANDX SMB_COM_TREE_CONNECT_ANDX
SMB_COM_FIND SMB_COM_FIND_UNIQUE
SMB_COM_FIND_CLOSE

The "LM1.2X002" dialect introduces these new SMBs:

SMB_COM_TRANSACTION2 SMB_COM_TRANSACTION2_SECONDARY
SMB_COM_FIND_CLOSE2 SMB_COM_LOGOFF_ANDX

"NT LM 0.12" dialect introduces:

SMB_COM_NT_TRANSACT SMB_COM_NT_TRANSACT_SECONDARY
SMB_COM_NT_CREATE_ANDX SMB_COM_NT_CANCEL
SMB_COM_NT_RENAME