//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// CommonHelpers satellite library | Author: Sergei Y.Kitáev
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
using System;
#if LEGACY
using System.Security.Permissions;
#endif // LEGACY

namespace CommonHelpers {

//**************************************************************************************************
#if LEGACY
[PermissionSet(SecurityAction.Demand,Unrestricted=true)]
#endif // LEGACY
[HFullFunctionalModeRequired]
static partial class PAccessHlp {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public static unsafe void* InterlockedExchangePtr(
   [HIn][HOut][HInterlockedAccess] void** pPointerOperand,
   void* substutionPointerValue )
{
   HUnsafePtrArgChecking.VerifyNotNulls( pPointerOperand, substutionPointerValue );
   return (void*)PAccessNL.InterlockedExchangePtr( "DD15F11B-05D5-45DA-9A10-D2CFC66CE997",
      (IntPtr)pPointerOperand, (IntPtr)substutionPointerValue );
}

//--------------------------------------------------------------------------------------------------

public static unsafe void* ClearMemoryBlock( [HOut] void* pDestinationBlock,
                                             UIntPtr length )
{
   HUnsafePtrArgChecking.VerifyNotNull( pDestinationBlock );
   if ( length == UIntPtr.Zero )
      throw new ArgumentException();
   return (void*)PAccessNL.ClearMemoryBlock( "2D03F363-CE2A-4297-88B0-0C748E61A687",
      (IntPtr)pDestinationBlock, length );
}
public static unsafe void* CopyMemoryBlock( [HIn] void* pSourceBlock,
                                            [HOut] void* pDestinationBlock,
                                            UIntPtr length )
{
   HUnsafePtrArgChecking.VerifyNotNulls( pSourceBlock, pDestinationBlock );
   if ( length == UIntPtr.Zero )
      throw new ArgumentException();
   return (void*)PAccessNL.CopyMemoryBlock( "3ABBE8F3-0F1C-444D-BB6B-7FB05A633D65",
      (IntPtr)pSourceBlock, (IntPtr)pDestinationBlock, length );
}

//--------------------------------------------------------------------------------------------------

public static unsafe T[] CopyBufferToArray<T>( [HIn] void* pSourceElements,
                                               T[] destinationElements ) where T: struct
{
   HUnsafePtrArgChecking.VerifyNotNull( pSourceElements );
   HArgChecking.VerifyNotNull( destinationElements );
   int count = destinationElements.Length;
   if ( count == 0 )
      throw new ArgumentException();
   var array = new T[ count ];
   using (var target = new HPinPtr(array))
      PAccessNL.CopyMemoryBlock( "F3E6C0EC-7C96-4D0D-8FE0-6098958A8165",
         (IntPtr)pSourceElements, target,
         (UIntPtr)(HMarshal.SizeOf( typeof(T) ) * count) );
   return array;
}

public static unsafe void* CopyArrayToBuffer<T>( T[] sourceElements,
                                                 [HOut] void* pDestinationElements )
                                                 where T: struct
{
   HArgChecking.VerifyNotNull( sourceElements );
   HUnsafePtrArgChecking.VerifyNotNull( pDestinationElements );
   int count = sourceElements.Length;
   if ( count == 0 )
      throw new ArgumentException();
   using (var source = new HPinPtr(sourceElements))
      return (void*)PAccessNL.CopyMemoryBlock( "E41DA0EF-7B97-43E0-9761-A72B0E7B0E45",
         source, (IntPtr)pDestinationElements,
         (UIntPtr)(HMarshal.SizeOf( typeof(T) ) * sourceElements.Length) );
}

//--------------------------------------------------------------------------------------------------

public static unsafe void ReleaseIUnknown([HIn][HOut] void* pIUnknown)
{
   HUnsafePtrArgChecking.VerifyNotNull( pIUnknown );
   PAccessNL.ReleaseIUnknown( "AC9B2AD6-9CC2-4EFE-A6FE-490F99E0FBAA",
      (IntPtr)pIUnknown );
}

//==================================================================================================

/// <exception cref="TypeInitializationException" />
public static void Access()
{}

//==================================================================================================

static PAccessHlp()
{
   HNativeLib.VerifyInitialized();
   CommonHelpers_PAccess.Access();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // PAccessHlp
//**************************************************************************************************

} // CommonHelpers
