There is a method within BCryptNative called GetInt32Property. It has the following signature:
internal static int GetInt32Property<T>(T algorithm, string property) where T : SafeHandle
This method only works when T is of type SafeBCryptAlgorithmHandle or SafeBCryptHashHandle. It calls native methods which are explicitly defined with those types of handles:
[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 uses function pointers / delegates to point to the correct native function. My question is, why didn't Microsoft just implemented the GetInt32Property method with the following signature:
internal static int GetInt32Property(SafeHandle algorithm, string property)
with the following native method:
[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);
Are there any downsides to this? (assuming that the SafeHandle passed to GetInt32Property is always either a SafeBCryptAlgorithmHandle or SafeBCryptHashHandle).
I'm just wondering about why Microsoft implemented this so relatively complicated.
Does it have to with:
According to the documentation the class must be inherited, and it is, however does a P/Invoked function handle it properly when given an abstract class of SafeHandle? Does it increment and decrement the reference counts appropriately?
It's hard to tell why Microsoft chose to implement something in one way or another, but I can answer your points.
GetInt32Property(algorithm, str)
.SafeHandle
.typeof(T) == typeof(SafeBCryptHashHandle)
type checks are not done in runtime, but in JIT time. This means that the method should perform slightly faster then a regular runtime check like algorith is SafeBCrypthHashHandle
.The SafeHandle
class is an abstract class. This means that you cannot create an instance of it, but you can inherit it. The native function only get marshaled data, they don't get real references to objects. Don't worry about reference counting.