SMB_COM_LOCKING_ANDX allows both locking and/or unlocking of file range(s).
Client Request ================================== |
Description ================================= |
UCHAR WordCount; | Count of parameter words = 8 |
UCHAR AndXCommand; | Secondary (X) command; 0xFF = none |
UCHAR AndXReserved; | Reserved (must be 0) |
USHORT AndXOffset; | Offset to next command WordCount |
USHORT Fid; | File handle |
UCHAR LockType; | See LockType table below |
UCHAR OplockLevel; | The new oplock level |
ULONG Timeout; | Milliseconds to wait for unlock |
USHORT NumberOfUnlocks; | Num. unlock range structs following |
USHORT NumberOfLocks; | Num. lock range structs following |
USHORT ByteCount; | Count of data bytes |
LOCKING_ANDX_RANGE Unlocks[]; | Unlock ranges |
LOCKING_ANDX_RANGE Locks[]; | Lock ranges |
LockType Flag Name ============================ |
Value ===== |
Description ================================ |
LOCKING_ANDX_SHARED_LOCK |
0x01 | Read-only lock |
LOCKING_ANDX_OPLOCK_RELEASE |
0x02 | Oplock break notification |
LOCKING_ANDX_CHANGE_LOCKTYPE |
0x04 | Change lock type |
LOCKING_ANDX_CANCEL_LOCK |
0x08 | Cancel outstanding request |
LOCKING_ANDX_LARGE_FILES |
0x10 | Large file locking format |
LOCKING_ANDX_RANGE Format ===================================================================== |
|
USHORT Pid; | PID of process "owning" lock |
ULONG Offset; | Offset to bytes to [un]lock |
ULONG Length; | Number of bytes to [un]lock |
Large File LOCKING_ANDX_RANGE Format ===================================================================== |
|
USHORT Pid; | PID of process "owning" lock |
USHORT Pad; | Pad to DWORD align (mbz) |
ULONG OffsetHigh; | Offset to bytes to [un]lock (high) |
ULONG OffsetLow; | Offset to bytes to [un]lock (low) |
ULONG LengthHigh; | Number of bytes to [un]lock (high) |
ULONG LengthLow; | Number of bytes to [un]lock (low) |
Server Response ================================== |
Description ================================= |
UCHAR WordCount; | Count of parameter words = 2 |
UCHAR AndXCommand; | Secondary (X) command; 0xFF = none |
UCHAR AndXReserved; | Reserved (must be 0) |
USHORT AndXOffset; | Offset to next command WordCount |
USHORT ByteCount; | Count of data bytes = 0 |
Locking is a simple mechanism for excluding other processes read/write access to regions of a file. The locked regions can be anywhere in the logical file. Locking beyond end-of-file is permitted. Any process using the fid specified in this request's fid has access to the locked bytes, other processes will be denied the locking of the same bytes.
The proper method for using locks is not to rely on being denied read or write access on any of the read/write protocols but rather to attempt the locking protocol and proceed with the read/write only if the locks succeeded.
Locking a range of bytes will fail if any subranges or overlapping ranges are locked. In other words, if any of the specified bytes are already locked, the lock will fail.
If numberofunlocks is non-zero, the unlocks vector contains numberofunlocks elements. Each element requests that a lock at offset of length be released. If numberoflocks is nonzero, the locks vector contains numberoflocks elements. Each element requests the acquisition of a lock at offset of length.
timeout is the maximum amount of time to wait for the byte range(s) specified to become unlocked. A timeout value of 0 indicates that the server should fail immediately if any lock range specified is locked. A timeout value of -1 indicates that the server should wait as long as it takes for each byte range specified to become unlocked so that it may be again locked by this protocol. Any other value of smb_timeout specifies the maximum number of milliseconds to wait for all lock range(s) specified to become available.
If any of the lock ranges timeout because of the area to be locked is already locked (or the lock fails), the other ranges in the protocol request which were successfully locked as a result of this protocol will be unlocked (either all requested ranges will be locked when this protocol returns to the client or none).
If locktype has the LOCKING_ANDX_SHARED_LOCK
flag set, the lock is specified as a shared lock. Locks for both read and write (where LOCKING_ANDX_SHARED_LOCK
is clear) should be prohibited, but other shared locks should be permitted. If shared locks can not be supported by a server, the server should map the lock to a lock for both read and write. Closing a file with locks still in force causes the locks to be released in no defined order.
If locktype has the LOCKING_ANDX_LARGE_FILES
flag set and if the negotiated protocol is NT LM 0.12
or later, then the Locks and Unlocks vectors are in the Large File LOCKING_ANDX_RANGE
format. This allows specification of 64 bit offsets for very large files.
If the one and only member of the locks vector has the LOCKING_ANDX_CANCEL_LOCK
flag set in the locktype field, the client is requesting the server to cancel a previously requested, but not yet responded to, lock.
If LockType has the LOCKING_ANDX_CHANGE_LOCKTYPE
flag set, the client is requesting that the server atomically change the lock type from a shared lock to an exclusive lock or vice versa. If the server can not do this in an atomic fashion, the server must reject this request. NT and W95 servers do not support this capability.
Oplocks are described in the "Opportunistic Locks" section elsewhere in this document. A client requests an oplock by setting the appropriate bit in the SMB_COM_OPEN_ANDX request when the file is being opened in a mode which is not exclusive. The server responds by setting the appropriate bit in the response SMB indicating whether or not the oplock was granted. By granting the oplock, the server tells the client the file is currently only being used by this one client process at the current time. The client can therefore safely do read ahead and write behind as well as local caching of file locks knowing that the file will not be accessed/changed in any way by another process while the oplock is in effect. The client will be notified when any other process attempts to open or modify the oplocked file.
When another user attempts to open or otherwise modify the file which a client has oplocked, the server delays the second attempt and notifies the client via an SMB_LOCKING_ANDX SMB
asynchronously sent from the server to the client. This message has the LOCKING_ANDX_OPLOCK_RELEASE
flag set indicating to the client that the oplock is being broken. oplocklevel indicates the type of oplock the client now owns. If oplocklevel is 0, the client possesses no oplocks on the file at all, if oplocklevel is 1 the client possesses a Level II oplock. The client is expected to flush any dirty buffers to the server, submit any file locks and respond to the server with either an SMB_LOCKING_ANDX
SMB having the LOCKING_ANDX_OPLOCK_RELEASE
flag set, or with a file close if the file is no longer in use by the client. If the client sends an SMB_LOCKING_ANDX
SMB with the LOCKING_ANDX_OPLOCK_RELEASE
flag set and numberoflocks is zero, the server does not send a response. Since a close being sent to the server and break oplock notification from the server could cross on the wire, if the client gets an oplock notification on a file which it does not have open, that notification should be ignored.
Due to timing, the client could get an "oplock broken" notification in a user's data buffer as a result of this notification crossing on the wire with a SMB_COM_READ_RAW
request. The client must detect this (use length of msg, "FFSMB", MID of -1 and command of SMB_COM_LOCKING_ANDX
) and honor the "oplock broken" notification as usual. The server must also note on receipt of an SMB_COM_READ_RAW
request that there is an outstanding (unanswered) "oplock broken" notification to the client and return a zero length response denoting failure of the read raw request. The client should (after responding to the "oplock broken" notification), use a standard read protocol to redo the read request. This allows a file to actually contain data matching an "oplock broken" notification and still be read correctly.
The entire message sent and received including the optional second protocol must fit in the negotiated maximum transfer size. The following are the only valid SMB commands for andxcommand for SMB_COM_LOCKING_ANDX:
SMB_COM_READ | SMB_COM_READ_ANDX |
SMB_COM_WRITE | SMB_COM_WRITE_ANDX |
SMB_COM_FLUSH |
ERRDOS/ERRbadfile
ERRDOS/ERRbadfid
ERRDOS/ERRlock
ERRDOS/ERRinvdevice
ERRSRV/ERRinvid
ERRSRV/ERRbaduid