// ReSharper disable UnusedMethodReturnValue.Global // ReSharper disable UnusedMember.Global using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using RGB.NET.Core.Exceptions; namespace RGB.NET.Devices.Asus.Native { // ReSharper disable once InconsistentNaming internal static class _AsusSDK { #region Libary Management private static IntPtr _dllHandle = IntPtr.Zero; /// /// Gets the loaded architecture (x64/x86). /// internal static string LoadedArchitecture { get; private set; } /// /// Reloads the SDK. /// internal static void Reload() { UnloadAsusSDK(); LoadAsusSDK(); } private static void LoadAsusSDK() { if (_dllHandle != IntPtr.Zero) return; // HACK: Load library at runtime to support both, x86 and x64 with one managed dll List possiblePathList = Environment.Is64BitProcess ? AsusDeviceProvider.PossibleX64NativePaths : AsusDeviceProvider.PossibleX86NativePaths; string dllPath = possiblePathList.FirstOrDefault(File.Exists); if (dllPath == null) throw new RGBDeviceException($"Can't find the Asus-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'"); SetDllDirectory(Path.GetDirectoryName(Path.GetFullPath(dllPath))); _dllHandle = LoadLibrary(dllPath); _enumerateMbControllerPointer = (EnumerateMbControllerPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "EnumerateMbController"), typeof(EnumerateMbControllerPointer)); _getMbLedCountPointer = (GetMbLedCountPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "GetMbLedCount"), typeof(GetMbLedCountPointer)); _setMbModePointer = (SetMbModePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetMbMode"), typeof(SetMbModePointer)); _setMbColorPointer = (SetMbColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetMbColor"), typeof(SetMbColorPointer)); _getMbColorPointer = (GetMbColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "GetMbColor"), typeof(GetMbColorPointer)); _enumerateGPUPointer = (EnumerateGPUPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "EnumerateGPU"), typeof(EnumerateGPUPointer)); _getGPULedCountPointer = (GetGPULedCountPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "GetGPULedCount"), typeof(GetGPULedCountPointer)); _setGPUModePointer = (SetGPUModePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetGPUMode"), typeof(SetGPUModePointer)); _setGPUColorPointer = (SetGPUColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetGPUColor"), typeof(SetGPUColorPointer)); _createClaymoreKeyboardPointer = (CreateClaymoreKeyboardPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CreateClaymoreKeyboard"), typeof(CreateClaymoreKeyboardPointer)); _getClaymoreKeyboardLedCountPointer = (GetClaymoreKeyboardLedCountPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "GetClaymoreKeyboardLedCount"), typeof(GetClaymoreKeyboardLedCountPointer)); _setClaymoreKeyboardModePointer = (SetClaymoreKeyboardModePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetClaymoreKeyboardMode"), typeof(SetClaymoreKeyboardModePointer)); _setClaymoreKeyboardColorPointer = (SetClaymoreKeyboardColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetClaymoreKeyboardColor"), typeof(SetClaymoreKeyboardColorPointer)); _enumerateRogMousePointer = (CreateRogMousePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CreateRogMouse"), typeof(CreateRogMousePointer)); _getRogMouseLedCountPointer = (GetRogMouseLedCountPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "RogMouseLedCount"), typeof(GetRogMouseLedCountPointer)); // DarthAffe 07.10.2017: Be careful with the naming here - i don't know why but there is no 'Get'! _setRogMouseModePointer = (SetRogMouseModePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetRogMouseMode"), typeof(SetRogMouseModePointer)); _setRogMouseColorPointer = (SetRogMouseColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetRogMouseColor"), typeof(SetRogMouseColorPointer)); //TODO DarthAffe 29.10.2017: I don't know why they are even documented, but the asus guy said they aren't in the SDK right now. //_enumerateDramPointer = (EnumerateDramPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "EnumerateDram"), typeof(EnumerateDramPointer)); //_getDramLedCountPointer = (GetDramLedCountPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "GetDramLedCount"), typeof(GetDramLedCountPointer)); //_setDramModePointer = (SetDramModePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetDramMode"), typeof(SetDramModePointer)); //_setDramColorPointer = (SetDramColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetDramColor"), typeof(SetDramColorPointer)); //_getDramColorPointer = (GetDramColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "GetDramColor"), typeof(GetDramColorPointer)); } private static void UnloadAsusSDK() { if (_dllHandle == IntPtr.Zero) return; // ReSharper disable once EmptyEmbeddedStatement - DarthAffe 07.10.2017: We might need to reduce the internal reference counter more than once to set the library free while (FreeLibrary(_dllHandle)) ; _dllHandle = IntPtr.Zero; } [DllImport("kernel32.dll")] private static extern bool SetDllDirectory(string lpPathName); [DllImport("kernel32.dll")] private static extern IntPtr LoadLibrary(string dllToLoad); [DllImport("kernel32.dll")] private static extern bool FreeLibrary(IntPtr dllHandle); [DllImport("kernel32.dll")] private static extern IntPtr GetProcAddress(IntPtr dllHandle, string name); #endregion #region SDK-METHODS #region Pointers private static EnumerateMbControllerPointer _enumerateMbControllerPointer; private static GetMbLedCountPointer _getMbLedCountPointer; private static SetMbModePointer _setMbModePointer; private static SetMbColorPointer _setMbColorPointer; private static GetMbColorPointer _getMbColorPointer; private static EnumerateGPUPointer _enumerateGPUPointer; private static GetGPULedCountPointer _getGPULedCountPointer; private static SetGPUModePointer _setGPUModePointer; private static SetGPUColorPointer _setGPUColorPointer; private static CreateClaymoreKeyboardPointer _createClaymoreKeyboardPointer; private static GetClaymoreKeyboardLedCountPointer _getClaymoreKeyboardLedCountPointer; private static SetClaymoreKeyboardModePointer _setClaymoreKeyboardModePointer; private static SetClaymoreKeyboardColorPointer _setClaymoreKeyboardColorPointer; private static CreateRogMousePointer _enumerateRogMousePointer; private static GetRogMouseLedCountPointer _getRogMouseLedCountPointer; private static SetRogMouseModePointer _setRogMouseModePointer; private static SetRogMouseColorPointer _setRogMouseColorPointer; private static EnumerateDramPointer _enumerateDramPointer; private static SetDramModePointer _setDramModePointer; private static GetDramLedCountPointer _getDramLedCountPointer; private static SetDramColorPointer _setDramColorPointer; private static GetDramColorPointer _getDramColorPointer; #endregion #region Delegates [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate int EnumerateMbControllerPointer(IntPtr handles, int size); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate int GetMbLedCountPointer(IntPtr handle); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate void SetMbModePointer(IntPtr handle, int mode); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate void SetMbColorPointer(IntPtr handle, byte[] colors, int size); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate int GetMbColorPointer(IntPtr handle, IntPtr colors, int size); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate int EnumerateGPUPointer(IntPtr handles, int size); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate int GetGPULedCountPointer(IntPtr handle); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate void SetGPUModePointer(IntPtr handle, int mode); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate void SetGPUColorPointer(IntPtr handle, byte[] colors, int size); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate bool CreateClaymoreKeyboardPointer(IntPtr handle); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate int GetClaymoreKeyboardLedCountPointer(IntPtr handle); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate void SetClaymoreKeyboardModePointer(IntPtr handle, int mode); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate void SetClaymoreKeyboardColorPointer(IntPtr handle, byte[] colors, int size); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate bool CreateRogMousePointer(IntPtr handle); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate int GetRogMouseLedCountPointer(IntPtr handle); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate void SetRogMouseModePointer(IntPtr handle, int mode); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate void SetRogMouseColorPointer(IntPtr handle, byte[] colors, int size); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate int EnumerateDramPointer(IntPtr handles, int size); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate int GetDramLedCountPointer(IntPtr handle); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate void SetDramModePointer(IntPtr handle, int mode); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate void SetDramColorPointer(IntPtr handle, byte[] colors, int size); [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate int GetDramColorPointer(IntPtr handle, IntPtr colors, int size); #endregion // ReSharper disable EventExceptionNotDocumented internal static int EnumerateMbController(IntPtr handles, int size) => _enumerateMbControllerPointer(handles, size); internal static int GetMbLedCount(IntPtr handle) => _getMbLedCountPointer(handle); internal static void SetMbMode(IntPtr handle, int mode) => _setMbModePointer(handle, mode); internal static void SetMbColor(IntPtr handle, byte[] colors) => _setMbColorPointer(handle, colors, colors.Length); internal static byte[] GetMbColor(IntPtr handle) { int count = _getDramColorPointer(handle, IntPtr.Zero, 0); byte[] colors = new byte[count]; IntPtr readColorsPtr = Marshal.AllocHGlobal(colors.Length); _getMbColorPointer(handle, readColorsPtr, colors.Length); Marshal.Copy(readColorsPtr, colors, 0, colors.Length); Marshal.FreeHGlobal(readColorsPtr); return colors; } internal static int EnumerateGPU(IntPtr handles, int size) => _enumerateGPUPointer(handles, size); internal static int GetGPULedCount(IntPtr handle) => _getGPULedCountPointer(handle); internal static void SetGPUMode(IntPtr handle, int mode) => _setGPUModePointer(handle, mode); internal static void SetGPUColor(IntPtr handle, byte[] colors) => _setGPUColorPointer(handle, colors, colors.Length); internal static bool CreateClaymoreKeyboard(IntPtr handle) => _createClaymoreKeyboardPointer(handle); internal static int GetClaymoreKeyboardLedCount(IntPtr handle) => _getClaymoreKeyboardLedCountPointer(handle); internal static void SetClaymoreKeyboardMode(IntPtr handle, int mode) => _setClaymoreKeyboardModePointer(handle, mode); internal static void SetClaymoreKeyboardColor(IntPtr handle, byte[] colors) => _setClaymoreKeyboardColorPointer(handle, colors, colors.Length); internal static bool CreateRogMouse(IntPtr handle) => _enumerateRogMousePointer(handle); internal static int GetRogMouseLedCount(IntPtr handle) => _getRogMouseLedCountPointer(handle); internal static void SetRogMouseMode(IntPtr handle, int mode) => _setRogMouseModePointer(handle, mode); internal static void SetRogMouseColor(IntPtr handle, byte[] colors) => _setRogMouseColorPointer(handle, colors, colors.Length); //internal static int EnumerateDram(IntPtr handles, int size) => _enumerateDramPointer(handles, size); //internal static int GetDramLedCount(IntPtr handle) => _getDramLedCountPointer(handle); //internal static void SetDramMode(IntPtr handle, int mode) => _setDramModePointer(handle, mode); //internal static void SetDramColor(IntPtr handle, byte[] colors) => _setDramColorPointer(handle, colors, colors.Length); //internal static byte[] GetDramColor(IntPtr handle) //{ // int count = _getDramColorPointer(handle, IntPtr.Zero, 0); // byte[] colors = new byte[count]; // IntPtr readColorsPtr = Marshal.AllocHGlobal(colors.Length); // _getDramColorPointer(handle, readColorsPtr, colors.Length); // Marshal.Copy(readColorsPtr, colors, 0, colors.Length); // Marshal.FreeHGlobal(readColorsPtr); // return colors; //} // ReSharper restore EventExceptionNotDocumented #endregion } }