// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace Microsoft.ClearScript.Util
{
internal static class NativeMethods
{
public static IntPtr LoadLibrary(string path)
{
if (MiscHelpers.PlatformIsWindows())
{
return NativeWindowsMethods.LoadLibraryW(path);
}
if (MiscHelpers.PlatformIsLinux())
{
return NativeLinuxMethods.LoadLibrary(path);
}
if (MiscHelpers.PlatformIsOSX())
{
return NativeOSXMethods.LoadLibrary(path);
}
throw new PlatformNotSupportedException();
}
public static bool FreeLibrary(IntPtr hLibrary)
{
if (MiscHelpers.PlatformIsWindows())
{
return NativeWindowsMethods.FreeLibrary(hLibrary);
}
if (MiscHelpers.PlatformIsLinux())
{
return NativeLinuxMethods.FreeLibrary(hLibrary) == 0;
}
if (MiscHelpers.PlatformIsOSX())
{
return NativeOSXMethods.FreeLibrary(hLibrary) == 0;
}
throw new PlatformNotSupportedException();
}
public static string GetLoadLibraryErrorMessage()
{
if (MiscHelpers.PlatformIsWindows())
{
return new Win32Exception().Message;
}
if (MiscHelpers.PlatformIsLinux())
{
return Marshal.PtrToStringAnsi(NativeLinuxMethods.GetLoadLibraryErrorMessage());
}
if (MiscHelpers.PlatformIsOSX())
{
return Marshal.PtrToStringAnsi(NativeOSXMethods.GetLoadLibraryErrorMessage());
}
throw new PlatformNotSupportedException();
}
public static uint CLSIDFromProgID(string progID, out Guid clsid)
{
if (MiscHelpers.PlatformIsWindows())
{
return NativeWindowsMethods.CLSIDFromProgID(progID, out clsid);
}
throw new PlatformNotSupportedException();
}
public static uint ProgIDFromCLSID(ref Guid clsid, out string progID)
{
if (MiscHelpers.PlatformIsWindows())
{
return NativeWindowsMethods.ProgIDFromCLSID(ref clsid, out progID);
}
throw new PlatformNotSupportedException();
}
public static uint CoCreateInstance(ref Guid clsid, IntPtr pOuter, uint clsContext, ref Guid iid, out IntPtr pInterface)
{
if (MiscHelpers.PlatformIsWindows())
{
return NativeWindowsMethods.CoCreateInstance(ref clsid, pOuter, clsContext, ref iid, out pInterface);
}
throw new PlatformNotSupportedException();
}
public static void VariantInit(IntPtr pVariant)
{
if (MiscHelpers.PlatformIsWindows())
{
NativeWindowsMethods.VariantInit(pVariant);
}
else
{
throw new PlatformNotSupportedException();
}
}
public static uint VariantClear(IntPtr pVariant)
{
if (MiscHelpers.PlatformIsWindows())
{
return NativeWindowsMethods.VariantClear(pVariant);
}
throw new PlatformNotSupportedException();
}
public static IntPtr HeapCreate(uint options, UIntPtr initialSize, UIntPtr maximumSize)
{
if (MiscHelpers.PlatformIsWindows())
{
return NativeWindowsMethods.HeapCreate(options, initialSize, maximumSize);
}
throw new PlatformNotSupportedException();
}
public static IntPtr HeapAlloc(IntPtr hHeap, uint flags, UIntPtr size)
{
if (MiscHelpers.PlatformIsWindows())
{
return NativeWindowsMethods.HeapAlloc(hHeap, flags, size);
}
throw new PlatformNotSupportedException();
}
public static bool HeapFree(IntPtr hHeap, uint flags, IntPtr pBlock)
{
if (MiscHelpers.PlatformIsWindows())
{
return NativeWindowsMethods.HeapFree(hHeap, flags, pBlock);
}
throw new PlatformNotSupportedException();
}
public static bool HeapDestroy(IntPtr hHeap)
{
if (MiscHelpers.PlatformIsWindows())
{
return NativeWindowsMethods.HeapDestroy(hHeap);
}
throw new PlatformNotSupportedException();
}
public static bool VirtualProtect(IntPtr pBlock, UIntPtr size, uint newProtect, out uint oldProtect)
{
if (MiscHelpers.PlatformIsWindows())
{
return NativeWindowsMethods.VirtualProtect(pBlock, size, newProtect, out oldProtect);
}
throw new PlatformNotSupportedException();
}
#region Nested type: NativeWindowsMethods
private static class NativeWindowsMethods
{
// ReSharper disable MemberHidesStaticFromOuterClass
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
public static extern IntPtr LoadLibraryW(
[In] [MarshalAs(UnmanagedType.LPWStr)] string path
);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool FreeLibrary(
[In] IntPtr hLibrary
);
[DllImport("ole32.dll", ExactSpelling = true)]
public static extern uint CLSIDFromProgID(
[In] [MarshalAs(UnmanagedType.LPWStr)] string progID,
[Out] out Guid clsid
);
[DllImport("ole32.dll")]
public static extern uint ProgIDFromCLSID(
[In] ref Guid clsid,
[Out] [MarshalAs(UnmanagedType.LPWStr)] out string progID
);
[DllImport("ole32.dll", ExactSpelling = true)]
public static extern uint CoCreateInstance(
[In] ref Guid clsid,
[In] IntPtr pOuter,
[In] uint clsContext,
[In] ref Guid iid,
[Out] out IntPtr pInterface
);
[DllImport("oleaut32.dll", ExactSpelling = true)]
public static extern void VariantInit(
[In] IntPtr pVariant
);
[DllImport("oleaut32.dll", ExactSpelling = true)]
public static extern uint VariantClear(
[In] IntPtr pVariant
);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr HeapCreate(
[In] uint options,
[In] UIntPtr initialSize,
[In] UIntPtr maximumSize
);
[DllImport("kernel32.dll", SetLastError = false)]
public static extern IntPtr HeapAlloc(
[In] IntPtr hHeap,
[In] uint flags,
[In] UIntPtr size
);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool HeapFree(
[In] IntPtr hHeap,
[In] uint flags,
[In] IntPtr pBlock
);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool HeapDestroy(
[In] IntPtr hHeap
);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool VirtualProtect(
[In] IntPtr pBlock,
[In] UIntPtr size,
[In] uint newProtect,
[Out] out uint oldProtect
);
// ReSharper restore MemberHidesStaticFromOuterClass
}
#endregion
#region Nested type: NativeLinuxMethods
private static class NativeLinuxMethods
{
// ReSharper disable MemberHidesStaticFromOuterClass
[Flags]
public enum LoadLibraryFlags
{
// ReSharper disable UnusedMember.Local
None = 0,
Lazy = 0x0001,
Now = 0x0002,
BindingMask = 0x0003,
NoLoad = 0x0004,
DeepBind = 0x0008,
Local = None,
Global = 0x0100,
NoDelete = 0x1000
// ReSharper restore UnusedMember.Local
}
[DllImport("libdl.so.2", EntryPoint = "dlopen")]
public static extern IntPtr LoadLibrary(
[In] [MarshalAs(UnmanagedType.LPStr)] string path,
[In] LoadLibraryFlags flags = LoadLibraryFlags.Now | LoadLibraryFlags.Global
);
[DllImport("libdl.so.2", EntryPoint = "dlclose")]
public static extern int FreeLibrary(
[In] IntPtr hLibrary
);
[DllImport("libdl.so.2", EntryPoint = "dlerror")]
public static extern IntPtr GetLoadLibraryErrorMessage();
// ReSharper restore MemberHidesStaticFromOuterClass
}
#endregion
#region Nested type: NativeOSXMethods
private static class NativeOSXMethods
{
// ReSharper disable MemberHidesStaticFromOuterClass
[Flags]
public enum LoadLibraryFlags
{
// ReSharper disable UnusedMember.Local
None = 0,
Lazy = 0x01,
Now = 0x02,
Local = 0x04,
Global = 0x08,
NoLoad = 0x10,
NoDelete = 0x80
// ReSharper restore UnusedMember.Local
}
[DllImport("libdl.dylib", EntryPoint = "dlopen")]
public static extern IntPtr LoadLibrary(
[In] [MarshalAs(UnmanagedType.LPStr)] string path,
[In] LoadLibraryFlags flags = LoadLibraryFlags.Now | LoadLibraryFlags.Global
);
[DllImport("libdl.dylib", EntryPoint = "dlclose")]
public static extern int FreeLibrary(
[In] IntPtr hLibrary
);
[DllImport("libdl.dylib", EntryPoint = "dlerror")]
public static extern IntPtr GetLoadLibraryErrorMessage();
// ReSharper restore MemberHidesStaticFromOuterClass
}
#endregion
}
}