3.3.5.30 Receiving an SMB_COM_LOCKING_ANDX Request
Upon receiving an SMB_COM_LOCKING_ANDX Request (section 2.2.4.32.1), the server MUST validate the FID and PID by finding a matching Server.Open entry in the Server.Connection.FileOpenTable and a Server.SMBRequest entry in the Server.Connection.PendingRequestsTable, respectively.
SMB_COM_LOCKING_ANDX Request is processed in three parts, all of which are executed:
If NumberOfRequestedUnlocks is nonzero, the Unlocks array contains NumberOfRequestedUnlocks entries. Each entry requests that a lock be released.<286>
If NumberOfRequestedLocks is nonzero, the Locks array contains NumberOfRequestedLocks entries. Each entry requests the acquisition of a lock.<287>
If the OPLOCK_RELEASE flag is set in the TypeOfLock field of the request, the request is an OpLock Break Request sent by the client in response to an OpLock Break Notification from the server. The server MUST release the OpLock on the Open, after which it MUST allow pending operations that were waiting for the OpLock release to proceed, in an implementation-specific fashion.<288> The server MUST set Server.Open.Oplock to NONE and MUST set Server.Open.OplockState to NONE.
The release or creation of a byte-range lock MUST follow these rules:
Overlapping locks are not allowed.
Offsets beyond the current end of file can be locked; the server MUST NOT allocate additional file space as a result of such locks.
The server MUST NOT allow a range to be unlocked by any PID other than the PID that performed the lock. If the PID in the unlock request does not match Server.Open.Locks in the Open, the server MUST send an error response message with status set to STATUS_RANGE_NOT_LOCKED (ERRDOS/ERROR_NOT_LOCKED). See [FSBO] section 3 for details of byte range lock semantics.
All locks are held based upon the FID used to create the lock. That is, any process (PID) using the FID specified in the creation of the lock has access to the locked bytes. If the lock is an exclusive lock, other FIDs indicating a separate Open of the same file MUST be denied access to the same bytes. If the lock is a shared read lock, other FIDs indicating a separate Open of the same file MUST be denied write access to the same bytes.
The release of an OpLock follows these rules:
If there are no outstanding OpLock breaks, or if the FID in the request does not match the FID of an outstanding OpLock Break Notification, then no OpLock is released. This does not generate an error.
If NumberOfRequestedUnlocks and NumberOfRequestedLocks are both zero (0x0000) in the SMB_COM_LOCKING_ANDX Request, the server MUST NOT send an SMB_COM_LOCKING_ANDX Response (section 2.2.4.32.2).
Note that NumberOfRequestedUnlocks SHOULD always be zero (0x0000) in an OpLock Break Request, because an OpLock is an exclusive file lock. A client holding an OpLock on a file has no need to request byte-range locks from the server. There SHOULD, therefore, be no existing byte-range locks to be unlocked by the OpLock Break Request message. No error is generated by a nonzero NumberOfRequestedUnlocks value in an OpLock Break Request.<289><290>
Locking a range of bytes SHOULD<291> fail with STATUS_LOCK_NOT_GRANTED(ERRDOS/ERRlock) if any subranges or overlapping ranges are locked, even if they are currently locked by the PID requesting the new lock.
This client request is atomic. If any of the lock ranges times out because the area to be locked is already locked, or the lock/unlock request otherwise fails, the lock state of the file MUST NOT be changed.
The server response indicates only success or failure. If failure, the response message is an error response, including the status code indicating the cause of the failure. The response messages MUST be sent to the client as specified in section 3.3.4.1.
For each byte-range lock that is granted, an entry MUST be added to Server.Open.Locks. The type of the lock MUST match the type indicated in the TypeOfLock field. If the LARGE_FILES bit of the TypeOfLock field is set, the entry MUST be formatted as a LOCKING_ANDX_RANGE64; otherwise, it MUST be formatted as a LOCKING_ANDX_RANGE32.
For each byte-range lock that is released, the corresponding entry in Server.Open.Locks MUST be removed.