3.3.5.19 Receiving an SMB2 CHANGE_NOTIFY Request
When the server receives a request that has an SMB2 header with a Command value equal to SMB2 CHANGE_NOTIFY, message handling proceeds as follows.
The server MUST locate the session, as specified in section 3.3.5.2.9.
The server MUST locate the tree connection, as specified in section 3.3.5.2.11.
Next, the server MUST locate the open on which the client is requesting a change notification by performing a lookup in the Session.OpenTable, using the FileId.Volatile of the request as the lookup key. If no open is found, or if Open.DurableFileId is not equal to FileId.Persistent, the server MUST fail the request with STATUS_FILE_CLOSED. Otherwise, the server MUST locate the Request in Connection.RequestList for which Request.MessageId matches the MessageId value in the SMB2 header, and set Request.Open to the Open.
If Open.IsPersistent is FALSE and Open.IsReplayEligible is TRUE, the server MUST set Open.IsReplayEligible to FALSE.
If OutputBufferLength is greater than Connection.MaxTransactSize, the server SHOULD<405> fail the request with STATUS_INVALID_PARAMETER.
If Connection.SupportsMultiCredit is TRUE, the server MUST validate CreditCharge based on OutputBufferLength, as specified in section 3.3.5.2.5. If the validation fails, it MUST fail the request with STATUS_INVALID_PARAMETER.
If the open is not an open to a directory, the request MUST be failed with STATUS_INVALID_PARAMETER.
If Open.GrantedAccess does not include FILE_LIST_DIRECTORY, the operation MUST be failed with STATUS_ACCESS_DENIED.
Because change notify operations are not guaranteed to complete within a deterministic amount of time, the server SHOULD<406> handle this operation asynchronously as specified in section 3.3.4.2.
If the underlying object store does not support change notifications, the server MUST fail this request with STATUS_NOT_SUPPORTED.
The server MUST register a change notification on the underlying object store for the directory that is specified by Open.LocalOpen, using the completion filter supplied in the CompletionFilter field of the client request.<407> If SMB2_WATCH_TREE is set in the Flags field of the client request, the server MUST request that the change notify monitor all subtrees of the directory that is specified by Open.LocalOpen. The server indicates the maximum amount of notification data that it can accept by passing in the OutputBufferLength that is received from the client. An OutputBufferLength of zero indicates that the client allows the occurrence of an event but the client does not allow the notification data details. A Change notification request processed by the server with invalid bits in the CompletionFilter field MUST ignore the invalid bits and process the valid bits. If there are no valid bits in the CompletionFilter, the request will remain pending until the change notification is canceled or the directory handle is closed.
The server MUST process a change notification request in the object store as specified by the algorithm in section 3.3.1.3.
The server MUST send an SMB2 CHANGE_NOTIFY Response only if a change occurs. An SMB2 CHANGE_NOTIFY Request (section 2.2.35) will result in, at most, one response from the server. The server can choose to aggregate multiple changes into the same response. The server MUST include at least one FILE_NOTIFY_INFORMATION structure if it detects a change.
If the server is unable to copy the results into the buffer of the SMB2 CHANGE_NOTIFY Response, then the server MUST construct the response as described below, with an OutputBufferLength of zero, and set the Status in the SMB2 header to STATUS_NOTIFY_ENUM_DIR.
If the object store returns an error, the server MUST fail the request with the error code received.
If the object store returns success, the server MUST construct an SMB2 CHANGE_NOTIFY Response following the syntax that is specified in section 2.2.36 with the following values:
OutputBufferOffset MUST be set to the offset, in bytes, from the beginning of the SMB2 header where the enumeration data is being placed, the offset to Buffer[].
OutputBufferLength MUST be set to the length, in bytes, of the result of the enumeration. It is valid for length to be 0, indicating a change occurred but it could not be fit within the buffer.
The change data MUST be copied into Buffer[].
The response MUST be sent to the client.
The status code returned by this operation MUST be one of those defined in [MS-ERREF]. Common status codes returned by this operation include:
STATUS_SUCCESS
STATUS_INSUFFICIENT_RESOURCES
STATUS_ACCESS_DENIED
STATUS_FILE_CLOSED
STATUS_NETWORK_NAME_DELETED
STATUS_USER_SESSION_DELETED
STATUS_NETWORK_SESSION_EXPIRED
STATUS_CANCELLED
STATUS_INVALID_PARAMETER
STATUS_NOTIFY_ENUM_DIR