句柄数
过程地址句柄的格式字符串说明中多达两个部分。 第一部分是过程说明handle_type<1> 字段,用于指示隐式句柄。 此部分始终存在。 第二部分是过程中任何显式句柄的参数说明。 以下各节将介绍这两者,并讨论了绑定句柄问题的存根描述符结构的其他 MIDL 编译器支持。
如果过程使用隐式句柄进行绑定,则过程说明的 handle_type<1> 字段包含三个有效的非零值之一。 在存根描述符结构的 IMPLICIT_HANDLE_INFO 字段中找到对隐式句柄的 MIDL 编译器支持:
typedef (__RPC_FAR * GENERIC_BINDING_ROUTINE)();
typedef struct
{
GENERIC_BINDING_ROUTINE pfnBind;
GENERIC_BINDING_ROUTINE pfnUnbind;
} GENERIC_BINDING_ROUTINE_PAIR;
typedef struct __GENERIC_BINDING_INFO
{
void __RPC_FAR* pObj;
unsigned char Size;
GENERIC_BINDING_ROUTINE pfnBind;
GENERIC_BINDING_ROUTINE pfnUnbind;
} GENERIC_BINDING_INFO, *PGENERIC_BINDING_INFO;
union
{
handle_t* pAutoHandle;
handle_t* pPrimitiveHandle;
PGENERIC_BINDING_INFO pGenericBindingInfo;
} IMPLICIT_HANDLE_INFO;
如果过程使用自动句柄, 则 pAutoHandle 成员包含存根定义的自动句柄变量的地址。
如果过程使用隐式基元句柄, 则 pPrimitiveHandle 成员包含存根定义基元句柄变量的地址。
最后,如果过程使用隐式泛型句柄, 则 pGenericBindingInfo 成员保留指向相应 GENERIC_BINDING_INFO 结构的指针的地址。 数据结构MIDL_STUB_DESC包含指向GENERIC_BINDING_PAIR结构集合的指针。 此集合零位置的条目是为与 pGenericBindingInfo 在 IMPLICIT_HANDLE_INFO 中引用的泛型绑定句柄对应的绑定和取消绑定例程保留的。 隐式绑定句柄的类型在格式字符串中指示。
有三种可能的显式句柄类型:上下文、泛型和基元。 如果显式句柄 (或仅 [out] 上下文句柄(其处理方式与) 相同),则绑定句柄信息显示为过程参数之一。 三种可能的说明如下所示。
基元
FC_BIND_PRIMITIVE, flag<1>, offset<2>.
标志<1> 指示句柄是否由指针传递。
偏移量<2> 提供从堆栈开头到基元句柄的偏移量。
备注
类型格式字符串中的基元句柄说明将简化为单个FC_IGNORE。
泛型
FC_BIND_GENERIC, flag_and_size<1>, offset<2>, binding_routine_pair_index<1>, FC_PAD
flag_and _size<1> 具有上旗小号和小号小号。 标志指示句柄是否由指针传递。 size 字段提供用户定义的泛型句柄类型的大小。 此大小在 32 位系统上限制为 1、2 或 4 个字节,在 64 位系统上限制为 1、2、4 或 8 个字节。
offset<2> 字段提供从指针堆栈开始到给定大小的数据的偏移量。
binding_routine_pair_index<1> 字段将存根描述符的 aGenericBindingRoutinePairs 字段的索引提供给泛型句柄的 绑定 和 取消绑定 例程函数指针。
备注
类型格式的泛型句柄说明只是相关数据类型的说明。
上下文
FC_BIND_CONTEXT flags<1> offset<2> context_rundown_routine_index<1> param_num<1>
标志<1> 指示句柄的传递方式及其类型。 下表显示了有效标志。
Hex | 标志 |
---|---|
80 | HANDLE_PARAM_IS_VIA_PTR |
40 | HANDLE_PARAM_IS_IN |
20 | HANDLE_PARAM_IS_OUT |
21 | HANDLE_PARAM_IS_RETURN |
08 | NDR_STRICT_CONTEXT_HANDLE |
04 | NDR_CONTEXT_HANDLE_NO_SERIALIZE |
02 | NDR_CONTEXT_HANDLE_SERIALIZE |
01 | NDR_CONTEXT_HANDLE_CANNOT_BE_NULL |
前四个标志一直存在,最后四个标志是在 Windows 2000 中添加的。
offset<2> 字段提供从堆栈开始到上下文句柄的偏移量。
context_rundown_routine_index<1 为用于此上下文句柄的 rundown 例程提供 Stub 描述符的 apfnNdrRundownRoutines 字段的>索引。 编译器始终生成索引。 对于没有运行例程的例程,这是一个索引,指向保留 null 的表位置。
对于 –Oi2 中内置的存根,param_num<1> 提供从零开始的序号计数,指定它在给定过程中的上下文句柄。
对于解释器的早期版本,param_num<1> 在其过程中提供上下文句柄的参数编号(从零开始)。
备注
类型格式字符串中的上下文句柄说明在说明中没有偏移量<2> 。
如前所述, –Oif 标头在 –Oi 标头上展开。 为方便起见,所有字段都如下所示:
(旧标头)
handle_type<1>
Oi_flags<1>
[rpc_flags<4>]
proc_num<2>
stack_size<2>
[explicit_handle_description<>]
(–Oif 扩展)
constant_client_buffer_size<2>
constant_server_buffer_size<2>
INTERPRETER_OPT_FLAGS<1>
number_of_params<1>
constant_client_buffer_size<2> 提供可能由编译器预先计算的封送缓冲区的大小。 这可能只是部分大小,因为 ClientMustSize 标志会触发大小调整。
constant_server_buffer_size<2> 提供由编译器预计算的封送缓冲区的大小。 这可能只是部分大小,因为 ServerMustSize 标志会触发大小调整。
INTERPRETER_OPT_FLAGS在 Ndrtypes.h 中定义:
typedef struct
{
unsigned char ServerMustSize : 1; // 0x01
unsigned char ClientMustSize : 1; // 0x02
unsigned char HasReturn : 1; // 0x04
unsigned char HasPipes : 1; // 0x08
unsigned char Unused : 1;
unsigned char HasAsyncUuid : 1; // 0x20
unsigned char HasExtensions : 1; // 0x40
unsigned char HasAsyncHandle : 1; // 0x80
} INTERPRETER_OPT_FLAGS, *PINTERPRETER_OPT_FLAGS;
- 如果服务器需要执行缓冲区大小调整传递,则会设置 ServerMustSize 位。
- 如果客户端需要执行缓冲区大小调整传递,则会设置 ClientMustSize 位。
- 如果过程具有返回值,则设置 HasReturn 位。
- 如果需要使用管道包来支持管道参数,则设置 HasPipes 位。
- 如果过程是异步 DCOM 过程,则设置 HasAsyncUuid 位。
- HasExtensions 位指示使用 Windows 2000 及更高版本的扩展。
- HasAsyncHandle 位指示异步 RPC 过程。
HasAsyncHandle 位最初已用于异步支持的不同 DCOM 实现,因此不能用于 DCOM 中的当前样式异步支持。 HasAsyncUuid 位当前指示这一点。