相关描述符

关联描述符是一种格式字符串,用于描述基于与另一个参数相关的一个参数的表达式。 处理与 [size_is () ]、 [length_is () ]、 [switch_is () ] 和 [iid_is () ] 等属性相关的语义时,需要使用相关描述符。 相关描述符与数组、大小指针、联合和接口指针一起使用。 最终表达式值可以分别为大小、长度、联合判别值或指向 IID 的指针。 在格式字符串方面,相关描述符与数组、联合和接口指针一起使用。 大小指针在格式字符串中描述为指向数组的指针。

有两个执行基本表达式计算的例程:NdrpComputeConformance 用于大小、开关和 IID*,而 NdrpComputeVariance 用于长度。 还有一个例程用于对拒绝攻击功能执行关联值验证。

相关描述符设计为仅支持非常有限的表达式。 对于复杂情况,编译器会生成一个表达式计算例程,供引擎在需要时调用。

相关描述符具有以下格式:

correlation_type<1>
correlation_operator<1>
offset<2>
[robust_flags<2>]

correlation_type 1> 的相关描述符<由两个小数组成:上 4 位描述可在何处找到表达式,低 4 位描述表达式值的类型。

上半部分可以有以下五个值之一:

00  FC_NORMAL_CONFORMANCE
10  FC_POINTER_CONFORMANCE
20  FC_TOP_LEVEL_CONFORMANCE
80  FC_TOP_LEVEL_MULTID_CONFORMANCE
40  FC_CONSTANT_CONFORMANCE

FC_NORMAL_CONFORMANCE

符合性的正常情况,如结构的字段中所述的情况。

FC_POINTER_CONFORMANCE

对于特性化指针 (size_is () length_is () ) 是结构中的字段。 这会影响基本内存指针的设置方式。

FC_TOP_LEVEL_CONFORMANCE

对于由另一个参数描述的顶级一致性。

FC_TOP_LEVEL_MULTID_CONFORMANCE

对于由另一个参数描述的多维数组的顶级一致性。

注意

多维大小的数组和指针触发切换到 –Oicf

 

FC_CONSTANT_CONFORMANCE

对于常量值。 编译器根据用户提供的常量表达式预先计算值。 在这种情况下,符合性说明中的后续 3 个字节包含描述符合性大小的长字节的低 3 个字节。 无需进一步计算。

较低的小数提供需要从内存中提取的值的类型:

FC_LONG | FC_ULONG | 
FC_SHORT | FC_USHORT | 
FC_SMALL | FC_USMALL | 
FC_HYPER

注意

不支持 64 位表达式。 FC_HYPER仅用于 64 位平台上 的 iid_is () ,以提取 IID*的指针值。

对于以下情况,编译器将类型小数设置为零:上面提到的常量表达式以及需要调用计算表达式例程时(例如,在使用FC_CONSTANT_CONFORMANCE和FC_CALLBACK时)。

 

size_is_op<1> 字段允许将下列操作之一应用于符合性变量:

FC_DEREFERENCE | 
FC_DIV_2 | FC_MULT_2 | FC_SUB_1 | FC_ADD_1 | 
FC_CALLBACK

FC_DEREFERENCE常量用于关联作为点,例如 [size_is (*pL) ]。 算术运算符仅使用指示的常量。 FC_CALLBACK常量指示需要调用表达式计算例程。

offset<2> 字段通常是表达式参数变量的相对内存偏移量。 它也可以是表达式计算例程索引。 如本文档前面所述,对于常量表达式,它是实际最终表达式值的一部分。

偏移量<2> 字段解释为内存偏移量取决于表达式的复杂性、表达式变量的位置,以及数组是否实际上是属性指针。

如果数组是特性化指针,并且符合性变量是结构中的字段,则偏移字段包含从结构开头到符合性描述字段的偏移量。 如果数组不是特性化指针,并且符合性变量是结构中的字段,则偏移量字段包含从结构的不合格部分的末尾到符合性描述字段的偏移量。 通常,符合性数组位于结构的末尾。

对于顶级一致性,偏移量字段包含从存根的第一个参数在堆栈上的位置到描述符合性的参数的偏移量。 这在 –Os 模式下未使用。 偏移字段的解释还有其他例外:这些类型的说明中介绍了此类异常。

当偏移量<2> 与FC_CALLBACK一起使用时,它在编译器生成的表达式计算例程表中包含索引。 存根消息将传递到评估例程,然后计算符合性值并将其分配给存根消息的 MaxCount 字段。

已为 Windows 2000> 添加了 robust_flags<2 字段以支持 /robust,例如拒绝攻击功能。 以下标志在第一个字节上定义:

typedef  struct  _NDR_CORRELATION_FLAGS
  {
  unsigned char   Early     : 1;
  unsigned char   Split     : 1;
  unsigned char   IsIidIs   : 1;
  unsigned char   DontCheck : 1;
  unsigned char   Unused    : 4;
  } NDR_CORRELATION_FLAGS;

“早期”标志指示早期关联与后期关联。 早期关联是表达式参数在描述的参数之前时,例如 size 参数位于大小指针参数之前。 后期关联是表达式参数位于相关参数之后时。 引擎立即执行早期相关值的验证,后期相关值将存储在取消封存后进行检查。

Split 标志指示 [in] 和 [out] 参数之间的异步拆分。 例如,size 参数可以是 [in],而大小指针可以是 [out]。 在 DCOM 异步上下文中,这些参数恰好位于不同的堆栈上,因此引擎必须了解这一点。

IsIidIs 标志指示 iid_is () 相关。 NdrComputeConformance 例程被欺骗获取指向 IID 的指针作为表达式值,但验证例程无法比较此类值 (它们是指针) ,因此标志指示需要比较实际 IID。

方差说明和其他数组属性

差异说明字段格式与符合性说明字段相同。 区别在于,NDR 引擎使用不同的存根消息字段作为临时变量。 在方差描述中,计算的长度为 ,相应的字段称为 ActualLength。

使用方差时,起始偏移量通常为零,并相应地优化引擎。 如果将 first_is () 属性应用于符合的可变数组,则会强制回调表达式计算例程。