使用SafeHandle

时间:2015-09-24 00:36:43

标签: c# pinvoke safehandle

BCryptNative中有一个名为GetInt32Property的方法。 它有以下签名:

internal static int GetInt32Property<T>(T algorithm, string property) where T : SafeHandle

此方法仅在T为SafeBCryptAlgorithmHandleSafeBCryptHashHandle类型时有效。它调用使用这些类型的句柄显式定义的本机方法:

[DllImport("bcrypt.dll", EntryPoint = "BCryptGetProperty", CharSet = CharSet.Unicode)]
internal static extern ErrorCode BCryptGetAlgorithmProperty(SafeBCryptAlgorithmHandle hObject,
                                                            string pszProperty,
                                                            [MarshalAs(UnmanagedType.LPArray), In, Out] byte[] pbOutput,
                                                            int cbOutput,
                                                            [In, Out] ref int pcbResult,
                                                            int flags);

[DllImport("bcrypt.dll", EntryPoint = "BCryptGetProperty", CharSet = CharSet.Unicode)]
internal static extern ErrorCode BCryptGetHashProperty(SafeBCryptHashHandle hObject,
                                                       string pszProperty,
                                                       [MarshalAs(UnmanagedType.LPArray), In, Out] byte[] pbOutput,
                                                       int cbOutput,
                                                       [In, Out] ref int pcbResult,
                                                       int flags);

Microsoft使用函数指针/委托指向正确的本机函数。我的问题是,为什么Microsoft没有使用以下签名实现GetInt32Property方法:

internal static int GetInt32Property(SafeHandle algorithm, string property)

使用以下原生方法:

[DllImport("bcrypt.dll", CharSet = CharSet.Unicode)]
internal static extern ErrorCode BCryptGetProperty(SafeHandle hObject,
                                                   string pszProperty,
                                                   [MarshalAs(UnmanagedType.LPArray), In, Out] byte[] pbOutput,
                                                   int cbOutput,
                                                   [In, Out] ref int pcbResult,
                                                   int flags);

这有什么缺点吗? (假设传递给GetInt32Property的SafeHandle始终是SafeBCryptAlgorithmHandleSafeBCryptHashHandle)。

我只是想知道为什么微软实施这个相对复杂的原因。

是否必须:

  • 安全透明代码?
  • 类型安全吗? (这样你就不会使用除这两种类型之外的任何其他类型)
  • 是否允许明确使用SafeHandle?

根据documentation,必须继承该类,然而,当给定一个抽象类的SafeHandle时,P / Invoked函数是否正确处理它?它是否适当增加和减少参考计数?

1 个答案:

答案 0 :(得分:1)

很难说微软选择以某种方式实现某些目标,但我可以回答你的观点。

  • 代码并不复杂。用法很明确(类似于GetInt32Property(algorithm, str)
  • 它不会强制您发送您提到的其中一种类型,只要它实现SafeHandle,您仍可以使用其他类调用它。
  • 使用的本机方法实际上是相同的。这有点奇怪,但我不是这个特定图书馆的专家,所以这可能是有充分理由的。
  • 像这样的通用方法有一个隐藏的好处。 typeof(T) == typeof(SafeBCryptHashHandle)类型检查不是在运行时完成的,而是在JIT时间内完成的。这意味着该方法的执行速度应该比algorith is SafeBCrypthHashHandle等常规运行时检查稍快一些。

SafeHandle类是一个抽象类。这意味着您无法创建它的实例,但您可以继承它。本机函数只获取封送数据,它们无法获得对象的真实引用。不要担心引用计数。