diff --git a/CTFAK/CTFAK.csproj b/CTFAK/CTFAK.csproj
index 6e765a8..8c120ac 100644
--- a/CTFAK/CTFAK.csproj
+++ b/CTFAK/CTFAK.csproj
@@ -275,6 +275,7 @@
+
diff --git a/CTFAK/MMFParser/Translation/PAME2MFA.cs b/CTFAK/MMFParser/Translation/PAME2MFA.cs
index f4fcf0e..798791e 100644
--- a/CTFAK/MMFParser/Translation/PAME2MFA.cs
+++ b/CTFAK/MMFParser/Translation/PAME2MFA.cs
@@ -79,8 +79,8 @@ namespace CTFAK.MMFParser.Translation
displaySettings["ResizeDisplay"] = flags["MDI"];
displaySettings["FullscreenAtStart"] = flags["FullscreenAtStart"];
displaySettings["AllowFullscreen"] = flags["FullscreenSwitch"];
- displaySettings["Heading"] = !flags["NoHeading"];
- displaySettings["HeadingWhenMaximized"] = true;
+ // displaySettings["Heading"] = !flags["NoHeading"];
+ // displaySettings["HeadingWhenMaximized"] = true;
displaySettings["MenuBar"] = flags["MenuBar"];
displaySettings["MenuOnBoot"] = !flags["MenuHidden"];
displaySettings["NoMinimize"] = newFlags["NoMinimizeBox"];
@@ -361,13 +361,13 @@ namespace CTFAK.MMFParser.Translation
newItem.Flags = item.Flags;
if (item.InkEffectValue == 0&&Settings.Build<=284)
{
- newItem.Chunks.GetOrCreateChunk().Blend = 255;
+ // newItem.Chunks.GetOrCreateChunk().Blend = 255;
}
else
{
- newItem.Chunks.GetOrCreateChunk().Blend = item.InkEffectValue;
+ // newItem.Chunks.GetOrCreateChunk().Blend = item.InkEffectValue;
}
- newItem.Chunks.GetOrCreateChunk().RGBCoeff = Color.White;
+ // newItem.Chunks.GetOrCreateChunk().RGBCoeff = Color.White;
newItem.IconHandle = 12;
diff --git a/CTFAK/Program.cs b/CTFAK/Program.cs
index a66b7a3..de51495 100644
--- a/CTFAK/Program.cs
+++ b/CTFAK/Program.cs
@@ -110,7 +110,13 @@ namespace CTFAK
Settings.Verbose = verbose;
if (path.ToLower().EndsWith(".exe"))
{
-
+ var icon = new IconLoader(path);
+ foreach (var ico in icon.GetAllIcons())
+ {
+ ico.Save(new FileStream($"{Settings.IconPath}\\{ico.Width}x{ico.Height}.png",FileMode.CreateNew));
+ }
+
+
var exeReader = new ByteReader(path, FileMode.Open);
var currentExe = new Exe();
Exe.Instance = currentExe;
@@ -139,6 +145,7 @@ namespace CTFAK
Directory.CreateDirectory($"{Settings.ExtensionPath}");
Directory.CreateDirectory($"{Settings.DLLPath}");
Directory.CreateDirectory($"{Settings.EXEPath}");
+ Directory.CreateDirectory($"{Settings.IconPath}");
Directory.CreateDirectory($"{PluginAPI.PluginAPI.PluginPath}");
}
public static void InitNativeLibrary()
diff --git a/CTFAK/Settings.cs b/CTFAK/Settings.cs
index 8704f22..a2cc769 100644
--- a/CTFAK/Settings.cs
+++ b/CTFAK/Settings.cs
@@ -27,6 +27,7 @@ namespace CTFAK
public static string ExtensionPath=>$"{DumpPath}\\PackData\\Extensions";
public static string DLLPath=>$"{DumpPath}\\PackData\\DLLs";
public static string EXEPath=>$"{DumpPath}\\PackData\\Exes";
+ public static string IconPath=>$"{DumpPath}\\Icons";
public static string AppName;
public static string Copyright;
diff --git a/CTFAK/Utils/IconLoader.cs b/CTFAK/Utils/IconLoader.cs
new file mode 100644
index 0000000..ec421e9
--- /dev/null
+++ b/CTFAK/Utils/IconLoader.cs
@@ -0,0 +1,260 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Security;
+using System.Text;
+
+namespace CTFAK.Utils
+{
+ public class IconLoader
+ {
+ private const uint LOAD_LIBRARY_AS_DATAFILE = 0x00000002;
+
+
+ private readonly static IntPtr RT_ICON = (IntPtr)3;
+ private readonly static IntPtr RT_GROUP_ICON = (IntPtr)14;
+
+ private const int MAX_PATH = 260;
+
+ private byte[][] iconData = null; // Binary data of each icon.
+
+ public string FileName
+ {
+ get;
+ private set;
+ }
+
+
+ public int Count
+ {
+ get { return iconData.Length; }
+ }
+
+ public IconLoader(string fileName)
+ {
+ Initialize(fileName);
+ }
+
+ public Icon GetIcon(int index)
+ {
+ if (index < 0 || Count <= index)
+ throw new ArgumentOutOfRangeException("index");
+
+ // Create an Icon from the .ico file in memory.
+
+ using (var ms = new MemoryStream(iconData[index]))
+ {
+ return new Icon(ms);
+ }
+ }
+
+
+ public Icon[] GetAllIcons()
+ {
+ var icons = new List();
+ for (int i = 0; i < Count; ++i)
+ icons.Add(GetIcon(i));
+
+ return icons.ToArray();
+ }
+
+ public void Save(int index, Stream outputStream)
+ {
+ if (index < 0 || Count <= index)
+ throw new ArgumentOutOfRangeException("index");
+
+ if (outputStream == null)
+ throw new ArgumentNullException("outputStream");
+
+ var data = iconData[index];
+ outputStream.Write(data, 0, data.Length);
+ }
+
+ private void Initialize(string fileName)
+ {
+ if (fileName == null)
+ throw new ArgumentNullException("fileName");
+
+ IntPtr hModule = IntPtr.Zero;
+ try
+ {
+ hModule = NativeMethods.LoadLibraryEx(fileName, IntPtr.Zero, LOAD_LIBRARY_AS_DATAFILE);
+ if (hModule == IntPtr.Zero)
+ throw new Win32Exception();
+
+ FileName = GetFileName(hModule);
+
+
+
+ var tmpData = new List();
+
+ ENUMRESNAMEPROC callback = (h, t, name, l) =>
+ {
+
+
+ var dir = GetDataFromResource(hModule, RT_GROUP_ICON, name);
+
+
+ int count = BitConverter.ToUInt16(dir, 4); // GRPICONDIR.idCount
+ int len = 6 + 16 * count; // sizeof(ICONDIR) + sizeof(ICONDIRENTRY) * count
+ for (int i = 0; i < count; ++i)
+ len += BitConverter.ToInt32(dir, 6 + 14 * i + 8); // GRPICONDIRENTRY.dwBytesInRes
+
+ using (var dst = new BinaryWriter(new MemoryStream(len)))
+ {
+ // Copy GRPICONDIR to ICONDIR.
+
+ dst.Write(dir, 0, 6);
+
+ int picOffset = 6 + 16 * count; // sizeof(ICONDIR) + sizeof(ICONDIRENTRY) * count
+
+ for (int i = 0; i < count; ++i)
+ {
+ // Load the picture.
+
+ ushort id = BitConverter.ToUInt16(dir, 6 + 14 * i + 12); // GRPICONDIRENTRY.nID
+ var pic = GetDataFromResource(hModule, RT_ICON, (IntPtr)id);
+
+ // Copy GRPICONDIRENTRY to ICONDIRENTRY.
+
+ dst.Seek(6 + 16 * i, SeekOrigin.Begin);
+
+ dst.Write(dir, 6 + 14 * i, 8); // First 8bytes are identical.
+ dst.Write(pic.Length); // ICONDIRENTRY.dwBytesInRes
+ dst.Write(picOffset); // ICONDIRENTRY.dwImageOffset
+
+ // Copy a picture.
+
+ dst.Seek(picOffset, SeekOrigin.Begin);
+ dst.Write(pic, 0, pic.Length);
+
+ picOffset += pic.Length;
+ }
+
+ tmpData.Add(((MemoryStream)dst.BaseStream).ToArray());
+ }
+
+ return true;
+ };
+ NativeMethods.EnumResourceNames(hModule, RT_GROUP_ICON, callback, IntPtr.Zero);
+
+ iconData = tmpData.ToArray();
+ }
+ finally
+ {
+ if (hModule != IntPtr.Zero)
+ NativeMethods.FreeLibrary(hModule);
+ }
+ }
+
+ private byte[] GetDataFromResource(IntPtr hModule, IntPtr type, IntPtr name)
+ {
+ // Load the binary data from the specified resource.
+
+ IntPtr hResInfo = NativeMethods.FindResource(hModule, name, type);
+ if (hResInfo == IntPtr.Zero)
+ throw new Win32Exception();
+
+ IntPtr hResData = NativeMethods.LoadResource(hModule, hResInfo);
+ if (hResData == IntPtr.Zero)
+ throw new Win32Exception();
+
+ IntPtr pResData = NativeMethods.LockResource(hResData);
+ if (pResData == IntPtr.Zero)
+ throw new Win32Exception();
+
+ uint size = NativeMethods.SizeofResource(hModule, hResInfo);
+ if (size == 0)
+ throw new Win32Exception();
+
+ byte[] buf = new byte[size];
+ Marshal.Copy(pResData, buf, 0, buf.Length);
+
+ return buf;
+ }
+
+ private string GetFileName(IntPtr hModule)
+ {
+
+
+ string fileName;
+ {
+ var buf = new StringBuilder(MAX_PATH);
+ int len = NativeMethods.GetMappedFileName(
+ NativeMethods.GetCurrentProcess(), hModule, buf, buf.Capacity);
+ if (len == 0)
+ throw new Win32Exception();
+
+ fileName = buf.ToString();
+ }
+
+
+
+ for (char c = 'A'; c <= 'Z'; ++c)
+ {
+ var drive = c + ":";
+ var buf = new StringBuilder(MAX_PATH);
+ int len = NativeMethods.QueryDosDevice(drive, buf, buf.Capacity);
+ if (len == 0)
+ continue;
+
+ var devPath = buf.ToString();
+ if (fileName.StartsWith(devPath))
+ return (drive + fileName.Substring(devPath.Length));
+ }
+
+ return fileName;
+ }
+
+
+ }
+ internal static class NativeMethods
+ {
+ [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ public static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ [SuppressUnmanagedCodeSecurity]
+ public static extern bool FreeLibrary(IntPtr hModule);
+
+ [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ public static extern bool EnumResourceNames(IntPtr hModule, IntPtr lpszType, ENUMRESNAMEPROC lpEnumFunc, IntPtr lParam);
+
+ [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ public static extern IntPtr FindResource(IntPtr hModule, IntPtr lpName, IntPtr lpType);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ [SuppressUnmanagedCodeSecurity]
+ public static extern IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ [SuppressUnmanagedCodeSecurity]
+ public static extern IntPtr LockResource(IntPtr hResData);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ [SuppressUnmanagedCodeSecurity]
+ public static extern uint SizeofResource(IntPtr hModule, IntPtr hResInfo);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ [SuppressUnmanagedCodeSecurity]
+ public static extern IntPtr GetCurrentProcess();
+
+ [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ public static extern int QueryDosDevice(string lpDeviceName, StringBuilder lpTargetPath, int ucchMax);
+
+ [DllImport("psapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ public static extern int GetMappedFileName(IntPtr hProcess, IntPtr lpv, StringBuilder lpFilename, int nSize);
+ }
+
+ [UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = true, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ internal delegate bool ENUMRESNAMEPROC(IntPtr hModule, IntPtr lpszType, IntPtr lpszName, IntPtr lParam);
+}