Does anyone know of an implementation similar to SafeHandle that doesn’t use an IntPtr that I can derive from? Or should I create a new handle altogether? I’d need functionality like DangerousGetHandle() and SetHandle() as these are used throughout the library I'm using.
The reason I ask is that I’m writing an application that uses the Atapi managed .NET library for TAPI 2.x (available here: http://atapi.codeplex.com/ ). The application targets both 32- and 64-bit platforms, and currently works fine on 32-bit, but when running on 64-bit it throws an error on this line in the library's TapiCall class:
rc = NativeMethods.lineGetCallStatus(_hCall, pLcs);
The first lines of the exception detail:
System.ObjectDisposedException was unhandled
Message=Safe handle has been closed
Source=mscorlib
ObjectName=""
StackTrace:
at System.StubHelpers.StubHelpers.SafeHandleC2NHelper(Object pThis, IntPtr pCleanupWorkList)
at JulMar.Atapi.Interop.NativeMethods.lineGetCallStatus(HTCALL hCall, IntPtr lpCallStatus)
I traced back a few calls and believe the source of the problem is the following call to a native function in Tapi32.dll:
int rc = NativeMethods.lineMakeCall(Line.Handle, out hCall, address, countryCode, lpCp);
(Defined in TAPI here: http://msdn.microsoft.com/en-us/library/ms735988(VS.85).aspx )
The hCall value in 64-bit is “0” whereas in 32-bit it is a 5 digit handle. The other parameters’ values seem ok and are identical on both platforms.
My guess is that part of the problem is with the Line.Handle, which is derived from SafeHandle and is defined in the library as follows:
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
internal class HTLINE : SafeHandle
{
internal HTLINE()
: base(IntPtr.Zero, true)
{
}
internal HTLINE(IntPtr preexistingHandle, bool ownsHandle)
: base(preexistingHandle, ownsHandle)
{
}
protected override bool ReleaseHandle()
{
if (handle != IntPtr.Zero)
{
NativeMethods.lineClose(handle);
handle = IntPtr.Zero;
}
return true;
}
public override bool IsInvalid
{
get { return handle == IntPtr.Zero; }
}
}
The underlying handle is an IntPtr and since it's different sizes on 32- and 64-bit, I thought this might be causing a problem if TAPI is expecting just 4 bytes as on 32-bit. To test this theory out I was thinking of creating a handle that doesn’t use an IntPtr. Does this sound like a reasonable approach?
Thanks for any advice.
I have just had the same problem on .net 3.5 (mscorlib is 32 bit) and in this case julmar ATAPI must be compiled as x86 because Any CPU or x64 is not an option for 64 bit operating systems.
I do not have dotnet 4.0 which supports mscorlib 64 bit, so I could not debug any further and my only option was x86.
For info, the TSP will need to be the 64 bit version on 64 bit systems.