diff --git a/DoW Mod Manager.sln b/DoW Mod Manager.sln index 5b73c6a..c70e328 100644 --- a/DoW Mod Manager.sln +++ b/DoW Mod Manager.sln @@ -1,20 +1,45 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30011.22 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32804.467 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DoW Mod Manager", "DoW Mod Manager\DoW Mod Manager.csproj", "{071DFF9E-1A7F-4F94-A1CE-4B5CB931D8EE}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UNI_EXT", "UNI_EXT\UNI_EXT.vcxproj", "{67138EE0-0823-4524-9453-4E9892296669}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {071DFF9E-1A7F-4F94-A1CE-4B5CB931D8EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {071DFF9E-1A7F-4F94-A1CE-4B5CB931D8EE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {071DFF9E-1A7F-4F94-A1CE-4B5CB931D8EE}.Debug|x64.ActiveCfg = Debug|Any CPU + {071DFF9E-1A7F-4F94-A1CE-4B5CB931D8EE}.Debug|x64.Build.0 = Debug|Any CPU + {071DFF9E-1A7F-4F94-A1CE-4B5CB931D8EE}.Debug|x86.ActiveCfg = Debug|Any CPU + {071DFF9E-1A7F-4F94-A1CE-4B5CB931D8EE}.Debug|x86.Build.0 = Debug|Any CPU {071DFF9E-1A7F-4F94-A1CE-4B5CB931D8EE}.Release|Any CPU.ActiveCfg = Release|Any CPU {071DFF9E-1A7F-4F94-A1CE-4B5CB931D8EE}.Release|Any CPU.Build.0 = Release|Any CPU + {071DFF9E-1A7F-4F94-A1CE-4B5CB931D8EE}.Release|x64.ActiveCfg = Release|Any CPU + {071DFF9E-1A7F-4F94-A1CE-4B5CB931D8EE}.Release|x64.Build.0 = Release|Any CPU + {071DFF9E-1A7F-4F94-A1CE-4B5CB931D8EE}.Release|x86.ActiveCfg = Release|Any CPU + {071DFF9E-1A7F-4F94-A1CE-4B5CB931D8EE}.Release|x86.Build.0 = Release|Any CPU + {67138EE0-0823-4524-9453-4E9892296669}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {67138EE0-0823-4524-9453-4E9892296669}.Debug|x64.ActiveCfg = Debug|x64 + {67138EE0-0823-4524-9453-4E9892296669}.Debug|x64.Build.0 = Debug|x64 + {67138EE0-0823-4524-9453-4E9892296669}.Debug|x86.ActiveCfg = Debug|Win32 + {67138EE0-0823-4524-9453-4E9892296669}.Debug|x86.Build.0 = Debug|Win32 + {67138EE0-0823-4524-9453-4E9892296669}.Release|Any CPU.ActiveCfg = Release|Win32 + {67138EE0-0823-4524-9453-4E9892296669}.Release|Any CPU.Build.0 = Release|Win32 + {67138EE0-0823-4524-9453-4E9892296669}.Release|x64.ActiveCfg = Release|x64 + {67138EE0-0823-4524-9453-4E9892296669}.Release|x64.Build.0 = Release|x64 + {67138EE0-0823-4524-9453-4E9892296669}.Release|x86.ActiveCfg = Release|Win32 + {67138EE0-0823-4524-9453-4E9892296669}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/DoW Mod Manager/DoW Mod Manager.csproj b/DoW Mod Manager/DoW Mod Manager.csproj index 3561e4a..78f215d 100644 --- a/DoW Mod Manager/DoW Mod Manager.csproj +++ b/DoW Mod Manager/DoW Mod Manager.csproj @@ -7,7 +7,7 @@ {071DFF9E-1A7F-4F94-A1CE-4B5CB931D8EE} WinExe DoW_Mod_Manager - DoW Mod Manager v2.3.1.0 + DoW Mod Manager v2.4.0.0 v4.8 512 true @@ -118,6 +118,7 @@ SystemPerformanceManagerForm.cs + AboutForm.cs diff --git a/DoW Mod Manager/FogRemover.cs b/DoW Mod Manager/FogRemover.cs index b68c250..7bfa24c 100644 --- a/DoW Mod Manager/FogRemover.cs +++ b/DoW Mod Manager/FogRemover.cs @@ -74,12 +74,14 @@ private static bool CheckToggleMemory(int addr, byte[] checkVal, byte[] setVal, { byte[] lpBuffer = new byte[checkVal.Length]; - if (!ReadProcessMemory(pHandle, addr, lpBuffer, lpBuffer.Length, out int lpNumberOfBytesRead) + int lpNumberOfBytesRead, lpflOldProtect, _; + + if (!ReadProcessMemory(pHandle, addr, lpBuffer, lpBuffer.Length, out lpNumberOfBytesRead) || lpNumberOfBytesRead != lpBuffer.Length || !((IEnumerable)lpBuffer).SequenceEqual(checkVal)) return false; - VirtualProtectEx(pHandle, addr, setVal.Length, PAGE_EXECUTE_READWRITE, out int lpflOldProtect); + VirtualProtectEx(pHandle, addr, setVal.Length, PAGE_EXECUTE_READWRITE, out lpflOldProtect); int returnCode = WriteProcessMemory(pHandle, addr, setVal, setVal.Length, out _) ? 1 : 0; VirtualProtectEx(pHandle, addr, setVal.Length, lpflOldProtect, out _); diff --git a/DoW Mod Manager/LatestStable/DoW Mod Manager.exe b/DoW Mod Manager/LatestStable/DoW Mod Manager.exe index 501217c..13d91cc 100644 Binary files a/DoW Mod Manager/LatestStable/DoW Mod Manager.exe and b/DoW Mod Manager/LatestStable/DoW Mod Manager.exe differ diff --git a/DoW Mod Manager/LatestStable/version b/DoW Mod Manager/LatestStable/version index 7118006..ac84e1c 100644 --- a/DoW Mod Manager/LatestStable/version +++ b/DoW Mod Manager/LatestStable/version @@ -1 +1 @@ -2.3.1.0 \ No newline at end of file +2.4.0.0 \ No newline at end of file diff --git a/DoW Mod Manager/ModManagerForm.Designer.cs b/DoW Mod Manager/ModManagerForm.Designer.cs index d6661e7..46aba8b 100644 --- a/DoW Mod Manager/ModManagerForm.Designer.cs +++ b/DoW Mod Manager/ModManagerForm.Designer.cs @@ -58,6 +58,7 @@ private void InitializeComponent() this.checkForErrorsButton = new System.Windows.Forms.Button(); this.noFogCheckbox = new System.Windows.Forms.CheckBox(); this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); + this.loadUNI_EXTDLLCheckBox = new System.Windows.Forms.CheckBox(); this.panel2 = new System.Windows.Forms.Panel(); this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel(); this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); @@ -283,8 +284,8 @@ private void InitializeComponent() // gameLAAStatusLabel // this.gameLAAStatusLabel.Anchor = System.Windows.Forms.AnchorStyles.Top; - this.gameLAAStatusLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.gameLAAStatusLabel.Location = new System.Drawing.Point(8, 73); + this.gameLAAStatusLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.gameLAAStatusLabel.Location = new System.Drawing.Point(8, 77); this.gameLAAStatusLabel.Margin = new System.Windows.Forms.Padding(3); this.gameLAAStatusLabel.Name = "gameLAAStatusLabel"; this.gameLAAStatusLabel.Size = new System.Drawing.Size(210, 15); @@ -294,8 +295,8 @@ private void InitializeComponent() // graphicsConfigLAAStatusLabel // this.graphicsConfigLAAStatusLabel.Anchor = System.Windows.Forms.AnchorStyles.Top; - this.graphicsConfigLAAStatusLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.graphicsConfigLAAStatusLabel.Location = new System.Drawing.Point(8, 89); + this.graphicsConfigLAAStatusLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.graphicsConfigLAAStatusLabel.Location = new System.Drawing.Point(8, 91); this.graphicsConfigLAAStatusLabel.Margin = new System.Windows.Forms.Padding(3); this.graphicsConfigLAAStatusLabel.Name = "graphicsConfigLAAStatusLabel"; this.graphicsConfigLAAStatusLabel.Size = new System.Drawing.Size(210, 15); @@ -462,13 +463,26 @@ private void InitializeComponent() this.flowLayoutPanel1.Controls.Add(this.highpolyCheckBox); this.flowLayoutPanel1.Controls.Add(this.optimizationsCheckBox); this.flowLayoutPanel1.Controls.Add(this.noFogCheckbox); + this.flowLayoutPanel1.Controls.Add(this.loadUNI_EXTDLLCheckBox); this.flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.TopDown; this.flowLayoutPanel1.Location = new System.Drawing.Point(12, 32); this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); this.flowLayoutPanel1.Name = "flowLayoutPanel1"; - this.flowLayoutPanel1.Size = new System.Drawing.Size(328, 110); + this.flowLayoutPanel1.Size = new System.Drawing.Size(330, 123); this.flowLayoutPanel1.TabIndex = 28; // + // loadUNI_EXTDLLCheckBox + // + this.loadUNI_EXTDLLCheckBox.AutoSize = true; + this.loadUNI_EXTDLLCheckBox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(200)))), ((int)(((byte)(200)))), ((int)(((byte)(200))))); + this.loadUNI_EXTDLLCheckBox.Location = new System.Drawing.Point(5, 103); + this.loadUNI_EXTDLLCheckBox.Margin = new System.Windows.Forms.Padding(5, 0, 0, 0); + this.loadUNI_EXTDLLCheckBox.Name = "loadUNI_EXTDLLCheckBox"; + this.loadUNI_EXTDLLCheckBox.Size = new System.Drawing.Size(318, 17); + this.loadUNI_EXTDLLCheckBox.TabIndex = 28; + this.loadUNI_EXTDLLCheckBox.Text = "UNI_EXT.DLL: Load experimental UNI_EXT.DLL into memory"; + this.loadUNI_EXTDLLCheckBox.UseVisualStyleBackColor = true; + // // panel2 // this.panel2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) @@ -481,7 +495,7 @@ private void InitializeComponent() this.panel2.Controls.Add(this.settingsButton); this.panel2.Location = new System.Drawing.Point(341, 32); this.panel2.Name = "panel2"; - this.panel2.Size = new System.Drawing.Size(245, 110); + this.panel2.Size = new System.Drawing.Size(245, 118); this.panel2.TabIndex = 29; // // flowLayoutPanel2 @@ -586,6 +600,7 @@ private void InitializeComponent() private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2; private System.Windows.Forms.Panel panel2; + private System.Windows.Forms.CheckBox loadUNI_EXTDLLCheckBox; private System.Windows.Forms.Button open_folder_button; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; } diff --git a/DoW Mod Manager/ModManagerForm.cs b/DoW Mod Manager/ModManagerForm.cs index 1e1ae91..832d444 100644 --- a/DoW Mod Manager/ModManagerForm.cs +++ b/DoW Mod Manager/ModManagerForm.cs @@ -7,9 +7,11 @@ using System.Security.Permissions; using System.Reflection; using System.Threading; +using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using System.Runtime; using SSNoFog; +using SSUNI_EXTTDLL; namespace DoW_Mod_Manager { @@ -52,6 +54,7 @@ public enum Action { None, CreateNativeImage, CreateNativeImageAndDeleteJITProfi public const string NO_MOVIES = "NoMovies"; public const string FORCE_HIGH_POLY = "ForceHighPoly"; public const string NO_FOG = "RemoveMapFog"; + public const string UNI_EXTDLL = "LoadUNI_EXTDLL"; public const string DOW_OPTIMIZATIONS = "DowOptimizations"; public const string AUTOUPDATE = "Autoupdate"; public const string MULTITHREADED_JIT = "MultithreadedJIT"; @@ -64,13 +67,18 @@ public enum Action { None, CreateNativeImage, CreateNativeImageAndDeleteJITProfi private bool _isMessageBoxOnScreen = false; private bool _isOldGame; private bool _IsNoFogTooltipShown = false; + private bool _IsUNI_EXTDLLNoFogTooltipShown = false; private string _dowProcessName = ""; private readonly ToolTip _disabledNoFogTooltip = new ToolTip(); - private Control _currentToolTipControl; + private readonly ToolTip _disabledLoadUNI_EXTDLLCheckBoxTooltip = new ToolTip(); + private Control _currentToolTipControl; private ModMergerForm modMerger = null; + public static int _maxDefeatedRaces = 0x0A; + public readonly string CurrentDir = Directory.GetCurrentDirectory(); public readonly string CurrentGameEXE = ""; + public readonly bool IsUNI_EXTDLL = false; public readonly string GraphicsConfigEXE = "GraphicsConfig.exe"; public string[] ModuleFilePaths; public string[] ModFolderPaths; @@ -89,6 +97,7 @@ public enum Action { None, CreateNativeImage, CreateNativeImageAndDeleteJITProfi [NO_MOVIES] = 1, [FORCE_HIGH_POLY] = 0, [NO_FOG] = 0, + [UNI_EXTDLL] = 0, [DOW_OPTIMIZATIONS] = 0, [AUTOUPDATE] = 1, [MULTITHREADED_JIT] = 0, @@ -154,9 +163,11 @@ public ModManagerForm() highpolyCheckBox.Checked = settings[FORCE_HIGH_POLY] == 1; optimizationsCheckBox.Checked = settings[DOW_OPTIMIZATIONS] == 1; noFogCheckbox.Checked = settings[NO_FOG] == 1; + loadUNI_EXTDLLCheckBox.Checked = settings[UNI_EXTDLL] == 1; CurrentGameEXE = GetCurrentGameEXE(); CheckForGraphicsConfigEXE(); + IsUNI_EXTDLL = FindUNI_EXTDLL(); currentDirTextBox.Text = CurrentDir; SetUpAllNecessaryMods(); @@ -181,13 +192,26 @@ public ModManagerForm() highpolyCheckBox.CheckedChanged += new EventHandler(HighpolyCheckBox_CheckedChanged); optimizationsCheckBox.CheckedChanged += new EventHandler(OptimizationsCheckBox_CheckedChanged); noFogCheckbox.CheckedChanged += new EventHandler(NoFogCheckboxCheckedChanged); + loadUNI_EXTDLLCheckBox.CheckedChanged += new EventHandler(loadUNI_EXTDLLCheckBox_CheckedChanged); - // Disable no Fog checkbox if it's not Soulstorm because it only works on Soulstorm at all. + // Disable no Fog checkbox and UNI_EXTDLL checkbox if it's not Soulstorm because it only works on Soulstorm at all. if (CurrentGameEXE != GameExecutable.SOULSTORM) { noFogCheckbox.Enabled = false; noFogCheckbox.Checked = false; + loadUNI_EXTDLLCheckBox.Enabled = false; + loadUNI_EXTDLLCheckBox.Checked = false; + flowLayoutPanel1.MouseMove += new MouseEventHandler(noFogCheckbox_hover); + flowLayoutPanel1.MouseMove += new MouseEventHandler(loadUNI_EXTDLLCheckBox_hover); + } + // Also disable UNI_EXTDLL checkbox if UNI_EXT.DLL is not found. + else if (!IsUNI_EXTDLL) + { + loadUNI_EXTDLLCheckBox.Enabled = false; + loadUNI_EXTDLLCheckBox.Checked = false; + + flowLayoutPanel1.MouseMove += new MouseEventHandler(loadUNI_EXTDLLNot_Found_CheckBox_hover); } // Perform Autoupdate @@ -207,12 +231,45 @@ public ModManagerForm() } /// - /// This function shows a tooltip, should the disable fog checkbox be disabled due to a wrong game version used. + /// This function shows a tooltip, should the load Uni_ext.dll checkbox be disabled due to a wrong game version used. /// It has to be done since using normal tooltips won't work on disabled controls. /// /// /// - private void noFogCheckbox_hover(object sender, MouseEventArgs e) + private void loadUNI_EXTDLLCheckBox_hover(object sender, MouseEventArgs e) + { + Control parent = sender as Control; + + if (parent == null) + return; + + Control ctrl = parent.GetChildAtPoint(e.Location); + if (ctrl != null) + { + if (ctrl == loadUNI_EXTDLLCheckBox && !_IsUNI_EXTDLLNoFogTooltipShown) + { + _disabledLoadUNI_EXTDLLCheckBoxTooltip.Show( + "Load UNI_EXT.DLL only works in Dawn of War: Soulstorm", + loadUNI_EXTDLLCheckBox, + loadUNI_EXTDLLCheckBox.Width / 2, + loadUNI_EXTDLLCheckBox.Height / 2); + _IsUNI_EXTDLLNoFogTooltipShown = true; + } + } + else + { + _disabledLoadUNI_EXTDLLCheckBoxTooltip.Hide(loadUNI_EXTDLLCheckBox); + _IsUNI_EXTDLLNoFogTooltipShown = false; + } + } + + /// + /// This function shows a tooltip, should the load Uni_ext.dll checkbox be disabled due to a wrong game version used. + /// It has to be done since using normal tooltips won't work on disabled controls. + /// + /// + /// + private void loadUNI_EXTDLLNot_Found_CheckBox_hover(object sender, MouseEventArgs e) { Control parent = sender as Control; @@ -221,6 +278,39 @@ private void noFogCheckbox_hover(object sender, MouseEventArgs e) Control ctrl = parent.GetChildAtPoint(e.Location); if (ctrl != null) + { + if (ctrl == loadUNI_EXTDLLCheckBox && !_IsUNI_EXTDLLNoFogTooltipShown) + { + _disabledLoadUNI_EXTDLLCheckBoxTooltip.Show( + "File UNI_EXT.DLL is missing", + loadUNI_EXTDLLCheckBox, + loadUNI_EXTDLLCheckBox.Width / 2, + loadUNI_EXTDLLCheckBox.Height / 2); + _IsUNI_EXTDLLNoFogTooltipShown = true; + } + } + else + { + _disabledLoadUNI_EXTDLLCheckBoxTooltip.Hide(loadUNI_EXTDLLCheckBox); + _IsUNI_EXTDLLNoFogTooltipShown = false; + } + } + + /// + /// This function shows a tooltip, should the disable fog checkbox be disabled due to a wrong game version used. + /// It has to be done since using normal tooltips won't work on disabled controls. + /// + /// + /// + private void noFogCheckbox_hover(object sender, MouseEventArgs e) + { + var parent = sender as Control; + if (parent == null) + { + return; + } + var ctrl = parent.GetChildAtPoint(e.Location); + if (ctrl != null) { if (ctrl == noFogCheckbox && !_IsNoFogTooltipShown) { @@ -332,6 +422,7 @@ private void ReadSettingsFromDoWModManagerINI() case MULTITHREADED_JIT: case AOT_COMPILATION: case NO_FOG: + case UNI_EXTDLL: if (value == 0 || value == 1) settings[setting] = value; else @@ -365,11 +456,27 @@ private void ReselectSavedMod() } /// - /// This method scans for either the Soulstorm, Dark Crusade, Winter Assault or Original version of the game. + /// This method scans for UNI_EXT.DLL file. /// /// string // Request the inlining of this method [MethodImpl(MethodImplOptions.AggressiveInlining)] + private bool FindUNI_EXTDLL() + { + if (File.Exists(CurrentDir + "\\UNI_EXT.DLL")) + { + return true; + } + + return false; + } + + /// + /// This method scans for either the Soulstorm, Dark Crusade, Winter Assault or Original version of the game. + /// + /// string + // Request the inlining of this method + [MethodImpl(MethodImplOptions.AggressiveInlining)] private string GetCurrentGameEXE() { if (File.Exists(CurrentDir + "\\" + GameExecutable.SOULSTORM)) @@ -636,7 +743,8 @@ private void ModManagerForm_Closing(object sender, EventArgs e) sw.WriteLine($"{AUTOUPDATE}={settings[AUTOUPDATE]}"); sw.WriteLine($"{MULTITHREADED_JIT}={settings[MULTITHREADED_JIT]}"); sw.WriteLine($"{AOT_COMPILATION}={settings[AOT_COMPILATION]}"); - sw.Write($"{NO_FOG}={settings[NO_FOG]}"); + sw.WriteLine($"{NO_FOG}={settings[NO_FOG]}"); + sw.WriteLine($"{UNI_EXTDLL}={settings[UNI_EXTDLL]}"); } // If Timer Resolution was lowered we have to keep DoW Mod Manager alive or Timer Resolution will be reset @@ -895,12 +1003,12 @@ private void StartGameWithOptions(string modName) arguments += " -nomovies"; if (settings[FORCE_HIGH_POLY] == 1) arguments += " -forcehighpoly"; - + Process proc = new Process(); proc.StartInfo.FileName = CurrentGameEXE; proc.StartInfo.Arguments = arguments; proc.Start(); - + _dowProcessName = proc.ProcessName; // Create new thread to change the process CPU affinity after the game has started. @@ -958,6 +1066,34 @@ private void StartGameWithOptions(string modName) } ).Start(); } + + // Create a new thread for UNI_EXTDLL which manipulates the process memory after the game has started. + if (settings[UNI_EXTDLL] == 1) + { + new Thread(() => + { + int timeOutCounter = 0; + string procName = _dowProcessName; + + // We will try 30 times and then Thread will be terminated regardless + while (timeOutCounter < 30) + { + Thread.Sleep(1000); + try + { + Process[] dow = Process.GetProcessesByName(procName); + UNI_EXTDLLLoader.UNI_EXTdllInjector(dow[0], CurrentDir + "\\UNI_EXT.DLL"); + break; // We've done what we intended to do + } + catch (Exception) + { + timeOutCounter++; + } + } + } + ).Start(); + } + } /// @@ -1031,6 +1167,19 @@ private void NoFogCheckboxCheckedChanged(object sender, EventArgs e) settings[NO_FOG] = 0; } + /// + /// This checkbox loads UNI_EXT.DLL to program memory. + /// + /// + /// + private void loadUNI_EXTDLLCheckBox_CheckedChanged(object sender, EventArgs e) + { + if (loadUNI_EXTDLLCheckBox.Checked) + settings[UNI_EXTDLL] = 1; + else + settings[UNI_EXTDLL] = 0; + } + /// /// This method collects and displays the list of required mods for a selected mod in order to function correctly. /// @@ -1340,7 +1489,7 @@ private void HomePageLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEv } /// - /// This event handles the case when the no fog checkbox is disabled, to show a tooltip why it is disabled. + /// This event handles the case when the no fog checkbox and UNI_EXT.dll is disabled, to show a tooltip why it is disabled. /// /// /// @@ -1355,10 +1504,17 @@ private void ModManagerForm_MouseMove(object sender, MouseEventArgs e) _disabledNoFogTooltip.Show(toolTipString, control, control.Width / 2, control.Height / 2); _currentToolTipControl = control; } + if (!control.Enabled && control == loadUNI_EXTDLLCheckBox) + { + string toolTipString = _disabledLoadUNI_EXTDLLCheckBoxTooltip.GetToolTip(control); + _disabledLoadUNI_EXTDLLCheckBoxTooltip.Show(toolTipString, control, control.Width / 2, control.Height / 2); + _currentToolTipControl = control; + } } else { if (_currentToolTipControl != null) _disabledNoFogTooltip.Hide(_currentToolTipControl); + if (_currentToolTipControl != null) _disabledLoadUNI_EXTDLLCheckBoxTooltip.Hide(_currentToolTipControl); _currentToolTipControl = null; } } diff --git a/DoW Mod Manager/Properties/AssemblyInfo.cs b/DoW Mod Manager/Properties/AssemblyInfo.cs index a09062a..adfe8c0 100644 --- a/DoW Mod Manager/Properties/AssemblyInfo.cs +++ b/DoW Mod Manager/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.3.1.0")] -[assembly: AssemblyFileVersion("2.3.1.0")] +[assembly: AssemblyVersion("2.4.0.0")] +[assembly: AssemblyFileVersion("2.4.0.0")] diff --git a/DoW Mod Manager/SettingsManagerForm.cs b/DoW Mod Manager/SettingsManagerForm.cs index a7cae85..383f209 100644 --- a/DoW Mod Manager/SettingsManagerForm.cs +++ b/DoW Mod Manager/SettingsManagerForm.cs @@ -882,34 +882,34 @@ private void WriteSettings(bool localINI, bool playercgfLUA) modManager.ChangeSetting(ModManagerForm.FORCE_HIGH_POLY, 0); disableHighPoly = false; } + } - void SearchForThatString(ref string[] strArray) - { - bool weFoundIt = false; + void SearchForThatString(ref string[] strArray) + { + bool weFoundIt = false; - for (int i = 0; i < strArray.Length; i++) + for (int i = 0; i < strArray.Length; i++) + { + if (strArray[i].StartsWith("allowhwcursor")) { - if (strArray[i].StartsWith("allowhwcursor")) - { - strArray[i] = ALLOWHWCURSOR + " " + settings[ALLOWHWCURSOR]; - weFoundIt = true; - break; // We found what we searched for - } + strArray[i] = ALLOWHWCURSOR + " " + settings[ALLOWHWCURSOR]; + weFoundIt = true; + break; // We found what we searched for } + } - if (!weFoundIt) + if (!weFoundIt) + { + using (StreamWriter sw = File.CreateText(DRIVER_SETTINGS_FILE)) { - using (StreamWriter sw = File.CreateText(DRIVER_SETTINGS_FILE)) - { - // TODO - maybe just write the new line ;-) + // TODO - maybe just write the new line ;-) - // Write all that was in file before - for (int i = 0; i < strArray.Length; i++) - sw.WriteLine(strArray[i]); + // Write all that was in file before + for (int i = 0; i < strArray.Length; i++) + sw.WriteLine(strArray[i]); - // And then add this new line - sw.WriteLine(ALLOWHWCURSOR + " " + settings[ALLOWHWCURSOR]); - } + // And then add this new line + sw.WriteLine(ALLOWHWCURSOR + " " + settings[ALLOWHWCURSOR]); } } } diff --git a/DoW Mod Manager/SystemPerformanceManagerForm.cs b/DoW Mod Manager/SystemPerformanceManagerForm.cs index b97d62a..9684b98 100644 --- a/DoW Mod Manager/SystemPerformanceManagerForm.cs +++ b/DoW Mod Manager/SystemPerformanceManagerForm.cs @@ -222,7 +222,7 @@ private void SetPowerPlanButton_Click(object sender, EventArgs e) { Guid powerPlanGUID = new Guid(GUID_BALANCED); - switch (powerPlanComboBox.SelectedItem) + switch (powerPlanComboBox.SelectedItem.ToString()) { case NAME_ULTIMATE_PERFORMANCE: if (ultimatePerformanceGUIDIndex == 2) diff --git a/DoW Mod Manager/UNIEXTDLLLoader.cs b/DoW Mod Manager/UNIEXTDLLLoader.cs new file mode 100644 index 0000000..cf7bc62 --- /dev/null +++ b/DoW Mod Manager/UNIEXTDLLLoader.cs @@ -0,0 +1,245 @@ +// DLL injection function available https://github.com/ihack4falafel/DLL-Injection +// Made by ihack4falafel + +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Runtime.ConstrainedExecution; +using System.Security; +using System.Text; +using DoW_Mod_Manager; + +namespace SSUNI_EXTTDLL +{ + public static class UNI_EXTDLLLoader + { + [Flags] + public enum ProcessAccessFlags : uint + { + All = 0x001F0FFF, + Terminate = 0x00000001, + CreateThread = 0x00000002, + VirtualMemoryOperation = 0x00000008, + VirtualMemoryRead = 0x00000010, + VirtualMemoryWrite = 0x00000020, + DuplicateHandle = 0x00000040, + CreateProcess = 0x000000080, + SetQuota = 0x00000100, + SetInformation = 0x00000200, + QueryInformation = 0x00000400, + QueryLimitedInformation = 0x00001000, + Synchronize = 0x00100000 + } + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern IntPtr OpenProcess( + ProcessAccessFlags processAccess, + bool bInheritHandle, + int processId); + public static IntPtr OpenProcess(Process proc, ProcessAccessFlags flags) + { + return OpenProcess(flags, false, proc.Id); + } + + // VirtualAllocEx signture https://www.pinvoke.net/default.aspx/kernel32.virtualallocex + [Flags] + public enum AllocationType + { + Commit = 0x1000, + Reserve = 0x2000, + Decommit = 0x4000, + Release = 0x8000, + Reset = 0x80000, + Physical = 0x400000, + TopDown = 0x100000, + WriteWatch = 0x200000, + LargePages = 0x20000000 + } + + // VirtualFreeEx signture https://www.pinvoke.net/default.aspx/kernel32.virtualfreeex + [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] + static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, + int dwSize, AllocationType dwFreeType); + + [Flags] + public enum MemoryProtection + { + Execute = 0x10, + ExecuteRead = 0x20, + ExecuteReadWrite = 0x40, + ExecuteWriteCopy = 0x80, + NoAccess = 0x01, + ReadOnly = 0x02, + ReadWrite = 0x04, + WriteCopy = 0x08, + GuardModifierflag = 0x100, + NoCacheModifierflag = 0x200, + WriteCombineModifierflag = 0x400 + } + + [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] + static extern IntPtr VirtualAllocEx( + IntPtr hProcess, + IntPtr lpAddress, + IntPtr dwSize, + AllocationType flAllocationType, + MemoryProtection flProtect); + + // WriteProcessMemory signture https://www.pinvoke.net/default.aspx/kernel32/WriteProcessMemory.html + [DllImport("kernel32.dll", SetLastError = true)] + public static extern bool WriteProcessMemory( + IntPtr hProcess, + IntPtr lpBaseAddress, + [MarshalAs(UnmanagedType.AsAny)] object lpBuffer, + int dwSize, + out IntPtr lpNumberOfBytesWritten); + + // GetProcAddress signture https://www.pinvoke.net/default.aspx/kernel32.getprocaddress + [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] + static extern IntPtr GetProcAddress(IntPtr hModule, string procName); + + // GetModuleHandle signture http://pinvoke.net/default.aspx/kernel32.GetModuleHandle + [DllImport("kernel32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr GetModuleHandle(string lpModuleName); + + // CreateRemoteThread signture https://www.pinvoke.net/default.aspx/kernel32.createremotethread + [DllImport("kernel32.dll")] + static extern IntPtr CreateRemoteThread( + IntPtr hProcess, + IntPtr lpThreadAttributes, + uint dwStackSize, + IntPtr lpStartAddress, + IntPtr lpParameter, + uint dwCreationFlags, + IntPtr lpThreadId); + + // CloseHandle signture https://www.pinvoke.net/default.aspx/kernel32.closehandle + [DllImport("kernel32.dll", SetLastError = true)] + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + [SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool CloseHandle(IntPtr hObject); + + public static void UNI_EXTdllInjector(Process process, string DllPath) + { + IntPtr Size = (IntPtr)DllPath.Length; + string message = ""; + + // Open handle to the target process + IntPtr ProcHandle = OpenProcess( + ProcessAccessFlags.All, + false, + process.Id); + if (ProcHandle == null) + { + ThemedMessageBox.Show("[!] Handle to target process could not be obtained!", "UNI_EXT.DLL messages"); + + System.Environment.Exit(1); + } + else + { + message += "[+] Handle (0x" + ProcHandle + ") to target process has been obtained.\n"; + } + + // Allocate DLL space + IntPtr DllSpace = VirtualAllocEx( + ProcHandle, + IntPtr.Zero, + Size, + AllocationType.Reserve | AllocationType.Commit, + MemoryProtection.ExecuteReadWrite); + + if (DllSpace == null) + { + ThemedMessageBox.Show(message+"[!] DLL space allocation failed.", "UNI_EXT.DLL messages"); + System.Environment.Exit(1); + } + else + { + message += "[+] DLL space (0x" + DllSpace + ") allocation is successful.\n"; + } + + // Write DLL content to VAS of target process + IntPtr bytesread; + byte[] bytes = Encoding.ASCII.GetBytes(DllPath); + bool DllWrite = WriteProcessMemory( + ProcHandle, + DllSpace, + bytes, + (int)bytes.Length, + out bytesread + ); + + if (DllWrite == false) + { + ThemedMessageBox.Show(message + "[!] Writing DLL content to target process failed.", "UNI_EXT.DLL messages"); + System.Environment.Exit(1); + } + else + { + message += "[+] Writing DLL content to target process is successful.\n"; + } + + // Get handle to Kernel32.dll and get address for LoadLibraryA + IntPtr Kernel32Handle = GetModuleHandle("Kernel32.dll"); + IntPtr LoadLibraryAAddress = GetProcAddress(Kernel32Handle, "LoadLibraryA"); + + if (LoadLibraryAAddress == null) + { + ThemedMessageBox.Show(message + "[!] Obtaining an addess to LoadLibraryA function has failed.", "UNI_EXT.DLL messages"); + System.Environment.Exit(1); + } + else + { + message += "[+] LoadLibraryA function address (0x" + LoadLibraryAAddress + ") has been obtained.\n"; + } + + // Create remote thread in the target process + IntPtr RemoteThreadHandle = CreateRemoteThread( + ProcHandle, + IntPtr.Zero, + 0, + LoadLibraryAAddress, + DllSpace, + 0, + IntPtr.Zero + ); + + if (RemoteThreadHandle == null) + { + ThemedMessageBox.Show(message + "[!] Obtaining a handle to remote thread in target process failed.", "UNI_EXT.DLL messages"); + System.Environment.Exit(1); + } + else + { + message += "[+] Obtaining a handle to remote thread (0x" + RemoteThreadHandle + ") in target process is successful.\n"; + System.Threading.Thread.Sleep(3000); + //ThemedMessageBox.Show(message + "[+] Obtaining a handle to remote thread (0x" + RemoteThreadHandle + ") in target process is successful.", "UNI_EXT.DLL messages"); + } + + // Deallocate memory assigned to DLL + bool FreeDllSpace = VirtualFreeEx( + ProcHandle, + DllSpace, + 0, + AllocationType.Release); + if (FreeDllSpace == false) + { + ThemedMessageBox.Show(message + "[!] Failed to release DLL memory in target process.", "UNI_EXT.DLL messages"); + System.Environment.Exit(1); + } + else + { + message += "[+] Successfully released DLL memory in target process.\n"; + //ThemedMessageBox.Show(message + "[+] Successfully released DLL memory in target process.", "UNI_EXT.DLL messages"); + } + + // Close remote thread handle + CloseHandle(RemoteThreadHandle); + + // Close target process handle + CloseHandle(ProcHandle); + + } + } +} \ No newline at end of file diff --git a/DoW Mod Manager/WinApiCalls.cs b/DoW Mod Manager/WinApiCalls.cs index a3b81a0..31c7e22 100644 --- a/DoW Mod Manager/WinApiCalls.cs +++ b/DoW Mod Manager/WinApiCalls.cs @@ -47,14 +47,14 @@ public static class WinApiCalls public static TimerCaps QueryTimerResolution() { TimerCaps caps = new TimerCaps(); - _ = NtQueryTimerResolution(out caps.PeriodMin, out caps.PeriodMax, out caps.PeriodCurrent); + var _ = NtQueryTimerResolution(out caps.PeriodMin, out caps.PeriodMax, out caps.PeriodCurrent); return caps; } public static ulong SetTimerResolution(uint timerResolutionIn100nsUnits, bool doSet = true) { uint currentRes = 0; - _ = NtSetTimerResolution(timerResolutionIn100nsUnits, doSet, ref currentRes); + var _ = NtSetTimerResolution(timerResolutionIn100nsUnits, doSet, ref currentRes); return currentRes; } diff --git a/UNI_EXT/Patch.cpp b/UNI_EXT/Patch.cpp new file mode 100644 index 0000000..5f4a476 --- /dev/null +++ b/UNI_EXT/Patch.cpp @@ -0,0 +1,139 @@ +// Based on slashdiablo-maphack implementation +// https://github.com/planqi/slashdiablo-maphack + +#include "Patch.h" +#include "SoulstormVersion.h" + +std::vector Patch::Patches; + +Patch::Patch(PatchType type, Dll dll, Offsets offsets, int function, int length) + : type(type), dll(dll), offsets(offsets), substitutions({ 0 }), function(function), length(length) { + oldCode = new BYTE[length]; + injected = false; + Patches.push_back(this); +} + +Patch::Patch(PatchType type, Dll dll, Offsets offsets, Substitutions substitutions, int length) + : type(type), dll(dll), offsets(offsets), substitutions(substitutions), function(NULL), length(length) { + oldCode = new BYTE[length]; + injected = false; + Patches.push_back(this); +} + +int Patch::GetDllOffset(Dll dll, int offset) { + const wchar_t* szDlls[] = { L"SOULSTORM.exe", L"UserInterface.dll", L"WXPMod.dll" }; + //Attempt to get the module of the given DLL + HMODULE hModule = GetModuleHandle(szDlls[dll]); + + //If DLL hasn't been loaded, then load it up! + if (!hModule) { + hModule = LoadLibrary(szDlls[dll]); + } + + //If the DLL isn't there, or failed to load, return. + if (!hModule) + return false; + + //Check if it is an ordinal, if so, get the proper address. + if (offset < 0) + return (DWORD)GetProcAddress(hModule, (LPCSTR)(-offset)); + + //If just regular offset, add the two and be done! + return ((DWORD)hModule) + offset; +} + +bool Patch::WriteBytes(int address, int len, BYTE* bytes) { + DWORD dwOld; + + if (!VirtualProtect((void*)address, len, PAGE_READWRITE, &dwOld)) + return FALSE; + + ::memcpy((void*)address, bytes, len); + return !!VirtualProtect((void*)address, len, dwOld, &dwOld); +} + +bool Patch::Install() { + + //Check if we have already installed this patch. + if (IsInstalled()) + return true; + + //Initalize variables for the exactly commands we are injecting. + BYTE* code = new BYTE[length]; + DWORD protect; + + // Select an offset based on Soulstorm version + int offset = *(&offsets._steam + SoulstormVersion::GetGameVersionID()); + + //Get the proper address that we are patching + int address = GetDllOffset(dll, offset); + + //Read the old code to allow proper patch removal + ReadProcessMemory(GetCurrentProcess(), (void*)address, oldCode, length, NULL); + + //Set the code with all NOPs by default + memset(code, 0x90, length); + + if (type == Overwrite) { + for (int i = 0; i < length; i++) + { + code[i] = substitutions._steam[i]; + } + } + else if (type != NOP) { + //Set the opcode + code[0] = type; + + //Set the address to redirect to + if (type == Call || type == Jump) { + *(DWORD*)&code[1] = function - (address + 5); + } + else { + code[1] = function; + } + } + + //Write the patch in + VirtualProtect((VOID*)address, length, PAGE_EXECUTE_READWRITE, &protect); + memcpy_s((VOID*)address, length, code, length); + VirtualProtect((VOID*)address, length, protect, &protect); +/* + DWORD old; + DWORD base = (DWORD)GetModuleHandle(NULL); + DWORD offset = 0x81F350; + + char* ptr = reinterpret_cast(base + offset); + const size_t length = 4; + char buffer[length] = { 0x0A, 0x00, 0x00, 0x00 }; + + VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old); + memcpy(ptr, buffer, length); + VirtualProtect(ptr, length, old, nullptr); + */ + //Set that we successfully patched + injected = true; + + return true; +} + +bool Patch::Remove() { + if (!IsInstalled()) + return true; + + // Select an offset based on D2 version + int offset = *(&offsets._steam); + + //Get the proper address + int address = GetDllOffset(dll, offset); + DWORD protect; + + //Revert to the previous code + VirtualProtect((VOID*)address, length, PAGE_EXECUTE_READWRITE, &protect); + memcpy_s((VOID*)address, length, oldCode, length); + VirtualProtect((VOID*)address, length, protect, &protect); + + + injected = false; + + return true; +} \ No newline at end of file diff --git a/UNI_EXT/Patch.h b/UNI_EXT/Patch.h new file mode 100644 index 0000000..a96b3b5 --- /dev/null +++ b/UNI_EXT/Patch.h @@ -0,0 +1,45 @@ +// Based on slashdiablo-maphack implementation +// https://github.com/planqi/slashdiablo-maphack + +#pragma once +#include +#include +#include + +class Patch; + +enum Dll { SOULSTORM = 0, USERINTERFACE, WXPMOD }; +enum PatchType { Jump = 0xE9, Call = 0xE8, NOP = 0x90, Push = 0x6A, Overwrite }; + +struct Offsets { + int _steam; + int _cdversion; +}; + +// substitutions have a limit of characters +struct Substitutions { + int _steam[100]; +}; + +class Patch { +private: + static std::vector Patches; + Dll dll; + PatchType type; + Offsets offsets; + Substitutions substitutions; + int length, function; + BYTE* oldCode; + bool injected; +public: + Patch(PatchType type, Dll dll, Offsets offsets, int function, int length); + Patch(PatchType type, Dll dll, Offsets offsets, Substitutions substitutions, int length); + + bool Install(); + bool Remove(); + + bool IsInstalled() { return injected; }; + + static int GetDllOffset(Dll dll, int offset); + static bool WriteBytes(int address, int len, BYTE* bytes); +}; \ No newline at end of file diff --git a/UNI_EXT/ReadMe.txt b/UNI_EXT/ReadMe.txt new file mode 100644 index 0000000..9df1183 --- /dev/null +++ b/UNI_EXT/ReadMe.txt @@ -0,0 +1,48 @@ +======================================================================== + DYNAMIC LINK LIBRARY : UNI_EXT Project Overview +======================================================================== + +AppWizard has created this UNI_EXT DLL for you. + +This file contains a summary of what you will find in each of the files that +make up your UNI_EXT application. + + +UNI_EXT.vcxproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +UNI_EXT.vcxproj.filters + This is the filters file for VC++ projects generated using an Application Wizard. + It contains information about the association between the files in your project + and the filters. This association is used in the IDE to show grouping of files with + similar extensions under a specific node (for e.g. ".cpp" files are associated with the + "Source Files" filter). + +UNI_EXT.cpp + This is the main DLL source file. + + When created, this DLL does not export any symbols. As a result, it + will not produce a .lib file when it is built. If you wish this project + to be a project dependency of some other project, you will either need to + add code to export some symbols from the DLL so that an export library + will be produced, or you can set the Ignore Input Library property to Yes + on the General propert page of the Linker folder in the project's Property + Pages dialog box. + +///////////////////////////////////////////////////////////////////////////// +Other standard files: + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named UNI_EXT.pch and a precompiled types file named StdAfx.obj. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/UNI_EXT/SoulstormIntercepts.cpp b/UNI_EXT/SoulstormIntercepts.cpp new file mode 100644 index 0000000..2fa88e1 --- /dev/null +++ b/UNI_EXT/SoulstormIntercepts.cpp @@ -0,0 +1,437 @@ +#include +#include "SoulstormPointers.h" + +//DWORD patch_clip_region; +//DWORD* base_address; +DWORD return_address; + +/* +int __declspec(naked) Metamap_Action_Selector_Function() +{ + __asm + { + push offset AD3A84; + call sub_66DE90; + call sub_777BD0; +// pushad; +// call GameLoop; +// popad; + +// pop eax; +// sub esp, 0x20; +// mov[esp + 0xC], ecx; +// push eax; +// ret; + } +} +*/ +int __stdcall runAction(int) +{ + /* + int v4, v5, v11, v58; + char v6; + int(__thiscall *v7)(int); + const wchar_t* v49; + const char *v50; + float v51; + + v4 = SOULSTORM_sub_96EAA0(); + v5 = ((int(__thiscall *)(int))SOULSTORM_sub_96F440)(v4); + v6 = (*(int(__thiscall **)(int))(*(DWORD *)v5 + 636))(v5); + v7 = *(int(__thiscall **)(int))(*(DWORD *)v5 + 640); + + v11 = *(DWORD *)(a1 + 376); + + v58 = SOULSTORM_sub_7761C0(v6, (char)v7); + SOULSTORM_sub_66DE90(SOULSTORM_dieActionString_I, v58); + SOULSTORM_runAnimationOnMetaMapMenuModel(*v49, *v50, v51); + return 0; + */ + + __asm + { + //push ebp + /* + push 0x0FFFFFFFF + push SOULSTORM_FrameHandler3Jump + mov eax, fs : 0 + push eax + mov fs : 0, esp + sub esp, 0x50 + */ + + + push ebx + push ebp + push esi + push edi + + + mov esi, ecx + call SOULSTORM_sub_96EAA0 + mov ecx, eax + call SOULSTORM_sub_96F440 + mov edi, eax + mov eax, [edi] + mov edx, [eax + 0x27C] + mov ecx, edi + call edx + mov bl, al + mov eax, [edi] + mov edx, [eax + 0x280] + mov ecx, edi + mov byte ptr[esp - 0x8], bl + call edx + mov byte ptr[esp - 0x4], al + + mov eax, [esp - 0x4] + mov edx, [esp - 0x8] + mov ecx, [esi + 0x178] + push eax + push edx + call SOULSTORM_toggleOverlayFunction + + + + sub esp, 0x0C + + mov ecx, esp + mov [esp + 0x7C], esp + lea edx, [esp + 0x7C] + push edx + push SOULSTORM_dieActionString_I + call SOULSTORM_findMotionByGivenName + mov ecx, [esi + 0x178] + call SOULSTORM_runMotionOnMetaMapMenuModel + //add esp, 0x1C + + fld SOULSTORM_flt_C1F44C + sub esp, 0x0C + mov eax, esp + fstp dword ptr[esp + 0x4] + mov [esp + 0x7C], esp + push esi + push SOULSTORM_setOverlayEnabledFunction + push eax + call SOULSTORM_setPointerToArgument2Function + add esp, 0x0C + mov ecx, esi + call SOULSTORM_sub_787020 + + //pop ebp + //pop esi + //retn 4 + /* + mov fs : 0, ecx + add esp, 0x5C + */ + pop edi + pop esi + pop ebp + //mov large fs : 0, ecx + pop ebx + //add esp, 0x50 + //retn 4 + + + } + /* + // setOverlayEnabledFunction function + __asm + { + mov ecx, [esi + 0x178] + call SOULSTORM_sub_776140 + //mov ecx, esi + //call SOULSTORM_setOverlayEnabledFunction + retn 4 + } + */ + /* + // definitionEnterMetamapScreenFunction + __asm + { + push ebx + mov ebx, [esp - 0x0C] + push esi + push ebx + mov esi, ecx + call SOULSTORM_sub_787340 + + mov eax, [esp + 0x24 - 0x18] + push eax + mov ecx, esi + call SOULSTORM_NewCampaignGameStart + pop esi + pop ebx + retn 8 + } + */ + /* + // runMotionOnMetaMapMenuModel function + __asm + { + //sub esp, 0x50 + //sub esp, 0x0C + push esi + mov esi, ecx + //mov ecx, esp + //sub esp, 0x0C + //mov [esp + 0x7C], esp + //lea eax, [esp + 0x7C] + lea edx, [esi + 0x50] + push edx + //lea eax, [esi + 0x40] + //push eax + //mov eax, [esp + 0x7C] + //push eax + push SOULSTORM_dieActionString_I + call SOULSTORM_findMotionByGivenName + mov ecx, [esi + 0x178] + //call SOULSTORM_runMotionOnMetaMapMenuModel + fld SOULSTORM_flt_C1F44C_I + //add esp, 0x0C + //mov eax, esp + //fstp dword ptr[esp + 8] + //mov[esp + 0x7C], esp + //push esi + //mov ecx, esi + //call SOULSTORM_sub_78EC00 + //add esp, 0x4 + pop esi + ret + } + + /* + // bigger chunk of runAnimationOnMetaMapMenuModel function + __asm + { + push esi + sub esp, 0x0C + mov ecx, esp + mov [esp + 0x7C], esp + lea edx, [esp + 0x7C] + push edx + push SOULSTORM_dieActionString_I + call SOULSTORM_sub_66DE90 + mov ecx, [esi + 0x178] + call SOULSTORM_runAnimationOnMetaMapMenuModel + fld SOULSTORM_flt_C1F44C_I + sub esp, 0x0C + mov eax, esp + fstp dword ptr[esp + 8] + mov [esp + 0x7C], esp + push esi + push SOULSTORM_sub_78EC00 + push eax + call SOULSTORM_sub_78F540 + add esp, 0x0C + mov ecx, esi + call SOULSTORM_sub_787020 + mov [esi + 0x183], 1 + mov ecx, SOULSTORM_off_C1F448_I + push 0 + push ecx + call SOULSTORM_sub_75EC70 + mov [esi + 0x182], 1 + pop esi + ret 4 + } + */ +} + +// NOT WORKING +int __stdcall runActionOnModel(int) +{ + __asm + { + push ebx + push esi + push edi + + mov esi, ecx + call SOULSTORM_sub_96EAA0 + mov ecx, eax + call SOULSTORM_sub_96F440 + mov ecx, [esi + 0x178] + test ecx, ecx + mov edi, [esp + 0x10] + mov ebx, eax + jz skip1 + push 1 + push edi + call SOULSTORM_runZoomAnimation +skip1: + //add esp, 0x4 + pop edi + pop esi + pop ebx + retn 4 + } +} + +// PARTIALLY WORKING +// copy of function from definitionButtonInspectClicked button +int __stdcall definitionButtonInspectClicked(int) +{ + __asm + { + push esi + mov esi, ecx + push SOULSTORM_String + lea eax, [esi + 0x50] + push SOULSTORM_a_root_sidebars + push eax + call USERINTERFACE_Invoke_SwfWidget_UI__QAAPBDPBD0ZZ + add esp, 0x10 + /* + add esp, 4 + mov ecx, esp + push esi + push SOULSTORM_loc_78E070 + push ecx + call SOULSTORM_setPointerToArgument2Function + add esp, 0x0C + + mov ecx, esi + call SOULSTORM_sub_787320 + */ + mov edx, [esi + 0x38] + push edx + mov ecx, esi + //call runActionOnModel + call SOULSTORM_openAnotherGFXFile + pop esi + retn 4 + } +} + +// WORKING +// copy of function from ToggleArmy button +int __stdcall definitionButtonToggleArmyClicked(int) +{ + __asm + { + push 1 + push SOULSTORM_aD_I //"%d" + add ecx, 0x50 //'P' + push SOULSTORM_a_root_showst_0_I //"_root.ShowStatsArmy" + push ecx + call USERINTERFACE_Invoke_SwfWidget_UI__QAAPBDPBD0ZZ + add esp, 0x10 + retn 4 + } + +} + +int __stdcall prepareAction(int) +{ + __asm + { + //mov eax, [esp + 0x0C] + //push eax + mov esi, ecx + mov ecx, esi + call runAction + //sub esp, 0x4 + } +} + +int __declspec(naked) new_BindButtonClickedEntry_Function() +{ + // save address to return in the future + // save stack + __asm + { + pop return_address + //push SOULSTORM_aOnsidebarexite + //mov ecx, edi + //call ebx + + //pushad + } + + __asm + { + push esi + lea ecx, [esp + 0x24 - 0x10] + //lea edx, [esp + 0x24 - 0x10] + //push definitionButtonInspectClicked + //push SOULSTORM_definitionEnterMetamapScreenFunction + push runAction + //push prepareAction + //push edx + push ecx + call SOULSTORM_sub_78F520 + //call SOULSTORM_sub_78F4C0 + add esp, 0x0C + push eax + push SOULSTORM_aDeepStrike_I + mov ecx, edi + call ebx + //} + + //restore stack + //restore overwritten code + __asm + //{ + //popad + push esi + lea edx, [esp + 0x24 - 0x10] + // call SOULSTORM_sub_96EAA0 +/* + push esi + lea edx, [esp + 0x24 - 0x8] + push SOULSTORM_loc_78DBD0 + push edx + call SOULSTORM_sub_78F520 + add esp, 0x0C + push eax + push SOULSTORM_aOnsidebarexite + mov ecx, edi + call ebx +*/ + push return_address + ret + } +} + + +// funciton that disables stuff in load game screen +int __declspec(naked) test_function() +{ + // save address to return in the future + // save stack + __asm + { + pop return_address + //pushad + } + + __asm + { + jmp SOULSTORM_loc_6CC271 + + push return_address + ret + } +} + +// funciton that disables stuff in load game screen +int __declspec(naked) test_function2() +{ + // save address to return in the future + // save stack + __asm + { + pop return_address + //pushad + } + + __asm + { + jmp SOULSTORM_loc_6CB20B + + push return_address + ret + } +} \ No newline at end of file diff --git a/UNI_EXT/SoulstormIntercepts.h b/UNI_EXT/SoulstormIntercepts.h new file mode 100644 index 0000000..12375c7 --- /dev/null +++ b/UNI_EXT/SoulstormIntercepts.h @@ -0,0 +1,8 @@ +#pragma once +int Metamap_Action_Selector_Function(); + +int new_BindButtonClickedEntry_Function(); + +int test_function(); + +int test_function2(); \ No newline at end of file diff --git a/UNI_EXT/SoulstormPointers.h b/UNI_EXT/SoulstormPointers.h new file mode 100644 index 0000000..0b244d8 --- /dev/null +++ b/UNI_EXT/SoulstormPointers.h @@ -0,0 +1,118 @@ +// Based on slashdiablo-maphack implementation +// https://github.com/planqi/slashdiablo-maphack + +#pragma once +#include "SoulstormVersion.h" +#include "Patch.h" + +#ifdef _DEFINE_PTRS +#define FUNCPTR(dll, name, callingret, args, ...) \ + static Offsets f##dll##_##name##_offsets = { __VA_ARGS__ }; \ + __declspec(naked) callingret dll##_##name##args \ + { \ + static DWORD f##dll##_##name = NULL; \ + if(f##dll##_##name == NULL) \ + { \ + __asm { pushad } \ + f##dll##_##name = Patch::GetDllOffset(dll, *(&f##dll##_##name##_offsets._steam + SoulstormVersion::GetGameVersionID())); \ + __asm { popad } \ + } \ + __asm jmp [f##dll##_##name] \ + } + +#define ASMPTR(dll, name, ...) \ + DWORD* Asm_##dll##_##name##(VOID) \ + { \ + static DWORD f##Asm_##dll##_##name = NULL; \ + if(f##Asm_##dll##_##name## == NULL) \ + { \ + static Offsets f##Asm_##_##name##_offsets = { __VA_ARGS__ }; \ + static int address = *(&f##Asm_##_##name##_offsets._steam + SoulstormVersion::GetGameVersionID()); \ + f##Asm_##dll##_##name## = Patch::GetDllOffset(dll, address); \ + } \ + return &##f##Asm_##dll##_##name; \ + } + +#define VARPTR(dll, name, type, ...) \ + type** Var_##dll##_##name##(VOID) \ + { \ + static DWORD f##Var_##dll##_##name = NULL; \ + if(f##Var_##dll##_##name## == NULL) \ + { \ + static Offsets f##Var_##_##name##_offsets = { __VA_ARGS__ }; \ + static int address = *(&f##Var_##_##name##_offsets._steam + SoulstormVersion::GetGameVersionID()); \ + f##Var_##dll##_##name## = Patch::GetDllOffset(dll, address); \ + } \ + return (type**)&##f##Var_##dll##_##name; \ + } + +#else +#define FUNCPTR(dll, name, callingret, args, ...) extern callingret dll##_##name##args; +#define ASMPTR(dll, name, ...) extern DWORD* Asm_##dll##_##name##(VOID); static DWORD dll##_##name = *Asm_##dll##_##name##(); +#define VARPTR(dll, name, type, ...) extern type** Var_##dll##_##name##(VOID); static type* p##_##dll##_##name = (type*)*Var_##dll##_##name##(); +#endif + +//offsets are in format _steam, _cd + +//for function new_BindButtonClickedEntry_Function +FUNCPTR(SOULSTORM, sub_78F520, int* __stdcall, (int, int, int), 0x38F520, -1) + +ASMPTR(SOULSTORM, buttonToggleArmyClicked_I, 0x38DB80, -1) +ASMPTR(SOULSTORM, aToggleArmy_I, 0x6D4058, -1) +ASMPTR(SOULSTORM, aDeepStrike_I, 0x6D4020, -1) + +//for function definitionButtonToggleArmyClicked +FUNCPTR(USERINTERFACE, Invoke_SwfWidget_UI__QAAPBDPBD0ZZ, char const* __cdecl, (char const*, char const*, ...), 0x4CEB0, -1) + +ASMPTR(SOULSTORM, aD_I, 0x7455BC, -1) +ASMPTR(SOULSTORM, a_root_showst_0_I, 0x6D3AA4, -1) + +//for function runAction +FUNCPTR(SOULSTORM, findMotionByGivenName, int __stdcall, (int, int), 0x26DE90, -1) +FUNCPTR(SOULSTORM, runMotionOnMetaMapMenuModel, int __stdcall, (int, int, int), 0x377BD0, -1) +FUNCPTR(SOULSTORM, sub_78F540, int __stdcall, (int, int, int), 0x38F540, -1) +FUNCPTR(SOULSTORM, sub_787020, int __stdcall, (int, int, int), 0x387020, -1) +FUNCPTR(SOULSTORM, sub_75EC70, int __stdcall, (int, int, int), 0x35EC70, -1) + +ASMPTR(SOULSTORM, dieActionString_I, 0x6D3A84, -1) +ASMPTR(SOULSTORM, flt_C1F44C_I, 0x81F44C, -1) +ASMPTR(SOULSTORM, sub_78EC00, 0x38EC00, -1) +ASMPTR(SOULSTORM, off_C1F448_I, 0x81F448, -1) + +// run standard metamap action +FUNCPTR(SOULSTORM, sub_776140, int __stdcall, (void), 0x376140, -1) +FUNCPTR(SOULSTORM, setOverlayEnabledFunction, int __stdcall, (void), 0x38EC00, -1) + +// definition for definitionEnterMetamapScreenFunction? +FUNCPTR(SOULSTORM, definitionEnterMetamapScreenFunction, int __stdcall, (int, int), 0x391990, -1) +FUNCPTR(SOULSTORM, sub_78F4C0, int __stdcall, (int, int, int), 0x38F4C0, -1) + +// definition for definitionButtonEndTurnClicked function +FUNCPTR(SOULSTORM, setPointerToArgument2Function, int __cdecl, (int, int, int), 0x38F540, -1) +FUNCPTR(SOULSTORM, sub_787320, int __stdcall, (int, int), 0x387320, -1) +FUNCPTR(SOULSTORM, openAnotherGFXFile, int __stdcall, (int), 0x38EC70, -1) +FUNCPTR(SOULSTORM, runZoomAnimation, int __stdcall, (int, int), 0x378080, -1) +FUNCPTR(SOULSTORM, sub_96EAA0, int, (void), 0x56EAA0, -1) +FUNCPTR(SOULSTORM, sub_96F440, int, (void), 0x56F440, -1) +FUNCPTR(SOULSTORM, NewCampaignGameStart, int __stdcall, (int), 0x3912E0, -1) +FUNCPTR(SOULSTORM, sub_787340, int __stdcall, (int), 0x387340, -1) +FUNCPTR(SOULSTORM, toggleOverlayFunction, int __stdcall, (char, char), 0x3761C0, -1) + +ASMPTR(SOULSTORM, String, 0x70DB8B, -1) +ASMPTR(SOULSTORM, a_root_sidebarh, 0x6D3174, -1) +ASMPTR(SOULSTORM, loc_78E070, 0x38E070, -1) +ASMPTR(SOULSTORM, FrameHandler3Jump, 0x668D1C, -1) +ASMPTR(SOULSTORM, flt_C1F44C, 0x81F44C, -1) + +ASMPTR(SOULSTORM, a_root_sidebars, 0x6D3188, -1) + +ASMPTR(SOULSTORM, loc_6CC271, 0x2CC271, -1) +ASMPTR(SOULSTORM, loc_6CB20B, 0x2CB20B, -1) + +FUNCPTR(SOULSTORM, loc_78DBD0, int __stdcall, (int), 0x38DBD0, -1) + +ASMPTR(SOULSTORM, aOnsidebarexite, 0x6D33B4, -1) + +#undef FUNCPTR +#undef ASMPTR +#undef VARPTR diff --git a/UNI_EXT/SoulstormVersion.cpp b/UNI_EXT/SoulstormVersion.cpp new file mode 100644 index 0000000..24f3148 --- /dev/null +++ b/UNI_EXT/SoulstormVersion.cpp @@ -0,0 +1,95 @@ +// Based on slashdiablo-maphack implementation +// https://github.com/planqi/slashdiablo-maphack + +#include "SoulstormVersion.h" +#include + +#pragma comment(lib,"Version.lib") + +VersionID SoulstormVersion::versionID = INVALID; + +void SoulstormVersion::Init() { + std::string version = GetGameVersionString(); + + if (version == "1.3.310.7442") { + versionID = VERSION_STEAM; + } + else if (version == "1.4.0.0") { + versionID = VERSION_CD; + } + else { + versionID = INVALID; + MessageBox(NULL, L"Game version not detected or is unsupported!", L"Failed to Detect Game Version", MB_OK); + exit(0); + } +} + +VersionID SoulstormVersion::GetGameVersionID() { + if (versionID == INVALID) { + Init(); + } + return versionID; +} + +// Taken from StackOverflow user crashmstr +std::string SoulstormVersion::GetGameVersionString() { + LPCWSTR szVersionFile = L"Soulstorm.exe"; + DWORD verHandle = 0; + UINT size = 0; + LPBYTE lpBuffer = NULL; + DWORD verSize = GetFileVersionInfoSize(szVersionFile, &verHandle); + + std::string returnValue; + + if (verSize != NULL) + { + LPSTR verData = new char[verSize]; + + if (GetFileVersionInfo(szVersionFile, verHandle, verSize, verData)) + { + if (VerQueryValue(verData, L"\\", (VOID FAR* FAR*)&lpBuffer, &size)) + { + if (size) + { + VS_FIXEDFILEINFO *verInfo = (VS_FIXEDFILEINFO *)lpBuffer; + if (verInfo->dwSignature == 0xfeef04bd) + { + char szBuffer[MAX_PATH]; + // Doesn't matter if you are on 32 bit or 64 bit, + // DWORD is always 32 bits, so first two revision numbers + // come from dwFileVersionMS, last two come from dwFileVersionLS + sprintf_s(szBuffer, "%d.%d.%d.%d", + (verInfo->dwFileVersionMS >> 16) & 0xffff, + (verInfo->dwFileVersionMS >> 0) & 0xffff, + (verInfo->dwFileVersionLS >> 16) & 0xffff, + (verInfo->dwFileVersionLS >> 0) & 0xffff + ); + + returnValue = std::string(szBuffer); + //std::string message = returnValue + "\n"; + //MessageBoxA(NULL, message.c_str(), "DLL Injected", MB_OK); + } + } + } + } + delete[] verData; + } + return returnValue; +} + +std::string SoulstormVersion::GetHumanReadableVersion() { + std::string returnValue; + + switch (GetGameVersionID()) { + case VERSION_STEAM: + returnValue = "steam"; + break; +// case VERSION_113d: +// returnValue = "1.13d"; +// break; + default: + returnValue = "unknown"; + } + + return returnValue; +} \ No newline at end of file diff --git a/UNI_EXT/SoulstormVersion.h b/UNI_EXT/SoulstormVersion.h new file mode 100644 index 0000000..dd2d7bf --- /dev/null +++ b/UNI_EXT/SoulstormVersion.h @@ -0,0 +1,25 @@ +// Based on slashdiablo-maphack implementation +// https://github.com/planqi/slashdiablo-maphack + +#pragma once + +#ifndef _SOULSTORMVERSION_H +#define _SOULSTORMVERSION_H + +#include + +enum VersionID { + INVALID = -1, + VERSION_STEAM = 0, + VERSION_CD +}; + +namespace SoulstormVersion { + extern VersionID versionID; + VersionID GetGameVersionID(); + void Init(); + std::string GetGameVersionString(); + std::string GetHumanReadableVersion(); +}; + +#endif \ No newline at end of file diff --git a/UNI_EXT/UNI_EXT.cpp b/UNI_EXT/UNI_EXT.cpp new file mode 100644 index 0000000..cc86b85 --- /dev/null +++ b/UNI_EXT/UNI_EXT.cpp @@ -0,0 +1,92 @@ +// UNI_EXT.cpp : Defines the exported functions for the DLL application. +// Based on slashdiablo-maphack implementation +// https://github.com/planqi/slashdiablo-maphack + +#define _DEFINE_PTRS +#include "stdafx.h" +#include "SoulstormPointers.h" +#include "UNI_EXT.h" +#include "Patch.h" +#include "SoulstormIntercepts.h" + +string UNI_EXT::path; +HINSTANCE UNI_EXT::instance; + +Patch* patches[] = { + +//*** FINISHED PATCHES *** + + // increase maximum number of defeated races in campaign commander screen + new Patch(Overwrite, SOULSTORM, { 0x81F350, 0x6BDD24 }, { 0x0A, 0x00, 0x00, 0x00 }, 4), + + // increase maximum number of honor guard units in campaign metamap screen + new Patch(Overwrite, SOULSTORM,{ 0x81F454, 0x6BDE28 },{ 0x12, 0x00, 0x00, 0x00 }, 4), + + // increase maximum number of honor guard units in campaign commander screen + new Patch(Overwrite, SOULSTORM,{ 0x81F348, 0x6BDD1C },{ 0x12, 0x00, 0x00, 0x00 }, 4), + + // fog remover coded in UNI_EXT.dll + /* + new Patch(Overwrite, SOULSTORM,{ 0x4282F0, -1 },{ 217, 238, 15, 31, 64, 0 }, 6), + new Patch(Overwrite, SOULSTORM,{ 0x6F54C8, -1 },{ 0, 0, 0, 68 }, 4), + new Patch(Overwrite, SOULSTORM,{ 0x42A33A, -1 },{ 221, 216, 15, 31, 64, 0 }, 6), + */ + //*** END OF FINISHED PATCHES + + // modify SWFwidget bind from 'ToggleArmy' to 'deep_strike' + //new Patch(Overwrite, SOULSTORM,{ 0x391C4E, -1 },{ 0x20, 0x40, 0xAD, 0x00 + + // insert new FSCommand + // Runs "die" action on metamap_main_menu model + //new Patch(Call, SOULSTORM,{ 0x391C79, -1 }, (int)new_BindButtonClickedEntry_Function, 29), + //new Patch(Call, SOULSTORM,{ 0x391C8D, -1 }, (int)new_BindButtonClickedEntry_Function, 5), + new Patch(Call, SOULSTORM,{ 0x391C39, -1 }, (int)new_BindButtonClickedEntry_Function, 5), + //new Patch(Call, SOULSTORM,{ 0x391C96, -1 }, (int)new_BindButtonClickedEntry_Function, 5), + + // + //new Patch(Overwrite, WXPMOD,{ 0x241E18, -1 },{ 0xC6, 0x45, 0xFC, 0x25 }, 4), + //new Patch(Overwrite, WXPMOD,{ 0x241C65, -1 },{ 0xC6, 0x45, 0xFC, 0x25 }, 4), + //new Patch(Overwrite, WXPMOD,{ 0x24137C, -1 },{ 0xC1, 0xE8, 0x25 }, 3), + + // disable stuff in load game screen + //new Patch(Call, SOULSTORM,{ 0x2CC067, -1 }, (int)test_function, 5), + + // disable stuff in critical location function + //new Patch(Call, SOULSTORM,{ 0x2CB1D2, -1 }, (int)test_function2, 5), + + //new Patch(Overwrite, SOULSTORM,{ 0x241E18, -1 },{ 0x0F, 0x84, 0x74, 0x01, 0x00, 0x00 }, 6), + // enable action 'die' in 'metamap.gfx' every time it's loaded + //new Patch(Overwrite, SOULSTORM,{ 0x3913C6, -1 },{ 0x90, 0x90 }, 2), + //new Patch(Overwrite, SOULSTORM,{ 0x3919A0, -1 },{ 0x90, 0x90 }, 2), + + // modify campaign model starting action from 'die' to 'idle' + //new Patch(Overwrite, SOULSTORM,{ 0x3913D7, -1 },{ 0x74, 0xBD, 0xB3, 0x00 }, 4), + + // create new strings in code + //new Patch(Overwrite, SOULSTORM,{ 0x6D2447, -1 },{ 0x00, 't','h','r','o','w','n' }, 7), + // modify runZoomAnimation? function to use new string + //new Patch(Overwrite, SOULSTORM,{ 0x378108, -1 },{ 0x48, 0x24 }, 2), + + //new Patch(Overwrite, SOULSTORM,{ 0x39C590, -1 }, (int)Metamap_Action_Selector_Function, 2), + //new Patch(Call, SOULSTORM,{ 0x378104, -1 }, (int)Animation_Selector_Function, 5), +}; + + +void UNI_EXT::Startup(HINSTANCE instance) +{ + // code that rewrites variable in program memory + // increased defeated races number + + for (int n = 0; n < (sizeof(patches) / sizeof(Patch*)); n++) { + patches[n]->Install(); + } + +// MessageBoxA(NULL, "DLL Injected", "DLL Injected", MB_OK); +// CreateThread(0, 0, MainThread, instance, 0, 0); + +} + +bool UNI_EXT::Shutdown() +{ + return true; +} \ No newline at end of file diff --git a/UNI_EXT/UNI_EXT.h b/UNI_EXT/UNI_EXT.h new file mode 100644 index 0000000..4c0fe9e --- /dev/null +++ b/UNI_EXT/UNI_EXT.h @@ -0,0 +1,16 @@ +// Based on slashdiablo-maphack implementation +// https://github.com/planqi/slashdiablo-maphack + +#pragma once +#include "stdafx.h" +#include +using namespace std; + +namespace UNI_EXT { + extern string path; + extern HINSTANCE instance; + + extern void Startup(HINSTANCE instance); + + extern bool Shutdown(); +} diff --git a/UNI_EXT/UNI_EXT.vcxproj b/UNI_EXT/UNI_EXT.vcxproj new file mode 100644 index 0000000..7f54678 --- /dev/null +++ b/UNI_EXT/UNI_EXT.vcxproj @@ -0,0 +1,190 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {67138EE0-0823-4524-9453-4E9892296669} + Win32Proj + UNI_EXT + 8.1 + + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\DoW Mod Manager\bin\Debug + + + true + + + false + $(SolutionDir)\DoW Mod Manager\bin\Release + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;UNI_EXT_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + /WHOLEARCHIVE %(AdditionalOptions) + + + + + + + Level3 + Disabled + _DEBUG;_WINDOWS;_USRDLL;UNI_EXT_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;UNI_EXT_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + %(AdditionalDependencies) + + + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_WINDOWS;_USRDLL;UNI_EXT_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + + + + + + + + + + + + + + + + + false + + + false + + + false + + + false + + + + + + + + + + + + + \ No newline at end of file diff --git a/UNI_EXT/UNI_EXT.vcxproj.filters b/UNI_EXT/UNI_EXT.vcxproj.filters new file mode 100644 index 0000000..d71cdb7 --- /dev/null +++ b/UNI_EXT/UNI_EXT.vcxproj.filters @@ -0,0 +1,63 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/UNI_EXT/dllmain.cpp b/UNI_EXT/dllmain.cpp new file mode 100644 index 0000000..db7f654 --- /dev/null +++ b/UNI_EXT/dllmain.cpp @@ -0,0 +1,22 @@ +// dllmain.cpp : Defines the entry point for the DLL application. +#include "stdafx.h" +#include "UNI_EXT.h" + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + UNI_EXT::Startup(hModule); + break; + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + UNI_EXT::Shutdown(); + break; + } + return TRUE; +} diff --git a/UNI_EXT/stdafx.cpp b/UNI_EXT/stdafx.cpp new file mode 100644 index 0000000..30b2865 --- /dev/null +++ b/UNI_EXT/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// UNI_EXT.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/UNI_EXT/stdafx.h b/UNI_EXT/stdafx.h new file mode 100644 index 0000000..f3a0737 --- /dev/null +++ b/UNI_EXT/stdafx.h @@ -0,0 +1,16 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files: +#include + + + +// TODO: reference additional headers your program requires here diff --git a/UNI_EXT/targetver.h b/UNI_EXT/targetver.h new file mode 100644 index 0000000..87c0086 --- /dev/null +++ b/UNI_EXT/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include