内容索引服务协议

注意

Windows Desktop Search 2.x 是一项过时的技术,最初是作为 Windows XP 和 Windows Server 2003 的插件提供的。 在以后的版本中,请使用 Windows Search 代替。

协议规范,版本 0.12

本文档是内容索引服务协议的规范。

工作组服务器协议程序 ((WSPP) 文档旨在与公共标准文档、网络编程艺术和 Windows 工作组分布式系统概念结合使用,并假定读者要么熟悉上述材料,要么可以立即获取这些材料。

WSPP 协议规范不要求被许可人使用 Microsoft 编程工具或编程环境来开发实现。 能使用 Microsoft 编程工具和环境的被许可人可以自由利用这些工具和环境。

1 简介

1.1 术语表

注意

以下术语的定义见 [MS-SYS] 术语表部分:

  • GUID
  • Little Endian
  • 命名管道
  • 路径

绑定:请求在返回的行集中包含特定绑定指定了要包含在搜索结果中的属性。

书签:在一组行中唯一标识一行的标记。

目录:索引服务中最高级别的组织单位。 它代表一组索引文件,可使用内容索引服务协议对其执行查询。

类别:行的分层分组。 例如,包含作者和标题列的查询结果可根据作者进行分类。 每组包含相同作者值的行构成一个类别。

章节:一组中的范围。

中单个类型信息的容器。 列映射到属性名称,并指定哪些属性用于搜索查询的命令元素。

命令树:为搜索查询指定的限制类别排序顺序的组合。

游标:在结果集中返回的一组数据中,一次处理一个或一小段的实体。 游标位于结果集中的单个上。 在将游标定位到某一行后,可以对该或从该位置开始的块执行操作。

句柄:可用于标识和访问游标章节书签的令牌。

索引:一个持久性结构,包含索引服务从文件中提取的文本内容。 这包括与包含随文件名、单词位置和区域设置一起存储的单词列表。

索引:从文件中提取文本和属性,并将提取值存储到索引(针对文本)和属性缓存(针对属性)的过程。

索引服务:为文件系统的内容和属性创建索引目录的服务。 应用程序可以从目录中搜索索引文件系统中的文件信息。

区域设置:[MS-GPSI] 附录 A 中规定的标识符,用于指定与语言有关的首选项。 这些首选项说明了如何设置日期和时间的格式、如何按字母顺序对项目进行排序、如何比较字符串等。

自然语言查询:使用人类语言而非查询语法构建的查询。

干扰词:在为搜索查询指定的限制中出现时,索引服务会忽略的词,因为它没有什么区分价值。 英语示例包括“a”、“and”和“the”。

属性缓存索引服务提取的文件属性的缓存。

属性索引:为文档的值类型属性(包括作者、主题、类型、字数、打印页数和任何其他属性)创建索引的过程。

限制索引服务在响应搜索查询时返回的搜索结果中包含文件时必须满足的一组条件。 限制缩小了搜索查询的范围,将索引服务包含在搜索结果中的文件限制为仅符合条件的文件。

的集合,其中包含的属性值描述了与提交给索引服务的搜索查询中指定的限制相匹配的文件集中的单个文件。

行集:搜索结果中返回的一组

排序顺序:搜索查询中定义搜索结果中记录排序的规则集。 每个规则由一个属性(名称、大小等)和一个排序方向(升序或降序)组成。 多个规则依次应用

文本类型属性:描述文档内容的属性,其名称只与未格式化的文本相关联。

值类型属性:描述整个文档单个属性的属性。 值类型属性有一个数据类型 ID 和一个与其名称相关的数据类型值。

虚拟根:文件夹的备用路径。 一个物理文件夹可以有零个或多个虚拟根。 以虚拟根开头的路径被称为虚拟路径。 例如,/server/vanityroot 可能是 C:\IIS\web\folder1 的虚拟根。 那么文件 C:\IIS\web\folder1\default.htm 的虚拟路径就是 /server/vanityroot/default.htm。

MAY、SHOULD、MUST、SHOULD NOT、MUST NOT:这些术语(全部大写)的用法如 [RFC2119] 所述。 所有可选行为的陈述使用“可以”、“应该”或“不应”。

1.2 参考

1.2.1 规范参考

[IEEE754] 电气与电子工程师协会,“二进制浮点运算标准”,IEEE 754-1985,1985 年 10 月,https://standards.ieee.org/standard/754-1985.html

[MS-DCOM] Microsoft Corporation,“分布式组件对象模型远程协议”,2006 年 6 月。

[MS-GPSI] Microsoft Corporation,“组策略软件安装扩展”,2006 年 6 月。

[MS-SMB] Microsoft Corporation,“Microsoft 服务器消息块 (SMB) 协议和扩展”,2006 年 5 月。

[MS-SYS] Microsoft Corporation,“系统概述 v4”,2006 年 7 月。

[SALTON] Salton,G.,“自动文本处理:计算机信息转换分析和检索”,1988 年,ISBN 0-201-2227-8。

[UNICODE] Unicode 联盟,“Unicode 标准版本 2.0”,1996,https://www.unicode.org

1.2.2 信息性参考

[MSDN-OLEDB] Microsoft Corporation,OLE DB,https://msdn.microsoft.com/library/default.asp?url=/library/oledb/htm/dasdkoledboverview.asp

[MSDN-QUERYERR] Microsoft Corporation,查询执行值,https://msdn.microsoft.com/library/default.asp?url=/library/indexsrv/html/ixreferr\_5df7.asp

1.3 协议概览(概要)

索引服务内容有助于有效组织文档集合的提取功能。 内容索引服务协议 (CISP) 允许客户端与托管索引服务的服务器进行通信,以发出查询并允许管理员管理索引服务器。

在处理文件时,索引服务会分析一组文件并重新组织其内容,以便在响应查询时高效地返回这些文件的属性。 可查询的文件集合由目录组成。 目录可能包含索引(用于快速参考文本)和属性缓存(用于快速检索属性值)。

从概念上讲,目录由一个逻辑属“表”组成,而表中的存储了文本或值以及相应的区域设置。 该表的每一“行”对应于目录范围内的一个单独的文档,表的每一“列”对应于一个属性。

CISP 执行的具体任务分为两个功能区域:

  • 远程管理索引服务目录,
  • 远程查询索引服务目录。

1.3.1 远程管理任务

CISP 支持客户端执行以下索引服务目录管理任务:

  • 查询服务器上索引服务目录的当前状态。
  • 更新索引服务目录的状态。
  • 启动一组特定文件的索引过程。
  • 启动索引优化以提高查询性能。

所有远程管理任务都遵循简单的请求/响应模式。 任何管理调用都不会在客户端上保留任何状态,而且管理调用可以按任何顺序进行。

1.3.2 远程查询

CISP 使客户端能够对托管索引服务的远程服务器进行搜索查询。

发送搜索查询是一个由客户端启动的多步骤过程。 步骤如下:

  1. 客户端请求连接到托管索引服务的服务器。

  2. 客户端发送的搜索查询参数,其中包括:

    • 用于指定搜索结果中包含和/或排除哪些文件的限制

    • 返回搜索结果的顺序。

    • 结果集中要返回的列。

    • 查询应返回的的最大数目。

    • 查询执行的最长时间。

      一旦服务器确认了客户端启动查询的请求,客户端就可以请求查询的状态信息,但这并不是必须的步骤。

  3. 然后,客户端指定服务器应在搜索结果中包含哪些属性。

  4. 客户端向服务器请求一个结果集,而服务器的回应是向客户端发送客户端搜索查询结果中包含的文件的属性值。 如果属性值过大,无法在单个响应缓冲区中容纳,则服务器将不会发送该属性,而是将属性状态设置为延迟。 随后,客户端通过一系列连续的请求来单独请求属性值,然后再继续请求其他值。

  5. 一旦客户端完成搜索查询,不再需要其他结果,客户端就会联系服务器以释放查询。

  6. 一旦服务器释放了查询,客户端就可以发送请求断开与服务器的连接。 然后连接将被关闭。 或者,客户端可以发出另一个查询,并重复步骤 2 中的序列。

Windows 行为:此协议在 Windows 2000、Windows XP、Windows Server 2003 和 Windows Vista 上实现。

1.4 与其他协议之间的关系

CISP 依靠 SMB [MS-SMB] 协议进行信息传输。 没有其他协议直接依赖于内容索引服务协议。

Windows 行为:应用程序通常与 OLE DB 接口包装器 [MSDN-OLEDB](如协议客户端)交互,而不是直接与协议交互。

1.5 前提和先决条件

假定客户端在调用该协议前已获得服务器名称和目录名称。 客户如何做到这一点不属于本规范的范围。

此外,还假定客户端和服务器具有可用于命名管道 [MS-SMB] 的安全关联。

1.6 适用性声明

CISP 用于从客户端查询和管理远程服务器上的目录。 CISP 已在 Windows Vista 上弃用。

1.7 版本控制和功能协商

此协议没有版本控制或功能协商机制。

1.8 供应商可扩展的字段

此协议使用可由供应商扩展的 HRESULT。 只要按照 [MS-SYS] 第 4.1.1 节的规定设置了 C 位 (0x20000000),表明它是客户代码,供应商就可以自由选择该字段的值。

此协议还使用 [MS-SYS] 中定义的 NTSTATUS 数字空间中的 NTSTATUS 值。 供应商应重新使用这些具有指定含义的值。 选择任何其他值都有可能在未来发生冲突。

Windows 行为:Windows 只使用 [MS-SYS] 第 4.1.3 节中指定的值。

1.8.1 属性 ID

属性由被称为属性 ID 的 ID 表示。 每个属性必须具有一个全局唯一的标识符。 此标识符由一个 GUID 和一个字符串或 32 位整数组成,前者代表一个属性集合,后者用于标识该集合中的属性。 如果使用整数形式的 ID,则 0x00000000、0xFFFFFFFF 和 0xFFFFFFFE 值会被视为无效。

供应商可将其属性置于由自己的 GUID 定义的属性集中,以确保其属性是唯一定义的。

1.9 标准分配

此协议没有标准分配,只有 Microsoft 使用其他协议规定的分配程序进行的专用分配。

Microsoft 已按照 [MS-SMB] 中的规定为该协议分配了一个命名管道。 任务是:

参数 参考
管道名称 \pipe\CI_SKADS [MS-SMB]

2 消息

2.1 传输

根据 [MS-SMB] 的规定,所有信息都必须使用命名管道来传输。 使用以下管道名称:

  • \pipe\CI_SKADS

此协议使用基础 SMB 命名管道协议来检索 [MS-SMB] 第 2.2.8 节中规定的建立连接的调用方的身份;客户端必须在打开命名管道的请求中将 SECURITY_IDENTIFICATION 设置为 ImpersonationLevel。

2.2 消息语法

以下部分中的一些结构和信息涉及章节或书签句柄。 句柄是一个 32 位长的不透明结构,用于唯一标识章节或书签。 通常情况下,客户端应用程序通过方法调用接收句柄值;但有几个众所周知的值无需从服务器获取,其含义如下表所示:

含义
DB_NULL_HCHAPTER 0x00000000 指向未编排行集的章节句柄,其中包含所有查询结果。
DBBMK_FIRST 0x00000001 用于标识行集中的第一行的书签句柄。
DBBMK_LAST 0x00000002 用于标识行集中的最后一行的书签句柄。

2.2.1 结构

本部分详细介绍了 CISP 定义和使用的数据结构。

以下结构中的所有 2 字节、4 字节和 8 字节有符号和无符号整数必须按小字节顺序传输。

下表概述了本部分定义的数据结构。

结构 说明
CBaseStorageVariant 包含对 CPropertyRestriction 结构中指定的属性执行匹配操作的值。
SAFEARRAY,SAFEARRAY2 包含一个多维数组。
SAFEARRAYBOUND 表示在 SAFEARRAY 结构中指定的数组维数的边界。
CFullPropSpec 包含属性规范。
CContentRestriction 包含一个用于匹配属性缓存中属性值的字符串。
CKey 包含一个属性值。
CInternalPropertyRestriction 包含与操作匹配的属性值。
CNatLanguageRestriction 包含一个属性的自然语言查询匹配项。
CNodeRestriction 包含一个命令树节点数组,其中指定了查询的限制条件。
COccRestriction 包含一个单词在短语中的位置。
CPropertyRestriction 包含与操作匹配的属性值。
CRangeRestriction 包含对一系列值的限制。
CScopeRestriction 包含对要搜索的文件的限制。
CSort 标识要排序的列。
CSynRestriction 包含查询短语的单词或同义词。
CVectorRestriction 包含对命令树节点的加权 OR 操作。
CWordRestriction 包含一个查询短语的单词。
CRestriction 包含查询命令树的一个节点。
CColumnSet 表示要返回的列数。
CCategorizationSet 包含一组查询结果的分组信息。
CCategorizationSpec 包含对查询结果进行分类的类别定义。
CDbColId 包含一列。
CDbProp 包含一个属性。
CDbPropSet 包含一个属性集。
CPidMapper 包含一个属性 ID 数组,其指定了要在行集中返回的属性。
CRowSeekAt 包含在 CPMGetRowsIn 信息中检索行的偏移量
CRowSeekAtRatio 标识开始检索 CPMGetRowsIn 信息的点。
CRowSeekByBookmark 标识要从中检索 CPMGetRowsIn 消息的行的书签。
CRowSeekNext 包含 CPMGetRowsIn 消息中要跳过的行数。
CRowsetProperties 包含查询的配置信息。
CSortSet 包含查询的排序顺序。
CTableColumn 包含 CPMSetBindings 消息的列。
SERIALIZEDPROPERTYVALUE 包含一个序列化值。

2.2.1.1 CBaseStorageVariant

CBaseStorageVariant 结构包含对 CPropertyRestriction 结构中指定的属性执行匹配操作的值。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

vType

vData1

vData2

vValue(变量)

vType:类型指示符,表示 vValue 的类型。 它必须是下表中指定的 VARENUM 值之一。

含义
VT_EMPTY (0x0000) vValue 不存在。
VT_NULL (0x0001) vValue 不存在。
VT_I1 (0x0010) 1 字节有符号整数。
VT_UI1 (0x0011) 1 字节无符号整数。
VT_I2 (0x0002) 2 字节有符号整数。
VT_UI2 (0x0012) 2 字节无符号整数。
VT_BOOL (0x000B) 一个布尔值;包含 0x0000 (FALSE) 或 0xFFFF (TRUE) 的 2 字节整数。
VT_I4 (0x0003) 4 字节有符号整数。
VT_UI4 (0x0013) 4 字节无符号整数。
VT_R4 (0x0004) IEEE 32 位浮点数,定义见 [IEEE754]。
VT_INT (0x0016) 4 字节有符号整数。
VT_UINT (0x0017) 4 字节无符号整数。
VT_ERROR (0x000A) 一个包含 HRESULT 的 4 字节无符号整数,如 [MS-SYS] 中所述。
VT_I8 (0x0014) 一个 8 字节有符号整数。
VT_UI8 (0x0015) 8 字节无符号整数。
VT_R8 (0x0005) IEEE 64 位浮点数,定义见 [IEEE754]。
VT_CY (0x0006) 一个 8 字节 2 的补码整数(按 10,000 倍缩放)。
VT_DATE (0x0007) 一个 64 位浮点数,表示自 1899 年 12 月 31 日 00:00:00(协调世界时)起的天数。
VT_FILETIME (0x0040) 一个 64 位整数,表示自 1601 年 1 月 1 日 00:00:00(协调世界时)起的 100 纳秒间隔数。
VT_DECIMAL (0x000E) 第 2.2.1.1.1 部分中指定的 DECIMAL 结构。
VT_CLSID (0x0048) 包含 GUID 的 16 字节二进制值。
VT_BLOB (0x0041) 一个 4 字节无符号整数,表示 blob 中的字节数,后面是相同字节数的数据。
VT_BSTR (0x0008) 字符串中字节数的 4 字节无符号整数,后跟一个字符串,如下文 vValue 所述。
VT_LPSTR (0x001E) 以 null 终止的 ANSI 字符串。
VT_LPWSTR (0x001F) 以 Null 值结束的 [UNICODE] 字符串。
VT_VARIANT (0x000C) CBaseStorageVariant。 必须与 VT_ARRAY 或 VT_VECTOR 类型修饰符结合使用。

下表列出了 vType 的类型修饰符。 类型修饰符可以是 vType 的二进制 ORed,以改变 vValue 的含义,使其成为两种可能的数组类型之一。

含义
VT_VECTOR (0x1000) 如果使用 OR 运算符将类型指示符与 VT_VECTOR 结合使用,则 vValue 就是一个由指定类型的值组成的计数数组。 有关详细信息,请参阅第 2.2.1.1.1.2 部分。
此类型修饰符不得与以下类型结合使用:VT_INT、VT_UINT、VT_DECIMAL、VT_BLOB、VT_BLOB_OBJECT。
VT_ARRAY (0x2000) 如果类型指示符通过 OR 运算符与 VT_ARRAY 相结合,则值是一个 SAFEARRAY(如第 2.2.1.1.1.3 部分所述),其中包含指示类型的值。
此类型修饰符不得与以下类型结合使用:VT_I8、VT_UI8、VT_FILETIME、VT_CLSID、VT_BLOB、VT_BLOB_OBJECT、VT_LPSTR、VT_LPWSTR。

vData1:当 vType 为 VT_DECIMAL 时,此字段值指定为第 2.2.1.1.1.1 部分中的“缩放”字段。 对于所有其他 vType,此值必须设置为 0x00。

vData2:当 vType 为 VT_DECIMAL 时,此字段值指定为第 2.2.1.1.1.1 部分中的“符号”字段。 对于所有其他 vType,此值必须设置为 0x00。

vValue:匹配操作的值。 语法必须如 vType 字段所示。

下表概述了 vValue 字段的大小,具体取决于固定长度数据类型的 vType 字段。 大小以字节为单位。

vType 大小
VT_I1、VT、_UI1 1
VT_I2、VT_UI2、VT_BOOL 2
VT_I4、VT_UI4、VT_R4、VT_INT、VT_UINT、VT_ERROR 4
VT_I8、VT_UI8、VT_R8、VT_CY、VT_DATE、VT_FILETIME 8
VT_DECIMAL,VT_CLSID 16

如果 vType 设置为 VT_BLOB、VT_BSTR 或 VT_LPSTR,则 vValue 的结构如下图所示:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

cbSize

blobData(变量,可选)

cbSize:无符号 32 位整数,表示 blobData 字段的大小(以字节为单位)。 如果 vType 设置为 VT_BSTR 或 VT_LPSTR,当所代表的字符串为空字符串时,cbSize 必须设置为 0x00000000。

blobData:长度必须为 cbSize(以字节为单位)。

如果 vType 设置为 VT_BLOB,则此字段为不透明二进制 blob 数据。

对于设置为 VT_BSTR 的 vType,此字段是 OEM 所选字符集中的一组字符。 客户端和服务器必须配置为可互操作的字符集(协议带外)。 不要求它以 null 结尾。

对于设置为 VT_LPSTR 的 vType,此字段是 OEM 所选字符集中以 null 结尾的字符串。 客户端和服务器必须配置为可互操作的字符集(协议带外)。

如果 vType 设置为 VT_LPWSTR,则 vValue 的结构如下图所示:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

ccLen

string(变量,可选)

ccLen:无符号 32 位整数,表示 Unicode 字符的字符串字段的大小。 如果是空字符串,必须设置为 0x00000000。

string:以 Null 值结束的 Unicode 字符串。

2.2.1.1.1 CBaseStorageVariant 结构

以下结构用于 CBaseStorageVariant 结构。

2.2.1.1.1.1 DECIMAL

DECIMAL 用于表示具有固定精度和固定小数位数的精确数值。

当 vType 设置为 VT_DECIMAL (0x0000E) 时,CBaseStorageVariant 的 vData1 和 vData2 字段必须解释如下:

vData1:小数点右边的位数。 必须在 0-28 范围之间。

vData2:数值的符号。 如果是正值,则设置为 0x00,如果是负值,则设置为 0x80。

vValue 字段的格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

Hi32

Lo32

Mid32

Hi32:96 位整数的最高 32 位。

Lo32:96 位整数的最低 32 位。

Mid32:96 位整数的中间 32 位。

2.2.1.1.1.2 VT_VECTOR

VT_Vector 用于传递一维数组。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

vVectorElements

vVectorData

vVectorElements:无符号 32 位整数,表示 vVectorData 字段中的元素个数。

vVectorData:一个项目数组,其类型由 vType 表示,0x1000 位已清除。 根据第 2.2.1.1 节的规定,可从固定长度数据类型表中获取单个固定长度项目的大小。 将 vVectorElements 乘以单个项目的大小,即可计算出该字段的长度(以字节为单位)。

对于可变长度数据类型,vVectorData 包含一串连续封送的简单类型,其中的类型由 vType 表示,并且 0x1000 位已清除。 这包括 vType VT_ARRAY | VT_VARIANT(即 0x100C)表示的特殊情况。

vVectorData 字段中的元素必须由 0 至 3 个填充字节分隔,这样每个元素开始的偏移量即为包含该数组的消息开头的 4 个字节的倍数。 如果存在填充字节,它们所包含的值是任意的。 接收方必须忽略填充字节的内容。

如果 vType 设置为 VT_ARRAY | VT_VARIANT,则此序列中的项目类型为 CBaseStorageVariant。

2.2.1.1.1.3 SAFEARRAY

SAFEARRAY 用于传递多维数组。 该结构包含数组大小信息以及数组中的数据。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

cDims

fFeatures

cbElements

Rgsabound(变量)

vData(变量)

cDims:无符号 16 位整数,表示多维数组的维数。

fFeatures:一个 16 位位域。 这些值代表由上层应用程序定义的特征,必须予以忽略。

cbElements:一个 32 位无符号整数,用于指定数组中每个元素的大小。

Rgsabound:一个数组,按照第 2.2.1.1.1.4 节的规定,SAFEARRAY 的每个维数包含一个 SAFEARRAYBOUND 结构。 此数组最左边的维度在前,最右边的维度在后。

vData:特定类型的封送项向量,由包含 CBaseStorageVariant 的 vType 表示,0x2000 位已清除。

根据第 2.2.1.1.1.2 部分的规定,vData 的封送方式 与 VT_VECTOR 类似,不同之处在于项数不存储在向量前面。 计算项数的方法是将 cElements 值与 Rgsabound 字段中给出的所有安全数组边界相乘。 元素按维度顺序存储在一个矢量中,从最右边的维度开始迭代。

下图直观地展示了一个二维数组示例。 第一个维度的 cElements 等于 4(水平表示),lLbound 等于 0,第二个维度的 cElements 等于 2(垂直表示),lLbound 等于 0。

0x00000001

0x00000002

0x00000003

0x00000005

::row:::

0x00000007

0x00000011

0x00000013

0x00000017

:::row-end:::

使用上图,vData 将包含以下序列:0x00000001、0x00000007、0x00000002、0x00000011、0x00000003、0x00000013、0x00000005、0x00000017(先迭代最右边的维度,然后递增下一个维度)。 前面的 Rgsabound(记录 cElements 和 Lbound)将是 0x00000004、0x00000000、0x00000002、0x00000000。

2.2.1.1.1.4 SAFEARRAYBOUND

SAFEARRAYBOUND 结构表示 SAFEARRAY 或 SAFEARRAY2 的一个维度的边界。 其格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

cElements

lLbound

cElements:一个 32 位无符号整数,指定维度中元素的个数。

lLbound:一个 32 位无符号整数,指定维度的下限。

2.2.1.1.1.5 SAFEARRAY2

SAFEARRAY2 用于在 SERIALIZEDPROPERTYVALUE 中传递多维数组。 该结构包含边界信息和数据。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

cDims

Rgsabound(变量)

vData(变量)

cDims:无符号 32 位整数,表示 SAFEARRAY2 的维度数。

Rgsabound:一个数组,按照第 2.2.1.1.1.4 节的规定,SAFEARRAY2 的每个维数包含一个 SAFEARRAYBOUND 结构。 此数组最左边的维度在前,最右边的维度在后。

vData:特定类型的封送项向量,由包含 SERIALIZEDPROPERTYVALUE 的 dwType 表示,0x2000 位已清除。 vData 的格式与第 2.2.1.1.1.3 部分中为 SAFEARRAY 的 vData 字段规定的格式相同。

2.2.1.2 CFullPropSpec

CFullPropSpec 结构包含一个属性集 GUID 和一个用于唯一标识属性的属性标识符。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_guidPropSet

...

...

...

ulKind

PrSpec

属性名称(变量)

_guidPropSet:属性所属的属性集的 GUID。

ulKind: 一个 32 位无符号整数。 以下数值之一,表示 PrSpec 的内容。

含义
PRSPEC_ LPWSTR
0x00000000
PrSpec 字段指定了“属性名称”字段中的非 NULL 字符数。
PRSPEC_PROPID
0x00000001
PrSpec 字段指定了属性 ID (PROPID)。

PrSpec:一个 32 位无符号整数,其含义由 ulKind 字段表示。

属性名称:如果 ulKind 设置为 PRSPEC_PROPID,则必须不存在此字段。 如果 ulKind 设置为 PRSPEC_LPWSTR,则此字段必须包含一个不区分大小写的 PrSpec 非空 Unicode 字符数组,其中包含属性名称。

2.2.1.3 CContentRestriction

CContentRestriction 结构包含一个与属性缓存中的属性匹配的字符串。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_Property(变量)

...

Padding1(变量)

Cc

_pwcsPhrase(变量)

...

Padding2(变量)

lcid

_ulGenerateMethod

_Property:CFullPropSpec 结构,如第 2.2.1.2 部分所述。 此字段表示要执行匹配操作的属性。

Padding1:此字段长度必须为 0 到 3 字节。 此字段的长度必须使下面的字段从包含该结构的消息开头开始的偏移量是 4 字节的倍数。 如果该字段存在(即长度不为零),则其包含的值为任意值。 接收方必须忽略此字段的内容。

Cc:一个 32 位无符号整数,用于指定 _pwcsPhrase 字段中的字符数。

_pwcsPhrase:一个非以 null 结尾的 Unicode 字符串,表示要为属性匹配的单词或短语。 此字段不得为空。 “Cc”字段包含字符串的长度。

Padding2:此字段长度必须为 0 到 3 字节。 此字段的长度必须使下面的字段从包含该结构的消息开头开始的偏移量是 4 字节的倍数。 如果该字段存在(即长度不为零),则其包含的值为任意值。 接收方必须忽略此字段的内容。

Lcid:一个 32 位无符号整数,表示 _pwcsPhrase 的地域,如 [MS-GPSI] 附录 A 所规定。

_ulGenerateMethod:一个 32 位无符号整数,指定生成备用单词表时使用的方法

含义
GENERATE_METHOD_EXACT
0x00000000
完全匹配。
GENERATE_METHOD_PREFIX
0x00000001
前缀匹配。
GENERATE_METHOD_INFLECT
0x00000002
匹配单词的词形变化。 单词的词形变化是言语中同一部分根词的变体,根据给定语言的语言规则进行了修改。 例如,英语中动词“swim”的词形变化包括“swim”、“swives”、“swiming”和“swam”。

2.2.1.4 CKey

CKey 结构包含一个属性值。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

PROPID

Cb

buf(变量)

PROPID:一个 32 位无符号整数,表示第 1.8.1 部分所述的属性 ID。 众所周知的值包括:

含义
0xFFFFFFFF 表示无效的属性 ID,不得使用。
0xFFFFFFFE 表示无效的属性 ID,不得使用。
0x00000000 表示任何属性 ID。

Cb:一个 32 位无符号整数,包含 buf 的长度(以字节为单位)。

buf:表示属性值的字节序列。

2.2.1.5 CInternalPropertyRestriction

CInternalPropertyRestriction 结构包含一个与操作匹配的属性值。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_relop

_pid

_prval(变量)

restrictionPresent

nextRestriction(变量)

_relop:一个 32 位整数,指定要在属性上执行的关系。 必须是以下值之一:

含义
PRLT 0x00000000 一个小于比较。
PRLE 0x00000001 一个小于或等于比较。
PRGT 0x00000002 一个大于比较。
PRGE 0x00000003 一个大于或等于比较。
PREQ 0x00000004 一个等式比较。
PRNE 0x00000005 一个不等于比较。
PRRE 0x00000006 一个正则表达式比较。
PRAllBits 0x00000007 一个按位 AND,返回右操作数。
PRSomeBits 0x00000008 一个按位 AND,返回一个非零值。
PRAll 0x00000100 该操作将针对行集的列执行,并且只有当操作对所有行都为 true 时才为 true。
PRAny 0x00000200 该操作将针对行集的列执行,并且当操作对任意行都为 true 时才为 true。

_pid:一个 32 位无符号整数,表示第 2.2.1.4 部分中 PROPID 所述的属性 ID。

_prval一个包含与属性相关的值的 CBaseStorageVariant。

restrictionPresent:表示 nextRestriction 字段是否存在的字节值。 必须设置为 0x00 或 0x01。 如果设置为 0x01,则 restrictionPresent 表示 nextRestriction 字段存在。 如果设置为 0x00,则 restrictionPresent 表示 nextRestriction 字段不存在。

nextRestriction:一个 CRestriction 结构,如第 2.2.1.16 部分所述,它指定了进一步的限制。

2.2.1.6 CNatLanguageRestriction

CNatLanguageRestriction 结构包含一个属性的自然语言查询匹配。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_Property(变量)

...

_padding_cc(变量)

Cc

_pwcsPhrase(变量)

...

_padding_lcid(变量)

Lcid

_Property:CFullPropSpec 结构,如第 2.2.1.3 部分所述。 此字段表示要执行匹配操作的属性。

_padding_cc:此字段长度必须为 0 到 3 字节。 此字段的长度必须使下面的字段从包含该结构的消息开头开始的偏移量是 4 字节的倍数。 如果该字段存在(即长度不为零),则其包含的值为任意值。 接收方必须忽略此字段的内容。

Cc:一个 32 位无符号整数。 _pwcsPhrase 字段中的字符数。

_pwcsPhrase:一个非以 null 结尾的 Unicode 字符串,表示要为属性匹配的单词或短语。 不得为空。 “Cc”字段包含字符串的长度。

_padding_lcid:此字段长度必须为 0 到 3 字节。 此字段的长度必须使下面的字段从包含该结构的消息开头开始的偏移量是 4 字节的倍数。 如果该字段存在(即长度不为零),则其包含的值为任意值。 接收方必须忽略此字段的内容。

Lcid:一个 32 位无符号整数,表示 _pwcsPhrase 的地域,如 [MS-GPSI] 附录 A 所规定。

2.2.1.7 CNodeRestriction

CNodeRestriction 结构包含一个由命令树节点组成的数组,它们指定了查询的限制条件。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_cNode

_paNode(变量)

_cNode:一个 32 位无符号整数,用于指定 _paNode 字段中包含的 CRestriction 结构的个数。

_paNode:一个 CRestriction 结构的数组。 数组中的结构必须由 0 至 3 个填充字节分隔,从而使每个结构的起始偏移量是包含该数组的消息开头的 4 个字节的倍数。 如果存在填充字节,它们所包含的值是任意的。 接收方必须忽略填充字节的内容。

2.2.1.8 COccRestriction

COccRestriction 结构包含一个单词在短语中的位置。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_occ

_cPrevNoiseWords

_cNextNoiseWords

_occ:一个 32 位无符号整数,用于指定查询字符串中单词的偏移量(以单词为单位)。 在本规范中,“单词”是指在任何区域设置中都有意义的语言单元。

_cPrevNoiseWords:一个 32 位无符号整数,其中包含本单词与短语中前一个字之间出现的干扰词数

_cNextNoiseWords:一个 32 位无符号整数,其中包含本单词与短语中下一个字之间出现的干扰词数。

2.2.1.9 CPropertyRestriction

CPropertyRestriction 结构包含一个与操作匹配的属性值。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_relop

_Property(变量)

_prval(变量)

_relop:一个 32 位无符号整数,指定要在属性上执行的关系。 必须是以下值之一。

含义
PRLT 0x00000000 一个小于比较。
PRLE 0x00000001 一个小于或等于比较。
PRGT 0x00000002 一个大于比较。
PRGE 0x00000003 一个大于或等于比较。
PREQ 0x00000004 一个等式比较。
PRNE 0x00000005 一个不等于比较。
PRRE 0x00000006 一个正则表达式比较。
PRAllBits 0x00000007 一个按位 AND,返回右操作数。
PRSomeBits 0x00000008 一个按位 AND,返回一个非零值。
PRAll 0x00000100 该操作将针对行集的列执行,并且只有当操作对所有行都为 true 时才为 true。
PRAny 0x00000200 该操作将针对行集的列执行,并且当操作对任意行都为 true 时才为 true。

_Property:一个 CFullPropSpec 结构,如第 2.2.1.2 部分所述,表示要执行匹配操作的属性。

_prval:一个 CBaseStorageVariant 结构,如第 2.2.1.1 部分中所述,包含要与属性相关的值。

2.2.1.10 CRangeRestriction

CRangeRestriction 结构包含对一系列值的限制。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_keyStart(变量)

_keyEnd(变量)

_keyStart:一个 CKey 结构,如第 2.2.1.4 部分中所述,包含范围的开头。

_keyEnd:包含范围末尾的 CKey 结构。

2.2.1.11 CScopeRestriction

CScopeRestriction 结构包含对要搜索的文件的限制

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

CcLowerPath

_lowerPath(变量)

...

_padding(变量)

_length

_fRecursive

_fVirtual

CcLowerPath:一个 32 位无符号整数,其中包含 _lowerPath 字段中的 Unicode 字符数。

_lowerPath:一个非空端 Unicode 字符串,表示查询应受限的路径路径。 CcLowerPath 字段包含字符串的长度。

_padding:此字段长度必须为 0 到 3 字节。 此字段的长度必须使下面的字段从包含该结构的消息开头开始的偏移量是 4 字节的倍数。 如果该字段存在(即长度不为零),则其包含的值为任意值。 接收方必须忽略此字段的内容。

_length:一个 32 位无符号整数,包含 _lowerPath 的长度(Unicode 字符)。 此值必须与 CcLowerPath 相同。

_fRecursive:一个 32 位无符号整数。 必须设置为 0x00000001 或 0x00000000。 如果设置为 0x00000001,则服务器将递归检查路径的所有子目录。 如果设置为 0x00000000,则服务器将不检查任何子目录。

_fVirtual:一个 32 位无符号整数。 必须设置为 0x00000001 或 0x00000000。 如果设置为 0x00000001,_lowerPath 就是网站的虚拟路径(与文件系统中物理目录相关联的统一资源定位符 (URL))。 如果设置为 0x00000000,则 _lowerPath 就是文件系统路径。

2.2.1.12 CSort

CSort 结构用于标识要排序的列。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

pidColumn

dwOrder

区域设置

pidColumn:一个 32 位无符号整数。 要排序的列的编号。

dwOrder:一个 32 位无符号整数。 必须是以下值之一,指定如何根据列进行排序。

含义
QUERY_SORTASCEND 0x00000000 行将根据指定列中的值以升序排序。
QUERY_DESCEND 0x00000001 行将根据指定列中的值以降序排序。

locale:一个 32 位无符号整数,表示GIA列的 [MS-GPSI] 附录 A 中指定的区域设置。

2.2.1.13 CSynRestriction

CSynRestriction 结构包含查询短语的一个单词或其同义词。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

Restriction

...

...

cKey

_keyArray(变量)

_isRange

Restriction:一个指定单词位置的 COccRestriction 结构。

cKey:一个 32 位无符号整数,用于指定 _keyArray 数组中元素的个数。

_keyArray:指定单词及其同义词的 CKey 结构的数组。

_isRange:如果设置为 0x01,则键是匹配的前缀。 如果设置为 0x00,则键值为精确匹配值。 不得将 _isRange 设置为任何其他值。

2.2.1.14 CVectorRestriction

CVectorRestriction 结构包含命令树节点上的加权 OR 操作。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_pres(变量)

...

_padding(变量)

_ulRankMethod

_pres:要对其执行排名 OR 操作的 CNodeRestriction 命令树。

_padding:此字段长度必须为 0 到 3 字节。 此字段的长度必须使下面的字段从包含该结构的消息开头开始的偏移量是 4 字节的倍数。 如果该字段存在(即长度不为零),则其包含的值为任意值。 接收方必须忽略此字段的内容。

_ulRankMethod:一个 32 位无符号整数,用于指定排名算法。 必须设置为以下值之一。

含义
VECTOR_RANK_MIN 0x00000000 使用最小算法 [SALTON]。
VECTOR_RANK_MAX 0x00000001 使用最大算法 [SALTON]。
VECTOR_RANK_INNER 0x00000002 使用内积算法 [SALTON]。
VECTOR_RANK_DICE 0x00000003 使用 Dice 系数算法 [SALTON]。
VECTOR_RANK_JACCARD 0x00000004 使用 Jaccard 系数算法 [SALTON]。

2.2.1.15 CWordRestriction

CWordRestriction 结构包含一个查询短语的单词。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

restriction

...

...

_key(变量)

_isRange

restriction:一个指定单词位置的 COccRestriction 结构。

_key:一个指定单词的 CKey 结构。

_isRange:如果设置为 0x01,则键是匹配的前缀。 如果设置为 0x00,则键为精确匹配值。 不得将 _isRange 设置为任何其他值。

2.2.1.16 CRestriction

CRestriction 结构包含查询命令树的一个节点。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_ulType

Weight

Restriction

_ulType:一个 32 位无符号整数,表示命令树节点使用的限制类型。 必须设置为以下值之一。

含义
RTNone 0x00000000 节点表示向量查询中的一个干扰词。
RTAnd 0x00000001 节点包含一个要对其执行逻辑 AND 操作的 CNodeRestriction。
RTOr 0x00000002 节点包含一个要对其执行逻辑 OR 操作的 CNodeRestriction。
RTNot 0x00000003 节点包含一个要对其执行 NOT 操作的 CRestriction。
RTContent 0x00000004 节点包含一个 CContentRestriction。
RTProperty 0x00000005 节点包含一个 CPropertyRestriction。
RTProximity 0x00000006 节点包含一个要对其进行邻近度排序的 CNodeRestriction,
RTVector 0x00000007 节点包含一个 CVectorRestriction。
RTNatLanguage 0x00000008 节点包含一个 CNatLanguageRestriction。
RTScope 0x00000009 节点包含一个 CScopeRestriction。
PRAny 0xFFFFFFFA 节点包含一个 CInternalPropertyRestriction。
RTRange 0xFFFFFFFC 节点包含一个 CRangeRestriction。
RTPhrase 0xFFFFFFFD 节点包含一个要对其执行短语匹配的 CNodeRestriction。
RTSynonym 0xFFFFFFFE 节点包含一个 CSynRestriction。
RTWord 0xFFFFFFFF 节点包含一个 CWordRestriction。

Weight:一个 32 位无符号整数,表示节点的权重。 权重表示节点相对于查询命令树中其他节点的重要性。 权重值越高越重要。

Restriction:命令树节点的限制类型。 语法必须如 _ulType 字段所示。

2.2.1.17 CColumnSet

CColumnSet 结构指定了要返回的列编号。 此结构始终用于引用特定的 CPidMapper 结构(第 2.2.1.23 部分)。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

count

indexes(变量)

count:一个 32 位无符号整数,用于指定索引数组中的元素个数。

indexes:4 字节无符号整数数组,表示相应 CPidMapper 结构中 aPropSpec 数组从零开始的索引。

2.2.1.18 CCategorizationSet

CCategorizationSet 结构包含关于查询结果集的分组信息。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

count

categories(变量)

count:一个 32 位无符号整数,包含类别数组中的元素个数。

categories:指定查询分组的 CCategorizationSpec 结构数组。

2.2.1.19 CCategorizationSpec

CCategorizationSpec 结构包含查询结果集的分组。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_csColumns(变量)

_ulCategType

_csColumns:一个 CColumnSet 结构,表示要按其对查询进行分组的列。

_ulCategType:一个 32 位无符号整数。 必须设置为 0x00000000。

2.2.1.20 CDbColId

CDbColId 结构包含一列。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

eKind

GUID

...

...

...

ulId

vString(变量)

eKind:必须设置为表示 GUID 和 vValue 的内容的以下值之一。

含义
DBKIND_GUID_NAME 0x00000000 vString 包含一个属性名称。
DBKIND_GUID_PROPID 0x00000001 ulId 包含一个表示属性 ID的 4 字节整数。
DBKIND_PGUID_NAME 0x00000003 vString 包含一个属性名称。 此值的处理必须与 DBKIND_GUID_NAME 相同。
DBKIND_PGUID_PROPID 0x00000004 ulId 包含一个表示属性 ID的 4 字节整数。 此值必须与 DBKIND_GUID_PROPID 相同。

GUID:属性 GUID。

ulId:如果 eKind 为 DBKIND_GUID_PROPID 或 DBKIND_PGUID_PROPID,则该字段包含一个用于指定属性 ID 的无符号整数。 如果 eKind 为 DBKIND_GUID_NAME 或 DBKIND_PGUID_NAME,该字段包含一个无符号整数,用于指定 vString 字段中包含的 Unicode 字符数。

vString:表示属性名称的非 null 终止 Unicode 字符串。 除非 eKind 字段设置为 DBKIND_GUID_NAME 或 DBKIND_PGUID_NAME,否则必须将其省略。

2.2.1.21 CDbProp

CDbProp 结构包含一个属性。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

DBPROPID

DBPROPOPTIONS

DBPROPSTATUS

colid(变量)

vValue(变量)

DBPROPID:一个 32 位无符号整数,用于表示属性 ID。

DBPROPOPTIONS:必须设置为 0x00000000。

DBPROPSTATUS:必须设置为 0x00000000。

colid:第 2.2.1.20 部分中指定的 CDbColId 结构,用于表示该属性适用的列。

vValue:包含属性值的 CBaseStorageVariant。

2.2.1.21.1 属性

本部分详细介绍 CISP 使用的属性。 这些属性被分为三个属性集,在 CDbPropSet 结构的 guidPropertySet 字段中标识(第 2.2.1.22 部分)。

下表列出了属于 DBPROPSET_FSCIFRMWRK_EXT 属性集的属性。

含义
DBPROP_CI_CATALOG_NAME 0x00000002 指定要查询的一个或多个目录的名称。 值必须是 VT_LPWSTR 或 VT_VECTOR | VT_LPWSTR
DBPROP_CI_INCLUDE_SCOPES 0x00000003 指定要在查询中包含的一个或多个路径。 值必须是 VT_LPWSTR 或 VT_VECTOR | VT_LPWSTR。
DBPROP_CI_SCOPE_FLAGS 0x00000004 指定如何处理 DBPROP_CI_INCLUDE_SCOPES 属性指定的路径。 值必须是 VT_I4 或 VT_VECTOR | VT_I4。
DBPROP_CI_QUERY_TYPE 0x00000007 指定查询的类型。 CDbColId 必须设置为 DB_NULLID。

下表列出了 DBPROP_CI_SCOPE_FLAGS 属性的标志:

含义
QUERY_DEEP 0x01 如果设置,则表示结果中包括范围目录和所有子目录中的文件。 如果清除,则结果中只包括范围目录中的文件。 不得与 QUERY_DEEP 结合使用。
QUERY_VIRTUAL_PATH 0x02 如果设置,则表示范围是一个虚拟路径。 如果清除,表示范围是一个物理目录。

下表列出了 DBPROP_CI_QUERY_TYPE 属性的查询类型:

含义
CiNormal 0x00000000 一个常规查询。
CiVirtualRoots 0x00000001 查询请求提供目录虚拟根的列表。 此值需要管理权限。
CiProperties 0x00000003 查询请求索引服务支持的所有属性列表。
CiAdminOp 0x00000004 查询是一项管理操作。 此值需要管理权限。

下表列出了作为 DBPROPSET_QUERYEXT 属性集一部分的属性。

含义
DBPROP_USECONTENTINDEX 0x00000002 指定索引服务如何处理慢速查询。 值必须是 VT_BOOL。 如果为 TRUE,则服务器允许这些查询失败。
DBPROP_DEFERNONINDEXEDTRIMMING 0x00000003 指明索引服务是否要执行结果修整。 如果为 TRUE,则服务器将考虑以优化客户端响应时间的方式执行结果修整。 值必须是 VT_BOOL。
DBPROP_USEEXTENDEDDBTYPES 0x00000004 指明客户端是否支持 VT_VECTOR 数据类型。 如果为 TRUE,则客户端支持 VT_VECTOR;如果为 FALSE,则服务器将把 VT_VECTOR 数据类型转换为 VT_ARRAY 数据类型。 值必须是 VT_BOOL。
DBPROP_FIRSTROWS 0x00000007 指明要返回的行匹配项。 如果为 TRUE,服务器将返回第一组匹配行。 如果为 FALSE,则应返回最佳匹配行。 值必须是 VT_BOOL。

下表列出了属于 DBPROPSET_CIFRMWRKCORE_EXT 属性集的属性。

值 / DBPROPID 含义
DBPROP_MACHINE 0x00000002 指定要处理查询的计算机名称。 值必须是 VT_BSTR 或 VT_ARRAY | VT_BSTR。
DBPROP_CLIENT_CLSID 0x00000003 指定索引服务的连接常量。 该值必须是包含 0x2A4880706FD911D0A80800A0C906241A 的 VT_CLSID。

2.2.1.22 CDbPropSet

CDbPropSet 结构包含一组属性。 请注意,第一个字段的大小是固定的,但不能与包含该结构的消息开头的 4 字节倍数的偏移量对齐。 但 cProperties 字段就是这样对齐的,因此格式如下:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

guidPropertySet

...

...

...

...

_padding(变量)

cProperties

aProps(变量)

guidPropertySet:标识属性集的 GUID。 必须设置为与下列值之一相对应(以字符串表示形式显示)二进制形式,以标识 aProps 字段所含属性的属性集。

值 / GUID 名称
DBPROPSET_FSCIFRMWRK_EXT
{A9BD1526-6A80-11D0-8C9D-0020AF1D740E}
文件系统内容索引框架属性集
DBPROPSET_QUERYEXT
{A7AC77ED-F8D7-11CE-A798-0020F8008025}
查询扩展属性集
DBPROPSET_CIFRMWRKCORE_EXT
{AFAFACA5-B5D1-11D0-8C62-00C04FC2DB8D}
内容索引框架核心属性集

_padding:此字段长度必须为 0 到 3 字节。 此字段的长度必须使下面的字段从包含该结构的消息开头开始的偏移量是 4 字节的倍数。 如果该字段存在(即长度不为零),则其包含的值为任意值。 接收方必须忽略此字段的内容。

cProperties:一个 32 位无符号整数,包含 aProps 数组中的元素个数。

aProps:一个 CDbProp 结构数组,如第 0 部分所述,其中包含属性。 数组中的结构必须由 0 至 3 个填充字节分隔,从而使每个结构的起始偏移量是包含该数组的消息开头的 4 个字节的倍数。 如果存在填充字节,它们所包含的值是任意的。 接收方必须忽略填充字节的内容。

2.2.1.23 CPidMapper

CPidMapper 结构包含一个属性 ID 数组,用于指定要在行集中返回的属性。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

count

aPropSpec

...(变量)

count:一个 32 位无符号整数,包含 aPropSpec 数组中的元素个数。

aPropSpec:表示要返回的属性的 CFullPropSpec 结构数组。 数组中的结构必须由 0 至 3 个填充字节分隔,以便每个结构与消息开头对齐 4 个字节。 这种填充字节可以是任意值,收到时必须予以忽略。

2.2.1.24 CRowSeekAt

CRowSeekAt 结构包含用于在 CPMGetRowsIn 信息中检索行的偏移量。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_hRegion

_cskip

_bmkOffset

_hRegion:必须设置为 0x00000000,并且必须忽略。

_cskip:一个 32 位无符号整数,包含行集中要跳过的行数。

_bmkOffset:一个 32 位值,代表书签的句柄,表示在开始检索之前跳过 _cskip 中指定的行数的起始位置。

2.2.1.25 CRowSeekAtRatio

CRowSeekAtRatio 结构用于确定 CPMGetRowsIn 消息的检索起始点。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

CiTblChapt

_hRegion

_ulNumerator

_ulDenominator

CiTblChapt:一个 32 位无符号整数,表示要从中检索记录的行集章节。

_hRegion:必须设置为 0x00000000,并且必须忽略。

_ulNumerator:一个无符号 32 位整数,表示开始检索的章节行数比率的分子。

_ulDenominator:一个无符号 32 位整数,表示开始检索的章节行数比率的分母。 必须大于零。

2.2.1.26 CRowSeekByBookmark

CRowSeekByBookmark 结构用于确定从哪些书签开始为 CPMGetRowsIn 消息检索记录。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_hRegion

_cBookmarks

_maxRet

_cValidRet

_aBookmarks(变量)

_ascRet(变量)

_hRegion:必须设置为 0x00000000,并且必须忽略。

_cBookmarks:一个无符号 32 位整数,表示 _aBookmarks 数组中元素的个数。

_maxRet:一个无符号 32 位整数,表示 _ascRet 数组中的元素个数。

_cValidRet:一个无符号 32 位整数,表示 _ascRet 数组中有效元素的个数。 有效元素已在数组中定义,而无效元素未定义。

_aBookmarks:从 CPMGetRowsOut 消息中获取的书签句柄数组(每个句柄由 4 个字节表示)。

_ascRet:一个 HRESULT 值数组。 当 CRowSeekByBookMark 作为 CPMGetRowsIn 请求的一部分发送时,数组中的条目数必须等于 _cBookMarks。 客户端发送时,这些值必须设置为零,并且服务器必须忽略数组的内容。 在由服务器(作为 CPMGetRowsOut 消息的一部分)发送时,数组中的值表示每条记录的检索结果状态。

2.2.1.27 CRowSeekNext

CRowSeekNext 结构包含 CPMGetRowsIn 消息中要跳过的行数。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

CiTblChapt

_hRegion

_cskip

CiTblChapt:一个无符号 32 位整数,指定要从中检索记录的行集章节。

_hRegion:必须设置为 0x00000000,并且必须忽略。

_cskip:一个无符号 32 位整数,表示行集中要跳过的行数。

2.2.1.28 CRowsetProperties

CRowsetProperties 结构包含查询的配置信息。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_uBooleanOptions

_ulMaxOpenRows

_ulMemoryUsage

_cMaxResults

_cCmdTimeout

_uBooleanOptions:此字段的最小有效 3 位必须包含以下三个值之一:

含义
eSequential 0x00000001 游标只能向前移动。
eLocatable 0x00000003 游标可以移动到任何位置。
eScrollable 0x00000007 游标可以移动到任何位置,也可以从任何方向获取数据。

其余位可以是明确的,也可以设置为以下逻辑 OR 值的任意组合:

含义
eAsynchronous 0x00000008 客户端不会等待执行完成。
eFirstRows 0x00000080 返回遇到的第一行,而不是最佳匹配项。
eHoldRows 0x00000200 在客户端完成查询之前,服务器不得丢弃行。
eChaptered 0x00000800 行集支持章节。
eUseCI 0x00001000 只回答索引中的查询,而不回答文件系统中的查询。
eDeferTrimming 0x00002000 索引服务在删除结果时应考虑优化客户端的响应时间。

_ulMaxOpenRows:一个无符号 32 位整数。 必须设置为 0x00000000。 未使用并且必须忽略。

_ulMemoryUsage:一个无符号 32 位整数。 必须设置为 0x00000000。 未使用并且必须忽略。

_cMaxResults:一个 32 位无符号整数,指定要为查询返回的最大行数。

_cCmdTimeout:一个 32 位无符号整数,用于指定查询超时并自动终止的秒数,从查询开始在服务器上执行时开始计算。 0x00000000 的值表示查询不会超时。

2.2.1.29 CRowVariant

CRowVariant 结构包含存储在 CPMGetRowsOut 消息中的可变长度数据类型的固定大小部分。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

vType

reserved1

reserved2

偏移量(可选)

vType:类型指示符,表示 vValue 的类型。 它必须是第 2.2.1.1 部分中指定的 VARENUM 值之一。

reserved1:未使用。 此值可任意设置,并在收到时必须将其忽略。

reserved2:未使用。 此值可任意设置,并在收到时必须将其忽略。

偏移量:可变长度数据(如字符串)的偏移量。 如果使用 32 位偏移量,则必须是 32 位值(4 个字节长)(根据第 2.2.3.16 部分中的规则);如果使用 64 位偏移,则必须是 64 字节值(8 个字节长)。

2.2.1.30 CSortSet

CSortSet 结构包含查询的排序顺序。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

计数

sortArray(变量)

count:一个 32 位无符号整数,用于指定 sortArray 中元素的个数。

sortArray:一个描述查询结果排序顺序的 CSort 结构的数组。 数组中的结构必须由 0 至 3 个填充字节分隔,以便每个结构与消息开头对齐 4 个字节。 这种填充字节可以是任意值,收到时必须予以忽略。

2.2.1.31 CTableColumn

CTableColumn 结构包含 CPMSetBindingsIn 信息的一列

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

PropSpec

...(变量)

vType

ValueUsed

_padding1(可选)

ValueOffset(可选)

ValueSize(可选)

StatusUsed

_padding2(可选)

StatusOffset(可选)

LengthUsed

_padding3(可选)

LengthOffset(可选)

PropSpec:一个 CFullPropSpec 结构,如第 2.2.1.3 部分所述。

vType:指定列中包含的数据值的类型。 有关 vType 字段的值列表,请参阅第 2.2.1.1 节中的 vType 字段。

ValueUsed:一个必须设置为 0x01 或 0x00 的单字节字段。 如果设置为 0x01,该列将在固定大小的行内传输。 如果设置为 0x00,则列值将在缓冲区末尾的可变长度部分传输。

_padding1:一个必须在 ValueOffset 之前插入的单字节字段,如果没有该字段,ValueOffset 将不会从消息开头的偶数偏移量开始。 此字节可以是任意值,并且必须忽略。 如果 ValueUsed 设置为 0x00,则此字段必须不存在。

ValueOffset:一个无符号 2 字节整数,用于指定列值在行中的偏移量。 如果 ValueUsed 设置为 0x00,则此字段必须不存在。

ValueSize:一个无符号 2 字节整数,指定列值的大小(以字节为单位)。 如果 ValueUsed 设置为 0x00,则此字段必须不存在。

StatusUsed:一个必须设置为 0x01 或 0x00 的单字节字段。 如果设置为 0x01,列的状态将在行内传输。 如果设置为 0x00,列的状态将不会在行内传输。

_padding2:一个必须在 StatusOffset 之前插入的单字节字段,否则 StatusOffset 字段将不会从消息开头的偶数偏移量开始。 此字节可以是任意值,并且必须忽略。 如果 StatusUsed 设置为 0x00,则此字段必须不存在。

StatusOffset:一个无符号 2 字节整数,用于指定列状态在行中的偏移量。 如果 StatusUsed 设置为 0x00,则此字段必须不存在。

LengthUsed:一个必须设置为 0x01 或 0x00 的单字节字段。 如果设置为 0x01,列的长度将在行内传输。 如果为 0x00,则列的长度不得在行内传输。

_padding3:一个必须在 LengthOffset 之前插入的单字节字段,如果没有该字段,LengthOffset 将不会从消息开头的偶数偏移开始。 此字节可以是任意值,并且必须忽略。 如果 LengthUsed 设置为 0x00,则此字段必须不存在。

LengthOffset:一个无符号 2 字节整数,用于指定列长度在行中的偏移量。 如果 LengthUsed 设置为 0x00,则此字段必须不存在。

2.2.1.32 SERIALIZEDPROPERTYVALUE

SERIALIZEDPROPERTYVALUE 结构包含一个序列化值。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

dwType

rgb(变量)

dwType:第 2.2.1.1 部分中定义的变量类型之一,可与变量类型修饰符结合使用。 对于所有变量类型(与 VT_ARRAY 结合的变量类型除外),SERIALIZEDPROPERTYVALUE 的布局与第 2.2.1.1 部分规定的 CBaseStorageVariant 相同。 如果变量类型与 VT_ARRAY 类型修饰符结合使用,则在 CBaseStorageVariant 的 vValue 字段中使用第 2.2.1.2.1 部分中指定的 SAFEARRAY2 代替 SAFEARRAY。

rgb:序列化值。 有关 vValue 序列化的详细信息,请参阅第 2.2.1.1 部分。

2.2.2 消息标头

所有内容索引服务协议消息都有一个 16 字节的标头。

下图显示了内容索引服务协议消息标头格式。

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_msg

_status

_ulChecksum

_ulReserved2

_msg:一个 32 位整数,用于标识标头后面的消息类型。 下表列出了内容索引服务协议消息和为每条消息指定的整数值。 如表所示,某些值在表中标识了 2 条消息。 在这种情况下,可以通过消息流的方向来识别标头之后的消息。 如果方向是客户端到服务器,则会显示在消息名称后附加“In”的消息。 如果方向是服务器到客户端,则会显示在消息名称后附加“Out”的消息。

含义
0x000000C8 CPMConnectIn 或 CPMConnectOut
0x000000C9 CPMDisconnect
0x000000CA CPMCreateQueryIn 或 CPMCreateQueryOut
0x000000CB CPMFreeCursorIn 或 CPMFreeCursorOut
0x000000CC CPMGetRowsIn 或 CPMGetRowsOut
0x000000CD CPMRatioFinishedIn 或 CPMRatioFinishedOut
0x000000CE CPMCompareBmkIn 或 CPMCompareBmkOut
0x000000CF CPMGetApproximatePositionIn 或 CPMGetApproximatePositionOut
0x000000D0 CPMSetBindingsIn
0x000000D1 CPMGetNotify
0x000000D2 CPMSendNotifyOut
0x000000D7 CPMGetQueryStatusIn 或 CPMGetQueryStatusOut
0x000000D9 CPMCiStateInOut
0x000000E1 CPMForceMergeIn
0x000000E4 CPMFetchValueIn 或 CPMFetchValueOut
0x000000E6 CPMUpdateDocumentsIn
0x000000E7 CPMGetQueryStatusExIn 或 PMGetQueryStatusExOut
0x000000E8 CPMRestartPositionIn
0x000000E9 CPMStopAsynchIn
0x000000EC CPMSetCatStateIn 或 CPMSetCatStateOut

_status:HRESULT [MS-SYS],表示所请求操作的状态。

* *

Windows 行为: 客户端始终将 _status 字段设置为 0x00000000。

_ulChecksum:_ulChecksum 必须按照第 3.2.4 部分中的规定计算,以用于以下消息:

  • CPMConnectIn
  • CPMCreateQueryIn
  • CPMSetBindingsIn
  • CPMGetRowsIn
  • CPMFetchValueIn

对于所有其他消息,_ulChecksum 必须设置为 0x00000000。 客户端必须忽略 _ulChecksum 字段。

_ulReserved2:必须设置为 0,并被接收方忽略。

2.2.3 消息

2.2.3.1 CPMCiStateInOut

CPMCiStateInOut 消息包含有关索引服务状态的信息。 标头后面的 CPMCiStateInOut 消息的格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

cbStruct

cWordList

cPersistentIndex

cQueries

cDocuments

cFreshTest

dwMergeProgress

eState

cFilteredDocuments

cTotalDocuments

cPendingScans

dwIndexSize

cUniqueKeys

cSecQDocuments

dwPropCacheSize

cbStruct:一个 32 位无符号整数。 此消息的大小(不包括普通标头),以字节为单位。 必须设置为 0x0000003C。

cWordList:一个 32 位无符号整数,表示为最近索引的文档创建的初始索引计数。

cPersistentIndex:一个 32 位无符号整数,表示永久性索引的计数。

cQueries:一个 32 位无符号整数,表示正在运行的查询次数。

cDocuments:一个 32 位无符号整数,表示等待索引的文件总数。

cFreshTest:一个 32 位无符号整数,表示索引中包含未完全优化性能信息的唯一文档数量。

dwMergeProgress:一个无符号 32 位整数,如果当前正在进行优化,则指定当前索引全面优化的完成百分比。 必须小于或等于 100。

eState:由下表中定义的一个或多个 CI_STATE_* 常量给出的内容索引状态。

含义
CI_STATE_SHADOW_MERGE 0x00000001 索引服务正在优化部分索引,以减少内存使用量并提高查询性能。
CI_STATE_MASTER_MERGE 0x00000002 索引服务正在对所有索引进行全面优化。
CI_STATE_CONTENT_SCAN_REQUIRED 0x00000004 索引中的某些文件已经更改,索引服务需要确定哪些文件被添加、更改或删除。
CI_STATE_ANNEALING_MERGE 0x00000008 索引服务正在优化索引,以减少内存使用量并提高查询性能。 此流程比 CI_STATE_SHADOW_MERGE 值标识的流程更全面,但不如 CI_STATE_MASTER_MERGE 值指定的流程全面。 这些优化是针对具体实现的,因为它们取决于内部存储数据的方式;除了响应时间外,这些优化不会对协议产生任何影响。
CI_STATE_SCANNING 0x00000010 索引服务正在检查一个目录或一组目录,以查看自上次索引该目录以来是否有任何文件被添加、删除或更新。
CI_STATE_RECOVERING 0x00000020 该服务从上次保存的状态开始,正在恢复中。
CI_STATE_LOW_MEMORY 0x00000080 服务器的大多数虚拟内存正在使用中。
CI_STATE_HIGH_IO 0x00000100 服务器上的输入/输出 (I/O) 活动水平相对较高。
CI_STATE_MASTER_MERGE_PAUSED 0x00000200 所有索引正在进行的全面优化进程已暂停。 这仅供参考,不影响 CISP。
CI_STATE_READ_ONLY 0x00000400 索引服务中获取新文档以编制索引的部分已暂停。 这仅供参考,不影响 CISP。
CI_STATE_BATTERY_POWER 0x00000800 为了节省电池使用时间,索引服务中用于获取新文档索引的部分已经暂停,但仍会回复查询。 这仅供参考,不影响 CISP。
CI_STATE_USER_ACTIVE 0x00001000 由于用户(键盘或鼠标)活动频繁,索引服务中获取新文档以编制索引的部分已暂停,但仍会回复查询。 这仅供参考,不影响 CISP。
CI_STATE_STARTING 0x00002000 服务正在开始。 可以运行查询,但尚未启用扫描和通知功能。 这仅供参考,不影响 CISP。
CI_STATE_READING_USNS 0x00004000 该服务没有读取文件系统保存的日志来跟踪卷中文件或目录的更改,因此索引可能并非最新。

cFilteredDocuments:一个 32 位无符号整数,表示自开始编制内容索引以来已编制索引的文档数量。

cTotalDocuments:一个 32 位无符号整数,表示系统中的文件总数。

cPendingScans:一个 32 位无符号整数,表示待处理的高级索引操作数。 该值的含义取决于提供商的具体情况,但数字越大,则表示仍有更多索引。

Windows 行为:此值通常为零,除非索引刚开始或通知队列溢出后。

dwIndexSize:一个 32 位无符号整数,表示索引(不包括属性缓存)的大小(以兆字节为单位)。

cUniqueKeys:一个 32 位无符号整数,表示目录中唯一键的大致数量。

cSecQDocuments:一个 32 位无符号整数,表示索引服务因初始索引尝试失败而重新尝试索引的文档数量。

dwPropCacheSize:一个 32 位无符号整数,表示属性缓存的大小(以兆字节为单位)。

2.2.3.2 CPMSetCatStateIn

CPMSetCatStateIn 消息用于设置目录的状态。 标头之后的 CPMSetCatStateIn 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_partID

_dwNewState

_CatName(变量,可选)

_partID:必须设置为 0x00000001。

_dwNewState:必须设置为以下值之一,表示目录的新状态。

含义
CICAT_STOPPED 0x00000001 目录已停止。 这种状态意味着不会为新文件编制索引,也不会处理搜索查询。
CICAT_READONLY 0x00000002 目录为只读。 不会为新文件编制索引。
CICAT_WRITABLE 0x00000004 目录可写入。 可对新文件编制索引,并处理搜索查询。
CICAT_NO_QUERY 0x00000008 目录不可用于查询。
CICAT_GET_STATE 0x00000010 目录的状态不能更改,只能检索。
CICAT_ALL_OPENED 0x00000020 检查是否所有目录都已启动。 如果是这样,则 CPMSetCatStateOut 回复此消息时发送的 _dwOldState 字段将被报告为非零。

_CatName:要修改其状态的目录的名称。 名称必须是以 null 结尾的 Unicode 字符串。 如果 _dwNewState 设置为 CICAT_ALL_OPENED,则必须省略此字段。

2.2.3.3 CPMSetCatStateOut

CPMSetCatStateOut 消息是对包含目录旧状态的 CPMSetCatStateIn 消息的回复。 标头之后的 CPMSetCatStateOut 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_dwOldState

_dwOldState:以下值之一,表示目录的旧状态。

含义
CICAT_STOPPED 0x00000001 目录已停止。
CICAT_READONLY 0x00000002 目录为只读。
CICAT_WRITABLE 0x00000004 目录可写入。
CICAT_NO_QUERY 0x00000008 目录不可用于查询。

2.2.3.4 CPMUpdateDocumentsIn

CPMUpdateDocumentsIn 消息指示服务器为指定路径编制索引。

服务器将回复 CPMUpdateDocumentsOut 消息的消息标头,而消息标头的 _status 字段中包含请求的结果。

标头之后的 CPMUpdateDocumentsIn 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_flag(可选)

_fRootPath(可选)

RootPath(变量,可选)

_flag:要执行的更新类型。 客户端发送消息时必须包含此字段,而服务器发送消息时不得包含此字段。 此字段必须设置为以下值之一:

含义
UPD_INCREM 0x00000000 将执行增量更新。
UPD_FULL 0x00000001 将进行全面更新。
UPD_INIT 0x00000002 将执行新的初始化。

_fRootPath:一个布尔值,表示 RootPath 字段是否指定了要对其执行更新的路径。 客户端发送消息时必须包含此字段,而服务器发送消息时不得包含此字段。 此字段必须设置为 0x00000001 或 0x00000000。 如果设置为 0x00000001,则在 RootPath 中包含执行更新的路径。 如果设置为 0x00000000,则对所有索引路径执行更新。

RootPath:要更新的路径的名称。 客户端发送消息时必须包含此字段,而服务器发送消息时不得包含此字段。 名称必须是以 null 结尾的 Unicode 字符串。 如果 _fRootPath 设置为 0x00000000,则必须省略此字段。

2.2.3.5 CPMForceMergeIn

CPMForceMergeIn 消息请求服务器进行必要的维护,以提高查询性能。 服务器将回复 CPMForceMergeIn 消息的消息标头,并在 _status 字段中包含请求结果。

标头之后的 CPMForceMergeIn 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_partID(可选)

_partID:客户端发送消息时必须包含此字段,而服务器发送消息时不得包含此字段。 当此字段存在时,必须设置为 0x00000001。

2.2.3.6 CPMConnectIn

CPMConnectIn 消息开始客户端与服务器之间的会话。

标头之后的 CPMConnectIn 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_iClientVersion

_fClientIsRemote

_cbBlob1

_cbBlob2

_padding

...

...

MachineName

...(变量)

UserName

...(变量)

_paddingcPropSets(可选,变量)

cPropSets

PropertySet1(变量)

PropertySet2(变量)

_paddingExtPropset(可选,变量)

cExtPropSet

aPropertySets(变量)

_iClientVersion:一个 32 位整数,表示服务器是否要验证客户端发送的消息的消息标头的 _ulChecksum 字段中指定的校验和值。 如果 _iClientVersion 字段被设置为 0x00000008 或更大,服务器必须验证以下消息的 _ulChecksum 字段值:

  • CPMConnectIn
  • CPMCreateQueryIn
  • CPMFetchValueIn
  • CPMGetRowsIn
  • CPMSetBindingsIn

有关服务器如何验证客户端在 ulChecksum 字段中为上述消息指定的值的详细信息,请参阅第 3.2.5 部分。

如果该值大于 0x00000008,则假定客户端能够处理 CPMGetRowsOut 消息中的 64 位偏移量。 有关详细信息,请参阅第 2.2.3.16 部分。

Windows 行为:在 Windows 客户端上,iClientVersion 设置如下

含义
0x00000005 客户端 OS 为 Windows 2000。
0x00000008 客户端 OS 为 32 位 Windows XP 或 32 位 Windows Server 2003。
0x00010008 客户端 OS 为 64 位 Windows XP 或 64 位 Windows Server 2003。

_fClientIsRemote:一个布尔值,表示客户端是否运行在与服务器不同的机器上。 必须设置为 0x00000001。

_cbBlob1:一个 32 位无符号整数,表示 cPropSet、PropertySet1 和 PropertySet2 字段合并后的大小(以字节为单位)。

_cbBlob2:一个 32 位无符号整数,表示 cExPropSet 和 aPropertySet 字段合并后的大小(以字节为单位)。

_padding:可包含任意值12 个字节的填充,必须予以忽略。

MachineName:客户端的计算机名称。 名称字符串必须是一个以 null 结尾的数组,包括空结束符在内,长度小于 512 个 Unicode 字符。

UserName:一个字符串,表示运行调用此协议的应用程序的用户名。 与 MachineName 串联时,名称字符串必须是小于 512 个 Unicode 字符的以 null 结尾的数组。

_paddingcPropSets:此字段长度必须为 0 至 7 个字节。 字节数必须是使 cPropSets 字段的字节偏移量从包含该结构的消息开头算起的 8 的倍数。 字节的值可以是任意值,并且接收方必须予以忽略。

cPropSets:一个 32 位无符号整数,表示该字段后面的 CDbPropSet 结构的个数。 此值必须设置为 0x0000002。

PropertySet1:一个 CDbPropSet 结构,其 guidPropertySet 包含 DBPROPSET_FSCIFRMWRK_EXT(请参阅第 2.2.1.22 部分)。

PropertySet1:一个 CDbPropSet 结构,其 guidPropertySet 包含 DBPROPSET_CIFRMWRKCORE_EXT(请参阅第 2.2.1.22 部分)。

_PaddingExtPropset:此字段长度必须为 0 至 7 个字节。 字节数必须是使 cExtPropSets 字段的字节偏移量从包含该结构的消息开头算起的 8 的倍数。 字节的值可以是任意值,并且接收方必须予以忽略。

cExtPropSet:一个 32 位无符号整数,表示该字段后面的 CDbPropSet 结构的个数。

aPropertySets:一个指定其他属性的 CDbPropSet 结构的数组。 此数组中的元素数量必须等于 cExtPropSet。

2.2.3.7 CPMConnectOut

CPMConnectOut 消息包含对 CPMConnectIn 消息的响应。

标头之后的 CPMConnectOut 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_serverVersion

_reserved(变量)

_serverVersion

一个 32 位整数,表示服务器是否支持 64 位偏移量*。*有关详细信息,请参阅第 2.2.3.16 部分。

含义
0x00000007 服务器只能发送 32 位偏移量。
0x00010007 服务器可发送 32 或 64 位偏移量。

_reserved:已保留。 服务器可以发送任意数量的任意值,而客户端必须忽略这些值(如果存在)。

2.2.3.8 CPMCreateQueryIn

CPMCreateQueryIn 消息会创建一个新的查询。 标头之后的 CPMCreateQueryIn 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

大小

CColumnSetPresent

ColumnSet(可选)

...(变量)

CRestrictionPresent。

Restriction(可选)

...(变量)

CSortSetPresent

SortSet(可选)

...(变量)

CCategorizationSetPresent

CategorizationSet(可选)

...(变量)

RowSetProperties

...

...

...

...

PidMapper(变量)

Size:一个 32 位无符号整数,表示从该字段开始到消息末尾的字节数。

CColumnSetPresent:一个表示 ColumnSet 字段是否存在的字节字段。 此字段必须设置为 0x01 或 0x00。 如果设置为 0x01,则 CColumnSet 字段必须存在。 如果设置为 0x00,则它必须不存在。

ColumnSet:一个 CColumnSet 结构,其中包含要返回 CPidMapper 属性的列编号。

restrictionPresent:一个表示 Restriction 字段是否存在的字节字段。 如果设置为任何非零值,则必须存在 Restriction 字段。 如果设置为 0x00,则 Restriction 必须不存在。

Restriction:一个包含查询命令树的 CRestriction 结构。

CSortSetPresent:一个表示 SortSet 字段是否存在的字节字段。 如果设置为任何非零值,则必须存在 SortSet 字段。 如果设置为 0x00,则 SortSet 必须不存在。

SortSet:一个表示查询的排序顺序的 CSortSet 结构。

CCategorizationSetPresent:一个表示 CCategorizationSet 字段是否存在的字节字段。 如果设置为任何非零值,则必须存在 CCategorizationSet 字段。 如果设置为 0x00,则 CCategorizationSet 必须不存在。

CCategorizationSet:一个包含查询组的 CCategorizationSet 结构。

RowSetProperties:一个为查询提供配置信息的 CRowsetProperties 结构。

PidMapper:一个包含要在行集中返回的属性的 CPidMapper 结构。

2.2.3.9 CPMCreateQueryOut

CPMCreateQueryOut 消息包含对 CPMCreateQueryIn 消息的响应。

标头之后的 CPMCreateQueryOut 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_fTrueSequential

_fWorkIdUnique

aCursors

_fTrueSequential:一个供参考的布尔值,表示查询是否有望更快地提供结果。 当 CPMCreateQueryIn 中提供的查询设置为 0x00000001 时,服务器使用索引的方式可能会加快查询结果的提供速度。 当设置为 0x00000000 时,提供查询结果的延迟时间会更长。 不得设置为任何其他值。

_fWorkIdUnique:一个布尔值,表示游标指向的文档标识符在整个查询结果中是否唯一。 如果设置为 0x00000001,则标识符是唯一的。 如果设置为 0x00000000,则它们在整个行集中都是唯一的。

aCursors:一个表示游标句柄的 32 位无符号整数数组,其元素个数等于 CPMCreateQueryIn 信息的 CategorizationSet 字段中的类别数。

2.2.3.10 CPMGetQueryStatusIn

CPMGetQueryStatusIn 消息请求查询的状态。 标头之后的 CPMGetQueryStatusIn 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_hCursor

_hCursor:一个 32 位无符号整数,表示 CPMCreateQueryOut 消息中的句柄,用于识别要检索状态信息的查询。

2.2.3.11 CPMGetQueryStatusOut

CPMGetQueryStatusOut 消息会用查询状态回复 CPMGetQueryStatusIn 消息。 标头之后的 CPMGetQueryStatusOut 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_Status

_Status:由下表中定义的值组成的位掩码,用于描述查询。

下表列出了通过对 _Status 与 0x00000007 进行位和运算得到的 STAT_* 值。 结果必须是以下之一:

返回的常量 含义
STAT_BUSY 0x00000000 异步查询仍在运行中。
STAT_ERROR 0x00000001 查询处于错误的状态。
STAT_DONE 0x00000002 查询完成。
STAT_REFRESH 0x00000003 查询已完成,但更新导致了额外的查询计算。

下表列出了可独立设置的其他 STAT_* 位。

返回的常量 含义
STAT_NOISE_WORDS 0x00000010 在内容查询中用通配符代替了干扰词。
STAT_CONTENT_OUT_OF_DATE 0x00000020 查询结果可能不正确,因为查询涉及已修改但未编制索引的文件。
STAT_REFRESH_INCOMPLETE 0x00000040 查询结果可能不正确,因为查询涉及修改和重新编制索引的文件,而这些文件的内容并未包括在内。
STAT_CONTENT_QUERY_INCOMPLETE 0x00000080 内容查询过于复杂,难以完成,或需要枚举而不是使用内容索引。
STAT_TIME_LIMIT_EXCEEDED 0x00000100 查询结果可能不正确,因为查询执行时间已达到最大允许时间。

2.2.3.12 CPMGetQueryStatusExIn

CPMGetQueryStatusExIn 消息请求查询的状态和其他信息,如已编制索引的文档数、有待编制索引的文档数等。 标头之后的 CPMGetQueryStatusExIn 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_hCursor

_bmk

_hCursor:一个 32 位值,表示 CPMCreateQueryOut 消息中的句柄,用于识别要检索状态信息的查询。

_bmk:一个 32 位值,表示应检索其位置的书签的句柄。

2.2.3.13 CPMGetQueryStatusExOut

CPMGetQueryStatusExOut 消息回复 CPMGetQueryStatusExIn 消息,其中包含查询状态和其他状态信息,如下图所示。 标头之后的 CPMGetQueryStatusExOut 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_Status

_cFilteredDocuments

_cDocumentsToFilter

_dwRatioFinishedDenominator

_dwRatioFinishedNumerator

_iRowBmk

_cRowsTotal

_Status:第 2.2.3.11 部分中指定的 STAT_* 值之一。

_cFilteredDocuments:一个 32 位无符号整数,表示已编制索引的文档数量

_cDocumentsToFilter:一个 32 位无符号整数,表示仍有待编制索引的文档数量。

_dwRatioFinishedDenominator:一个 32 位无符号整数,表示查询已完成处理的文档比例的分母。

_dwRatioFinishedNumerator:一个 32 位无符号整数,表示查询已完成处理的文档比例的分子。

_iRowBmk:一个 32 位无符号整数,以行为单位表示书签在行集中的大致位置。

_cRowsTotal:一个 32 位无符号整数,用于指定行集中的总行数。

2.2.3.14 CPMSetBindingsIn

CPMSetBindingsIn 消息请求会将列绑定到行集中。 服务器将使用 CPMBindingsIn 消息的标头部分回复 CPMSetBindingsIn 请求消息,并在 _status 字段中包含请求结果。 标头之后的 CPMSetBindingsIn 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_hCursor(可选)

_cbRow(可选)

_cbBindingDesc(可选)

_dummy(可选)

cColumns(可选)

aColumns(变量,可选)

_hCursor:一个 32 位值,表示 CPMCreateQueryOut 消息中的句柄,该句柄用于标识要设置绑定的行。 客户端发送消息时必须包含此字段,而服务器发送消息时不得包含此字段。

_cbRow:一个 32 位无符号整数,表示一行的大小(以字节为单位)。 客户端发送消息时必须包含此字段,而服务器发送消息时不得包含此字段。

_cbBindingDesc:一个 32 位无符号整数,表示 _dummy 字段后面字段的长度(以字节为单位)。 客户端发送消息时必须包含此字段,而服务器发送消息时不得包含此字段。

_dummy:此字段未使用,必须忽略。 可将其设为任意值。 客户端发送消息时必须包含此字段,而服务器发送消息时不得包含此字段。

cColumns:一个 32 位无符号整数,表示 aColumns 数组中元素的个数。 客户端发送消息时必须包含此字段,而服务器发送消息时不得包含此字段。

aColumns:一个描述行集中某一行列的 CTableColumn 结构的数组。 客户端发送消息时必须包含此字段,而服务器发送消息时不得包含此字段。 数组中的结构必须由 0 至 3 个填充字节分隔,以便每个结构与消息开头对齐 4 个字节。 这种填充字节可以是任意值,收到时必须予以忽略。

2.2.3.15 CPMGetRowsIn

CPMGetRowsIn 消息会从查询请求行。 标头后面的 CPMGetRowsIn 消息的格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_hCursor

_cRowsToTransfer

_cbRowWidth

_cbSeek

_cbReserved

_cbReadBuffer

_ulClientBase

_fBwdFetch

eType

_chapt

SeekDescription

...

...(变量)

_hCursor:一个 32 位值,表示 CPMCreateQueryOut 消息中的句柄,用于识别要检索行的查询。

_cRowsToTransfer:一个 32 位无符号整数,表示客户端希望收到的响应此消息的最大行数。

_cbRowWidth:一个 32 位无符号整数,表示行的长度(以字节为单位)。

_cbSeek:一个 32 位无符号整数,表示以 eType 开头的消息的大小。

_cbReserved:一个 32 位无符号整数,表示 CPMGetRowsOut 消息(不含 Rows 和 SeekDescriptions 字段)的大小(以字节为单位)。 此字段中的值与 _cbSeek 字段的值相加,然后用于计算 CPMGetRowsOut 消息中行字段的偏移量。

_cbReadBuffer:一个 32 位无符号整数,必须设置为 _cbRowWidth 值的最大值或 _cRowsToTransfer 值的 1000 倍,四舍五入为最接近的 512 字节倍数。 该值不得超过 0x00004000。

_ulClientBase:一个 32 位无符号整数,表示在行缓冲区中计算指针时使用的基准值。 如果使用的是 64 位偏移量,那么消息标头的 reserved2 字段将用作 64 位值的高 32 位,而 _ulClientBase 则用作低 32 位。 有关详细信息,请参阅第 2.2.3.16 部分。

_fBwdFetch:一个 32 位无符号整数,表示获取行的顺序。 如果设置为 0x00000001,则按相反顺序获取行。 如果设置为 0x00000000,则按正向顺序获取行。 不得设置为任何其他值。

eType:一个 32 位无符号整数,包含以下值之一,用于指示要执行的操作类型。

含义
eRowSeekNext 0x00000001 SeekDescription 包含一个 CRowSeekNext 结构。
eRowSeekAt 0x00000002 SeekDescription 包含一个 CRowSeekAt 结构。
eRowSeekAtRatio 0x00000003 SeekDescription 包含一个 CRowSeekAtRatio 结构。
eRowSeekByBookmark 0x00000004 SeekDescription 包含一个 CRowSeekByBookmark 结构。

_chapt:一个表示行集章节句柄的 32 位值。

SeekDescription:此字段必须包含 eType 值所指示类型的结构。

2.2.3.16 CPMGetRowsOut

CPMGetRowsOut 消息使用查询行回复 CPMGetRowsIn 消息。 服务器必须在 Rows 字段中设置可变长度数据类型的偏移量的格式,如下所示:

  • 客户端表示它是一个 32 位系统(在 CPMConnectIn 的 iClientVersion 字段中为 0x00000008 或更小):偏移量为 32 位整数。
  • 客户端表示它是一个 64 位系统(在 CPMConnectIn 中 _iClientVersion > 0x00000008),而服务器表示它是一个 32 位系统(在 CPMConnectOut 中 _serverVersion 设置为 0x00000007):偏移量为 32 位整数
  • 客户端表示它是一个 64 位系统(在 CPMConnectIn 中 _iClientVersion > 0x00000008),而服务器表示它是一个 64 位系统(在 CPMConnectOut 中 _serverVersion 设置为 0x00010007):偏移量为 64 位整数

标头后面的 CPMGetRowsOut 消息的格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_cRowsReturned

eType

_chapt

SeekDescription(可选,变量)

...

...

paddingRows(可选,变量)

“行”

_cRowsReturned:一个 32 位无符号整数,表示行中返回的行数。

eType:一个 32 位无符号整数,包含以下值之一,用于指示要执行的 rowseek 操作类型

含义
eRowsSeekNone 0x00000000 无 SeekDescription,忽略 SeekDescription 字段。
eRowSeekNext 0x00000001 SeekDescription 包含一个 CRowSeekNext 结构。
eRowSeekAt 0x00000002 SeekDescription 包含一个 CRowSeekAt 结构。
eRowSeekAtRatio 0x00000003 SeekDescription 包含一个 CRowSeekAtRatio 结构。
eRowSeekByBookmark 0x00000004 SeekDescription 包含一个 CRowSeekByBookmark 结构。

_chapt:一个表示行集章节句柄的 32 位值。

SeekDescription:此字段必须包含 eType 字段所指示类型的结构。

paddingRows:此字段必须有足够的长度(0 至 _cbReserved-1 个字节),以便将 Rows 字段填充到从消息开头开始的 _cbReserved 偏移量,其中 _cbReserved 是 CPMGetRowsIn 消息中的值。 此字段中使用的填充字节可以是任意值。 接收方必须忽略此字段。

Rows:行数据,格式为最新 CPMSetBindingsIn 消息中的列信息规定的格式。 行必须按正向顺序存储(例如,第 1 行在第 2 行之前)。

固定大小的列必须存储在最新 CPMSetBindingsIn 消息指定的偏移量位置。

大小可变的列(如字符串)必须按以下方式存储:

  • 变量数据本身(如字符串)按降序存储在缓冲区末端附近(如第 1 行的所有变量数据集合在末端,第 2 行最靠近,等等)。
  • 固定大小的区域(位于行缓冲区的开头)必须包含每一列的 CRowVariant,并存储在最近 CPMSetBindingsIn 消息中指定的偏移量位置。 vType 必须包含数据类型(例如:VT_LPWSTR)。 如果根据本部分开头的规则确定使用 32 位偏移量,那么 CRowVariant 中的 Offset 字段必须包含一个 32 位值,即从 CPMGetRowsOut 消息开始的变量数据偏移量,加上最近 CPMGetRowsIn 消息中指定的 _ulClientBase 值。 如果使用的是 64 位偏移量,那么 CRowVariant 中的 Offset 字段必须包含一个 64 位值,该值是从 CPMGetRowsOut 消息开头的偏移量加到一个 64 位值上,而该 64 位值由 _ulClientBase 作为低 32 位和 _ulReserved2 作为高 32 位组成。

例如,如果 CPMSetBindingsIn 消息指定了两列大小 (VT_I4) 和 Title (VT_LPWSTR),而 CPMGetRowsIn 中的 _ulClientBase 为 0x10000,则会出现如下两行。 标为灰色的部分是缓冲区的固定长度部分。

cpmsetbindingsin 消息示例

2.2.3.17 CPMRatioFinishedIn

CPMRatioFinishedIn 消息请求查询的完成百分比。 标头之后的 CPMRatioFinishedIn 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_hCursor

_fQuick

_hCursor:CPMCreateQueryOut 消息中的句柄,用于标识要请求完成信息的查询。

_fQuick:必须设置为 0x00000001。 未使用并且必须被服务器忽略。

2.2.3.18 CPMRatioFinishedOut

CPMRatioFinishedOut 消息使用查询的完成率来回复 CPMRatioFinishedIn 消息。 标头之后的 CPMRatioFinishedOut 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_ ulNumerator

_ulDenominator

_cRows

_fNewRows

_ulNumerator:一个 32 位无符号整数,表示以行为单位的完成率分子。

_ulDenominator:一个 32 位无符号整数,表示以行为单位的完成比的分母。 必须大于零。

_cRows:一个 32 位无符号整数,表示查询的总行数。

_fNewRows:一个布尔值,表示是否有可用的新行。 值为 0x00000001 表示行集中有新的行。 值为 0x00000000 表示行集不包含任何新的行。 此字段不得设置为任何其他值。

2.2.3.19 CPMFetchValueIn

CPMFetchValueIn 消息请求的属性值过大,无法在行集中返回。 根据第 3.2.4.2.5 部分的规定,将重复发送此消息以检索属性的所有字节,并更新 _cbSoFar,直到 CPMFetchValueOut 消息的 _fMoreExists 字段被设置为 FALSE

标头之后的 CPMFetchValueIn 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_wid

_cbSoFar

_cbPropSpec

_cbChunk

PropSpec(变量)

...

_padding(变量)

_wid:一个 32 位无符号整数,包含文档 ID 的相关信息,而该 ID 可用于识别应获取属性的文档。

_cbSoFar:一个包含此属性之前传输的字节数的 32 位无符号整数。 必须在第一条消息中设置为 0x00000000。

_cbPropSpec:一个包含 PropSpec 字段的大小(以字节为单位)的 32 位无符号整数。

_cbChunk:一个 32 位无符号整数,包含发送方在 CPMFetchValueOut 消息中可接受的最大字节数。

Windows行为:对于所有版本的 Windows,此字段均设置为 0x00004000。

PropSpec:一个 CFullPropSpec 结构,指定要检索的属性。

_padding:此字段必须具有必要的长度(0 至 3 个字节),以便将消息填充为长度为 4 个字节的倍数。 填充字节的值可以是任意值。 接收方必须忽略此字段。

2.2.3.20 CPMFetchValueOut

CPMFetchValueOut 消息会回复 CPMFetchValueIn 消息,其中包含先前查询的属性值。 根据第 3.1.5.2.8 部分的规定,此消息在每个 CPMFetchValueIn 消息后发送,直到属性的所有字节均已传输完毕。

标头之后的 CPMFetchValueOut 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_cbValue

_fMoreExists

_fValueExists

vType

vValue(变量)

_cbValue:一个包含 vValue 中的总大小(以字节为单位)的 32 位无符号整数。

_fMoreExists:一个布尔值,表示是否有其他 CPMFetchValueOut 消息可用。 如果设置为 0x00000001,则会出现额外的 CPMFetchValueOut 消息。 如果设置为 0x00000000,则没有其他 CPMFetchValueOut 消息可用。

_fValueExists:一个表示属性是否存在值的布尔值。 如果设置为 0x00000001,则表示存在属性值。 如果设置为 0x00000000,则表示不存在该属性的值。

vType:VARENUM 枚举中描述属性类型的值,有关详细信息,请参阅第 2.2.1.1 部分。

vValue:一个字节数组的一部分,其中包含第 2.2.1.32 部分中规定的 SERIALIZEDPROPERTYVALUE 结构,该部分的起始偏移量为 CPMFetchValueIn 中的_cbSoFar 值。 如果 _fMoreExists 设置为 0x00000001,则 _cbValue 字段表示的部分长度必须等于 CPMFetchValueIn 中 _cbChunk 的值,否则必须小于或等于 _cbChunk 的值。

2.2.3.21 CPMGetNotify

CPMGetNotify 消息请求客户端希望接收行集的变更通知。

消息不得包含正文;只能发送第 2.2.2 部分规定的消息标头。

2.2.3.22 CPMSendNotifyOut

CPMSendNotifyOut 消息会通知客户端查询结果发生变化。

只有在发生更改时才会发送此信息。 标头之后的 CPMSendNotifyOut 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_watchNotify

_watchNotify:查询的更改。 它必须是以下值之一:

含义
DBWATCHNOTIFY_ROWSCHANGED 0x00000001 查询行集中的行数已更改。
DBWATCHNOTIFY_QUERYDONE 0x00000002 查询已完成。
DBWATCHNOTIFY_QUERYREEXECUTED 0x00000003 查询已重新执行。

2.2.3.23 CPMGetApproximatePositionIn

CPMGetApproximatePositionIn 消息请求书签在章节中的大致位置。 标头之后的 CPMGetApproximatePositionIn 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_hCursor

_chapt

_bmk

_hCursor:一个 32 位值,表示从 CPMCreateQueryOut 获取的包含书签的行集的查询游标。

_chapt:一个 32 位值,表示包含书签的章节的句柄。

_bmk:一个 32 位值,表示要为其检索近似位置的书签的句柄。

2.2.3.24 CPMGetApproximatePositionOut

CPMGetApproximatePositionOut 消息回复 CPMGetApproximatePositionIn 消息,描述书签在章节中的大致位置。 标头之后的 CPMGetApproximatePositionOut 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_numerator

_denominator

_numerator:一个包含行集中书签行号的 32 位无符号整数。 如果没有行,此字段必须设置为 0x00000000。

_denominator:一个包含行集中的行数的 32 位无符号整数。

2.2.3.25 CPMCompareBmkIn

CPMCompareBmkIn 消息要求比较一个章节中的两个书签。

标头之后的 CPMCompareBmkIn 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_hCursor

_chapt

_bmkFirst

_bmkSecond

_hCursor:一个 32 位值,表示 CPMCreateQueryOut 消息中包含书签的行集的句柄。

_chapt:一个 32 位值,表示包含要比较的书签的章节句柄。

_bmkFirst:一个 32 位值,表示要比较的第一个书签的句柄。

_bmkSecond:一个 32 位值,表示要比较的第二个书签的句柄。

2.2.3.26 CPMCompareBmkOut

CPMCompareBmkOut 消息答复 CPMCompareBmkIn 消息,并比较章节中的两个书签。 标头之后的 CPMCompareBmkOut 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_dwComparison

_dwComparison:以下值之一,表示两个书签在章节中的相对位置。

含义
DBCOMPARE_LT 0x00000000 第一个书签的位置在第二个书签之前。
DBCOMPARE_EQ 0x00000001 第一个书签的位置与第二个相同。
DBCOMPARE_GT 0x00000002 第一个书签位于第二个书签之后。
DBCOMPARE_NE 0x00000003 第一个书签与第二个书签的位置不同。
DBCOMPARE_NOTCOMPARABLE 0x00000004 第一个书签与第二个书签无法对比。

2.2.3.27 CPMRestartPositionIn

CPMRestartPositionIn 消息会将游标的提取位置移动到章节开头。 如第 3.1.5.2.12 部分所述,服务器将使用相同的消息进行回复,并在 CISP 头的 _status 字段中包含请求结果。

标头之后的 CPMRestartPositionIn 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_hCursor(可选)

_chapt(可选)

_hCursor:一个 32 位值,表示从 CPMCreateQueryOut 消息中获取的句柄,该句柄用于标识要重新启动位置的查询。 客户端发送消息时必须包含此字段,而服务器发送消息时不得包含此字段。

_chapt:一个 32 位值,表示要从中检索行的章节的句柄。 客户端发送消息时必须包含此字段,而服务器发送消息时不得包含此字段。

2.2.3.28 CPMFreeCursorIn

CPMFreeCursorIn 消息请求释放游标。 标头之后的 CPMFreeCursorIn 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_hCursor

_hCursor:一个 32 位值,表示 CPMCreateQueryOut 消息中要释放的游标句柄。

2.2.3.29 CPMFreeCursorOut

CPMFreeCursorOut 消息会回复 CPMFreeCursorIn 消息,其中包含释放游标的结果。 标头之后的 CPMFreeCursorOut 消息格式为:

0

1

2

3

4

5

6

7

8

9

1
0

1

2

3

4

5

6

7

8

9

2
0

1

2

3

4

5

6

7

8

9

3
0

1

_cCursorsRemaining

_cCursorsRemaining:一个 32 位无符号整数,表示查询中仍在使用的游标数。

2.2.3.30 CPMDisconnect

CPMDisconnect 消息结束与服务器的连接

消息不得包含正文;只能发送第 2.2.2 部分规定的消息标头。

2.2.4 错误

所有内容索引服务协议消息在成功时必须返回 0x00000000,否则将返回 32 位非零错误代码,该代码可以是 HRESULT 或 NTSTATUS 值(请参阅第 1.8 部分)。 如果缓冲区太小,无法容纳结果,则必须返回 STATUS_INSUFFICIENT_RESOURCES (0xC0000009A) 状态代码,并使用更大的缓冲区重试失败的操作。

所有其他错误值也必须进行同样的处理。

(请注意,目前 HRESULT 和 NTSTATUS 的编号空间不会重叠,除非值的含义完全相同,但即使将来发生冲突,只要 STATUS_INSUFFICIENT_RESOURCES 的值保持唯一,也不会造成任何协议问题,因为所有其他错误值的处理方法均相同。)

3 协议详细信息

用于远程查询索引服务目录的 CISP 消息请求不需要任何特定序列。 建议上层遵守有意义的消息序列,因为如果收到的消息不在此序列内或消息数据无效,服务器将作出错误响应。 有些消息还依赖于上层提供在消息序列中较早收到的有效数据。

下图显示了从客户端到远程计算机进行简单查询的典型消息序列。

简单查询的消息序列

上图中显示的消息是用于查询远程索引服务目录的所有 CISP 消息的子集。

3.1 服务器详细信息

3.1.1 抽象化数据模型

下一部分说明了 CISP 服务器维护的数据和状态。 此处提供的数据是为了便于解释协议的行为方式。 只要外部行为与本文档中描述的一致,本部分就并不强制要求实现者遵守此模型。

实现 CISP 的索引服务必须维护以下抽象数据元素:

  • 连接到服务器的客户端列表

  • 有关每个客户端的信息,其中包括:

    • 客户端版本(如第 2.2.3.6 部分所述 CPMConnectIn 消息所示)
    • 与客户端关联的目录(通过 CPMConnectIn 消息)
    • 第 2.2.1.21.1 部分中所规定的其他客户端属性。
    • 客户端的搜索查询
    • 查询的游标句柄列表,以及每个句柄在结果集中的位置。
    • 当前绑定集
    • 查询的当前状态,其中包括(针对每个游标):
      • 查询结果中的行数
      • 查询完成度的分子和分母
      • 此游标最近的 CPMRatioFinishedOut 消息所报告的最后行数
      • 服务器是否监控查询结果的变化,如果受到监控,自 CPMSendNotifyOut 上次向客户端报告后,查询结果发生了哪些变化
      • 由此查询提供给客户端的章节句柄列表。
      • 每个游标的书签句柄列表,由此查询提供给客户端。
  • 索引服务的当前状态,可能是“未初始化”、“正在运行”或“正在关闭”。 请注意,服务器大部分时间都处于“正在运行”状态。 以下是服务器的状态计算机图:

    索引服务服务器的状态计算机图

  • 每个目录的信息:索引的文档数、索引大小、唯一键数等(完整列表请参阅第 2.2.3.1 部分)、状态(与第 2.2.3.2 部分中 dwNewState 的值相对应)。

  • 第 2.2.1.3 部分中讨论的每种支持语言的单词变体数据库。

3.1.2 计时器

无需协议计时器。

3.1.3 初始化

在初始化时,服务器必须将其状态设置为“未初始化”,并开始侦听第 1.9 部分中指定的管道上的消息。 在进行任何其他内部初始化后,它必须转换为“正在运行”状态。

3.1.4 较高层触发的事件

无。

3.1.5 消息处理和排序规则

在处理客户端发送的消息过程中出现错误时,服务器必须向客户端报告错误,具体如下:

  • 停止处理客户端发送的消息
  • 仅回复客户端发送的消息的消息标头,从而让 _msg 字段保持不变。
  • 将 _status 字段设置为错误代码值。

当消息到达时,服务器必须检查 _msg 字段值是否为已知类型(请参阅第 2.2.2 部分)。 如果类型未知,则必须报告 STATUS_INVALID_PARAMETER (0xC000000D) 错误。

如果消息类型是以下之一,则服务器必须验证 _ulChecksum 字段值:

  • CPMConnectIn (0x000000C8)
  • CPMCreateQueryIn (0x000000CA)
  • CPMSetBindingsIn (0x000000D0)
  • CPMGetRowsIn (0x000000CC)
  • CPMFetchValueIn (0x000000E4)

要验证 _ulChecksum 字段值,服务器必须检查客户端在 CPMConnectIn 消息的 _iClientVersion 字段中指定的值。

如果 _iClientVersion 字段未设置为 0x00000008,且 _ulChecksum 字段未设置为 0x00000000,则服务器必须报告 STATUS_INVALID_PARAMETER (0xC000000D) 错误。 对于将 _iClientVersion 字段设置为小于 0x00000008 的值的客户端,服务器不得验证 _ulChecksum 字段。

如果 _iClientVersion 字段值为 0x00000008 或更大,则服务器必须验证 _ulChecksum 字段是按照第 3.2.4 部分的规定计算得出的。 如果 _ulChecksum 值无效,则服务器必须报告 STATUS_INVALID_PARAMETER (0xC000000D) 错误。

接下来,服务器会检查它处于哪种状态。 如果其状态为“未初始化”,则服务器必须报告 CI_E_NOT_INITIALIZED (0x8004180B) 错误。 如果状态为“正在关闭”,则服务器必须报告 CI_E_SHUTDOWN (0x80041812) 错误。

一旦确定标头有效且服务器处于“正在运行”状态,就必须按照下面各小节的规定进一步处理特定消息。

3.1.5.1 远程索引服务目录管理

3.1.5.1.1 接收 CPMCiStateInOut 请求

当服务器收到客户端的 CPMCIStateInOut 消息请求时,服务器必须首先检查客户端是否在已连接客户端列表中。 如果客户端不在列表中,则服务器必须报告 STATUS_INVALID_PARAMETER (0xC000000D) 错误。 否则,必须使用用 CPMCIStateInOut 消息来响应客户端,并按照第 2.2.3.1 部分的规定填写客户端相关目录的信息。

3.1.5.1.2 接收 CPMSetCatStateIn 请求

当服务器收到来自客户端的 CPMSetCatStateIn 消息请求时,服务器必须执行以下操作:

  • 检查客户端是否具有管理访问权限。 如果客户端没有管理访问权限,则服务器必须报告 STATUS_ACCESS_DENIED (0xC0000022) 错误。
  • 如果 _dwNewState 不等于 CICAT_ALL_OPENED,则按照 _dwNewState 字段的指定更改 CatName 字段中指定的目录状态。 有关更多详细信息,请参阅第 2.2.3.2 部分。 如果服务器找不到 CatName 字段中指定名称的目录,则服务器必须返回 STATUS_INVALID_PARAMETER (0xC000000D) 错误。
  • 使用 CPMSetCatStateOut 消息响应客户端,其中 _dwOldState 必须设置为目录的先前状态。 如果 _dwNewState 等于 CICAT_ALL_OPENED,则服务器必须检查所有目录的状态,如果所有目录都已启动,则必须将 _dwOldState 设置为 0x00000001,否则将 _dwOldState 设置为 0x00000000。

3.1.5.1.3 接收 CPMUpdateDocumentsIn 请求

当服务器收到 CPMUpdateDocumentsIn 消息请求时,服务器必须执行以下操作:

  • 检查客户端是否在已连接客户端列表中(其具有已关联的目录)。 如果客户端不在列表中,则服务器必须报告 STATUS_INVALID_PARAMETER (0xC000000D) 错误。
  • 检查客户端是否具有管理访问权限。 如果客户端没有服务器的管理访问权限,则服务器必须报告 STATUS_ACCESS_DENIED (0xC0000022) 错误。
  • 根据 CPMUpdateDocumentsIn 消息中 _flag 字段的值,开始对客户端指定的路径编制索引,进行全面或增量扫描。 如果该路径以前未编制索引,则必须将其添加到编入索引的位置集合中,并执行全面扫描。 如果指定了 _flag 字段的非法值,则服务器必须将 _flag 设置为 UPD_INIT,并执行全面扫描。 此操作必须在与客户端关联的目录中执行。
  • 使用 CPMUpdateDocumentsIn 的消息标头响应客户端,并将 _status 字段设置为请求的结果。

3.1.5.1.4 接收 CPMForceMergeIn 请求

当服务器收到 CPMForceMergeIn 消息请求时,服务器必须执行以下操作:

  • 检查客户端是否在已连接客户端列表中(其具有已关联的目录)。 如果客户端不在列表中,则服务器必须报告 STATUS_INVALID_PARAMETER (0xC000000D) 错误。
  • 检查客户端是否具有管理访问权限。 如果客户端没有管理访问权限,则服务器必须报告 STATUS_ACCESS_DENIED (0xC0000022) 错误。
  • 开始任何必要的维护进程,以提高与客户端相关联的目录的查询性能。
  • 使用 CPMForceMergeIn 的消息标头响应客户端,并将 _status 字段设置为请求的结果。

请注意,维护过程是异步进行的,在客户端收到响应消息后仍会继续。 这一过程不会对协议产生任何直接影响(除响应时间外)。

3.1.5.2 远程索引服务查询

3.1.5.2.1 接收 CPMConnectIn 请求

当服务器收到客户端的 CPMConnectIn 请求时,服务器必须执行以下操作:

  • 检查客户端是否在已连接客户端列表中。 如果出现这种情况,则服务器必须报告 STATUS_INVALID_PARAMETER (0xC000000D) 错误。
  • 检查指定目录是否存在且未处于停止状态。 如果不是这种情况,则服务器必须报告 CI_E_NO_CATALOG (0x8004181D) 错误。
  • 将客户端添加到已连接客户端列表中。
  • 将目录与客户端关联。
  • 在客户端状态中存储 CPMConnectIn 消息中传递的信息(如目录名称、客户端版本等)。
  • 以 CPMConnectOut 消息响应客户端。

3.1.5.2.2 接收 CPMCreateQueryIn 请求

当服务器收到客户端的 CPMCreateQueryIn 信息请求时,服务器必须执行以下操作:

  • 检查客户端是否在已连接客户端列表中。 否则,服务器必须报告 STATUS_INVALID_PARAMETER (0xC000000D) 错误。
  • 检查客户端是否有已之关联的查询。 如果出现这种情况,则服务器必须报告 STATUS_INVALID_PARAMETER (0xC000000D) 错误。
  • 检查与客户端关联的目录是否处于允许处理查询的状态(CICAT_READONLY 或 CICAT_WRITABLE)。 否则,服务器必须报告 QUERY_S_NO_QUERY (0x8004160C) 错误。
  • 解析查询中指定的限制集、排序顺序和分组。 如果服务器遇到错误,则必须报告相应的错误。 如果该步骤因任何其他原因失败,则服务器必须报告所遇到的错误。 有关索引服务查询错误的信息,请参阅 [MSDN-QUERYERR]。
  • 为客户端保存状态中的搜索查询。
  • 根据 CPMCreateQueryIn 消息中传递的信息,做好向客户端提供记录所需的准备工作,并将查询与适当的游标句柄相关联。
  • 将这些句柄添加到客户端的游标句柄列表中,并初始化章节句柄和书签的列表。
  • 将此查询中每个游标的章节句柄列表初始化为 DB_NULL_HCHAPTER
  • 将此查询中每个游标的书签句柄列表初始化为一组 DBBMK_FIRST 和 DBBMK_LAST。
  • 将查询标记为未监控更改。
  • 将行数初始化为当前计算出的行数(如果查询未开始执行,则行数为 0;如果查询正在执行,则行数为某个数字),并初始化查询完成度的分子和分母。
  • 向客户端发送 CPMCreateQueryOut 消息。

3.1.5.2.3 接收 CPMGetQueryStatusIn 请求

当服务器收到客户端的 CPMGetQueryStatusIn 信息请求时,服务器必须执行以下操作:

  • 检查客户端是否具有与之关联的查询。 否则,服务器必须报告 STATUS_INVALID_PARAMETER (0xC000000D) 错误。
  • 检查游标句柄是否在客户端游标句柄列表中。 否则,服务器必须报告 E_FAIL (0x80004005) 错误。
  • 准备 CPMGetQueryStatusOut 消息。 服务器必须检索当前查询状态,并在 _QStatus 字段中设置它(有关可能的值,请参阅第 2.2.3.11 部分)。 如果此步骤因故失败,则服务器必须报告错误。
  • 使用 CPMGetQueryStatusOut 消息响应客户端。

3.1.5.2.4 接收 CPMGetQueryStatusExIn 请求

当服务器收到客户端的 CPMGetQueryStatusExIn 信息请求时,服务器必须执行以下操作:

  • 检查客户端是否具有一个与之关联的查询。 否则,服务器必须报告 STATUS_INVALID_PARAMETER (0xC000000D) 错误。
  • 检查传送的游标句柄是否在客户端游标句柄列表中。 否则,服务器必须报告 E_FAIL (0x80004005) 错误。
  • 准备 CPMGetQueryStatusExOut 消息。 服务器必须检索当前查询状态和查询进度,并分别设置 QStatus(请参阅第 2.2.3.11 部分了解可能的值)、_dwRatioFinishedDenominator 和 _dwRatioFinishedNumerator。 然后,必须将查询结果中的行数设置为 _cRowsTotal。 如果此步骤因故失败,则服务器必须报告遇到错误。
  • 检索客户目录的相关信息并填写 _cFilteredDocuments 和 _cDocumentsToFilter。 如果此步骤因故失败,则服务器必须报告遇到错误。
  • 检索 _bmk 字段中句柄指示的书签位置,并将剩余的 _iRowBmk 字段填入 CPMGetQueryStatusExOut 消息中。 如果此步骤因故失败,则服务器必须报告遇到错误。
  • 使用 CPMGetQueryStatusExOut 消息响应客户端。

3.1.5.2.5 接收 CPMRatioFinishedIn 请求

当服务器收到客户端的 CPMRatioFinishedIn 消息请求时,服务器必须执行以下操作:

  • 检查客户端是否具有与之关联的查询。 否则,服务器必须报告 STATUS_INVALID_PARAMETER (0xC000000D) 错误。
  • 检查传入的游标句柄是否在客户端的游标句柄列表中。 否则,服务器必须报告 E_FAIL (0x80004005) 错误。
  • 准备 CPMRatioFinishedOut 消息。 服务器必须检索客户端的查询状态,并填写 _ulNumerator、_ulDenominator 和 _cRows 字段。 如果此步骤因故失败,则服务器必须报告遇到错误。
  • 如果 _cRows 等于上次报告的查询行数,则将 _fNewRows 设置为 0x00000000,否则将其设置为 0x00000001。
  • 将上次报告的查询行数更新为 _cRows 的值。
  • 使用 CPMRatioFinishedOut 消息响应客户端。

3.1.5.2.6 接收 CPMSetBindingsIn 请求

当服务器收到客户端的 CPMSetBindingsIn 消息请求时,服务器必须执行以下操作:

  • 检查客户端是否具有一个与之关联的查询。 否则,服务器必须报告 STATUS_INVALID_PARAMETER (0xC000000D) 错误。
  • 检查传入的游标句柄是否在客户端的游标句柄列表中。 否则,服务器必须报告 E_FAIL (0x80004005) 错误。
  • 验证绑定信息是否有效(即列至少指定了要返回的值、长度或状态;值、长度或状态的绑定没有重叠;值、长度和状态符合指定的行大小),如果无效,则报告 DB_E_BADBINDINFO (0x80040E08) 错误。
  • 保存与 aColumns 字段中指定的列相关联的绑定信息。 如果此步骤因故失败,则服务器必须报告遇到错误。
  • 使用_msg 设置为 CPMSetBindingsIn,_status 设置为指定绑定结果的消息标头(仅)来响应客户端。

3.1.5.2.7 接收 CPMGetRowsIn 请求

当服务器收到客户端的 CPMGetRowsIn 消息请求时,服务器必须执行以下操作:

  • 检查客户端是否具有与之关联的查询。 否则,服务器必须报告 STATUS_INVALID_PARAMETER (0xC000000D) 错误。
  • 检查传入的游标句柄是否在客户端的游标句柄列表中。 否则,服务器必须报告 E_FAIL (0x80004005) 错误。
  • 检查客户端是否有当前的绑定集。 否则,服务器必须报告 E_FAIL (0x80004005) 错误。
  • 准备 CPMGetRowsOut 消息。 服务器必须按照寻道描述的指示在查询结果中定位游标。 如果此步骤因故失败,则服务器必须报告遇到错误。
  • 提取一个缓冲区中尽可能多的记录,缓冲区的大小由 _cbReadBuffer 指明,但不能超过 _cRowsToTransfer 指明的大小。 提取行时,服务器必须将每个选定列的属性值类型与客户端当前绑定集(第 3.1.1 部分)中指定的类型进行比较。 如果绑定中的类型不是 VT_VARIANT,则服务器必须尝试将列的属性值转换为该类型。 否则,如果在客户端的 DBPROPSET_QUERYEXT 属性集中设置了 DBPROP_USEEXTENDEDDBTYPES 标志,或者如果列的属性值不是 VT_VECTOR 类型,则必须以其正常类型返回属性值。 如果上述情况都不存在(即服务器具有 VT_VECTOR 类型,而客户端不支持 VT_VECTOR),则服务器必须按以下方式尝试将其转换为 VT_ARRAY 类型: VT_I8、VT_UI8、VT_FILETIME 和 VT_CLSID 数组元素不能转换,否则会失败;VT_LPSTR 和 VT_LPWSTR 数组元素必须转换为 VT_BSTR;所有其他类型的数组元素必须保持不变。 最后,如果行列包含章节句柄或书签句柄,则服务器必须更新相应的列表。 如果此步骤因故失败,则服务器必须报告遇到错误。
  • 在 _cRowsReturned 中存储实际获取的记录数。
  • 将 CPMGetRowsIn 中的寻道描述和章节字段复制到要发送的 CPMGetRowsOut 消息中。
  • 将获取的记录存储在 Rows 字段中(请参阅下文关于状态字节的说明和第 2.2.3.16 部分中关于行字段结构的内容)。
  • 使用 CPMGetRowsOut 消息响应客户端。

有关状态字节字段的说明:

如果在 CPMSetBindingIn 消息的 CTableColumn 中将该列的 StatusUsed 设置为 0x01,则服务器必须将该列的状态字节(位于从行开始的 StatusOffset 处)设置为以下值之一:

含义
0x00 StatusOK
0x01 StatusDeferred
0x02 StatusNull

如果此行没有属性值,则服务器必须将状态字节设置为 StatusNull。 如果数值太大,无法在 CPMGetRowsOut 消息中传输,则服务器必须将状态字节设置为 StatusDeferred。 否则,服务器必须将状态字节设置为 StatusOK。

3.1.5.2.8 接收 CPMFetchValueIn 请求

当服务器收到客户端的 CPMFetchValueIn 消息请求时,服务器必须执行以下操作:

  • 检查客户端是否具有与之关联的查询。 否则,服务器必须报告 STATUS_INVALID_PARAMETER (0xC000000D) 错误。

  • 准备 CPMFetchValueOut 消息。 如果此步骤因故失败,则服务器必须报告错误。

  • 查找 _wid 字段指示的文档,并检查 PropSpec 结构指示的此文档的属性 ID(以下称为“属性值”)是否可供该客户端使用。 如果该值不可用,则服务器必须将 _fValueExists 设置为 0x00000000,否则将 _fValueExists 设置为 0x00000001。 如果此步骤因故失败,则服务器必须报告错误。

  • 如果 _fValueExists 等于 0x00000001,则服务器必须执行以下操作:

    • 将属性值序列化为 SERIALIZEDPROPERTYVALUE 结构,并从 _cbSoFar 偏移量开始,复制最多 _cbChunk 个字节(但不能超过序列化属性的末尾)到 vValue 字段。 如果此步骤因任何原因失败,则服务器必须报告错误。
    • 将 _cbValue 设置为上一步所复制的字节数。
    • 将 vType 设置为属性值的属性类型。
    • 如果序列化属性的长度大于 _cbSoFar 加上 _cbValue,则将 _fMoreExists 设置为 0x00000001,否则将其设置为 0x00000000。
  • 使用 CPMFetchValueOut 消息响应客户端

3.1.5.2.9 接收 CPMGetNotify 请求

当服务器收到客户端发送的 CPMGetNotify 消息时,服务器必须执行以下操作:

  • 检查客户端是否具有与之关联的查询。 否则,服务器必须报告 STATUS_INVALID_PARAMETER (0xC000000D) 错误。
  • 如果自该客户端上次发送 CPMSendNotifyOut 消息以来查询结果集没有任何变化,或者如果当前未监控查询结果集的变化,则服务器必须响应 CPMGetNotify 消息,并开始监控查询结果集的变化。 如果稍后查询结果集发生变化,则服务器必须向客户端发送一条 CPMSendNotifyOut 消息,并在 _watchNotify 字段中说明变化情况。
  • 如果自上次 CPMSendNotifyOut 消息发出后查询结果集发生了更改,服务器必须回复 CPMSendNotifyOut,并必须在 _watchNotify 字段中指定更改。 请注意,在查询结果发生多次更改的情况下,DBWATCHNOTIFY_ROWSCHANGED 会优先处理(也就是说,如果查询完成后重新执行,然后行数发生变化,再次执行查询,那么报告的事件将是 DBWATCHNOTIFY_ROWSCHANGED)。

3.1.5.2.10 接收 CPMGetApproximatePositionIn 请求

当服务器收到来自客户端的 CPMGetApproximatePositionIn 消息请求时,服务器必须执行以下操作:

  • 检查客户端是否具有一个与之关联的查询。 否则,服务器必须报告 STATUS_INVALID_PARAMETER (0xC000000D) 错误。
  • 检查传递的游标句柄、章节句柄和书签句柄是否都位于相应的列表中。 否则,服务器必须报告 E_FAIL (0x80004005) 错误。
  • 在查询结果中查找与书签句柄相关联的记录,并根据章节句柄近似计算该记录在行集中的位置,然后确定位置的分子和分母。 请注意,当章节句柄为 DB_NULL_HCHAPTER 时,相应的章节就是查询的主行集。 如果此步骤因故失败,则服务器必须报告错误。
  • 使用 CPMFetchValueOut 消息响应客户端

3.1.5.2.11 接收 CPMCompareBmkIn 请求

当服务器收到来自客户端的 CPMCompareBmkIn 消息请求时,服务器必须执行以下操作:

  • 检查客户端是否具有一个与之关联的查询。 否则,服务器必须报告 STATUS_INVALID_PARAMETER (0xC000000D) 错误。

  • 检查传递的游标句柄、章节句柄和书签句柄是否都位于相应的列表中。 否则,服务器必须报告 E_FAIL (0x80004005) 错误。

  • 准备 CPMCompareBmkOut 消息。

  • 如果书签句柄相等,则 _dwComparison 必须设置为 DBCOMPARE_EQ。

  • 否则,如果书签句柄之一是 DBBMK_FIRST 或 DBBMK_LAST,则 _dwComparison 必须设置为 DBCOMPARE_NE。

  • 否则,服务器必须执行以下操作:

    • 查找查询结果中每个书签句柄引用的行
    • 如果其中任何一行不在 CPMCompareBmkIn 中的章节句柄所指示的章节中,则 _dwComparison 必须设置为 DBCOMPARE_NOTCOMPARABLE。
    • 否则,当这两行都在同一章节中时,服务器必须近似确定这两行在该章节句柄所指行集中的位置。 然后,它必须比较位置值,如果第一行的位置小于第二行的位置,则将_dwComparison 设置为 DBCOMPARE_LT;否则_dwComparison 必须设置为 DBCOMPARE_GT。
  • 使用填充的 CPMCompareBmkOut 消息响应客户端。

3.1.5.2.12 接收 CPMRestartPositionIn 请求

当服务器收到客户端发出的 CPMRestartPositionIn 消息请求时,服务器必须执行以下操作:

  • 检查客户端是否具有一个与之关联的查询。 否则,服务器必须报告 STATUS_INVALID_PARAMETER (0xC000000D) 错误。
  • 检查所传递的游标句柄和章节句柄是否在相应的列表中。 否则,服务器必须报告 E_FAIL (0x80004005) 错误。
  • 将光标移至由章节句柄标识的章节开头位置。 请注意,当章节句柄为 DB_NULL_HCHAPTER 时,相应的章节就是查询的主行集。 如果此步骤因故失败,则服务器必须报告错误。
  • 使用 CPMRestartPositionIn 消息响应客户端。

3.1.5.2.13 接收 CPMFreeCursorIn 请求

当服务器收到来自客户端的 CPMFreeCursorIn 消息请求时,服务器必须执行以下操作:

  • 检查客户端是否具有一个与之关联的查询。 否则,服务器必须报告 STATUS_INVALID_PARAMETER (0xC000000D) 错误。
  • 检查传入的游标句柄是否在客户端的游标句柄列表中。 否则,服务器必须报告 E_FAIL (0x80004005) 错误。
  • 释放该游标句柄的游标和相关资源(请参阅第 3.1.1 部分,了解完整列表)。
  • 从该客户端的游标列表中删除游标。
  • 使用 CPMFreeCursorOut 消息进行响应,使用剩余游标数来设置 _cCursorsRemaining 字段。 在此客户端的列表中。
  • 如果此客户端已没有更多游标,则服务器必须释放查询和相关资源(请参阅第 3.1.1 部分)。

3.1.5.2.14 接收 CPMDisconnect 请求

当服务器收到客户端发出的 CPMDisconnect 消息请求时,服务器必须将客户端从已连接客户端列表中删除,并释放与客户端相关的所有资源。

3.1.6 计时器事件

无。

3.1.7 其他本地事件

服务器停止时,必须首先转换为“正在关闭”状态。 然后,它必须停止侦听管道,执行任何其他特定的关闭任务,然后转换为“已停止”状态。

3.2 客户端详细信息

3.2.1 抽象数据模型

以下部分说明了内容索引服务协议客户端维护的数据和状态。 提供的数据是为了便于解释协议的行为方式。 只要外部行为与本文档中描述的一致,本部分就并不强制要求实现者遵守此模型。

客户端具有以下抽象状态:

  • 上次发送的消息:发送到服务器的最后一条消息的副本。
  • 当前属性值:正在检索的“延迟”属性的部分值。
  • 当前接收的字节数:当前属性值到目前为止收到的字节数。
  • 命名管道连接状态:与服务器的连接

3.2.2 计时器

无需协议计时器。

3.2.3 初始化

在收到上层请求之前,不会采取任何行动。

3.2.4 上层触发事件

当收到来自上层的请求时,客户端必须使用第 2.1 部分中规定的详细信息,创建一个与服务器的命名管道连接。 如果无法做到这一点,则上层请求必须失败。 也就是说,在连接失败的情况下,更高级别有责任根据需要重试。

标头必须附加到第 2.2.2 部分中指定的字段。

对于指定为需要非零校验和的消息,_ulChecksum 值必须按以下方式计算:

  1. 消息标头中 _ulReserved2 字段之后的消息内容必须解释为 32 位整数序列。 客户端必须计算这些整数的数值总和。
  2. 使用 0x59533959 计算此值的按位 XOR。
  3. 从按位 XOR 生成的值中减去由 _msg 给出的值。

3.2.4.1 远程索引服务目录管理

每条消息都由上一层的请求触发。 对于用于远程管理目录的 CISP 消息请求,客户端没有强制执行消息顺序,但(CPMSetCatStateIn 消息除外)只有在客户端之前通过 CPMConnectIn 消息连接时,服务器才会成功回复。

3.2.4.1.1 发送 CPMCiStateInOut 请求

通常情况下,当协议客户端需要服务器上的索引服务信息时,上层会要求协议客户端发送 CPMCiStateInOut 消息。

当被要求发送此信息时,客户端必须执行以下操作:

  • 向服务器发送第 2.2.3.1 部分中规定的 CPMCiStateInOut 消息。
  • 等待接收来自服务器的 CPMCiStateInOut 消息,从而以无提示方式放弃所有其他消息。
  • 向上层报告响应中 _status 字段的值,如果成功,则报告信息结构。

3.2.4.1.2 发送 CPMSetCatStateIn 请求

通常情况下,上层在需要有关目录或所有目录的信息时,会要求协议客户端发送 CPMSetCatStateIn 消息。 对于此消息,上层需要向协议客户端提供 _dwNewState 的值,并根据需要提供目录名称。

当被要求发送此信息时,客户端必须执行以下操作:

  • 将第 2.2.3.2 部分中指定的 CPMSetCatStateIn 消息发送到服务器。
  • 等待接收来自服务器的 CPMSetCatStateOut 消息,从而以无提示方式放弃所有其他消息。
  • 向上层报告响应中 _status 字段的值,如果成功,则报告 _dwOldState 值。

3.2.4.1.3 发送 CPMUpdateDocumentsIn 请求

上层在需要更新现有路径中的文件或在索引中添加新文件路径时,通常会要求发送此消息。 因此,上层要提供扫描的路径和类型,具体如第 2.2.3.4 节所述,增量或完全更新适用于现有路径,而新的初始化适用于新路径。

为了向上层请求提供服务,客户端必须执行以下操作:

  • 向服务器发送第 2.2.3.4 部分中规定的 CPMUpdateDocumentsIn 消息。
  • 等待接收服务器发送的 CPMUpdateDocumentsIn 消息,从而以无提示方式放弃所有其他消息。
  • 向上层报告响应中 _status 字段的值。

3.2.4.1.4 发送 CPMForceMergeIn 请求

通常情况下,上层会在需要提高查询性能时请求发送此消息,或者这是索引服务计划维护的一部分。

为了向上层提供服务,客户端必须执行以下操作:

  • 向服务器发送第 2.2.3.5 部分中规定的 CPMForceMergeIn 消息。
  • 等待接收服务器发送的 CPMUpdateDocumentsIn 消息,从而以无提示方式放弃所有其他消息。
  • 向上层报告响应中 _status 字段的值。

3.2.4.2 远程索引服务目录查询消息

除 CPMGetRowsIn/CPMGetRowsOut 和 CPMFetchValueIn/CPMFetchValueOut 外,CISP 信息与上层请求之间是一对一的关系。 对于上述两种例外情况,客户端可能会生成多条信息,以满足大小要求或检索完整的属性。 上层通常会跟踪所有查询特定信息(如打开的游标句柄、书签和章节句柄的合法值、延迟属性值的 wid 值等),并跟踪客户端是否处于连接状态,但客户端不会以任何方式强制执行。

为便于说明,第 3 部分中示意图的客户端部分说明了简单索引服务查询的序列。

3.2.4.2.1 发送 CPMConnectIn 请求

此消息通常是来自上层的第一个请求(因为如果客户端未连接,服务器将拒绝大部分消息,但 CPMSetCatStateIn 除外)。 上一级向协议客户端提供连接所需的信息。

为了向上层提供服务,客户端必须执行以下操作:

  • 使用上层客户端提供的 _iClientVersion、MachineName、UserName、PropertySet1、PropertySet2 和 aPropertySet 中的信息(请参阅第 2.2.3.6 部分)填写消息。
  • 按照第 2.2.3.6 部分中的规定设置 _fClientIsRemote、_cbBlob、_cbBlob2、cPropSet 和 cExtPropSet。
  • 在 _ulChecksum 字段中设置校验和。
  • 向服务器发送 CPMConnectIn 消息。
  • 等待接收服务器发送的 CPMConnectOut 消息,从而以无提示方式放弃所有其他消息。
  • 向上层报告响应中 _status 字段的值,如果成功,则报告 _serverVersion 值。

为了提供信息,预计高层通常会在连接成功后执行以下操作,但 CISP 客户端不会强制执行这些操作:

  • 将远程索引服务目录管理消息用于管理任务
  • 使用 CPMCreateQueryIn 请求创建搜索查询,以便从目录中检索结果。

3.2.4.2.2 发送 CPMCreateQueryIn 请求

在协议客户端连接后,上层通常会提供创建查询的信息。 上层为客户端提供限制集、列集、排序规则和分类集(每个都可以省略)、行集属性和属性 ID 映射器结构。

从上一层收到此请求时,客户端必须执行以下操作:

  • 准备 CPMCreateQueryOut,如下所示。

    • 如果存在列集,则将 CColumnsSetPreset 设置为 0x01,并填写 ColumnsSet 字段。
    • 如果存在限制,则将 CRestrictionPresent 设置为 0x01,并填写 Restriction 字段。
    • 如果存在排序集,则填写 SortSet 字段。
    • 如果存在分类集,则将 CSortSetPresent 设置为 0x01,并填写 CategorizationSet 字段。
    • 按照 2.2.3.8 中的规定设置其余字段
  • 计算标头中的 _ulCheckSum 字段。

  • 向服务器发送 CPMCreateQueryIn 消息。

  • 等待接收 CPMCreateQueryOut 消息(有关详细信息,请参阅第 3.2.5.1.1 部分),以无提示方式放弃所有其他消息。

  • 向上层报告响应中 _status 字段的值,如果响应成功,则报告游标句柄数组和布尔信息值(如第 2.2.3.9 部分所述)。

3.2.4.2.3 发送 CPMSetBindingsIn 请求

通常情况下,上层在已经拥有有效游标句柄(成功接收 CPMCreateQueryOut 后,请参阅第 3.2.5.1.1 部分)时,会为要返回的行中的每一列设置绑定。 上级程序应根据第 2.2.4.31 部分的规定,为 aColumns 字段提供 CTableColumn 结构数组和有效的游标句柄。

从上一层收到此请求时,客户端必须执行以下操作:

  • 计算 aColumns 数组中 CTableColumn 结构的数量,并将 cColumns 字段设置为该值。
  • 计算 cColumns 和 aColumns 字段的总大小(以字节为单位),并将 _cbBindingDesc 字段设置为该值。
  • 将 CPMSetBindingsIn 消息中的指定字段设置为上一级应用层提供的值。 将 _ulChecksum 字段设置为第 3.2.5 部分规定的计算值。
  • 向服务器发送完成的 CPMSetBindignsIn 消息。
  • 等待接收来自服务器的 CPMSetBindingsIn 消息,丢弃其他消息。
  • 指明从上层响应的 _status 字段中的状态。

出于参考目的,预计上层通常会要求客户端发送 CPMGetRowsIn 消息,但内容索引服务协议不会强制执行。

3.2.4.2.4 发送 CPMGetRowsIn 请求

上层在接收行信息时,会向协议客户端提供有效的游标和章节句柄,并给出适当的寻道说明。 通常情况下,上层在拥有有效游标和/或章节句柄,且绑定已通过 CPMSetBindingsIn 消息设置时,就会这样执行。 要访问章节中的行集,则上层需要使用在之前的 CPMGetRowsOut 消息中从服务器接收到的章节句柄。

从上一层收到此请求时,客户端必须执行以下操作:

  • 确定为 _cbReadBuffer 字段指定的无符号整数值。 要确定该值,客户端必须从以下值中获取最大值:
    • c_RowsToTransfer 字段值的一千倍。
    • _cbRowWidth 的值,四舍五入为最接近的 512 字节倍数。
    • 取这两个值中的较高值,上限为 16K。
    • 如果单行大于 16K,则服务器将无法返回查询结果。

在 _ulClientBase 字段中指定客户端地址空间中可变大小行数据的客户端基数。

Windows 行为:对于与 32 位服务器通信的 32 位客户端或与 64 位服务器通信的 64 位客户端,该值将设置为应用程序进程中接收缓冲区的内存地址。 这样,在 CPMGetRowsOut 的 Rows 字段中接收到的指针就可以成为客户端应用程序进程中正确的内存指针。 否则,它将被设置为 0x00000000。

  • 计算搜索说明的大小,并在 _cbSeek 字段中进行设置。
  • 将 cbReserved 的值(作为行开始的偏移量)设为 _cbSeek 加上 0x14 的值。
  • 向服务器发送第 2.2.3.15 部分中规定的 CPMConnectIn 消息。

3.2.4.2.5 发送 CPMFetchValueIn 请求

如果客户端从服务器收到的 CPMGetRowsOut 响应中,列的 Status 字段设置为 StatusDeferred (0x01),则表示属性值未包含在 CPMGetRowsOut 信息的 Rows 字段中。 在这种情况下,上层通常会要求协议客户端通过 CPMFetchValueIn 消息检索值,并为递延属性提供 PropSpec 和 _wid 值,协议客户端必须在第一条 CPMFetchValueIn 消息中使用该值。

如果这是客户端为请求指定属性而发送的第一条 CPMFetchValueIn 消息,客户端必须执行以下操作:

  • 按照第 2.2.3.19 部分的规定设置消息中的所有字段。
  • 将 _cbSoFar 设置为 0x00000000。
  • 将当前接收字节数设为 0。
  • 向服务器发送 CPMFetchValueIn 消息。

3.2.4.2.6 发送 CPMFreeCursorIn 请求

一旦上一级不再使用搜索查询,它就可以通过要求客户端发送 CPMFreeCursorIn 消息来释放服务器上的资源。

收到此请求后,客户端必须向服务器发送第 2.2.3.28 部分中规定的 CPMFreeCursorIn 消息,其中包含了上层指定的句柄。

3.2.4.2.7 发送 CPMDisconnect 消息

如果上层没有更多的索引服务查询,为了释放更多的服务器资源,应用程序可以要求客户端向服务器发送 CPMDisconnect 消息。 收到此查询后,客户端必须按要求发送信息。 服务器对此消息无响应。

3.2.5 消息处理和排序规则

当客户端收到服务器的消息响应时,客户端必须使用上次发送的消息来确定从服务器收到的消息是否是客户端预期的消息。 所有 _msg 字段与上次发送信息字段不同的消息都必须忽略。

3.2.5.1 接收 CPMCreateQueryOut 响应

当客户端收到服务器的 CPMCreateQueryOut 消息响应时,客户端必须向上层返回 _status 和游标句柄值(如果状态成功)。 任何进一步的操作都取决于上一层。

由于上层知道查询结构,因此总是希望在 CPMCreateOueryOut 消息中返回游标句柄的正确数量。 游标句柄按以下顺序返回:第一个句柄是未编排的行集,第二个句柄是第一个已编排行集(这是根据在 CPMCreateQueryIn 消息的 CategorizationSet 字段中指定的第一个类别对结果进行的分组)。

出于参考目的,预计上层可以执行以下操作,但 CISP 客户端不会强制执行这些操作:

  • 使用 CPMSetBindingsIn 为单个列设置绑定,并在查询路径上执行任何后续操作
  • 使用 CPMGetQueryStatusIn 检查查询的执行进度。
  • 使用 CPMRatioFinishedIn 请求查询的完成百分比。

3.2.5.2 接收 CPMGetRowsOut 响应

当客户端收到服务器发出的 CPMGetRowsOut 消息响应时,客户端必须执行以下操作:

  • 检查标头中的 _status 字段是否显示成功或失败。
  • 如果 _status 值为 STATUS_BUFFER_TOO_SMALL (0xC0000023),客户端必须检查“上次发送的消息”状态。 如果未包含 CPMGetRowsIn 消息,则必须以无提示方式忽略接收到的消息。 否则,客户端必须向服务器发送一条新的 CPMGetRowsIn 消息,除了 _cbReadBuffer 必须增加 512(但不得大于 0x4000)之外,所有字段都与存储的消息相同。 如果 _status 为 STATUS_BUFFER_TOO_SMALL (0xC0000023),且最后发送的消息的 _cbReadBuffer 已等于 0x4000,则客户端必须向上一级报告错误。
  • 如果 _status 值是任何其他错误值,则客户端必须向上层指出故障。
  • 如果 _status 值指出已成功,则必须向请求信息的上一层指示结果,并由上一层采取进一步行动。

出于参考目的,预计上层通常会执行以下操作,但内容索引服务协议客户端不会强制执行这些操作:

  • 如果行中的值代表文档 ID、章节或书签句柄,则上层通常会存储这些值,以便在后续涉及有效文档 ID、章节或书签句柄的操作中使用。
  • 上层通常会存储、显示或使用行值数据。
  • 对于标记为延迟的值,上层将使用 CPMFetchValueIn 消息来获取该值。
  • 寻道说明也会返回上一层,以供上一层重复使用或检查。

出于参考目的,如果上层要求获得各行中的章节和书签的句柄,可以采取以下措施:

  • 使用 CPMGetQueryStatusExIn 可检查查询的执行进度以及其他状态信息,如已筛选的文档数量、剩余待筛选的文档数量、查询已处理文档的比例、查询的总行数以及书签在行集中的位置。
  • 使用 CPMGetNotify 请求服务器通知客户端行集的更改。
  • 使用 CPMGetApproximatePositionIn 请求书签在章节中的大致位置。
  • 使用 CPMCompareBmkIn 请求对章节中的两个书签进行比较。
  • 对服务器使用 CPMRestartPositionIn,将游标的位置更改为行集的起始位置。

3.2.5.3 接收 CPMFetchValueOut 响应

当客户端收到服务器发出的 CPMGetRowsOut 消息响应时,客户端必须执行以下操作:

  • 检查标头中的 _status 字段是否显示成功或失败。 如果出现故障,则通知上一层。 否则,请继续以下操作。
  • 检查 _fValueExist,如果设置为 0x00000000,则通知上层未找到该值。
  • 否则,将 vValue 中的 _ cbValue 字节附加到当前属性值中。
  • 如果 __fMoreExists 被设置为 0x00000001,那么_Current Bytes Received 将递增 _cbValue,并向服务器发送 CPMFetchValueIn 消息,同时将 _cbSoFar 设置为 Current Bytes Received 的值,将 _cbPropSpec 设置为零,将 _cbChunk 设置为上层所需的缓冲区大小。
  • 如果 _fMoreExists 设置为 0x00000000,则将当前属性值中的属性值指示给上一层。

3.2.5.4 接收 CPMFreeCursorOut 响应

当客户端从服务器成功接收到 CPMFreeCursorOut 消息响应时,客户端必须向上层返回 _cCursorsRemaining 值。

以下信息仅供参考,CISP 客户端不会强制执行。 上层应跟踪游标句柄,而不使用已经释放的游标句柄。 一旦 _cCursorsRemaining 的数量等于 0x00000000,上层就可以使用连接指定另一个查询(使用 CPMCreateQueryIn 消息)。

3.2.6 计时器事件

无。

3.2.7 其他本地事件

无。

4 协议示例

4.1 示例 1

在以下示例中,我们考虑了一种方案:计算机 A 上的用户 JOHN 希望从目录 SYSTEM 中存储在服务器 X 上的文档集中获取包含“Microsoft”一词的文件大小。 假设计算机 A 运行的是 32 位 Windows XP 操作系统,计算机 X 运行的是 32 位 Windows Server 2003 操作系统。

  1. 用户启动搜索应用程序并输入搜索查询。 应用程序反过来会将搜索查询传递给协议客户端。

  2. 协议客户端与索引服务器 X 建立连接。协议客户端使用命名管道 \pipe\CI_SKADS 通过 SMB 与服务器 X 建立连接。

  3. 然后,协议客户端准备 CPMConnectIn 消息,其中包含以下值:

    消息的标头填充如下:

    • _msg 设置为0x000000C8,表明这是一条 CPMConnectIn 消息。
    • _status 设置为 0x00000000。
    • _ulChecksum 包含校验和,计算结果为第 3.2.4 部分中所述。
    • _ulReserved2 设置为0x00000000。

    消息的正文填充如下:

    • _iClientVersion 设置为 0x00000008,表示服务器将验证校验和字段。

    • _fClientIsRemote 设置为0x00000001,表明服务器是远程服务器。

    • _cbBlob1 被设置为 cPropSet、PropertySet1 和 PropertySet2 字段的总和,以字节为单位。

    • _cbBlob2 被设置为 0x00000004(表示没有额外的属性集)。

    • MachineName 被设置为 A。

    • UserName 设置为 JOHN。

    • cPropSets 被设置为 0x00000002。

    • PropertySet1 字段的类型是 CDbPropSet。 由 PropertySet1 字段组成的 CDbPropSet 结构填充如下:

      • GuidPropSet 字段设置为 A9BD1526-6A80-11D0-8C9D-0020AF1D740E (DBPROPSET_FSCIFRMWRK_EXT)。

      • cProperties 字段设置为 0x00000004。

      • aProps 字段是一个 CDbProp 结构的数组。

        对于 aProps[0] 元素:

        • PropId 设置为 0x00000002 (DBPROP_CI_CATALOG_NAME)。
        • DBPROPOPTIONS 设置为 0x0000000。
        • DBPROPSTATUS 设置为 0x00000000。
        • 对于 ColId 元素:
          • eKind 设置为 0x00000001 (DBKIND_GUID_PROPID)
          • GUID 为 null(全部为零),这意味着该值适用于查询,而不仅仅是单个列。
          • ulID 设置为 0x00000000。
        • 对于 vValue 元素:
          • vType 设置为 0x001F (VT_LPWSTR)。
          • vValue 设置为“SYSTEM”,即所需目录的名称。

        对于 aProps[1] 元素:

        • PropId 设置为 0x00000007 (DBPROP_CI_QUERY_TYPE)
        • DBPROPOPTIONS 设置为 0x0000000。
        • DBPROPSTATUS 设置为 0x00000000。
        • 对于 ColId 元素:
          • eKind 设置为 0x00000001 (DBKIND_GUID_PROPID)。
          • GUID 为 null(全部为零),这意味着该值适用于查询,而不仅仅是单个列。
          • ulID 设置为 0x00000000。
        • 对于 vValue 元素:
          • vType 设置为0x0003 (VT_I4)。
          • vValue 设置为 0x00000000 (CiNormal),表示它是一个常规查询。

        对于 aProps[2] 元素:

        • PropId 设置为 0x00000004 (DBPROP_CI_SCOPE_FLAGS)。
        • DBPROPOPTIONS 设置为 0x0000000。
        • DBPROPSTATUS 设置为 0x00000000。
        • 对于 ColId 元素:
          • eKind 设置为 0x00000001 (DBKIND_GUID_PROPID)。
          • GUID 为 null(全部为零),这意味着该值适用于查询,而不仅仅是单个列。
          • ulID 设置为 0x00000000。
        • 对于 vValue 元素:
          • vType:0x1003 (VT_VECTOR | VT_I4)
          • vValue:0x00000001 / 0x00000001(一个值为 1 的元素),表示搜索子文件夹

        对于 aProps[3] 元素:

        • PropId:0x00000003 (DBPROP_CI_INCLUDE_SCOPES)
        • DBPROPOPTIONS:0x0000000
        • DBPROPSTATUS:0x00000000
        • 对于 ColId 元素:
          • eKind 设置为 0x00000001 (DBKIND_GUID_PROPID)。
          • GUID 为 null(全部为零),这意味着该值适用于查询,而不仅仅是单个列。
          • ulID 设置为 0x00000000
        • 对于 vValue 元素:
          • vType 设置为 0x101F (VT_VECTOR | VT_LPWSTR)。
          • vValue 设置为 0x00000001 / 0x00000002 / "\"(一个带有 2 个字符的 null 终止字符串),表示根范围。
    • PropertySet2 字段的类型是 CDbPropSet。

      由 PropertySet1 字段组成的 CDbPropSet 结构填充如下:

      • GuidPropSet 设置为 AFAFACA5-B5D1-11D0-8C62-00C04FC2DB8D (DBPROPSET_CIFRMWRKCORE_EXT)。

      • cProperties 字段设置为 0x00000001。

      • aProps 字段是一个 CDbProp 结构的数组。

        对于 aProps[0] 元素:

        • PropId 设置为 0x00000002 (DBPROP_MACHINE)。
        • DBPROPOPTIONS 设置为 0x0000000。
        • DBPROPSTATUS 设置为 0x00000000。
        • 对于 ColId 元素:
          • eKind 设置为 0x00000001 (DBKIND_GUID_PROPID),
          • GUID 为 null(全部为零),这意味着该值适用于查询,而不仅仅是单个列。
          • ulID 设置为 0x00000000。
        • 对于 vValue 元素:
          • vType:0x0008 (VT_BSTR)
          • vValue:0x04/"X"(4 个字节/null 终止的 Unicode 字符串),表示服务器名称“X”。
    • cExtPropSet 字段设置为 0x00000000。

    • aPropertySets 数组不存在。

    • 根据需要填充各种填充字段。 消息会被发送到服务器。

  4. 服务器将验证 _ulChecksum 是否正确,验证用户是否有权发出该请求,并以 CPMConnectOut 消息作为响应。

    消息的标头填充如下:

    • _msg 设置为0x000000C8,表明这是一条 CPMConnectOut 消息。
    • _status 设置为表示 SUCCESS 的 0x0000000。
    • _ulChecksum 设置为 0。
    • _ulReserved2 设置为0x00000000。

    消息的正文填充如下:

    • _serverVersion 字段设置为 0x00000007(32 位 Windows XP 或 32 位 Windows Server 2003)。
    • _reserved 字段可填充任意数据。
  5. 客户端准备 CPMCreateQueryIn 消息。

    消息的标头填充如下:

    • _msg 设置为 0x000000CA,表明这是一条 CPMCreateQueryIn 消息。
    • _status 设置为 0x00000000。
    • _ulChecksum 包含根据第 3.2.5 部分计算的校验和。
    • _ulReserved2 设置为0x00000000。

    消息的正文填充如下:

    • Size 字段设置为消息其余部分的大小。
    • CColumnSetPresent 字段设置为 0x01。
    • ColumnSet 字段的类型为 CColumnSet。 组成此字段的 CColumnSet 结构设置如下:
      • _count 字段设置为 0x00000001,表示返回一列。
      • indexes 数组为 0x00000000,表示 _aPropSpec 中的第一个条目。
    • CRestrictionPresent 字段设置为 0x01,表示 Restriction 字段存在。
    • Restriction 字段属于 CRestriction 类型,并被设置为:
      • _ulType 设置为 0x00000004 (RTContent)。
      • _weight 设置为 0x00000000。
    • 字段的其余部分包含一个 CContentRestriction 结构:
      • _Property 设置为 GUID B725F130-47EF-101A-A5F1-02608c9eebac / 0x00000001(用于 PRSPEC_PROPID)/ 0x13,表示文档正文。
      • _Cc 设置为 0x00000009。
      • _pwcsphrase 设置为字符串“Microsoft”。
      • _lcid 设置为 0x409(英语)。
      • _ulGenerateMethod 设置为 0x00000000(完全匹配)。
    • CSortPresent 设置为 0x00。
    • CCategorizationSetPresent 设置为0x00。
    • RowSetProperties 的设置如下:
      • _uBooleanOptions 设置为 0x00000001(顺序)。
      • _ulMaxOpenRows 设置为 0x00000000。
      • _ulMemoryUsage 设置为 0x00000000。
      • _cMaxResults 设置为 0x00000100(最多返回 256 行)。
      • _cCmdTimeOut 设置为 0x00000000(永不超时)。
    • PidMapper 设置为:
      • _count 设置为 0x00000001。
      • _aPropSpec 被设置为 GUID B725F130-47EF-101A-A5-F1-02608C9EEBAC / 0x00000001(用于 PRSPEC_PROPID)/ 0x0000000c,它表示 Windows 文件大小属性。
  6. 服务器对其进行处理,并以 CPMCreateQueryOut 消息进行响应。

    消息的标头填充如下:

    • _msg 设置为 0x000000CA,表明这是一条 CPMCreateQueryOut 消息。
    • _status 设置为 SUCCESS。
    • _ulChecksum 设置为 0x00000000(或任何其他任意值)。
    • _ulReserved 设置为 0x00000000(或任何其他任意值)。

    消息的正文填充如下:

    • _fTrueSeqeuntial 设置为 0x00000000,表示查询可以使用索引。
    • _fWorkIdUnique 设置为 0x00000001。
    • aCursors 数组只包含一个元素,表示此查询的游标句柄。 此值取决于服务器的状态。 假设返回值为 0xAAAAAAAA。
  7. 客户端发出 CPMSetBindingsIn 请求消息,以定义行的格式。

    消息的标头填充如下:

    • _msg 设置为 0x000000D0,表明这是一条 CPMSetBindingsIn 消息。
    • _status 设置为 SUCCESS。
    • _ulChecksum 设置为 0x00000000(或任何其他任意值)。
    • _ulReserved 设置为 0x00000000(或任何其他任意值)。

    消息的正文填充如下:

    • _hCursor 设置为 0xAAAAAAAA。
    • _cbRow 设置为 0x10(大到足以容纳列)。
    • _cbBindingDesc 设置为 _cColumns_aColumns 字段合并后的大小。
    • _cColumns 设置为 0x00000001。
    • _aColumns 数组被设置为包含一个 CTableColumn 结构,其中包含:
      • _PropSpec 被设置为 GUID b725f130-47ef-101a-a5-f1-02608c9eebac/0x00000001(用于 PRSPEC_PROPID)/0x0000000c,它表示 Windows 文件大小属性。
      • _vType 设置为 0x0015 (VT_UI8)。
      • _ValueUsed 设置为 0x01(行中传输的列)。
      • _ValueOffset 设置为 0x0002(行开头)。
      • _ValueSize 设置为 0x08(VT_UI8 的大小)。
      • _StatusUsed 设置为 0x01。
      • _StatusOffset 设置为 0x0A。
      • _LengthUsed 设置为 0x00。
  8. 服务器对其进行处理,并以 CPMSetBindingsIn 消息进行响应。

    消息的标头填充如下:

    • _msg 设置为 0x000000D0。
    • _status 设置为 SUCCESS。
    • _ulChecksum 设置为 0x00000000(或任何其他任意值)。
    • _ulReserved 设置为 0x00000000(或任何其他任意值)。
  9. 客户端发出 CPMGetRowsIn 请求消息。 假设客户端此时准备好接受 100 行,并希望以升序排列。

    消息的标头填充如下:

    • _msg 设置为 0x000000CC,表明这是一条 CPMConnectIn 消息。
    • _status 设置为 0x00000000
    • _ulChecksum 包含根据部分 0 计算的校验和。
    • _ulReserved2 设置为0x00000000。

    消息的正文填充如下:

    • _hCursor 设置为 0xAAAAAAAA。
    • _cRowsToTransfer 设置为 0x00000064。
    • _cRowWidth 设置为 0x00000010(从绑定)。
    • _cbSeek 设置为 0x14,即 eType、_chapt 和 CRowSeekNext 字段的总和。
    • _cbReserved 设置为 0x18(0x14 加上 _cbSeek)。
    • _cbReadBuffer 设置为 0x800(0x64*0x10 四舍五入为 0x200 的下一个倍数)。
    • _ulClientBase 设置为 0x00000000。
    • _fBwdfetch 设置为 0x00000000,表示按正向顺序提取行。
    • eType 设置为 0x0000001,表示客户端想要后面的行。
    • _chapt 设置为 0(而不是分章结果)。
    • SeekDescription 设置为 CRowSeekNext。 CRowSeekNext 结构包含以下值:
      • CiTblChapt 设置为 0x00000000。
      • _hRegion 设置为 0x00000000。
      • _cSkip 设置为 0 表示客户端不想跳过行。
  10. 服务器对其进行处理,并以 CPMGetRowsOut 消息进行响应。 假设服务器找到 100 个包含“Microsoft”一词的文档。

    消息的标头填充如下:

    • _msg 设置为 0x000000CC,表明这是一条 CPMGetRowsOut 消息。
    • _status 设置为 SUCCESS。
    • _ulChecksum 设置为 0x00000000。
    • _ulReserved2 设置为0x00000000。

    消息的正文填充如下:

    • _CRowsReturned 设置为 0x00000064。
    • eType 设置为 0x00000001。
    • _chapt 设置为 0x00000000(而不是分章结果)。
    • SeekDescription 包含一个 CRowSeekNext 结构,其填充方式如下:
      • CiTblChapt 设置为 0x00000000。
      • _hRegion 设置为 0x00000000。
      • _cSkip 设置为 0 表示客户端不想跳过行。
    • Rows 包含包含“Microsoft”一词的 100 个文档的大小。 由于这是固定大小的数据,因此只需将其结构化为 100 个 8 字节无符号整数的列表。
  11. 客户端发送 CPMDisconnect 消息以结束连接。

    消息的标头填充如下:

    • _msg 设置为 0x000000C9,表明这是一条 CPMDisconnect 消息。
    • _status 设置为 0x00000000。
    • _ulChecksum 设置为 0x00000000。
  12. 服务器处理消息并删除所有客户端状态。

4.2 示例 2

在前面的示例中,查询非常简单。 现在让我们考虑一个稍微复杂一点的查询。 假设用户希望检索包含以下两个单词的文档的大小:“Microsoft”和“Office”。 具体做法是更改步骤 5 中发送的 CPMCreateQueryIn 消息中的限制字段,如下所示:

Restriction 字段属于 CRestriction 类型,并被设置为:

    • _ulType 设置为 0x00000004 (RTAnd)。
    • _weight 设置为 0x00000000。

字段的其余部分包含一个 CNodeRestriction 结构:

    • _cNode 设置为 0x00000002,表示 paNode 数组中有两个节点。

    • _paNode 字段是由两个 CRestriction 结构组成的数组。

      _paNode[0] 包含:

        • _ulType 设置为 0x00000004 (RTContent)。
        • _weight 设置为 0x00000000。
        • 字段的其余部分包含一个 CContentRestriction 结构:
          • _Property 设置为 GUID b725f130-47ef-101a-a5f1-02608c9eebac / 0x00000001(用于 PRSPEC_PROPID)/ 0x13。
          • _Cc 设置为 0x00000009。
          • _pwcsphrase 设置为字符串“Microsoft”。
          • _lcid 设置为 0x409(英语)。
          • _ulGenerateMethod 设置为 0x00000000(完全匹配)。

      _paNode[1] 包含:

        • _ulType 设置为 0x00000004 (RTContent)。
        • _weight 设置为 0x00000000。
        • 字段的其余部分包含一个 CContentRestriction 结构:
          • _Property 设置为 GUID b725f130-47ef-101a-a5f1-02608c9eebac / 0x00000001(用于 PRSPEC_PROPID)/ 0x13。
          • _Cc 设置为 0x00000006。
          • _pwcsphrase 设置为字符串“Office”。
          • _lcid 设置为 0x409(英语)。
          • _ulGenerateMethod 设置为 0x00000000(完全匹配)。

5 安全性

5.1 实现者的安全注意事项

索引安全内容的索引实现应考虑使用 SMB [MS-SMB] 提供的用户上下文来调整搜索结果,只返回调用方可访问的结果。

5.2 安全参数的索引

安全参数 部分
模拟级别 2.1

6 版本特定行为索引

版本特定行为 部分 Windows 2000 Windows XP Windows Server 2003
此协议在 Windows 2000、Windows XP、Windows Server 2003 和 Windows Vista 上实现。 1.3.2 X X X
应用程序通常与 OLE DB 接口包装器交互 1.4 X X X
NTSTATUS 值 1.8 X X X
客户端在每个消息标头中设置 _status 字段。 2.2.2 X X X
cPendingScans 值通常为零 2.2.3.1 X X X
iClientVersion 值 2.2.3.6 X X X
_cbChunk 值 2.2.3.19 X X X
32 位和 64 位内存地址 3.2.4.2.4 X X X