Abstract Data Model
The following section specifies data and state maintained by the Windows Search Protocol client. The data is provided to explain how the protocol behaves. This section does not mandate that implementations adhere to this model as long as their external behavior is consistent with that described in this document.
A client has the following abstract state:
State
|
Description
|
Last Message Sent
|
A copy of the last message sent to the server.
|
Current Property Value
|
A partial value of a "deferred" property, which is in the process of being retrieved.
|
Current Bytes Received
|
The number of bytes received for the Current Property Value so far.
|
Named Pipe Connection
|
A connection to the server.
|
Timers
None.
Initialization
No actions are taken until a higher-layer request is received.
Higher-Layer Triggered Events
When a request is received from a higher layer, the client MUST create a named pipe connection to the server as specified in section 2.1. If it is unable to do so, the higher-layer request MUST be failed. That is, in case of a failure to connect, the higher level MUST retry the connection.
A header MUST be pre-pended with fields set as specified in section 2.2.2.
For messages that are specified as requiring a nonzero checksum, the _ulChecksum value MUST be calculated as follows:
The contents of the message after the _ulReserved2 field in the message header MUST be interpreted as a sequence of 32-bit integers. The client MUST calculate the sum of the numeric values given by these integers.
Calculate the bitwise XOR of this value with 0x59533959.
Subtract the value given by _msg from the value that results from the bitwise XOR.
Remote Windows Search Service Catalog Management
Each message is triggered by a request from the higher layer. There is no message sequence enforced by the client for the Windows Search Protocol message requests for remotely managing the catalog. However, the server will reply with success only if the client previously connected by means of a CPMConnectIn message.
Sending a CPMCiStateInOut Request
Typically, the higher layer asks the protocol client to send a CPMCiStateInOut message when it requires information about the GSS on the server.
When requested to send this message, the client MUST do the following:
Send a CPMCiStateInOut message to the server.
Wait to receive a CPMCiStateInOut message from the server, silently discarding all other messages.
Report the value of the _status field of the response, and if it was successful, report the informational structure back to the higher layer.
Remote Windows Search Service Catalog Query Messages
With the exceptions of CPMGetRowsIn/CPMGetRowsOut and CPMFetchValueIn/CPMFetchValueOut, there is a one-to-one relationship between the Windows Search Protocol messages and higher-layer requests. For the two exceptions previously mentioned, multiple messages can be generated by the client to either satisfy size requirements or to retrieve a complete property. The higher layer typically keeps track of all query-specific information (such as cursor handles opened, legal values for bookmark and chapter handles, and _wid values for deferred property values) and also tracks if the client is in a connected state, but this is not enforced in any way by the client.
For illustrative purposes, the client portion of the diagram in section 3 illustrates this sequence for a simple GSS query.
Sending a CPMConnectIn Request
This message is typically the very first request from the higher layer. The higher level provides the protocol client with the information necessary to connect.
To serve the higher layer, the client MUST do the following:
Fill in the message, using the information provided by the higher-layer client (see section 2.2.3.2) in _iClientVersion, MachineName, UserName, PropertySet1, PropertySet2, and aPropertySet.
Set _fClientIsRemote, _cbBlob, _cbBlob2, cPropSet, and cExtPropSet, as specified in section 2.2.3.2.
Set the checksum in the _ulChecksum field.
Send the CPMConnectIn message to the server.
Wait to receive a CPMConnectOut message back from the server, silently discarding all other messages.
Report the value of the _status field of the response and, if it was successful, report the value of the _serverVersion back to the higher layer.
Compare 4 DWORDs past the _serverVersion field with the 4 DWORDs at the same offset of CPMConnectIn message. If the value of the DWORDs is different, assume that the server supports version information and decode dwWinVerMajor, dwWinVerMinor, dwNLSVerMajor, dwNLSVerMinor fields. If requested, the values or the information that the server does not support versioning MAY be reported to a higher layer.
For informative purposes, it is expected that higher layers will typically do the following actions upon successful connection, but these are not enforced by the Windows Search Protocol client:
Use remote GSS catalog management messages for administrative tasks.
Use a CPMCreateQueryIn request to create a search query for the purpose of retrieving results from the catalog.
Sending a CPMCreateQueryIn Request
The higher layer will typically provide the information for the query creation after the protocol client is connected. The higher layer provides the client with a restrictions set, column set, sort order rules, and categorization set (each of which can be omitted), rowset properties, and property ID mapper structure.
When this request is received from a higher layer, the client MUST perform the following:
Prepare a CPMCreateQueryIn as follows.
If a columns set is present, set CColumnsSetPresent to 0x01 and fill the ColumnsSet field.
If restrictions are present, set CRestrictionPresent to 0x01 and fill the Restriction field.
If a sort set is present, fill the SortSet field.
If a categorization set is present, set CSortSetPresent to 0x01 and fill the CategorizationSet field.
Set the rest of fields as specified in section 2.2.3.4.
Calculate _ulCheckSum field in the header.
Send the CPMCreateQueryIn message to the server.
Wait to receive the CPMCreateQueryOut message, silently discarding all other messages.
Report the value of the _status field of the response and, if it was successful, report the array of cursor handles and informative Boolean values (as specified in section 2.2.3.5) back to the higher layer.
Sending a CPMSetBindingsIn Request
Typically, the higher layer will set bindings for each column to be returned in the rows when it already has a valid cursor handle (after successfully receiving CPMCreateQueryOut). The higher layer is expected to provide an array of CTableColumn structures for the aColumns field and a valid cursor handle.
When this request is received from the higher layer, the client MUST perform the following:
Calculate the number of CTableColumn structures in the aColumns array, and set the cColumns field to this value.
Calculate the total size in bytes of the cColumns and aColumns fields, and set the _cbBindingDesc field to this value.
Set the specified fields in the CPMSetBindingsIn message to the values provided by the higher application layer. Set the _ulChecksum field to the value calculated, as specified in section 3.2.5.
Send the completed CPMSetBindingsIn message to the server.
Wait to receive a CPMSetBindingsIn message from the server, discarding all other messages.
Indicate the status from the _status field of the response to the higher layer.
For informative purposes, it is expected that higher layers will typically request a client to send a CPMGetRowsIn message, but this is not enforced by the Windows Search Protocol.
Sending a CPMGetRowsIn Request
When the higher layer is about to receive rows information, it will provide the protocol client with valid cursor and chapter handles and give an appropriate seek description. Typically, a higher layer is expected to do so when it has a valid cursor and/or chapter handle, and the bindings have been set with the CPMSetBindingsIn message. To access the rowset in a chapter, the higher layer is to use the chapter handle received from the server in a previous CPMGetRowsOut message.
When this request is received from the higher layer, the client MUST perform the following:
Determine what unsigned integer value to specify for the _cbReadBuffer field. To determine this value, the client MUST take the maximum value from the following:
One thousand times the value of the c_RowsToTransfer field.
The value of _cbRowWidth, rounded up to the nearest 512-byte multiple.
Take the higher of these two values, up to the 16-KB limit.
In cases where a single row is larger than 16 KB, the server cannot return results to this query.
Specify a client base for variable-sized row data in the client address space in the _ulClientBase field.<43>
Calculate the size of the seek description and set it in the _cbSeek field.
Set the value of cbReserved (which would act as an offset for the start of the rows contained in the Rows field in the CPMGetRowsOut message) to the value of _cbSeek plus 0x14.
Send a CPMGetRowsIn message to the server.
Sending a CPMFetchValueIn Request
If the client receives a CPMGetRowsOut response from the server with the column's Status field set to StoreStatusDeferred (0x01), it means that the property value was not included in the Rows field of the CPMGetRowsOut message. In this case, the higher layer typically requests that the protocol client retrieve the value by means of a CPMFetchValueIn message, and provides the PropSpec and _wid value for a deferred property, which the protocol client MUST use in the first CPMFetchValueIn message.
If this is the first CPMFetchValueIn message the client has sent to request the specified property, the client MUST perform the following:
Set all the fields in a message, as specified in section 2.2.3.15.
Set _cbSoFar to 0x00000000.
Set current bytes received to 0.
Send the CPMFetchValueIn message to the server.
Sending a CPMFreeCursorIn Request
After the higher level is no longer using the search query, it can release the resources on the server by requesting that the client send a CPMFreeCursorIn message.
When this request is received, the client MUST send a CPMFreeCursorIn message to the server containing the handle specified by the upper layer.
Sending a CPMDisconnect Message
If the higher layer has no more queries for the Generic Search service (GSS), to free up more server resources, the application can request that the client send a CPMDisconnect message to the server. When this query is received, the client MUST simply send the message as requested. There is no response to this message from the server.
Sending a CPMFindIndicesIn Request
When the higher layer is about to request document identifier location within a rowset information, it will provide the protocol client with a set of document identifiers to look for. The higher layer can also provide a previous hierarchical group coordinate indicating where to start searching. The higher layer can use the coordinate returned in a previous CPMFindIndicesOut message for this purpose.
When this request is received from the higher layer, the client MUST perform the following:
Ensure there is at least one document identifier to search for. This is enforced by setting _cWids greater than zero.
Write exactly _cWids document identifiers to the _pwids array.
Write the coordinate retrieved from the higher layer to the _prgiRowPrev array and write its size to the _cDepthPrev value. If no such coordinate is available, the client MUST set _cDepthPrev to zero.
Send the CPMFindIndicesIn message to the server.
Sending a CPMGetRowsetNotifyIn Request
If the higher layer requires rowset eventing, it can send a CPMGetRowsetNotifyIn message to the server to request the next available event at any timed interval it chooses.
Sending a CPMGetScopeStatisticsIn Request
When the higher layer wants to retrieve statistics regarding the number of indexed items, number of outstanding items to be indexed, or number of items needing re-indexed that are relevant to its query, it can send a CPMGetScopeStatisticsIn message to the server to request these values at any interval it chooses.
Sending a CPMSetScopePrioritizationIn Request
When the higher layer wants to modify the indexing priority of documents that may be relevant to its query, it will send a CPMSetScopePrioritizationIn message to the server to request that the priority of items relevant to this query be modified.
When this request is received form the higher layer, the client MUST perform the following:
Set the priority in the CPMSetScopePrioritizationIn message to the priority requested by the higher layer.
Set the eventFrequency in the CPMSetScopePrioritizationIn message to the frequency requested by the higher layer, or to zero if the priority requested is PRIORITY_LEVEL_DEFAULT.
Send the CPMSetScopePrioritizationIn message to the server.
Processing and Sequencing Rules
When the client receives a message response from the server, the client MUST use the Last Sent Message to determine if the message received from the server is the one expected by the client. All messages with the _msg field different from that in the Last Sent Message MUST be ignored.
Receiving a CPMCreateQueryOut Response
When the client receives a CPMCreateQueryOut message response from the server, the client MUST return _status, and if the status is successful, return the cursor handle values back to the higher layer. Any further actions are determined by the higher layer.
Because the higher layer can detect the query structure, it is expected that the correct number of cursor handles will be returned in the CPMCreateQueryOut message. The cursor handles are returned in the following order: the first handle is to the unchaptered rowset and the second handle is to the first chaptered rowset (which is the grouping of results based on the first category specified in the CategorizationSet field of the CPMCreateQueryIn message).
For informative purposes, it is expected that higher layers can perform the following actions, but these are not enforced by the Windows Search Protocol client:
Use CPMSetBindingsIn to set the bindings for individual columns and perform any subsequent actions on query the path.
Use CPMGetQueryStatusIn to check on the execution progress of a query.
Use CPMRatioFinishedIn to request the completion percentage of a query.
Receiving a CPMGetRowsOut Response
When the client receives a CPMGetRowsOut message response from the server, the client MUST perform the following:
Check whether the _status field in the header indicates success or failure.
If the _status value is STATUS_BUFFER_TOO_SMALL (0xC0000023), the client MUST check the Last Message Sent state. If it does not contain a CPMGetRowsIn message, the received message MUST be silently ignored. Otherwise the client MUST send to the server a new CPMGetRowsIn message with all fields identical to the stored one, except that the _cbReadBuffer MUST be increased by 512 (but not greater than 0x4000). If _status is STATUS_BUFFER_TOO_SMALL (0xC0000023), and the Last Message Sent already has _cbReadBuffer equal to 0x4000, the client MUST report the error to the higher level.
If the _status value is any other error value, the client MUST report the failure to the higher layer.
If the _status value indicates success, the results MUST be reported to the higher layer requesting the information, and further actions are determined by the higher layer.
For informative purposes, it is expected that higher layers will typically perform the following actions, but these are not enforced by the Windows Search Protocol client:
If the values in rows represent the document IDs, chapter handles, or bookmark handles, the higher layer will typically store them for use in subsequent operations that involve valid document IDs, chapter handles, or bookmark handles.
The higher layer will typically store or display or otherwise use the data from row values.
For the values that were marked as deferred, the higher layer will fetch the value using CPMFetchValueIn messages.
The seek description is returned back to the higher layer as well, and can be reused or examined by the higher layer.
For informative purposes, if the higher layer requested handles to chapters and bookmarks that were received in the rows, it MAY perform the following:
Use CPMGetQueryStatusExIn to check on the execution progress of a query as well as additional status information, such as the number of filtered documents, documents remaining to be filtered, the ratio of documents processed by the query, the total number of rows in the query, and the position of the bookmark in the rowset.
Use CPMGetNotify to request that the server notify the client of rowset changes.
Use CPMGetApproximatePositionIn to request the approximate position of a bookmark in a chapter.
Use CPMCompareBmkIn to request a comparison of two bookmarks in a chapter.
Use CPMRestartPositionIn to request the server changes the location of the cursor to the start of rowset.
Receiving a CPMFetchValueOut Response
When the client receives a CPMFetchValueOut message response from the server, the client MUST perform the following:
Check whether the _status field in the header indicates success or failure. In a case of failure, notify the higher layer. Otherwise, continue as per the following:
Check _fValueExist, and if set to 0x00000000, notify the higher layer that the value was not found.
Otherwise, append _cbValue bytes from vValue to the Current Property Value.
If _fMoreExists is set to 0x00000001, increment _Current Bytes Received by _cbValue and send a CPMFetchValueIn message to the server, setting _cbSoFar to the value of Current Bytes Received, _cbPropSpec to zero, and _cbChunk to the buffer size required by the higher layer.
If _fMoreExists is set to 0x00000000, indicate the property value from the Current Property Value to the higher layer.
Receiving a CPMFreeCursorOut Response
When the client receives a successful CPMFreeCursorOut message response from the server, the client MUST return the _cCursorsRemaining value to the higher layer.
The following information is given for informative purposes only and is not enforced by the Windows Search Protocol client. The higher layer is expected to keep track of cursor handles and not to use those which have already been freed. When the value of _cCursorsRemaining is equal to 0x00000000, the higher layer can use the connection to specify another query (using a CPMCreateQueryIn message).
Receiving a CPMFindIndicesOut Response
When the client receives a CPMFindIndicesOut message response from the server, the client MUST perform the following:
If the _status value is an error value, the client MUST report the failure to the higher layer.
If the _status value indicates success, the results MUST be reported to the higher layer requesting the information, and further actions are determined by the higher layer.
If the _cDepthNext value is zero, the client MUST report to the higher layer that no occurrence of the given document identifiers was found.
For informative purposes, it is expected that higher layers will typically perform the following actions, but these are not enforced by the Windows Search Protocol client:
Store the returned coordinate if an occurrence was found and use it to send another CPMFindIndicesIn message in order to retrieve the next occurrence. This procedure can be repeated until no results are found.
Receiving a CPMGetRowsetNotifyOut Response
When the client receives a CPMGetRowsetNotifyOut message response from the server, the client MUST perform the following:
If the _status value is an error value, the client MUST report the failure to the higher layer.
If the _status value indicates success, the results MUST be reported to the higher layer requesting the information, and further actions are determined by the higher layer.
If the eventType value indicates PROPAGATE_NONE then no further action is required; otherwise the higher layer is informed of the type of event and relevant information for the event.
Receiving a CPMGetScopeStatisticsOut Response
When the client receives a CPMGetScopeStatisticsOut message response from the server, the client MUST perform the following:
If the _status value is an error value, the client MUST report the failure to the higher layer.
If the _status value indicates success, the results MUST be reported to the higher layer requesting the information, and further actions are determined by the higher layer.
Otherwise the client MUST report the dwIndexedItems, dwOutstandingAdds, and dwOutstandingModifies values returned in the message to the higher layer.
Receiving a CPMSetScopePrioritizationOut Response
When the client receives a CPMSetScopePrioritizationOut message response from the server, the client MUST perform the following:
If the _status value is an error value, the client MUST report the failure to the higher layer.
If the _status value indicates success, the results MUST be reported to the higher layer requesting the information, and further actions are determined by the higher layer.
Timer Events
None.
Other Local Events
None.
43>
|