diff --git a/CSharp/Content/UniversalEditor.Content.PlatformIndependent/Associations/Executable.xml b/CSharp/Content/UniversalEditor.Content.PlatformIndependent/Associations/Executable.xml
new file mode 100644
index 00000000..29524462
--- /dev/null
+++ b/CSharp/Content/UniversalEditor.Content.PlatformIndependent/Associations/Executable.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+ *.exe
+ *.com
+ *.dll
+ *.rll
+ *.fon
+ *.olb
+ *.tlb"
+
+
+
+ MZ
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CSharp/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj b/CSharp/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj
index 34a7c02c..67b30a3f 100644
--- a/CSharp/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj
+++ b/CSharp/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj
@@ -37,6 +37,7 @@
+
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/DOSExecutableHeader.cs b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/DOSExecutableHeader.cs
new file mode 100644
index 00000000..4a0ca890
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/DOSExecutableHeader.cs
@@ -0,0 +1,76 @@
+using System;
+
+namespace UniversalEditor.DataFormats.Executable.Microsoft
+{
+ ///
+ /// Description of DOSExecutableHeader.
+ ///
+ public class DOSExecutableHeader
+ {
+ private bool mvarEnabled = true;
+ ///
+ /// Determines whether to write the 16-bit DOS executable header in the Microsoft executable file.
+ ///
+ public bool Enabled { get { return mvarEnabled; } set { mvarEnabled = value; } }
+
+
+ private ushort mvarLastBlockLength = 0;
+ public ushort LastBlockLength { get { return mvarLastBlockLength; } set { mvarLastBlockLength = value; } }
+
+ private ushort mvarNumBlocksInEXE = 0;
+ public ushort NumBlocksInEXE { get { return mvarNumBlocksInEXE; } set { mvarNumBlocksInEXE = value; } }
+
+ private ushort mvarNumRelocEntriesAfterHeader = 0;
+ public ushort NumRelocEntriesAfterHeader { get { return mvarNumRelocEntriesAfterHeader; } set { mvarNumRelocEntriesAfterHeader = value; } }
+
+ private ushort mvarNumParagraphsInHeader = 0;
+ public ushort NumParagraphsInHeader { get { return mvarNumParagraphsInHeader; } set { mvarNumParagraphsInHeader = value; } }
+
+ private ushort mvarNumParagraphsAdditionalMemory = 0;
+ public ushort NumParagraphsAdditionalMemory { get { return mvarNumParagraphsAdditionalMemory; } set { mvarNumParagraphsAdditionalMemory = value; } }
+
+ private ushort mvarNumMaxParagraphsAdditionalMemory = 0;
+ public ushort NumMaxParagraphsAdditionalMemory { get { return mvarNumMaxParagraphsAdditionalMemory; } set { mvarNumMaxParagraphsAdditionalMemory = value; } }
+
+ private ushort mvarRelativeStackSegmentValue = 0;
+ public ushort RelativeStackSegmentValue { get { return mvarRelativeStackSegmentValue; } set { mvarRelativeStackSegmentValue = value; } }
+
+ private ushort mvarInitialValueRegisterSP = 0;
+ public ushort InitialValueRegisterSP { get { return mvarInitialValueRegisterSP; } set { mvarInitialValueRegisterSP = value; } }
+
+ private ushort mvarWordChecksum = 0;
+ public ushort WordChecksum { get { return mvarWordChecksum; } set { mvarWordChecksum = value; } }
+
+ private ushort mvarInitialValueRegisterIP = 0;
+ public ushort InitialValueRegisterIP { get { return mvarInitialValueRegisterIP; } set { mvarInitialValueRegisterIP = value; } }
+
+ private ushort mvarInitialValueRegisterCS = 0;
+ public ushort InitialValueRegisterCS { get { return mvarInitialValueRegisterCS; } set { mvarInitialValueRegisterCS = value; } }
+
+ private ushort mvarFirstRelocationItemOffset = 0;
+ public ushort FirstRelocationItemOffset { get { return mvarFirstRelocationItemOffset; } set { mvarFirstRelocationItemOffset = value; } }
+
+ private ushort mvarOverlayNumber = 0;
+ public ushort OverlayNumber { get { return mvarOverlayNumber; } set { mvarOverlayNumber = value; } }
+
+ public long EXEDataStart
+ {
+ get
+ {
+ return (mvarNumParagraphsInHeader * 16L);
+ }
+ }
+ public long ExtraDataStart
+ {
+ get
+ {
+ long tmp = mvarNumBlocksInEXE * 512L;
+ if (mvarLastBlockLength > 0)
+ {
+ tmp -= (512 - mvarLastBlockLength);
+ }
+ return tmp;
+ }
+ }
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/MicrosoftExecutableDataFormat.cs b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/MicrosoftExecutableDataFormat.cs
new file mode 100644
index 00000000..1e1c97cd
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/MicrosoftExecutableDataFormat.cs
@@ -0,0 +1,529 @@
+// one line to give the program's name and an idea of what it does.
+// Copyright (C) yyyy name of author
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+using System;
+using UniversalEditor.Accessors;
+using UniversalEditor.IO;
+using UniversalEditor.ObjectModels.Executable;
+using UniversalEditor.ObjectModels.FileSystem;
+
+#if EXECUTABLE_LOAD_RESOURCES
+using UniversalEditor.DataFormats.Resource.Microsoft;
+using UniversalEditor.ObjectModels.Resource;
+using UniversalEditor.ObjectModels.Resource.Blocks;
+#endif
+
+namespace UniversalEditor.DataFormats.Executable.Microsoft
+{
+ ///
+ /// Description of DOSExecutable.
+ ///
+ public class MicrosoftExecutableDataFormat : DataFormat
+ {
+ private DOSExecutableHeader mvarDOSHeader = new DOSExecutableHeader();
+ public DOSExecutableHeader DOSHeader { get { return mvarDOSHeader; } }
+
+ private NameValuePair.NameValuePairCollection mvarImportTable = new NameValuePair.NameValuePairCollection();
+ public NameValuePair.NameValuePairCollection ImportTable { get { return mvarImportTable; } }
+
+ private System.Reflection.Assembly mvarCLRAssembly = null;
+ public System.Reflection.Assembly CLRAssembly { get { return mvarCLRAssembly; } }
+
+ private static DataFormatReference _dfr = null;
+ public override DataFormatReference MakeReference()
+ {
+ if (_dfr == null)
+ {
+ _dfr = base.MakeReference();
+ _dfr.Capabilities.Add(typeof(ExecutableObjectModel), DataFormatCapabilities.All);
+ // _dfr.Capabilities.Add(typeof(FileSystemObjectModel), DataFormatCapabilities.All);
+ }
+ return _dfr;
+ }
+
+ protected override void AfterLoadInternal(System.Collections.Generic.Stack objectModels)
+ {
+ base.AfterLoadInternal(objectModels);
+
+ FileAccessor fa = (base.Accessor as FileAccessor);
+ if (fa != null)
+ {
+ try
+ {
+ mvarCLRAssembly = System.Reflection.Assembly.LoadFile(fa.FileName);
+ }
+ catch (BadImageFormatException)
+ {
+ mvarCLRAssembly = null;
+ }
+ }
+ }
+
+ /*
+ C++ Name Mangling
+Compiler void h(int) void h(int, char) void h(void)
+Intel C++ 8.0 for Linux _Z1hi _Z1hic _Z1hv
+HP aC++ A.05.55 IA-64 _Z1hi _Z1hic _Z1hv
+IAR EWARM C++ 5.4 ARM _Z1hi _Z1hic _Z1hv
+GCC 3.x and 4.x _Z1hi _Z1hic _Z1hv
+GCC 2.9x h__Fi h__Fic h__Fv
+HP aC++ A.03.45 PA-RISC h__Fi h__Fic h__Fv
+Microsoft Visual C++ v6-v10 ?h@@YAXH@Z ?h@@YAXHD@Z ?h@@YAXXZ
+Digital Mars C++ ?h@@YAXH@Z ?h@@YAXHD@Z ?h@@YAXXZ
+Borland C++ v3.1 @h$qi @h$qizc @h$qv
+OpenVMS C++ V6.5 (ARM mode) H__XI H__XIC H__XV
+OpenVMS C++ V6.5 (ANSI mode) CXX$__7H__FI0ARG51T CXX$__7H__FIC26CDH77 CXX$__7H__FV2CB06E8
+OpenVMS C++ X7.1 IA-64 CXX$_Z1HI2DSQ26A CXX$_Z1HIC2NP3LI4 CXX$_Z1HV0BCA19V
+SunPro CC __1cBh6Fi_v_ __1cBh6Fic_v_ __1cBh6F_v_
+Tru64 C++ V6.5 (ARM mode) h__Xi h__Xic h__Xv
+Tru64 C++ V6.5 (ANSI mode) __7h__Fi __7h__Fic __7h__Fv
+Watcom C++ 10.6 W?h$n(i)v W?h$n(ia)v W?h$n()v
+
+ */
+
+ private string DecodeMangledName(string name, PECompiler compiler)
+ {
+ System.Text.StringBuilder sb = new System.Text.StringBuilder();
+ switch (compiler)
+ {
+ case PECompiler.IntelCPP80Linux:
+ {
+ // _Z1hi _Z1hic _Z1hv
+ // void h(int) void h(int, char) void h(void)
+
+ string _Z1 = name.Substring(0, 2);
+
+ break;
+ }
+ case PECompiler.MsVCpp:
+ case PECompiler.DigitalMars:
+ {
+ // ?h@@YAXH@Z ?h@@YAXHD@Z ?h@@YAXXZ
+ // void h(int) void h(int, char) void h(void)
+
+ string prefix = name.Substring(0, 1); // ?
+ string funcName = name.Substring(1, name.IndexOf('@', 1) - 2); // h
+ string suffix = name.Substring(1 + funcName.Length, 4); // @@YA
+ //XH@Z
+ break;
+ }
+ }
+ return sb.ToString();
+ }
+
+ protected override void LoadInternal(ref ObjectModel objectModel)
+ {
+ Reader br = base.Accessor.Reader;
+
+ FileSystemObjectModel fsom = (objectModel as FileSystemObjectModel);
+ ExecutableObjectModel exec = (objectModel as ExecutableObjectModel);
+ if (fsom == null && exec == null) throw new ObjectModelNotSupportedException("Object model must be a FileSystem or an Executable");
+
+ ExecutableObjectModel exe = new ExecutableObjectModel();
+
+ #region DOS part
+ {
+ string signature = br.ReadFixedLengthString(2); // 0x4d, 0x5a. This is the "magic number" of an EXE file. The first byte of the file is 0x4d and the second is 0x5a.
+ if (signature != "MZ") throw new InvalidDataFormatException("File does not begin with \"MZ\"");
+ mvarDOSHeader.LastBlockLength = br.ReadUInt16(); // The number of bytes in the last block of the program that are actually used. If this value is zero, that means the entire last block is used (i.e. the effective value is 512).
+ mvarDOSHeader.NumBlocksInEXE = br.ReadUInt16(); // Number of blocks in the file that are part of the EXE file. If mvarDOSHeader.LastBlockLength is non-zero, only that much of the last block is used.
+ mvarDOSHeader.NumRelocEntriesAfterHeader = br.ReadUInt16(); // Number of relocation entries stored after the header. May be zero.
+ mvarDOSHeader.NumParagraphsInHeader = br.ReadUInt16(); // Number of paragraphs in the header. The program's data begins just after the header, and this field can be used to calculate the appropriate file offset. The header includes the relocation entries. Note that some OSs and/or programs may fail if the header is not a multiple of 512 bytes.
+ mvarDOSHeader.NumParagraphsAdditionalMemory = br.ReadUInt16(); // Number of paragraphs of additional memory that the program will need. This is the equivalent of the BSS size in a Unix program. The program can't be loaded if there isn't at least this much memory available to it.
+ mvarDOSHeader.NumMaxParagraphsAdditionalMemory = br.ReadUInt16(); // Maximum number of paragraphs of additional memory. Normally, the OS reserves all the remaining conventional memory for your program, but you can limit it with this field.
+ mvarDOSHeader.RelativeStackSegmentValue = br.ReadUInt16(); // Relative value of the stack segment. This value is added to the segment the program was loaded at, and the result is used to initialize the SS register.
+ mvarDOSHeader.InitialValueRegisterSP = br.ReadUInt16(); // Initial value of the SP register.
+ mvarDOSHeader.WordChecksum = br.ReadUInt16(); // Word checksum. If set properly, the 16-bit sum of all words in the file should be zero. Usually, this isn't filled in.
+ mvarDOSHeader.InitialValueRegisterIP = br.ReadUInt16(); // Initial value of the IP register.
+ mvarDOSHeader.InitialValueRegisterCS = br.ReadUInt16(); // Initial value of the CS register, relative to the segment the program was loaded at.
+ mvarDOSHeader.FirstRelocationItemOffset = br.ReadUInt16(); // Offset of the first relocation item in the file.
+ mvarDOSHeader.OverlayNumber = br.ReadUInt16(); // Overlay number. Normally zero, meaning that it's the main program.
+ }
+ #endregion
+ #region Portable Executable
+ {
+ br.Accessor.Position = 0x3C;
+
+ int e_lfanew = br.ReadInt32(); // offset to PE header
+ if (e_lfanew != 0)
+ {
+ br.Accessor.Position = e_lfanew;
+
+ #region PE header
+ PEHeader pe = new PEHeader();
+ pe.signature = br.ReadFixedLengthString(4);
+ if (pe.signature == "PE\0\0")
+ {
+ pe.enabled = true;
+ pe.machine = (PEMachineType)br.ReadUInt16();
+ pe.sectionCount = br.ReadInt16();
+ pe.unknown1 = br.ReadInt16();
+ pe.unknown2 = br.ReadInt16();
+ pe.unknown3 = br.ReadInt16();
+ pe.unknown4 = br.ReadInt16();
+ pe.unknown5 = br.ReadInt16();
+ pe.unknown6 = br.ReadInt16();
+ pe.sizeOfOptionalHeader = br.ReadInt16(); // relative offset to sectiontable
+ pe.characteristics = (PECharacteristics)br.ReadUInt16();
+
+ exe.TargetMachineType = (ExecutableMachine)pe.machine;
+ exe.Characteristics = (ExecutableCharacteristics)pe.characteristics;
+ }
+ else
+ {
+ pe.enabled = false;
+ br.Accessor.Position -= 4;
+ }
+ #endregion
+ #region Optional Header
+ PEOptionalHeader peoh = new PEOptionalHeader();
+ if (pe.sizeOfOptionalHeader > 0)
+ {
+ // offset: 0x58
+ peoh.enabled = true;
+ peoh.magic = br.ReadUInt16();
+ peoh.unknown1 = br.ReadUInt16();
+ peoh.unknown2 = br.ReadUInt32();
+ peoh.unknown3 = br.ReadUInt32();
+ peoh.unknown4 = br.ReadUInt32();
+ peoh.entryPointAddr = br.ReadUInt32();
+ peoh.unknown5 = br.ReadUInt32();
+ peoh.unknown6 = br.ReadUInt32();
+ peoh.imageBase = br.ReadUInt32();
+ peoh.sectionAlignment = br.ReadUInt32();
+ peoh.fileAlignment = br.ReadUInt32();
+ peoh.unknown7 = br.ReadUInt32();
+ peoh.unknown8 = br.ReadUInt32();
+ peoh.majorSubsystemVersion = br.ReadUInt16(); // 4 = NT 4 or later
+ peoh.unknown9 = br.ReadUInt16();
+ peoh.unknown10 = br.ReadUInt32();
+ peoh.imageSize = br.ReadUInt32();
+ peoh.headerSize = br.ReadUInt32();
+ peoh.unknown11 = br.ReadUInt32();
+ peoh.subsystem = br.ReadUInt16();
+ peoh.unknown12 = br.ReadUInt16();
+ peoh.unknown13 = br.ReadUInt32();
+ peoh.unknown14 = br.ReadUInt32();
+ peoh.unknown15 = br.ReadUInt32();
+ peoh.unknown16 = br.ReadUInt32();
+ peoh.unknown17 = br.ReadUInt32();
+ peoh.rvaCount = br.ReadUInt32();
+ }
+ else
+ {
+ peoh.enabled = false;
+ }
+ #endregion
+ #region Data Directories
+ {
+ for (int i = 0; i < peoh.rvaCount; i++)
+ {
+ uint rva = br.ReadUInt32();
+ }
+ }
+ #endregion
+ #region Sections Table
+ {
+ // offset: 0x138
+ br.Accessor.Seek(64, SeekOrigin.Current);
+
+ uint lastRawDataPtr = 0;
+ for (short i = 0; i < pe.sectionCount; i++)
+ {
+ PESectionHeader pesh = new PESectionHeader();
+ pesh.name = br.ReadFixedLengthString(8).TrimNull();
+ pesh.virtualSize = br.ReadUInt32();
+ pesh.virtualAddress = br.ReadUInt32();
+ pesh.rawDataSize = br.ReadUInt32();
+ pesh.rawDataPtr = br.ReadUInt32();
+ pesh.unknown1 = br.ReadUInt32();
+ pesh.unknown2 = br.ReadUInt32();
+ pesh.unknown3 = br.ReadUInt32();
+ pesh.characteristics = (PESectionCharacteristics)br.ReadUInt32();
+
+ if (fsom != null)
+ {
+ File file = new File();
+ file.Name = pesh.name;
+ file.Properties.Add("reader", br);
+ file.Properties.Add("offset", pesh.rawDataPtr);
+ file.Properties.Add("length", pesh.rawDataSize);
+
+ file.Size = pesh.rawDataSize;
+ file.DataRequest += file_DataRequest;
+ fsom.Files.Add(file);
+ }
+
+ ExecutableSection sect = new ExecutableSection();
+ sect.Name = pesh.name;
+ // sect.DataRequest += sect_DataRequest;
+ sect.VirtualSize = pesh.virtualSize;
+ sect.VirtualAddress = pesh.virtualAddress;
+ sect.PhysicalAddress = pesh.rawDataPtr;
+ sect.Characteristics = (ExecutableSectionCharacteristics)pesh.characteristics;
+
+ long ofs = br.Accessor.Position;
+ br.Accessor.Position = pesh.rawDataPtr;
+ sect.Data = br.ReadBytes(pesh.rawDataSize);
+ br.Accessor.Position = ofs;
+
+ exe.Sections.Add(sect);
+ }
+ }
+ #endregion
+ }
+ else
+ {
+ #region New Executable
+ // not a PE file, try NE?
+ br.Accessor.Position = 128;
+ string NE = br.ReadFixedLengthString(2);
+ if (NE == "NE")
+ {
+ byte MajLinkerVersion = br.ReadByte(); ; //The major linker version
+ byte MinLinkerVersion = br.ReadByte(); //The minor linker version
+ ushort EntryTableOffset = br.ReadUInt16(); //Offset of entry table, see below
+ ushort EntryTableLength = br.ReadUInt16(); //Length of entry table in bytes
+ uint FileLoadCRC = br.ReadUInt32(); //UNKNOWN - PLEASE ADD INFO
+ byte ProgFlags = br.ReadByte(); //Program flags, bitmapped
+ byte ApplFlags = br.ReadByte(); //Application flags, bitmapped
+ byte AutoDataSegIndex = br.ReadByte(); //The automatic data segment index
+ ushort InitHeapSize = br.ReadUInt16(); //The intial local heap size
+ ushort InitStackSize = br.ReadUInt16(); //The inital stack size
+ uint EntryPoint = br.ReadUInt32(); //CS:IP entry point, CS is index into segment table
+ uint InitStack = br.ReadUInt32(); //SS:SP inital stack pointer, SS is index into segment table
+ ushort SegCount = br.ReadUInt16(); //Number of segments in segment table
+ ushort ModRefs = br.ReadUInt16(); //Number of module references (DLLs)
+ ushort NoResNamesTabSiz = br.ReadUInt16(); //Size of non-resident names table, in bytes (Please clarify non-resident names table)
+ ushort SegTableOffset = br.ReadUInt16(); //Offset of Segment table
+ ushort ResTableOffset = br.ReadUInt16(); //Offset of resources table
+ ushort ResidNamTable = br.ReadUInt16(); //Offset of resident names table
+ ushort ModRefTable = br.ReadUInt16(); //Offset of module reference table
+ ushort ImportNameTable = br.ReadUInt16(); //Offset of imported names table (array of counted strings, terminated with string of length 00h)
+ uint OffStartNonResTab = br.ReadUInt32(); //Offset from start of file to non-resident names table
+ ushort MovEntryCount = br.ReadUInt16(); //Count of moveable entry point listed in entry table
+ ushort FileAlnSzShftCnt = br.ReadUInt16(); //File alligbment size shift count (0=9(default 512 byte pages))
+ ushort nResTabEntries = br.ReadUInt16(); //Number of resource table entries
+ byte targOS = br.ReadByte(); //Target OS
+ byte OS2EXEFlags = br.ReadByte(); //Other OS/2 flags
+ ushort retThunkOffset = br.ReadUInt16(); //Offset to return thunks or start of gangload area - what is gangload?
+ ushort segrefthunksoff = br.ReadUInt16(); //Offset to segment reference thunks or size of gangload area
+ ushort mincodeswap = br.ReadUInt16(); //Minimum code swap area size
+ byte expctwinver_min = br.ReadByte(); //Expected windows version (minor)
+ byte expctwinver_maj = br.ReadByte(); //Expected windows version (major)
+ }
+ #endregion
+ }
+ }
+ #endregion
+
+#if EXECUTABLE_LOAD_RESOURCES
+ #region Resources
+ {
+ ExecutableSection sectRSRC = exe.Sections[".rsrc"];
+ if (sectRSRC != null)
+ {
+ byte[] rsrc_data = sectRSRC.Data;
+
+ ResourceObjectModel resources = new ResourceObjectModel();
+ Win32EmbeddedResourceDataFormat rsrc = new Win32EmbeddedResourceDataFormat();
+ rsrc.AddressOffset = sectRSRC.VirtualAddress;
+
+ FileAccessor fa = new FileAccessor(resources, rsrc);
+ fa.Open(ref rsrc_data);
+ fa.Load();
+ fa.Close();
+
+ if (fsom != null)
+ {
+ Folder fldrResources = fsom.Folders.Add("Resources");
+ foreach (ResourceBlock block in resources.Blocks)
+ {
+ RecursiveLoadResourceBlock(block, fldrResources);
+ }
+ }
+
+ #region Version Information
+ {
+ // find the VS_VERSION_INFO resource
+ DirectoryResourceBlock drbVersion = (resources.Blocks["Version"] as DirectoryResourceBlock);
+ if (drbVersion != null)
+ {
+ DirectoryResourceBlock drb1 = (drbVersion.Blocks[0] as DirectoryResourceBlock);
+
+ ContentResourceBlock crb = (drb1.Blocks[0] as ContentResourceBlock);
+
+ ObjectModels.Version.VersionObjectModel ver = new ObjectModels.Version.VersionObjectModel();
+ Version.Microsoft.Win32VersionDataFormat vs_version_info = new Version.Microsoft.Win32VersionDataFormat();
+ FileAccessor fa_ver = new FileAccessor(ver, vs_version_info);
+ byte[] ver_data = crb.Data;
+ fa_ver.Open(ref ver_data);
+ fa_ver.Load();
+ fa_ver.Close();
+ }
+ }
+ #endregion
+ }
+ }
+ #endregion
+#endif
+
+ #region Push out Executable to the ObjectModel
+ {
+ if (exec != null)
+ {
+ exe.CopyTo(exec);
+ }
+ else if (fsom != null)
+ {
+ // don't do this again
+ /*
+ foreach (ExecutableSection sect in exe.Sections)
+ {
+ fsom.Files.Add(sect.Name, sect.Data);
+ }
+ */
+ }
+ }
+ #endregion
+ }
+
+#if EXECUTABLE_LOAD_RESOURCES
+ private void RecursiveLoadResourceBlock(ResourceBlock block, Folder parent)
+ {
+ if (block is UniversalEditor.ObjectModels.Resource.Blocks.DirectoryResourceBlock)
+ {
+ UniversalEditor.ObjectModels.Resource.Blocks.DirectoryResourceBlock dir = (block as UniversalEditor.ObjectModels.Resource.Blocks.DirectoryResourceBlock);
+ Folder fldr1 = parent.Folders.Add(dir.Name);
+ foreach (ResourceBlock block1 in dir.Blocks)
+ {
+ RecursiveLoadResourceBlock(block1, fldr1);
+ }
+ }
+ else if (block is UniversalEditor.ObjectModels.Resource.Blocks.ContentResourceBlock)
+ {
+ UniversalEditor.ObjectModels.Resource.Blocks.ContentResourceBlock crb = (block as UniversalEditor.ObjectModels.Resource.Blocks.ContentResourceBlock);
+ File file = parent.Files.Add(crb.Name, crb.Data);
+ }
+ }
+#endif
+
+ private void file_DataRequest(object sender, DataRequestEventArgs e)
+ {
+ File file = (sender as File);
+ Reader br = (Reader)(file.Properties["reader"]);
+ uint offset = (uint)(file.Properties["offset"]);
+ uint length = (uint)(file.Properties["length"]);
+
+ br.Accessor.Position = offset;
+ e.Data = br.ReadBytes(length);
+ }
+
+ protected override void SaveInternal(ObjectModel objectModel)
+ {
+ Writer bw = base.Accessor.Writer;
+ FileSystemObjectModel fsom = (objectModel as FileSystemObjectModel);
+ ExecutableObjectModel exe = (objectModel as ExecutableObjectModel);
+ if (fsom == null && exe == null) throw new ObjectModelNotSupportedException("Object model must be a FileSystem or an Executable");
+
+ #region DOS part
+ bw.WriteFixedLengthString("MZ");
+ bw.WriteUInt16(mvarDOSHeader.LastBlockLength); // The number of bytes in the last block of the program that are actually used. If this value is zero, that means the entire last block is used (i.e. the effective value is 512).
+ bw.WriteUInt16(mvarDOSHeader.NumBlocksInEXE); // Number of blocks in the file that are part of the EXE file. If mvarDOSHeader.LastBlockLength is non-zero, only that much of the last block is used.
+ bw.WriteUInt16(mvarDOSHeader.NumRelocEntriesAfterHeader); // Number of relocation entries stored after the header. May be zero.
+ bw.WriteUInt16(mvarDOSHeader.NumParagraphsInHeader); // Number of paragraphs in the header. The program's data begins just after the header, and this field can be used to calculate the appropriate file offset. The header includes the relocation entries. Note that some OSs and/or programs may fail if the header is not a multiple of 512 bytes.
+ bw.WriteUInt16(mvarDOSHeader.NumParagraphsAdditionalMemory); // Number of paragraphs of additional memory that the program will need. This is the equivalent of the BSS size in a Unix program. The program can't be loaded if there isn't at least this much memory available to it.
+ bw.WriteUInt16(mvarDOSHeader.NumMaxParagraphsAdditionalMemory); // Maximum number of paragraphs of additional memory. Normally, the OS reserves all the remaining conventional memory for your program, but you can limit it with this field.
+ bw.WriteUInt16(mvarDOSHeader.RelativeStackSegmentValue); // Relative value of the stack segment. This value is added to the segment the program was loaded at, and the result is used to initialize the SS register.
+ bw.WriteUInt16(mvarDOSHeader.InitialValueRegisterSP); // Initial value of the SP register.
+ bw.WriteUInt16(mvarDOSHeader.WordChecksum); // Word checksum. If set properly, the 16-bit sum of all words in the file should be zero. Usually, this isn't filled in.
+ bw.WriteUInt16(mvarDOSHeader.InitialValueRegisterIP); // Initial value of the IP register.
+ bw.WriteUInt16(mvarDOSHeader.InitialValueRegisterCS); // Initial value of the CS register, relative to the segment the program was loaded at.
+ bw.WriteUInt16(mvarDOSHeader.FirstRelocationItemOffset); // Offset of the first relocation item in the file.
+ bw.WriteUInt16(mvarDOSHeader.OverlayNumber); // Overlay number. Normally zero, meaning that it's the main program.
+ #endregion
+ #region Portable Executable
+ bw.Accessor.Position = 0x3C;
+ int e_lfanew = (int)(bw.Accessor.Position + 4);
+ bw.WriteInt32(e_lfanew);
+
+ #region PE header
+ PEHeader pe = new PEHeader();
+ pe.signature = "PE\0\0";
+ pe.sectionCount = (short)fsom.Files.Count;
+
+ bw.WriteFixedLengthString(pe.signature);
+ bw.WriteUInt16((ushort)pe.machine);
+ bw.WriteUInt16((ushort)pe.sectionCount);
+ bw.WriteUInt16((ushort)pe.unknown1);
+ bw.WriteUInt16((ushort)pe.unknown2);
+ bw.WriteUInt16((ushort)pe.unknown3);
+ bw.WriteUInt16((ushort)pe.unknown4);
+ bw.WriteUInt16((ushort)pe.unknown5);
+ bw.WriteUInt16((ushort)pe.unknown6);
+ bw.WriteUInt16((ushort)pe.sizeOfOptionalHeader); // relative offset to sectiontable
+ bw.WriteUInt16((ushort)pe.characteristics);
+ #endregion
+ #region PE Optional Header
+ PEOptionalHeader peoh = new PEOptionalHeader();
+ peoh.enabled = true;
+ peoh.magic = 267;
+ peoh.entryPointAddr = 4096;
+ peoh.imageBase = 4194304;
+ peoh.sectionAlignment = 4096;
+ peoh.fileAlignment = 512;
+ peoh.majorSubsystemVersion = 4;
+ peoh.imageSize = 16384;
+ peoh.headerSize = 512;
+ peoh.subsystem = 2;
+ peoh.rvaCount = 16;
+
+ if (peoh.enabled)
+ {
+ bw.WriteUInt16((ushort)peoh.magic);
+ bw.WriteUInt16((ushort)peoh.unknown1);
+ bw.WriteUInt32((uint)peoh.unknown2);
+ bw.WriteUInt32((uint)peoh.unknown3);
+ bw.WriteUInt32((uint)peoh.unknown4);
+ bw.WriteUInt32((uint)peoh.entryPointAddr);
+ bw.WriteUInt32((uint)peoh.unknown5);
+ bw.WriteUInt32((uint)peoh.unknown6);
+ bw.WriteUInt32((uint)peoh.imageBase);
+ bw.WriteUInt32((uint)peoh.sectionAlignment);
+ bw.WriteUInt32((uint)peoh.fileAlignment);
+ bw.WriteUInt32((uint)peoh.unknown7);
+ bw.WriteUInt32((uint)peoh.unknown8);
+ bw.WriteUInt32((uint)peoh.majorSubsystemVersion); // 4 = NT 4 or later
+ bw.WriteUInt32((uint)peoh.unknown9);
+ bw.WriteUInt32((uint)peoh.unknown10);
+ bw.WriteUInt32((uint)peoh.imageSize);
+ bw.WriteUInt32((uint)peoh.headerSize);
+ bw.WriteUInt32((uint)peoh.unknown11);
+ bw.WriteUInt16((ushort)peoh.subsystem);
+ bw.WriteUInt16((ushort)peoh.unknown12);
+ bw.WriteUInt32((uint)peoh.unknown13);
+ bw.WriteUInt32((uint)peoh.unknown14);
+ bw.WriteUInt32((uint)peoh.unknown15);
+ bw.WriteUInt32((uint)peoh.unknown16);
+ bw.WriteUInt32((uint)peoh.unknown17);
+ bw.WriteUInt32((uint)peoh.rvaCount);
+ }
+ #endregion
+ #endregion
+ }
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/PECharacteristics.cs b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/PECharacteristics.cs
new file mode 100644
index 00000000..7848aed2
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/PECharacteristics.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.Executable.Microsoft
+{
+ ///
+ /// A set of bit flags indicating attributes of the file.
+ ///
+ [Flags()]
+ public enum PECharacteristics : ushort
+ {
+ ///
+ /// No characteristics defined.
+ ///
+ None = 0,
+ ///
+ /// Relocation information stripped from a file.
+ ///
+ RelocationInformationStripped = 0x0001,
+ ///
+ /// The file is executable.
+ ///
+ ExecutableImage = 0x0002,
+ ///
+ /// Line numbers stripped from file.
+ ///
+ LineNumbersStripped = 0x0004,
+ ///
+ /// Local symbols stripped from file.
+ ///
+ LocalSymbolsStripped = 0x0008,
+ ///
+ /// Lets the OS aggressively trim the working set.
+ ///
+ AggressiveWorkingSetTrim = 0x0010,
+ ///
+ /// Lets the OS aggressively trim the working set.
+ ///
+ MinimalObject = 0x0010,
+ ///
+ /// The application can handle addresses greater than two gigabytes.
+ ///
+ UpdateObject = 0x0020,
+ ///
+ /// The application can handle addresses greater than two gigabytes.
+ ///
+ LargeAddressAware = 0x0020,
+ ///
+ /// This requires a 32-bit word machine.
+ ///
+ Require32BitWord = 0x0100,
+ ///
+ /// Debug information is stripped to a .DBG file.
+ ///
+ DebugStripped = 0x0200,
+ ///
+ /// If the image is on removable media, copy to and run from the swap file.
+ ///
+ RemovableRunFromSwap = 0x0400,
+ ///
+ /// If the image is on a network, copy to and run from the swap file.
+ ///
+ NetworkRunFromSwap = 0x0800,
+ ///
+ /// File is a system file.
+ ///
+ IsSystemFile = 0x1000,
+ ///
+ /// File is a DLL.
+ ///
+ IsDynamicLinkLibrary = 0x2000,
+ ///
+ /// The file should only be run on single-processor machines.
+ ///
+ UniprocessorOnly = 0x4000,
+ ///
+ /// Bytes of machine word are reversed
+ ///
+ ReverseByteOrder = 0x8000
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/PECompiler.cs b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/PECompiler.cs
new file mode 100644
index 00000000..4c3f0211
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/PECompiler.cs
@@ -0,0 +1,75 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.Executable.Microsoft
+{
+ public enum PECompiler
+ {
+ ///
+ /// Intel C++ 8.0 for Linux
+ ///
+ IntelCPP80Linux,
+ ///
+ /// HP aC++ A.05.55 IA-64
+ ///
+ HPaCppIA64,
+ ///
+ /// IAR EWARM C++ 5.4 ARM
+ ///
+ IAREwarmCPP54ARM,
+ ///
+ /// GCC 3.x and 4.x
+ ///
+ GCC3or4x,
+ ///
+ /// GCC 2.9x
+ ///
+ GCC29x,
+ ///
+ /// HP aC++ A.03.45 PA-RISC
+ ///
+ HPaCppPARISC,
+ ///
+ /// Microsoft Visual C++ v6-v10
+ ///
+ MsVCpp,
+ ///
+ /// Digital Mars C++
+ ///
+ DigitalMars,
+ ///
+ /// Borland C++ v3.1
+ ///
+ Borland31,
+ ///
+ /// OpenVMS C++ V6.5 (ARM mode)
+ ///
+ OpenVMS65ARM,
+ ///
+ /// OpenVMS C++ V6.5 (ANSI mode)
+ ///
+ OpenVMS65ANSI,
+ ///
+ /// OpenVMS C++ X7.1 IA-64
+ ///
+ OpenVMS71IA64,
+ ///
+ /// SunPro CC
+ ///
+ SunProCC,
+ ///
+ /// Tru64 C++ V6.5 (ARM mode)
+ ///
+ Tru64ARM,
+ ///
+ /// Tru64 C++ V6.5 (ANSI mode)
+ ///
+ Tru64ANSI,
+ ///
+ /// Watcom C++ 10.6
+ ///
+ Watcom
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/PEHeader.cs b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/PEHeader.cs
new file mode 100644
index 00000000..db33cd82
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/PEHeader.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.Executable.Microsoft
+{
+ public struct PEHeader
+ {
+ public bool enabled;
+ public string signature;
+ public PEMachineType machine;
+ public short sectionCount;
+ public short unknown1;
+ public short unknown2;
+ public short unknown3;
+ public short unknown4;
+ public short unknown5;
+ public short unknown6;
+ public short sizeOfOptionalHeader; // relative offset to sectiontable
+ public PECharacteristics characteristics;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/PEMachineType.cs b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/PEMachineType.cs
new file mode 100644
index 00000000..58e88757
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/PEMachineType.cs
@@ -0,0 +1,99 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.Executable.Microsoft
+{
+ public enum PEMachineType : ushort
+ {
+ ///
+ /// The contents of this field are assumed to be applicable to any machine type
+ ///
+ Unknown = 0,
+ ///
+ /// Matsushita AM33
+ ///
+ AM33 = 0x1d3,
+ ///
+ /// x64
+ ///
+ AMD64 = 0x8664,
+ ///
+ /// ARM little endian
+ ///
+ ARM = 0x1c0,
+ ///
+ /// ARMv7 (or higher) Thumb mode only
+ ///
+ ARMNT = 0x1c4,
+ ///
+ /// ARMv8 in 64-bit mode
+ ///
+ ARM64 = 0xaa64,
+ ///
+ /// EFI byte code
+ ///
+ EBC = 0xebc,
+ ///
+ /// Intel 386 or later processors and compatible processors
+ ///
+ Intel386 = 0x14c,
+ ///
+ /// Intel Itanium processor family
+ ///
+ Itanium64 = 0x200,
+ ///
+ /// Mitsubishi M32R little endian
+ ///
+ M32R = 0x9041,
+ ///
+ /// MIPS16
+ ///
+ MIPS16 = 0x266,
+ ///
+ /// MIPS with FPU
+ ///
+ MIPSFloatingPoint = 0x366,
+ ///
+ /// MIPS16 with FPU
+ ///
+ MIPS16FloatingPoint = 0x466,
+ ///
+ /// Power PC little endian
+ ///
+ PowerPC = 0x1f0,
+ ///
+ /// Power PC with floating point support
+ ///
+ PowerPCFloatingPoint = 0x1f1,
+ ///
+ /// MIPS little endian
+ ///
+ R4000 = 0x166,
+ ///
+ /// Hitachi SH3
+ ///
+ HitachiSH3 = 0x1a2,
+ ///
+ /// Hitachi SH3 DSP
+ ///
+ HitachiSH3DSP = 0x1a3,
+ ///
+ /// Hitachi SH4
+ ///
+ HitachiSH4 = 0x1a6,
+ ///
+ /// Hitachi SH5
+ ///
+ HitachiSH5 = 0x1a8,
+ ///
+ /// ARM or Thumb ("interworking")
+ ///
+ Thumb = 0x1c2,
+ ///
+ /// MIPS little-endian WCE v2
+ ///
+ MIPSWCEv2 = 0x169
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/PEOptionalHeader.cs b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/PEOptionalHeader.cs
new file mode 100644
index 00000000..6d18fa82
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/PEOptionalHeader.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.Executable.Microsoft
+{
+ public struct PEOptionalHeader
+ {
+ public bool enabled;
+ public ushort magic;
+ public ushort unknown1;
+ public uint unknown2;
+ public uint unknown3;
+ public uint unknown4;
+ public uint entryPointAddr;
+ public uint unknown5;
+ public uint unknown6;
+ public uint imageBase;
+ public uint sectionAlignment;
+ public uint fileAlignment;
+ public uint unknown7;
+ public uint unknown8;
+ public ushort majorSubsystemVersion; // 4 = NT 4 or later
+ public ushort unknown9;
+ public uint unknown10;
+ public uint imageSize;
+ public uint headerSize;
+ public uint unknown11;
+ public ushort subsystem;
+ public ushort unknown12;
+ public uint unknown13;
+ public uint unknown14;
+ public uint unknown15;
+ public uint unknown16;
+ public uint unknown17;
+ public uint rvaCount;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/PESectionCharacteristics.cs b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/PESectionCharacteristics.cs
new file mode 100644
index 00000000..9bca8db0
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/PESectionCharacteristics.cs
@@ -0,0 +1,108 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.Executable.Microsoft
+{
+ [Flags()]
+ public enum PESectionCharacteristics : uint
+ {
+ None = 0x00000000,
+ ///
+ /// Reserved.
+ ///
+ TypeNoPad = 0x00000008,
+ ///
+ /// Section contains code.
+ ///
+ ContainsCode = 0x00000020,
+ ///
+ /// Section contains initialized data.
+ ///
+ ContainsInitializedData = 0x00000040,
+ ///
+ /// Section contains uninitialized data.
+ ///
+ ContainsUninitializedData = 0x00000080,
+ ///
+ /// Reserved.
+ ///
+ LinkOther = 0x00000100,
+ ///
+ /// Section contains comments or some other type of information.
+ ///
+ LinkInformation = 0x00000200,
+ ///
+ /// Section contents will not become part of image.
+ ///
+ LinkRemove = 0x00000800,
+ ///
+ /// Section contents comdat.
+ ///
+ LinkComdat = 0x00001000,
+ ///
+ /// Reset speculative exceptions handling bits in the TLB entries for this section.
+ ///
+ ResetSpeculativeExceptions = 0x00004000,
+ ///
+ /// Section content can be accessed relative to GP
+ ///
+ GPRelative = 0x00008000,
+ MemoryFarData = 0x00008000,
+ MemoryPurgeable = 0x00020000,
+ Memory16Bit = 0x00020000,
+ MemoryLocked = 0x00040000,
+ MemoryPreload = 0x00080000,
+ Align1Byte = 0x00100000,
+ Align2Bytes = 0x00200000,
+ Align4Bytes = 0x00300000,
+ Align8Bytes = 0x00400000,
+ ///
+ /// Default alignment if no others are specified.
+ ///
+ Align16Bytes = 0x00500000,
+ Align32Bytes = 0x00600000,
+ Align64Bytes = 0x00700000,
+ Align128Bytes = 0x00800000,
+ Align256Bytes = 0x00900000,
+ Align512Bytes = 0x00A00000,
+ Align1024Bytes = 0x00B00000,
+ Align2048Bytes = 0x00C00000,
+ Align4096Bytes = 0x00D00000,
+ Align8192Bytes = 0x00E00000,
+ AlignMask = 0x00F00000,
+ ///
+ /// Section contains extended relocations.
+ ///
+ LinkExtendedRelocations = 0x01000000,
+ ///
+ /// Section can be discarded.
+ ///
+ MemoryDiscardable = 0x02000000,
+ ///
+ /// Section is not cachable.
+ ///
+ MemoryNotCached = 0x04000000,
+ ///
+ /// Section is not pageable.
+ ///
+ MemoryNotPaged = 0x08000000,
+ ///
+ /// Section is shareable.
+ ///
+ MemoryShared = 0x10000000,
+ ///
+ /// Section is executable.
+ ///
+ MemoryExecutable = 0x20000000,
+ ///
+ /// Section is readable.
+ ///
+ MemoryReadable = 0x40000000,
+ ///
+ /// Section is writeable.
+ ///
+ MemoryWritable = 0x80000000
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/PESectionHeader.cs b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/PESectionHeader.cs
new file mode 100644
index 00000000..5cee71c1
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/PESectionHeader.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.Executable.Microsoft
+{
+ public struct PESectionHeader
+ {
+ public string name;
+ public uint virtualSize;
+ public uint virtualAddress;
+ public uint rawDataSize;
+ public uint rawDataPtr;
+ public uint unknown1;
+ public uint unknown2;
+ public uint unknown3;
+ public PESectionCharacteristics characteristics;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Executable/UniversalEditor.Plugins.Executable.csproj b/CSharp/Plugins/UniversalEditor.Plugins.Executable/UniversalEditor.Plugins.Executable.csproj
index f92b6ac2..13803e1d 100644
--- a/CSharp/Plugins/UniversalEditor.Plugins.Executable/UniversalEditor.Plugins.Executable.csproj
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Executable/UniversalEditor.Plugins.Executable.csproj
@@ -44,6 +44,15 @@
+
+
+
+
+
+
+
+
+