2

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.

DeltaVax
  • 21
  • 2
  • 1
    The simple solution is that if the Atapi library is not working with a 64-bit IntPtr then you should be sending a 32-bit value. Once you recieve the value convert it into a IntPtr. Of course the fact its not working sounds like a bug in the library because IntPtr is the correct way to do SafeHandles. You can do this by making your application a 32-bit application even on a x64 operating system – Security Hound Oct 11 '11 at 11:42
  • You are on the wrong track with this, an operating system handle is an IntPtr. SafeHandle is just a wrapper for it. Set a breakpoint on the ReleaseHandle() method to ensure the handle isn't released too soon. But more likely is TAPI itself, it hasn't done well. I'd definitely avoid trying to use it in 64-bit mode. – Hans Passant Oct 11 '11 at 12:13
  • Thanks for the feedback. The ReleaseHandle() is not being released too soon, and in fact the handle that causes the error (HTCALL) is marked Closed and Invalid upon creation because it is passed the hCall value of 0. hCall is defined in Atapi as an IntPtr that the lineMakeCall function is supposed to assign a value to. I'll try to find another workaround. – DeltaVax Oct 12 '11 at 03:27

1 Answers1

0

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.

Polluks
  • 525
  • 2
  • 8
  • 19
27k1
  • 2,212
  • 1
  • 22
  • 22