|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.Win32.SafeHandles;
namespace System.DirectoryServices.Protocols
{
internal sealed class ConnectionHandle : SafeHandleZeroOrMinusOneIsInvalid
{
internal bool _needDispose;
public ConnectionHandle()
: base(true)
{
Interop.Ldap.ldap_initialize(out handle, null);
_needDispose = true;
}
internal ConnectionHandle(string uri)
: base(true)
{
Interop.Ldap.ldap_initialize(out handle, uri);
_needDispose = true;
}
internal ConnectionHandle(IntPtr value, bool disposeHandle) : base(true)
{
_needDispose = disposeHandle;
if (value == IntPtr.Zero)
{
throw new LdapException(SR.LDAP_CONNECT_ERROR);
}
else
{
SetHandle(value);
}
}
protected override bool ReleaseHandle()
{
if (_needDispose)
{
IntPtr nullPointer = IntPtr.Zero;
Interop.Ldap.ldap_unbind_ext_s(handle, ref nullPointer, ref nullPointer);
}
handle = IntPtr.Zero;
return true;
}
}
internal sealed class SafeBerHandle : SafeHandleZeroOrMinusOneIsInvalid
{
public SafeBerHandle() : base(true)
{
SetHandle(Interop.Ldap.ber_alloc(1));
if (handle == IntPtr.Zero)
{
throw new OutOfMemoryException();
}
}
internal SafeBerHandle(BerVal value) : base(true)
{
// In Linux if bv_val is null ber_init will segFault instead of returning IntPtr.Zero.
// In Linux if bv_len is 0 ber_init returns a valid pointer which will then fail when trying to use it,
// so we fail early by throwing exception if this is the case.
if (value.bv_val == IntPtr.Zero || value.bv_len.Value == 0)
{
throw new BerConversionException();
}
SetHandle(Interop.Ldap.ber_init(value));
if (handle == IntPtr.Zero)
{
throw new BerConversionException();
}
}
protected override bool ReleaseHandle()
{
Interop.Ldap.ber_free(handle, 1);
return true;
}
}
}
|