A really safe way to handle this is to pass SafeHandle instead of the IntPtr link - the P / Invoke level is safe and will automatically work for you. The only exception is when you call your own API to close your handle, as SafeHandle becomes disposed of while you use it.
For example:
[DllImport( "qwave.dll", CallingConvention = CallingConvention.Winapi, SetLastError = true )] internal static extern bool QOSCreateHandle( ref QosVersion version, out QosSafeHandle qosHandle ); [DllImport( "qwave.dll", CallingConvention = CallingConvention.Winapi, SetLastError = true )] [ReliabilityContract( Consistency.WillNotCorruptState, Cer.Success )] internal static extern bool QOSCloseHandle( IntPtr qosHandle ); [DllImport( "qwave.dll", CallingConvention = CallingConvention.Winapi, SetLastError = true )] internal static extern bool QOSAddSocketToFlow( QosSafeHandle qosHandle, IntPtr socket, byte[] destAddr, QosTrafficType trafficType, QosFlowFlags flags, ref uint flowId );
However, this may not be possible if the SafeHandle implementation is passed as a parameter in the structure, or if the base descriptor is larger than IntPtr. For example, the Win32 SSPI api uses descriptors, which are two IntPtrs. To deal with this situation, you must do the CER manually.
Improper use of CER. DangerousAddRef may still not work. The following is a template used by Microsoft in a .Net source:
public static bool Write( string filename ) { using( var fs = new System.IO.FileStream( filename, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None ) ) { bool got_handle; bool result; // The CER is here to ensure that reference counting on fs.SafeFileHandle is never // corrupted. RuntimeHelpers.PrepareConstrainedRegions(); try { fs.SafeFileHandle.DangerousAddRef( ref got_handle ); } catch( Exception e ) { if( got_handle ) { fs.SafeFileHandle.DangerousRelease(); } got_handle = false; throw; } finally { if( got_handle ) { result = NativeMethods.Foo( fs.SafeFileHandle.DangerousGetHandle() ); fs.SafeFileHandle.DangerousRelease(); } } return result; } }
This template can be seen in the Microsoft help source - see _ SafeNetHandle.cs , line 2071.
antiduh
source share