Initial commit: Complete open-source Decal rebuild

All 5 phases of the open-source Decal rebuild:

Phase 1: 14 decompiled .NET projects (Interop.*, Adapter, FileService, DecalUtil)
Phase 2: 10 native DLLs rewritten as C# COM servers with matching GUIDs
  - DecalDat, DHS, SpellFilter, DecalInput, DecalNet, DecalFilters
  - Decal.Core, DecalControls, DecalRender, D3DService
Phase 3: C++ shims for Inject.DLL (D3D9 hooking) and LauncherHook.DLL
Phase 4: DenAgent WinForms tray application
Phase 5: WiX installer and build script

25 C# projects building with 0 errors.
Native C++ projects require VS 2022 + Windows SDK (x86).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
erik 2026-02-08 18:27:56 +01:00
commit d1442e3747
1382 changed files with 170725 additions and 0 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,48 @@
using System.CodeDom.Compiler;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Resources;
using System.Runtime.CompilerServices;
namespace DecalUtil.Properties;
[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[DebuggerNonUserCode]
[CompilerGenerated]
internal class Resources
{
private static ResourceManager resourceMan;
private static CultureInfo resourceCulture;
[EditorBrowsable(EditorBrowsableState.Advanced)]
internal static ResourceManager ResourceManager
{
get
{
if (resourceMan == null)
{
resourceMan = new ResourceManager("DecalUtil.Properties.Resources", typeof(Resources).Assembly);
}
return resourceMan;
}
}
[EditorBrowsable(EditorBrowsableState.Advanced)]
internal static CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
internal Resources()
{
}
}

View file

@ -0,0 +1,14 @@
using System.CodeDom.Compiler;
using System.Configuration;
using System.Runtime.CompilerServices;
namespace DecalUtil.Properties;
[CompilerGenerated]
[GeneratedCode("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
internal sealed class Settings : ApplicationSettingsBase
{
private static Settings defaultInstance = (Settings)(object)SettingsBase.Synchronized((SettingsBase)(object)new Settings());
public static Settings Default => defaultInstance;
}

View file

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AssemblyName>DecalUtil</AssemblyName>
<OutputType>WinExe</OutputType>
<UseWindowsForms>True</UseWindowsForms>
<ApplicationIcon>app.ico</ApplicationIcon>
<ApplicationManifest>app.manifest</ApplicationManifest>
<RootNamespace />
<GenerateResourceUsePreserializedResources>true</GenerateResourceUsePreserializedResources>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Resources.Extensions" Version="8.0.0" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,441 @@
using System;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Microsoft.Win32;
namespace DecalUtil;
public class DecalUtilMain : Form, IFormStatus
{
private enum KEY_INFORMATION_CLASS
{
KeyBasicInformation,
KeyNodeInformation,
KeyFullInformation,
KeyNameInformation,
KeyCachedInformation,
KeyFlagsInformation,
KeyVirtualizationInformation,
MaxKeyInfoClass
}
private enum CONTROL_FLAGS
{
RegKeyClearFlags = 0,
RegKeyDontVirtualize = 2,
RegKeyDontSilentFail = 4,
RegKeyRecurseFlag = 8
}
private enum KEY_SET_INFORMATION_CLASS
{
KeyWriteTimeInformation,
KeyWow64FlagsInformation,
KeyControlFlagsInformation,
KeySetVirtualizationInformation,
KeySetDebugInformation,
MaxKeySetInfoClass
}
private struct KEY_CONTROL_FLAGS_INFORMATION
{
public uint ControlFlags;
}
private struct KEY_FLAGS_INFO
{
public uint _unk1;
public uint _unk2;
public uint _ControlFlags;
}
private const int KEY_ALL_ACCESS = 983103;
private const int KEY_CREATE_LINK = 32;
private const int KEY_CREATE_SUB_KEY = 4;
private const int KEY_ENUMERATE_SUB_KEYS = 8;
private const int KEY_EXECUTE = 131097;
private const int KEY_NOTIFY = 16;
private const int KEY_QUERY_VALUE = 1;
private const int KEY_READ = 131097;
private const int KEY_SET_VALUE = 2;
private const int KEY_WRITE = 131078;
private UIntPtr HKEY_LOCAL_MACHINE = (UIntPtr)2147483650u;
private IContainer components;
private Button doUpdate;
private StatusStrip statusStrip1;
private ToolStripStatusLabel status;
private TextBox history;
private Button diagnostics;
private CheckBox AdapterDebug;
private ToolStripProgressBar downloadProgress;
private Button RegVirt;
private CheckBox crashDumpsEnable;
public int Max
{
get
{
return downloadProgress.Maximum;
}
set
{
downloadProgress.Maximum = value;
}
}
public int Current
{
get
{
return downloadProgress.Value;
}
set
{
downloadProgress.Value = value;
}
}
public bool ProgressEnabled
{
get
{
return ((ToolStripItem)downloadProgress).Visible;
}
set
{
((ToolStripItem)downloadProgress).Visible = value;
}
}
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
private static extern int RegOpenKeyEx(UIntPtr hKey, string subKey, int ulOptions, int samDesired, out UIntPtr hkResult);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern int RegCloseKey(UIntPtr hKey);
[DllImport("NTDLL.dll")]
private static extern uint NtQueryKey(UIntPtr KeyHandle, KEY_INFORMATION_CLASS KeyInformationClass, ref KEY_FLAGS_INFO KeyInformation, uint Length, out IntPtr ResultLength);
[DllImport("NTDLL.dll")]
private static extern uint NtSetInformationKey(UIntPtr KeyHandle, KEY_SET_INFORMATION_CLASS InformationClass, ref KEY_CONTROL_FLAGS_INFORMATION KeyInformationData, uint DataLength);
public DecalUtilMain()
{
InitializeComponent();
((ToolStripItem)status).Text = "";
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Decal\\Decal.Adapter");
using (registryKey)
{
bool flag = false;
try
{
flag = (int)registryKey.GetValue("Tracing", 0) > 0;
}
catch
{
}
AdapterDebug.Checked = flag;
}
crashDumpsEnable.Checked = CrashDumpsEnabled();
}
private void doUpdate_Click(object sender, EventArgs e)
{
((Control)doUpdate).Enabled = false;
UriBuilder uriBuilder = new UriBuilder((string)Registry.LocalMachine.OpenSubKey("SOFTWARE\\Decal\\Agent").GetValue("DecalDirectory", "http://update.decaldev.com"));
if (!uriBuilder.Path.EndsWith("/"))
{
uriBuilder.Path += "/";
}
uriBuilder.Path += "updatelist.xml";
ReportStatus($"Start Download at: {DateTime.Now:hh:mm:ss}");
Update update = new Update(uriBuilder.ToString());
if (!update.FetchUpdateList(this))
{
ReportStatus($"Failed to download updatelist.xml");
}
else
{
update.DownloadFiles(this);
}
((Control)doUpdate).Enabled = true;
}
private void status_Click(object sender, EventArgs e)
{
}
public void ReportStatus(string statusData)
{
((ToolStripItem)status).Text = statusData;
TextBox obj = history;
((Control)obj).Text = ((Control)obj).Text + statusData + "\r\n";
Application.DoEvents();
}
private void diagnostics_Click(object sender, EventArgs e)
{
}
private void AdapterDebug_CheckedChanged(object sender, EventArgs e)
{
RegistryKey registryKey = Registry.LocalMachine.CreateSubKey("SOFTWARE\\Decal\\Decal.Adapter");
using (registryKey)
{
bool flag = false;
try
{
flag = (int)registryKey.GetValue("Tracing", 0) > 0;
}
catch
{
}
if (flag != AdapterDebug.Checked)
{
if (AdapterDebug.Checked)
{
registryKey.SetValue("Tracing", 1, RegistryValueKind.DWord);
}
else
{
registryKey.SetValue("Tracing", 0, RegistryValueKind.DWord);
}
}
}
}
private void DecalUtilMain_Load(object sender, EventArgs e)
{
}
private void RegVirt_Click(object sender, EventArgs e)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
if (Environment.OSVersion.Version.Major < 6)
{
MessageBox.Show("This only works on Vista and above.");
}
else if (Environment.OSVersion.Version.Major >= 6)
{
KEY_FLAGS_INFO KeyInformation = new KEY_FLAGS_INFO
{
_unk1 = 0u,
_unk2 = 0u,
_ControlFlags = 0u
};
UIntPtr hkResult = UIntPtr.Zero;
int num = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Decal\\Plugins", 0, 983103, out hkResult);
IntPtr ResultLength = IntPtr.Zero;
uint num2 = NtQueryKey(hkResult, KEY_INFORMATION_CLASS.KeyFlagsInformation, ref KeyInformation, 12u, out ResultLength);
RegCloseKey(hkResult);
ReportStatus($"OpenKeyEx Return is {num}, NTQueryKey Return is {num2}, flags mask for HKLM\\Software\\Decal\\Plugins is {KeyInformation._ControlFlags}");
}
}
private bool CrashDumpsEnabled()
{
bool result = false;
try
{
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\Windows Error Reporting\\LocalDumps\\DenAgent.exe");
if (registryKey != null)
{
registryKey.Close();
result = true;
}
}
catch
{
}
return result;
}
private void EnableCrashDumps(string appName)
{
string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
folderPath = Path.Combine(folderPath, "Decal\\Dumps");
Directory.CreateDirectory(folderPath);
using RegistryKey registryKey = Registry.LocalMachine.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\Windows Error Reporting\\LocalDumps\\" + appName);
registryKey.SetValue("DumpFolder", folderPath, RegistryValueKind.String);
registryKey.SetValue("DumpCount", 5, RegistryValueKind.DWord);
registryKey.SetValue("DumpType", 2, RegistryValueKind.DWord);
}
private void DisableCrashDumps(string appName)
{
Registry.LocalMachine.DeleteSubKey("SOFTWARE\\Microsoft\\Windows\\Windows Error Reporting\\LocalDumps\\" + appName);
}
private void crashDumpsEnable_CheckedChanged(object sender, EventArgs e)
{
if (crashDumpsEnable.Checked)
{
EnableCrashDumps("DenAgent.exe");
EnableCrashDumps("acclient.exe");
EnableCrashDumps("aclauncher.exe");
}
else
{
DisableCrashDumps("DenAgent.exe");
DisableCrashDumps("acclient.exe");
DisableCrashDumps("aclauncher.exe");
}
}
protected override void Dispose(bool disposing)
{
if (disposing && components != null)
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Expected O, but got Unknown
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Expected O, but got Unknown
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Expected O, but got Unknown
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Expected O, but got Unknown
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Expected O, but got Unknown
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Expected O, but got Unknown
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Expected O, but got Unknown
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Expected O, but got Unknown
//IL_0545: Unknown result type (might be due to invalid IL or missing references)
//IL_054f: Expected O, but got Unknown
ComponentResourceManager componentResourceManager = new ComponentResourceManager(typeof(DecalUtilMain));
doUpdate = new Button();
statusStrip1 = new StatusStrip();
status = new ToolStripStatusLabel();
downloadProgress = new ToolStripProgressBar();
history = new TextBox();
diagnostics = new Button();
AdapterDebug = new CheckBox();
RegVirt = new Button();
crashDumpsEnable = new CheckBox();
((Control)statusStrip1).SuspendLayout();
((Control)this).SuspendLayout();
((Control)doUpdate).Location = new Point(269, 12);
((Control)doUpdate).Name = "doUpdate";
((Control)doUpdate).Size = new Size(92, 41);
((Control)doUpdate).TabIndex = 0;
((Control)doUpdate).Text = "Auto-Update (XML etc)";
((ButtonBase)doUpdate).UseVisualStyleBackColor = true;
((Control)doUpdate).Click += doUpdate_Click;
((ToolStrip)statusStrip1).Items.AddRange((ToolStripItem[])(object)new ToolStripItem[2]
{
(ToolStripItem)status,
(ToolStripItem)downloadProgress
});
((Control)statusStrip1).Location = new Point(0, 244);
((Control)statusStrip1).Name = "statusStrip1";
((ToolStrip)statusStrip1).RenderMode = (ToolStripRenderMode)2;
((Control)statusStrip1).Size = new Size(562, 22);
statusStrip1.SizingGrip = false;
((Control)statusStrip1).TabIndex = 1;
((ToolStripItem)status).Name = "status";
((ToolStripItem)status).Size = new Size(547, 17);
status.Spring = true;
((ToolStripItem)status).Text = "status";
((ToolStripItem)status).Click += status_Click;
((ToolStripItem)downloadProgress).Name = "downloadProgress";
((ToolStripItem)downloadProgress).Size = new Size(100, 16);
((ToolStripItem)downloadProgress).Visible = false;
history.AcceptsReturn = true;
((Control)history).Location = new Point(12, 110);
((TextBoxBase)history).Multiline = true;
((Control)history).Name = "history";
((TextBoxBase)history).ReadOnly = true;
history.ScrollBars = (ScrollBars)2;
((Control)history).Size = new Size(446, 122);
((Control)history).TabIndex = 2;
((Control)diagnostics).Enabled = false;
((Control)diagnostics).Location = new Point(367, 12);
((Control)diagnostics).Name = "diagnostics";
((Control)diagnostics).Size = new Size(91, 41);
((Control)diagnostics).TabIndex = 3;
((Control)diagnostics).Text = "Decal.Adapter Diagnostics";
((ButtonBase)diagnostics).UseVisualStyleBackColor = true;
((Control)diagnostics).Click += diagnostics_Click;
((Control)AdapterDebug).AutoSize = true;
((Control)AdapterDebug).Location = new Point(12, 24);
((Control)AdapterDebug).Name = "AdapterDebug";
((Control)AdapterDebug).Size = new Size(198, 17);
((Control)AdapterDebug).TabIndex = 4;
((Control)AdapterDebug).Text = "Enable Decal.Adapter Debug output";
((ButtonBase)AdapterDebug).UseVisualStyleBackColor = true;
AdapterDebug.CheckedChanged += AdapterDebug_CheckedChanged;
((Control)RegVirt).Location = new Point(464, 12);
((Control)RegVirt).Name = "RegVirt";
((Control)RegVirt).Size = new Size(102, 41);
((Control)RegVirt).TabIndex = 5;
((Control)RegVirt).Text = "Registry Virt. Settings";
((ButtonBase)RegVirt).UseVisualStyleBackColor = true;
((Control)RegVirt).Click += RegVirt_Click;
((Control)crashDumpsEnable).AutoSize = true;
((Control)crashDumpsEnable).Location = new Point(12, 47);
((Control)crashDumpsEnable).Name = "crashDumpsEnable";
((Control)crashDumpsEnable).Size = new Size(125, 17);
((Control)crashDumpsEnable).TabIndex = 6;
((Control)crashDumpsEnable).Text = "Enable Crash Dumps";
((ButtonBase)crashDumpsEnable).UseVisualStyleBackColor = true;
crashDumpsEnable.CheckedChanged += crashDumpsEnable_CheckedChanged;
((ContainerControl)this).AutoScaleDimensions = new SizeF(6f, 13f);
((ContainerControl)this).AutoScaleMode = (AutoScaleMode)1;
((Form)this).ClientSize = new Size(562, 266);
((Control)this).Controls.Add((Control)(object)crashDumpsEnable);
((Control)this).Controls.Add((Control)(object)RegVirt);
((Control)this).Controls.Add((Control)(object)AdapterDebug);
((Control)this).Controls.Add((Control)(object)diagnostics);
((Control)this).Controls.Add((Control)(object)history);
((Control)this).Controls.Add((Control)(object)statusStrip1);
((Control)this).Controls.Add((Control)(object)doUpdate);
((Form)this).Icon = (Icon)componentResourceManager.GetObject("$this.Icon");
((Form)this).MaximizeBox = false;
((Control)this).MaximumSize = new Size(578, 304);
((Control)this).MinimumSize = new Size(478, 304);
((Control)this).Name = "DecalUtilMain";
((Form)this).SizeGripStyle = (SizeGripStyle)2;
((Control)this).Text = "Decal 3.0 Utilities";
((Form)this).Load += DecalUtilMain_Load;
((Control)statusStrip1).ResumeLayout(false);
((Control)statusStrip1).PerformLayout();
((Control)this).ResumeLayout(false);
((Control)this).PerformLayout();
}
}

View file

@ -0,0 +1,12 @@
namespace DecalUtil;
internal interface IFormStatus
{
int Max { get; set; }
int Current { get; set; }
bool ProgressEnabled { get; set; }
void ReportStatus(string statusData);
}

View file

@ -0,0 +1,15 @@
using System;
using System.Windows.Forms;
namespace DecalUtil;
internal static class Program
{
[STAThread]
private static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run((Form)(object)new DecalUtilMain());
}
}

View file

@ -0,0 +1,125 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Runtime.InteropServices;
using System.Xml;
using Microsoft.Win32;
namespace DecalUtil;
internal class Update
{
private delegate int DllRegisterServerInvoker();
private string updateUrl;
private Queue<UpdateFile> files;
public Update(string UpdateUrl)
{
updateUrl = UpdateUrl;
files = new Queue<UpdateFile>();
}
public bool FetchUpdateList(IFormStatus status)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Expected O, but got Unknown
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Expected O, but got Unknown
XmlDocument val = new XmlDocument();
WebClient webClient = new WebClient();
try
{
val.Load(webClient.OpenRead(updateUrl));
status.ReportStatus($"Parsing update list");
}
catch (WebException ex)
{
status.ReportStatus($"Error Occured: {ex.ToString()}");
if (ex.Status == WebExceptionStatus.ProtocolError)
{
ex.Response.Close();
}
return false;
}
catch (Exception ex2)
{
status.ReportStatus($"Unknown Error Occured {ex2.ToString()}");
return false;
}
webClient.Dispose();
foreach (XmlNode item2 in ((XmlNode)val).SelectNodes("updatelist/file"))
{
XmlNode val2 = item2;
string value = ((XmlNode)val2.Attributes["type"]).Value;
string value2 = ((XmlNode)val2.Attributes["localname"]).Value;
string value3 = ((XmlNode)val2.Attributes["remotename"]).Value;
UpdateFile item = new UpdateFile(value, value2, value3);
if (val2.Attributes["version"].Specified)
{
item.Version = ((XmlNode)val2.Attributes["version"]).Value;
}
files.Enqueue(item);
}
return true;
}
public void DownloadFiles(IFormStatus status)
{
string text = (string)Registry.LocalMachine.OpenSubKey("SOFTWARE\\Decal\\Agent").GetValue("AgentPath");
status.Max = files.Count;
status.Current = 0;
status.ProgressEnabled = true;
while (files.Count > 0)
{
UpdateFile updateFile = files.Dequeue();
WebClient webClient = new WebClient();
try
{
status.ReportStatus($"Fetching {updateFile.LocalName}");
if (updateFile.Version == string.Empty || NewerVersion(updateFile.Version, updateFile.LocalName))
{
webClient.DownloadFile(updateFile.RemoteName, text + updateFile.LocalName);
}
}
catch (WebException ex)
{
status.ReportStatus($"Failed to get file: {updateFile.LocalName}, {ex.ToString()}");
if (ex.Status == WebExceptionStatus.ProtocolError)
{
ex.Response.Close();
}
}
webClient.Dispose();
status.Current++;
}
status.ReportStatus("Download Complete");
status.ProgressEnabled = false;
}
private bool NewerVersion(string newVersion, string localFile)
{
FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(localFile);
return string.Compare(newVersion, versionInfo.FileVersion, ignoreCase: true) > 0;
}
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true)]
private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32.dll")]
private static extern IntPtr LoadLibrary(string lpFileName);
private void RegisterDll(string fileName)
{
try
{
((DllRegisterServerInvoker)Marshal.GetDelegateForFunctionPointer(GetProcAddress(LoadLibrary(fileName), "DllRegisterServer"), typeof(DllRegisterServerInvoker)))();
}
catch (Exception ex)
{
Console.WriteLine("Error Registering {0} -- {1}", fileName, ex.Message);
}
}
}

View file

@ -0,0 +1,20 @@
namespace DecalUtil;
internal struct UpdateFile
{
public string Type;
public string LocalName;
public string RemoteName;
public string Version;
public UpdateFile(string Type, string Local, string Remote)
{
this.Type = Type;
LocalName = Local;
RemoteName = Remote;
Version = string.Empty;
}
}

View file

@ -0,0 +1,17 @@
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
[assembly: AssemblyTitle("DecalUtil")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Insanity-Inc")]
[assembly: AssemblyProduct("DecalUtil")]
[assembly: AssemblyCopyright("Copyright © Insanity-Inc 2006")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("25dc2d7b-8af4-4cd2-9b6d-680cbb8fdf28")]
[assembly: AssemblyFileVersion("2.9.8.3")]
[assembly: AssemblyVersion("2.9.8.3")]

BIN
Managed/DecalUtil/app.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

View file

@ -0,0 +1,9 @@
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"></requestedExecutionLevel>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>