From bd6261e3de366317ba9c74a53e62ef6a6536e2c5 Mon Sep 17 00:00:00 2001 From: KrossX Date: Mon, 29 Jul 2019 13:53:43 -0300 Subject: [PATCH] GSDumpGUI: Watch for directory changes. Also try to avoid unclosed file handles. --- tools/GSDumpGUI/Core/Program.cs | 3 + tools/GSDumpGUI/Forms/Helper/GsDumpFinder.cs | 2 +- tools/GSDumpGUI/Forms/frmMain.cs | 98 +++++++++++++++++ tools/GSDumpGUI/Library/GSDXWrapper.cs | 107 +++++++++---------- 4 files changed, 154 insertions(+), 56 deletions(-) diff --git a/tools/GSDumpGUI/Core/Program.cs b/tools/GSDumpGUI/Core/Program.cs index 40329a321bde8..a62bf674f1f6c 100644 --- a/tools/GSDumpGUI/Core/Program.cs +++ b/tools/GSDumpGUI/Core/Program.cs @@ -48,6 +48,7 @@ static class Program static private TreeNode CurrentNode; static public IntPtr hMainIcon; + static public bool prog_running; [STAThread] static void Main(String[] args) @@ -117,12 +118,14 @@ static void Main(String[] args) Server.OnClientAfterConnect += new TCPLibrary.Core.Server.ConnectedHandler(Server_OnClientAfterConnect); Server.OnClientAfterDisconnected += new TCPLibrary.Core.Server.DisconnectedHandler(Server_OnClientAfterDisconnected); Server.Enabled = true; + prog_running = true; Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); frmMain = new GSDumpGUI(); Application.Run(frmMain); + prog_running = false; Server.Enabled = false; } } diff --git a/tools/GSDumpGUI/Forms/Helper/GsDumpFinder.cs b/tools/GSDumpGUI/Forms/Helper/GsDumpFinder.cs index d0e0e6b663c17..d40606e0b875f 100644 --- a/tools/GSDumpGUI/Forms/Helper/GsDumpFinder.cs +++ b/tools/GSDumpGUI/Forms/Helper/GsDumpFinder.cs @@ -53,7 +53,7 @@ public IEnumerable GetValidGsdxDumps(DirectoryInfo directory) foreach (var dump in dumps) { int crc; - using (var fileStream = File.Open(dump.FullName, FileMode.Open)) + using (var fileStream = File.OpenRead(dump.FullName)) { using (var br = new BinaryReader(fileStream)) { diff --git a/tools/GSDumpGUI/Forms/frmMain.cs b/tools/GSDumpGUI/Forms/frmMain.cs index ec9bb78807455..9f6164d2810e6 100644 --- a/tools/GSDumpGUI/Forms/frmMain.cs +++ b/tools/GSDumpGUI/Forms/frmMain.cs @@ -24,9 +24,11 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Collections.Concurrent; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; +using System.Threading; using System.IO; using System.Diagnostics; using System.Linq; @@ -92,6 +94,11 @@ public Int32 SelectedRad private readonly GsDumps _availableGsDumps; private readonly GsDlls _availableGsDlls; + private List dll_watcher; + private List dump_watcher; + + private ConcurrentQueue watcher_events; + public GSDumpGUI() { PortableXmlSettingsProvider.ApplyProvider(Settings); @@ -116,6 +123,47 @@ public GSDumpGUI() Processes = new List(); NoImage = CreateDefaultImage(); + + dll_watcher = new List(); + dump_watcher = new List(); + watcher_events = new ConcurrentQueue(); + + Thread wt = new Thread(changes_watchdog_thread); + wt.Start(); + } + + private void changes_watchdog_thread() + { + while (Program.prog_running) + { + bool dll_reload = false; + bool dump_reload = false; + + int evt; + while (watcher_events.TryDequeue(out evt)) + { + if (evt == 1) dll_reload = true; + else if (evt == 2) dump_reload = true; + } + + if (dll_reload) this.Invoke((MethodInvoker)delegate { ReloadGsdxDlls(); }); + if (dump_reload) this.Invoke((MethodInvoker)delegate { ReloadGsdxDumps(); }); + + Thread.Sleep(1000); + } + } + + + private void OnDllDirChange(object source, FileSystemEventArgs e) + { + watcher_events.Enqueue(1); + //ReloadGsdxDlls(); + } + + private void OnDumpDirChange(object source, FileSystemEventArgs e) + { + watcher_events.Enqueue(2); + //ReloadGsdxDumps(); } private static void BindListControl(ListControl lb, TModel model, Func> collectionAccessor, Expression> displayTextAccessor, Expression> selectedIndexAccessor) @@ -151,6 +199,31 @@ private void ReloadGsdxDlls() Settings.GSDXDir = gsdxFolder.FullName; _internalLogger.Information("Completed GSdx Loading Procedures"); + + string[] paths = { "", "\\plugins", "\\dll", "\\dlls" }; + + foreach (FileSystemWatcher w in dll_watcher) + { + w.EnableRaisingEvents = false; + w.Dispose(); + } + + dll_watcher.Clear(); + + for (int i = 0; i < 4; i++) + { + try + { + FileSystemWatcher w = new FileSystemWatcher(Settings.GSDXDir + paths[i], "*.dll"); + //w.Changed += OnDllDirChange; + w.Created += OnDllDirChange; + w.Deleted += OnDllDirChange; + w.Renamed += OnDllDirChange; + w.EnableRaisingEvents = true; + dll_watcher.Add(w); + } + catch { } + } } private void ReloadGsdxDumps() @@ -165,6 +238,31 @@ private void ReloadGsdxDumps() Settings.DumpDir = dumpFolder.FullName; _internalLogger.Information("...Completed GSdx Dump Loading Procedures"); + + string[] paths = { "", "\\dumps", "\\gsdumps" }; + + foreach (FileSystemWatcher w in dump_watcher) + { + w.EnableRaisingEvents = false; + w.Dispose(); + } + + dump_watcher.Clear(); + + for (int i = 0; i < 3; i++) + { + try + { + FileSystemWatcher w = new FileSystemWatcher(Settings.DumpDir + paths[i], "*.gs"); + //w.Changed += OnDumpDirChange; + w.Created += OnDumpDirChange; + w.Deleted += OnDumpDirChange; + w.Renamed += OnDumpDirChange; + w.EnableRaisingEvents = true; + dump_watcher.Add(w); + } + catch { } + } } private void GSDumpGUI_Load(object sender, EventArgs e) diff --git a/tools/GSDumpGUI/Library/GSDXWrapper.cs b/tools/GSDumpGUI/Library/GSDXWrapper.cs index eaaca9cce8fc7..1ac2f780fc954 100644 --- a/tools/GSDumpGUI/Library/GSDXWrapper.cs +++ b/tools/GSDumpGUI/Library/GSDXWrapper.cs @@ -101,62 +101,58 @@ public void Load(String DLL) Unload(); string dir = DLL; - while (true) - { - dir = Path.GetDirectoryName(dir); - if (dir == null) - break; - Directory.SetCurrentDirectory(dir); - IntPtr hmod = NativeMethods.LoadLibrary(DLL); - if (hmod.ToInt64() > 0) - { - DLLAddr = hmod; - - IntPtr funcaddrLibName = NativeMethods.GetProcAddress(hmod, "PS2EgetLibName"); - IntPtr funcaddrConfig = NativeMethods.GetProcAddress(hmod, "GSconfigure"); - - IntPtr funcaddrGIF = NativeMethods.GetProcAddress(hmod, "GSgifTransfer"); - IntPtr funcaddrGIF1 = NativeMethods.GetProcAddress(hmod, "GSgifTransfer1"); - IntPtr funcaddrGIF2 = NativeMethods.GetProcAddress(hmod, "GSgifTransfer2"); - IntPtr funcaddrGIF3 = NativeMethods.GetProcAddress(hmod, "GSgifTransfer3"); - IntPtr funcaddrVSync = NativeMethods.GetProcAddress(hmod, "GSvsync"); - IntPtr funcaddrSetBaseMem = NativeMethods.GetProcAddress(hmod, "GSsetBaseMem"); - IntPtr funcaddrGSReset = NativeMethods.GetProcAddress(hmod, "GSreset"); - IntPtr funcaddrOpen = NativeMethods.GetProcAddress(hmod, "GSopen"); - IntPtr funcaddrSetCRC = NativeMethods.GetProcAddress(hmod, "GSsetGameCRC"); - IntPtr funcaddrClose = NativeMethods.GetProcAddress(hmod, "GSclose"); - IntPtr funcaddrShutdown = NativeMethods.GetProcAddress(hmod, "GSshutdown"); - IntPtr funcaddrFreeze = NativeMethods.GetProcAddress(hmod, "GSfreeze"); - IntPtr funcaddrGSreadFIFO2 = NativeMethods.GetProcAddress(hmod, "GSreadFIFO2"); - IntPtr funcaddrinit = NativeMethods.GetProcAddress(hmod, "GSinit"); - IntPtr funcmakeSnapshot = NativeMethods.GetProcAddress(hmod, "GSmakeSnapshot"); - - if (!((funcaddrConfig.ToInt64() > 0) && (funcaddrLibName.ToInt64() > 0) && (funcaddrGIF.ToInt64() > 0))) - { - break; - } + dir = Path.GetDirectoryName(dir); + if (dir == null) return; - gsConfigure = (GSConfigure) Marshal.GetDelegateForFunctionPointer(funcaddrConfig, typeof(GSConfigure)); - PsegetLibName = (PSEgetLibName) Marshal.GetDelegateForFunctionPointer(funcaddrLibName, typeof(PSEgetLibName)); - - this.GSgifTransfer = (GSgifTransfer) Marshal.GetDelegateForFunctionPointer(funcaddrGIF, typeof(GSgifTransfer)); - this.GSgifTransfer1 = (GSgifTransfer1) Marshal.GetDelegateForFunctionPointer(funcaddrGIF1, typeof(GSgifTransfer1)); - this.GSgifTransfer2 = (GSgifTransfer2) Marshal.GetDelegateForFunctionPointer(funcaddrGIF2, typeof(GSgifTransfer2)); - this.GSgifTransfer3 = (GSgifTransfer3) Marshal.GetDelegateForFunctionPointer(funcaddrGIF3, typeof(GSgifTransfer3)); - this.GSVSync = (GSVSync) Marshal.GetDelegateForFunctionPointer(funcaddrVSync, typeof(GSVSync)); - this.GSsetBaseMem = (GSsetBaseMem) Marshal.GetDelegateForFunctionPointer(funcaddrSetBaseMem, typeof(GSsetBaseMem)); - this.GSopen = (GSopen) Marshal.GetDelegateForFunctionPointer(funcaddrOpen, typeof(GSopen)); - this.GSsetGameCRC = (GSsetGameCRC) Marshal.GetDelegateForFunctionPointer(funcaddrSetCRC, typeof(GSsetGameCRC)); - this.GSclose = (GSclose) Marshal.GetDelegateForFunctionPointer(funcaddrClose, typeof(GSclose)); - this.GSshutdown = (GSshutdown) Marshal.GetDelegateForFunctionPointer(funcaddrShutdown, typeof(GSshutdown)); - this.GSfreeze = (GSfreeze) Marshal.GetDelegateForFunctionPointer(funcaddrFreeze, typeof(GSfreeze)); - this.GSreset = (GSreset) Marshal.GetDelegateForFunctionPointer(funcaddrGSReset, typeof(GSreset)); - this.GSreadFIFO2 = (GSreadFIFO2) Marshal.GetDelegateForFunctionPointer(funcaddrGSreadFIFO2, typeof(GSreadFIFO2)); - this.GSinit = (GSinit) Marshal.GetDelegateForFunctionPointer(funcaddrinit, typeof(GSinit)); - this.GSmakeSnapshot = (GSmakeSnapshot)Marshal.GetDelegateForFunctionPointer(funcmakeSnapshot, typeof(GSmakeSnapshot)); - - Loaded = true; - } + Directory.SetCurrentDirectory(dir); + System.Diagnostics.Trace.WriteLine("LoadLibrary: " + DLL); + IntPtr hmod = NativeMethods.LoadLibrary(DLL); + if (hmod != IntPtr.Zero) + { + DLLAddr = hmod; + + IntPtr funcaddrLibName = NativeMethods.GetProcAddress(hmod, "PS2EgetLibName"); + IntPtr funcaddrConfig = NativeMethods.GetProcAddress(hmod, "GSconfigure"); + + IntPtr funcaddrGIF = NativeMethods.GetProcAddress(hmod, "GSgifTransfer"); + IntPtr funcaddrGIF1 = NativeMethods.GetProcAddress(hmod, "GSgifTransfer1"); + IntPtr funcaddrGIF2 = NativeMethods.GetProcAddress(hmod, "GSgifTransfer2"); + IntPtr funcaddrGIF3 = NativeMethods.GetProcAddress(hmod, "GSgifTransfer3"); + IntPtr funcaddrVSync = NativeMethods.GetProcAddress(hmod, "GSvsync"); + IntPtr funcaddrSetBaseMem = NativeMethods.GetProcAddress(hmod, "GSsetBaseMem"); + IntPtr funcaddrGSReset = NativeMethods.GetProcAddress(hmod, "GSreset"); + IntPtr funcaddrOpen = NativeMethods.GetProcAddress(hmod, "GSopen"); + IntPtr funcaddrSetCRC = NativeMethods.GetProcAddress(hmod, "GSsetGameCRC"); + IntPtr funcaddrClose = NativeMethods.GetProcAddress(hmod, "GSclose"); + IntPtr funcaddrShutdown = NativeMethods.GetProcAddress(hmod, "GSshutdown"); + IntPtr funcaddrFreeze = NativeMethods.GetProcAddress(hmod, "GSfreeze"); + IntPtr funcaddrGSreadFIFO2 = NativeMethods.GetProcAddress(hmod, "GSreadFIFO2"); + IntPtr funcaddrinit = NativeMethods.GetProcAddress(hmod, "GSinit"); + IntPtr funcmakeSnapshot = NativeMethods.GetProcAddress(hmod, "GSmakeSnapshot"); + + if (!((funcaddrConfig.ToInt64() > 0) && (funcaddrLibName.ToInt64() > 0) && (funcaddrGIF.ToInt64() > 0))) + throw new InvalidGSPlugin(""); + + gsConfigure = (GSConfigure) Marshal.GetDelegateForFunctionPointer(funcaddrConfig, typeof(GSConfigure)); + PsegetLibName = (PSEgetLibName) Marshal.GetDelegateForFunctionPointer(funcaddrLibName, typeof(PSEgetLibName)); + + this.GSgifTransfer = (GSgifTransfer) Marshal.GetDelegateForFunctionPointer(funcaddrGIF, typeof(GSgifTransfer)); + this.GSgifTransfer1 = (GSgifTransfer1) Marshal.GetDelegateForFunctionPointer(funcaddrGIF1, typeof(GSgifTransfer1)); + this.GSgifTransfer2 = (GSgifTransfer2) Marshal.GetDelegateForFunctionPointer(funcaddrGIF2, typeof(GSgifTransfer2)); + this.GSgifTransfer3 = (GSgifTransfer3) Marshal.GetDelegateForFunctionPointer(funcaddrGIF3, typeof(GSgifTransfer3)); + this.GSVSync = (GSVSync) Marshal.GetDelegateForFunctionPointer(funcaddrVSync, typeof(GSVSync)); + this.GSsetBaseMem = (GSsetBaseMem) Marshal.GetDelegateForFunctionPointer(funcaddrSetBaseMem, typeof(GSsetBaseMem)); + this.GSopen = (GSopen) Marshal.GetDelegateForFunctionPointer(funcaddrOpen, typeof(GSopen)); + this.GSsetGameCRC = (GSsetGameCRC) Marshal.GetDelegateForFunctionPointer(funcaddrSetCRC, typeof(GSsetGameCRC)); + this.GSclose = (GSclose) Marshal.GetDelegateForFunctionPointer(funcaddrClose, typeof(GSclose)); + this.GSshutdown = (GSshutdown) Marshal.GetDelegateForFunctionPointer(funcaddrShutdown, typeof(GSshutdown)); + this.GSfreeze = (GSfreeze) Marshal.GetDelegateForFunctionPointer(funcaddrFreeze, typeof(GSfreeze)); + this.GSreset = (GSreset) Marshal.GetDelegateForFunctionPointer(funcaddrGSReset, typeof(GSreset)); + this.GSreadFIFO2 = (GSreadFIFO2) Marshal.GetDelegateForFunctionPointer(funcaddrGSreadFIFO2, typeof(GSreadFIFO2)); + this.GSinit = (GSinit) Marshal.GetDelegateForFunctionPointer(funcaddrinit, typeof(GSinit)); + this.GSmakeSnapshot = (GSmakeSnapshot)Marshal.GetDelegateForFunctionPointer(funcmakeSnapshot, typeof(GSmakeSnapshot)); + + Loaded = true; } if (!Loaded) @@ -178,6 +174,7 @@ public void Load(String DLL) public void Unload() { + System.Diagnostics.Trace.WriteLine("FreeLibrary: " + DLL); NativeMethods.FreeLibrary(DLLAddr); Loaded = false; }