/// <summary> /// Free resources. /// </summary> /// TODO: does this even get called? public void Dispose() { if (_dll == IntPtr.Zero) { return; } Kernel32Natives.FreeLibrary(_dll); _isInitialized = false; }
/// <summary> /// Initializes library. /// </summary> static XInputDll() { Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); Log.InfoFormat("Library loaded by process {0} [{1}]", Process.GetCurrentProcess().ProcessName, Process.GetCurrentProcess().MainWindowTitle); var myself = Assembly.GetExecutingAssembly().GetName(); var myPath = Assembly.GetExecutingAssembly().Location; var myName = Path.GetFileName(myPath); Log.InfoFormat("Initializing library {0} [{1}]", myName, myself.Version); try { var basePath = BasePath; Log.DebugFormat("ScpToolkit bin path: {0}", basePath); var controlPath = ScpControlPath; Log.DebugFormat("ScpControl bin path: {0}", controlPath); // resolve assembly dependencies AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { var asmName = new AssemblyName(args.Name).Name; var asmPath = Path.Combine(basePath, string.Format("{0}.dll", asmName)); Log.DebugFormat("Loading assembly {0} from {1}", asmName, asmPath); return(Assembly.LoadFrom(asmPath)); }; var scpControl = Assembly.LoadFrom(controlPath); var scpProxyType = scpControl.GetType("ScpControl.ScpProxy"); Proxy = Activator.CreateInstance(scpProxyType); Proxy.Start(); } catch (Exception ex) { Log.FatalFormat("Error during library initialization: {0}", ex); return; } // if no custom path specified by user, use DLL in system32 dir var xinputPath = (!string.IsNullOrEmpty(XInputDllPath) && File.Exists(XInputDllPath)) ? XInputDllPath : Path.Combine(Environment.SystemDirectory, myName); Log.DebugFormat("Original XInput DLL path: {0}", xinputPath); NativeDllHandle = Kernel32Natives.LoadLibrary(xinputPath); if (NativeDllHandle == IntPtr.Zero) { Log.FatalFormat("Couldn't load native DLL: {0}", new Win32Exception(Marshal.GetLastWin32Error())); return; } Log.Info("Library initialized"); }
/// <summary> /// Translates a native method into a managed delegate. /// </summary> /// <typeparam name="T">The type of the target delegate.</typeparam> /// <param name="module">The module name to search the function in.</param> /// <param name="methodName">The native finctions' name.</param> /// <returns>Returns the managed delegate.</returns> private static Delegate GetMethod <T>(IntPtr module, string methodName) { return(Marshal.GetDelegateForFunctionPointer(Kernel32Natives.GetProcAddress(module, methodName), typeof(T))); }
/// <summary> /// Loads native dependencies. /// </summary> private static void Initialize() { if (_isInitialized) { return; } #region Prepare logger var hierarchy = (Hierarchy)LogManager.GetRepository(); var logFile = new FileAppender { AppendToFile = true, File = string.Format("XInput1_3_{0}.log.xml", Environment.UserName), Layout = new XmlLayoutSchemaLog4j(true) }; logFile.ActivateOptions(); hierarchy.Root.AddAppender(logFile); hierarchy.Root.Level = Level.Debug; hierarchy.Configured = true; #endregion Log.InfoFormat("Library loaded by process {0} [{1}]", Process.GetCurrentProcess().ProcessName, Process.GetCurrentProcess().MainWindowTitle); Log.Info("Initializing library"); var iniOpts = new IniOptions { CommentStarter = IniCommentStarter.Semicolon }; var ini = new IniFile(iniOpts); var fullPath = Path.Combine(WorkingDirectory, CfgFile); Log.DebugFormat("INI-File path: {0}", fullPath); if (!File.Exists(fullPath)) { Log.FatalFormat("Configuration file {0} not found", fullPath); return; } try { // parse data from INI ini.Load(fullPath); var basePath = ini.Sections["ScpControl"].Keys["BinPath"].Value; Log.DebugFormat("ScpToolkit bin path: {0}", basePath); var binName = ini.Sections["ScpControl"].Keys["BinName"].Value; Log.DebugFormat("ScpControl bin path: {0}", binName); // load all assembly dependencies AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { var asmName = new AssemblyName(args.Name).Name; Log.DebugFormat("Loading assembly: {0}", asmName); return(Assembly.LoadFrom(Path.Combine(basePath, string.Format("{0}.dll", asmName)))); }; var scpControl = Assembly.LoadFrom(Path.Combine(basePath, binName)); var scpProxyType = scpControl.GetType("ScpControl.ScpProxy"); _scpProxy = Activator.CreateInstance(scpProxyType); _scpProxy.Start(); } catch (Exception ex) { Log.FatalFormat("Error during library initialization: {0}", ex); return; } // if no custom path specified by user, use DLL in system32 dir var xinput13Path = ini.Sections["xinput1_3"].Keys.Contains("OriginalFilePath") ? ini.Sections["xinput1_3"].Keys["OriginalFilePath"].Value : Path.Combine(Environment.SystemDirectory, "xinput1_3.dll"); Log.DebugFormat("Original XInput 1.3 DLL path: {0}", xinput13Path); _dll = Kernel32Natives.LoadLibrary(xinput13Path); if (_dll != IntPtr.Zero) { _isInitialized = true; } Log.Info("Library initialized"); }