diff --git a/CSharp/Content/UniversalEditor.Content.PlatformIndependent/Extensions/DocumentationWriter/Associations/WinHelp.uexml b/CSharp/Content/UniversalEditor.Content.PlatformIndependent/Extensions/DocumentationWriter/Associations/WinHelp.uexml
new file mode 100644
index 00000000..913e203a
--- /dev/null
+++ b/CSharp/Content/UniversalEditor.Content.PlatformIndependent/Extensions/DocumentationWriter/Associations/WinHelp.uexml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+ *.hlp
+
+
+
+ 3F5F0300
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CSharp/Content/UniversalEditor.Content.PlatformIndependent/Extensions/FileSystem/Associations/BPlus.uexml b/CSharp/Content/UniversalEditor.Content.PlatformIndependent/Extensions/FileSystem/Associations/BPlus.uexml
deleted file mode 100644
index 759243e1..00000000
--- a/CSharp/Content/UniversalEditor.Content.PlatformIndependent/Extensions/FileSystem/Associations/BPlus.uexml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
- 3F5F0300
-
-
-
-
-
-
-
-
-
-
-
-
-
\ 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 51e45f75..ed277733 100644
--- a/CSharp/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj
+++ b/CSharp/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj
@@ -106,7 +106,6 @@
-
@@ -670,6 +669,9 @@
+
+
+
diff --git a/CSharp/Libraries/UniversalEditor.Core/Association.cs b/CSharp/Libraries/UniversalEditor.Core/Association.cs
index 441a6453..0bd41804 100644
--- a/CSharp/Libraries/UniversalEditor.Core/Association.cs
+++ b/CSharp/Libraries/UniversalEditor.Core/Association.cs
@@ -143,6 +143,35 @@ namespace UniversalEditor
///
public DataFormatReference.DataFormatReferenceCollection DataFormats { get { return mvarDataFormats; } }
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.Append('[');
+ for (int i = 0; i < mvarFilters.Count; i++)
+ {
+ sb.Append(mvarFilters[i].Title);
+ if (i < mvarFilters.Count - 1) sb.Append(", ");
+ }
+ sb.Append(']');
+ sb.Append(' ');
+ sb.Append('{');
+ for (int i = 0; i < mvarObjectModels.Count; i++)
+ {
+ sb.Append(mvarObjectModels[i].TypeName);
+ if (i < mvarObjectModels.Count - 1) sb.Append(", ");
+ }
+ sb.Append('}');
+ sb.Append(' ');
+ sb.Append('(');
+ for (int i = 0; i < mvarDataFormats.Count; i++)
+ {
+ sb.Append(mvarDataFormats[i].TypeName);
+ if (i < mvarDataFormats.Count - 1) sb.Append(", ");
+ }
+ sb.Append(')');
+ return sb.ToString();
+ }
+
public static Association[] FromCriteria(AssociationCriteria ac)
{
List associations = new List();
diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/TemporaryFileManager.cs b/CSharp/Libraries/UniversalEditor.UserInterface/TemporaryFileManager.cs
index d100b4da..7e8bc7ba 100644
--- a/CSharp/Libraries/UniversalEditor.UserInterface/TemporaryFileManager.cs
+++ b/CSharp/Libraries/UniversalEditor.UserInterface/TemporaryFileManager.cs
@@ -9,6 +9,23 @@ namespace UniversalEditor.UserInterface
private static System.Collections.Specialized.StringCollection mvarTemporaryFileNames = new System.Collections.Specialized.StringCollection();
private static string mvarTemporaryFilePath = null;
+ private static string SanitizeFileName(string FileName)
+ {
+ if (String.IsNullOrEmpty(FileName)) return "_";
+ string[] invalidCharacters = new string[]
+ {
+ "\\", "/", ":", "*", "\"", "<", ">", "?", "|"
+ };
+ foreach (string invalidCharacter in invalidCharacters)
+ {
+ FileName = FileName.Replace(invalidCharacter, "_");
+ }
+
+ // Check twice because we might have encountered a filename consisting solely of invalid chars (weird, but possible)
+ if (String.IsNullOrEmpty(FileName)) return "_";
+ return FileName;
+ }
+
public static string CreateTemporaryFile(string FileName, byte[] FileData = null)
{
if (mvarTemporaryFilePath == null) throw new InvalidOperationException();
@@ -17,6 +34,7 @@ namespace UniversalEditor.UserInterface
System.IO.Directory.CreateDirectory(mvarTemporaryFilePath);
}
+ FileName = SanitizeFileName(FileName);
FileName = System.IO.Path.GetFileName(FileName);
string filePath = mvarTemporaryFilePath + System.IO.Path.DirectorySeparatorChar.ToString() + FileName;
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/BPlus/BPlusFileSystemDataFormat.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/BPlus/BPlusFileSystemDataFormat.cs
index acd1ff11..9cac8586 100644
--- a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/BPlus/BPlusFileSystemDataFormat.cs
+++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/BPlus/BPlusFileSystemDataFormat.cs
@@ -20,6 +20,8 @@ namespace UniversalEditor.DataFormats.FileSystem.BPlus
{
_dfr = base.MakeReferenceInternal();
_dfr.Capabilities.Add(typeof(FileSystemObjectModel), DataFormatCapabilities.All);
+ _dfr.Sources.Add("Based on documentation contributed by M. Winterhoff, Pete Davis, Holger Haase, and Bent Lynggaard.");
+ _dfr.Sources.Add("http://sourceforge.net/projects/helpdeco/");
}
return _dfr;
}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/HLPDataFormat.cs b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/HLPDataFormat.cs
new file mode 100644
index 00000000..c80abe71
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/HLPDataFormat.cs
@@ -0,0 +1,352 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using UniversalEditor.Accessors;
+using UniversalEditor.IO;
+
+using UniversalEditor.DataFormats.FileSystem.BPlus;
+
+using UniversalEditor.ObjectModels.FileSystem;
+using UniversalEditor.ObjectModels.Help.Compiled;
+
+namespace UniversalEditor.DataFormats.Help.Compiled.WinHelp
+{
+ ///
+ /// The Windows Help (WinHelp) HLP data format. Much of the framework for reading these files is contained in BPlusFileSystemDataFormat, since the container file format
+ /// itself is remarkably generic (albeit unused, as far as I can tell, apart from WinHelp files), but WinHelp-specific stuff is here.
+ ///
+ public class HLPDataFormat : BPlusFileSystemDataFormat
+ {
+ private static DataFormatReference _dfr = null;
+ protected override DataFormatReference MakeReferenceInternal()
+ {
+ if (_dfr == null)
+ {
+ _dfr = new DataFormatReference(GetType());
+ _dfr.Capabilities.Add(typeof(CompiledHelpObjectModel), DataFormatCapabilities.All);
+ }
+ return _dfr;
+ }
+
+ protected override void BeforeLoadInternal(Stack objectModels)
+ {
+ base.BeforeLoadInternal(objectModels);
+ objectModels.Push(new FileSystemObjectModel());
+ }
+ protected override void AfterLoadInternal(Stack objectModels)
+ {
+ base.AfterLoadInternal(objectModels);
+
+ FileSystemObjectModel fsom = (objectModels.Pop() as FileSystemObjectModel);
+ CompiledHelpObjectModel help = (objectModels.Pop() as CompiledHelpObjectModel);
+
+ bool compressed = false;
+ int topicBlockSize = 0;
+
+ #region System Header
+ {
+ File fileSystem = fsom.Files["|SYSTEM"];
+ byte[] dataSystem = fileSystem.GetData();
+
+ MemoryAccessor maSystem = new MemoryAccessor(dataSystem);
+ Reader readerSystem = new Reader(maSystem);
+
+ Internal.SYSTEMHEADER systemHeader = ReadSYSTEMHEADER(readerSystem);
+
+ if (systemHeader.Version.Minor <= 16)
+ {
+ // not compressed
+ compressed = false;
+ topicBlockSize = 2048;
+ }
+ else if (systemHeader.Version.Minor > 16)
+ {
+ if (systemHeader.Flags == Internal.SystemHeaderFlags.None)
+ {
+ compressed = false;
+ topicBlockSize = 4096;
+ }
+ else if (systemHeader.Flags == Internal.SystemHeaderFlags.CompressedLZ77TopicBlockSize4k)
+ {
+ compressed = true;
+ topicBlockSize = 4096;
+ }
+ else if (systemHeader.Flags == Internal.SystemHeaderFlags.CompressedLZ77TopicBlockSize2k)
+ {
+ compressed = true;
+ topicBlockSize = 2048;
+ }
+ }
+
+ if (systemHeader.Version.Minor <= 16)
+ {
+ // help file title follows SYSTEMHEADER
+ string helpFileTitle = readerSystem.ReadNullTerminatedString();
+ }
+ else
+ {
+ // If Minor is above 16, one or more SYSTEMREC records follow instead up to the internal end of the |SYSTEM file:
+ while (!readerSystem.EndOfStream)
+ {
+ Internal.SYSTEMRECORD systemRecord = ReadSYSTEMRECORD(readerSystem);
+ switch (systemRecord.RecordType)
+ {
+ case Internal.SystemRecordType.Title:
+ {
+ help.Title = System.Text.Encoding.Default.GetString(systemRecord.Data).TrimNull();
+ break;
+ }
+ case Internal.SystemRecordType.Copyright:
+ {
+ help.Copyright = System.Text.Encoding.Default.GetString(systemRecord.Data).TrimNull();
+ break;
+ }
+ case Internal.SystemRecordType.Contents:
+ {
+ int topicOffset = BitConverter.ToInt32(systemRecord.Data, 0);
+ break;
+ }
+ case Internal.SystemRecordType.Config:
+ {
+ string macro = System.Text.Encoding.Default.GetString(systemRecord.Data).TrimNull();
+ // help.Macros.Add(macro);
+ break;
+ }
+ case Internal.SystemRecordType.Icon:
+ {
+ break;
+ }
+ case Internal.SystemRecordType.Window:
+ {
+ break;
+ }
+ case Internal.SystemRecordType.Citation:
+ {
+ break;
+ }
+ case Internal.SystemRecordType.LanguageID:
+ {
+ MemoryAccessor maSystemRecord = new MemoryAccessor(systemRecord.Data);
+ Reader readerSystemRecord = new Reader(maSystemRecord);
+ ushort[] langaugeIDs = readerSystemRecord.ReadUInt16Array((int)((double)systemRecord.Data.Length / 2));
+ break;
+ }
+ case Internal.SystemRecordType.TableOfContents:
+ {
+ break;
+ }
+ case Internal.SystemRecordType.CharacterSet:
+ {
+ break;
+ }
+ }
+ }
+ }
+ }
+ #endregion
+ #region Font File
+ {
+ File file = fsom.Files["|FONT"];
+ byte[] data = file.GetData();
+
+ MemoryAccessor ma = new MemoryAccessor(data);
+ Reader reader = new Reader(ma);
+
+ Internal.FONTHEADER fontHeader = ReadFONTHEADER(reader);
+ List faceNames = new List();
+ reader.Seek(fontHeader.FacenamesOffset, SeekOrigin.Begin);
+ int faceNameLength = (int)((double)(fontHeader.DescriptorsOffset - fontHeader.FacenamesOffset) / fontHeader.NumFacenames);
+ for (int i = 0; i < fontHeader.NumFacenames; i++)
+ {
+ string faceName = reader.ReadFixedLengthString(faceNameLength).TrimNull();
+ faceNames.Add(faceName);
+ }
+
+ if (fontHeader.FacenamesOffset >= 12)
+ {
+ // Multimedia MVB files use different structures to store font descriptors. Assume this structure for descriptors if FacenamesOffset is at least 12.
+ // If this kind of descriptor is used, any metric is given in twips.
+ }
+ else
+ {
+ List listFonts = new List();
+
+ // At DescriptorsOffset is an array located describing all fonts used in the help file.
+ // If this kind of descriptor appears in a help file, any metric value is given in HalfPoints.
+ reader.Seek(fontHeader.DescriptorsOffset, SeekOrigin.Begin);
+ for (int i = 0; i < fontHeader.NumDescriptors; i++)
+ {
+ Internal.OLDFONT font = ReadOLDFONT(reader);
+ listFonts.Add(font);
+ }
+ }
+ }
+ #endregion
+ #region Topic File
+ {
+ File file = fsom.Files["|TOPIC"];
+ byte[] data = file.GetData();
+
+ MemoryAccessor ma = new MemoryAccessor(data);
+ Reader reader = new Reader(ma);
+
+ Internal.TOPICBLOCKHEADER topicBlockHeader = ReadTOPICBLOCKHEADER(reader);
+
+ while (!reader.EndOfStream)
+ {
+ Internal.TOPICLINK topicLink = ReadTOPICLINK(reader);
+
+ switch (topicLink.RecordType)
+ {
+ case Internal.TopicLinkRecordType.TopicHeader:
+ {
+ Internal.TOPICHEADER topicHeader = ReadTOPICHEADER(reader);
+
+ // The LinkData2 of Topic RecordType 2 contains NUL terminated strings. The first string is the topic title, the next strings contain all macros to be
+ // executed on opening this topic (specified using the ! footnote).
+ string datastr = reader.ReadFixedLengthString(topicLink.DataLen2);
+ string[] datastrs = datastr.Split(new char[] { '\0' });
+
+ string topicTitle = datastrs[0];
+ List macros = new List();
+ for (int i = 1; i < datastrs.Length; i++)
+ {
+ macros.Add(datastrs[i]);
+ }
+ break;
+ }
+ case Internal.TopicLinkRecordType.Display31:
+ {
+ // TODO: test with putty.hlp
+ byte unknown1 = reader.ReadByte();
+ byte unknown2 = reader.ReadByte();
+ ushort id = reader.ReadUInt16();
+ ushort flags = reader.ReadUInt16(); // unknownfollows, spacingabovefollows, rightindentfollows, etc.
+ byte[] blahblah = reader.ReadBytes(7);
+
+ ushort sanityCheck0xFF = reader.ReadUInt16();
+ if (sanityCheck0xFF == 0xFF)
+ {
+ // end of character formatting. proceed with next ParagraphInfo if RecordType is 0x23, else you are done
+ string value = reader.ReadNullTerminatedString();
+ }
+ break;
+ }
+ }
+ }
+ }
+ #endregion
+ }
+
+ private Internal.TOPICHEADER ReadTOPICHEADER(Reader reader)
+ {
+ Internal.TOPICHEADER item = new Internal.TOPICHEADER();
+ item.BlockSize = reader.ReadInt32();
+ item.BrowseSequencePreviousTopic = reader.ReadInt32();
+ item.BrowseSequenceNextTopic = reader.ReadInt32();
+ item.TopicNum = reader.ReadInt32();
+ item.NonScrollingRegionOffset = reader.ReadInt32();
+ item.ScrollingRegionOffset = reader.ReadInt32();
+ item.NextTopic = reader.ReadInt32();
+ return item;
+ }
+
+ private Internal.TOPICLINK ReadTOPICLINK(Reader reader)
+ {
+ Internal.TOPICLINK item = new Internal.TOPICLINK();
+ item.BlockSize = reader.ReadInt32();
+ item.DataLen2 = reader.ReadInt32();
+ item.PrevBlock = reader.ReadInt32();
+ item.NextBlock = reader.ReadInt32();
+ item.DataLen1 = reader.ReadInt32();
+ item.RecordType = (Internal.TopicLinkRecordType)reader.ReadByte();
+ return item;
+ }
+
+ private Internal.TOPICBLOCKHEADER ReadTOPICBLOCKHEADER(Reader reader)
+ {
+ Internal.TOPICBLOCKHEADER item = new Internal.TOPICBLOCKHEADER();
+ item.LastTopicLink = reader.ReadInt32();
+ item.FirstTopicLink = reader.ReadInt32();
+ item.LastTopicHeader = reader.ReadInt32();
+ return item;
+ }
+
+ private Internal.OLDFONT ReadOLDFONT(Reader reader)
+ {
+ Internal.OLDFONT item = new Internal.OLDFONT();
+ item.Attributes = (Internal.FontAttributes)reader.ReadByte();
+ item.HalfPoints = reader.ReadByte(); // PointSize * 2
+ item.FontFamily = (Internal.FontFamily)reader.ReadByte();
+ item.FacenameIndex = reader.ReadUInt16();
+ item.ForegroundColor = reader.ReadBytes(3);
+ item.BackgroundColor = reader.ReadBytes(3);
+ return item;
+ }
+
+ private Internal.FONTHEADER ReadFONTHEADER(Reader reader)
+ {
+ Internal.FONTHEADER item = new Internal.FONTHEADER();
+ item.NumFacenames = reader.ReadUInt16();
+ item.NumDescriptors = reader.ReadUInt16();
+ item.FacenamesOffset = reader.ReadUInt16();
+ item.DescriptorsOffset = reader.ReadUInt16();
+ if (item.FacenamesOffset >= 12)
+ {
+ item.NumStyles = reader.ReadUInt16();
+ item.StyleOffset = reader.ReadUInt16();
+ if (item.FacenamesOffset >= 16)
+ {
+ item.NumCharMapTables = reader.ReadUInt16();
+ item.CharMapTableOffset = reader.ReadUInt16();
+ }
+ }
+ return item;
+ }
+
+ private Internal.SYSTEMHEADER ReadSYSTEMHEADER(Reader reader)
+ {
+ Internal.SYSTEMHEADER item = new Internal.SYSTEMHEADER();
+
+ short magic = reader.ReadInt16();
+ if (magic != 0x036C) throw new InvalidDataFormatException("|SYSTEM header does not begin with { 0x6C, 0x03 }");
+
+ short minorVersion = reader.ReadInt16();
+ short majorVersion = reader.ReadInt16();
+ item.Version = new Version(majorVersion, minorVersion);
+
+ int GenDate = reader.ReadInt32();
+ item.GenDate = time_tToDateTime(GenDate);
+ item.Flags = (Internal.SystemHeaderFlags)reader.ReadUInt16();
+
+ return item;
+ }
+ private Internal.SYSTEMRECORD ReadSYSTEMRECORD(Reader reader)
+ {
+ Internal.SYSTEMRECORD item = new Internal.SYSTEMRECORD();
+ item.RecordType = (Internal.SystemRecordType)reader.ReadUInt16();
+ item.DataSize = reader.ReadUInt16();
+ item.Data = reader.ReadBytes(item.DataSize);
+ return item;
+ }
+
+ private DateTime time_tToDateTime(int time_t)
+ {
+ // hory shet
+ // http://blogs.msdn.com/b/brada/archive/2003/07/30/50205.aspx
+ long win32FileTime = 10000000 * (long)time_t + 116444736000000000;
+ return DateTime.FromFileTimeUtc(win32FileTime);
+ }
+ protected override void BeforeSaveInternal(Stack objectModels)
+ {
+ base.BeforeSaveInternal(objectModels);
+
+ CompiledHelpObjectModel help = (objectModels.Pop() as CompiledHelpObjectModel);
+ FileSystemObjectModel fsom = new FileSystemObjectModel();
+
+ objectModels.Push(fsom);
+ }
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/FONTHEADER.cs b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/FONTHEADER.cs
new file mode 100644
index 00000000..e08bd482
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/FONTHEADER.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.Help.Compiled.WinHelp.Internal
+{
+ public struct FONTHEADER
+ {
+ ///
+ /// Number of face names
+ ///
+ public ushort NumFacenames;
+ ///
+ /// Number of font descriptors
+ ///
+ public ushort NumDescriptors;
+ ///
+ /// Start of array of face names relative to &NumFacenames
+ ///
+ public ushort FacenamesOffset;
+ ///
+ /// Start of array of font descriptors relative to &NumFacenames
+ ///
+ public ushort DescriptorsOffset;
+
+ // only if FacenamesOffset >= 12
+ ///
+ /// Number of style descriptors
+ ///
+ public ushort NumStyles;
+ ///
+ /// Start of array of style descriptors relative to &NumFacenames
+ ///
+ public ushort StyleOffset;
+
+ // only if FacenamesOffset >= 16
+ ///
+ /// Number of character mapping tables
+ ///
+ public ushort NumCharMapTables;
+ ///
+ /// Start of array of character mapping table names relative to &NumFacenames
+ ///
+ public ushort CharMapTableOffset;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/FontAttributes.cs b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/FontAttributes.cs
new file mode 100644
index 00000000..115a3b40
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/FontAttributes.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.Help.Compiled.WinHelp.Internal
+{
+ [Flags()]
+ public enum FontAttributes : byte
+ {
+ None = 0x00,
+ Bold = 0x01,
+ Italic = 0x02,
+ Underline = 0x04,
+ Strikeout = 0x08,
+ DoubleUnderline = 0x10,
+ SmallCaps = 0x20
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/FontFamily.cs b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/FontFamily.cs
new file mode 100644
index 00000000..031b23df
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/FontFamily.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.Help.Compiled.WinHelp.Internal
+{
+ ///
+ /// This is a different order than FF_ROMAN, FF_SWISS, etc. of Windows!
+ ///
+ public enum FontFamily : byte
+ {
+ Modern = 0x01,
+ Roman = 0x02,
+ Swiss = 0x03,
+ Tech = 0x03,
+ Nil = 0x03,
+ Script = 0x04,
+ Decor = 0x05
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/OLDFONT.cs b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/OLDFONT.cs
new file mode 100644
index 00000000..adf99c5e
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/OLDFONT.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.Help.Compiled.WinHelp.Internal
+{
+ public struct OLDFONT
+ {
+ public FontAttributes Attributes;
+ public byte HalfPoints;
+ public FontFamily FontFamily;
+ public ushort FacenameIndex;
+ ///
+ /// RGB values of foreground
+ ///
+ public byte[] ForegroundColor;
+ ///
+ /// Unused background RGB Values
+ ///
+ public byte[] BackgroundColor;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/SYSTEMHEADER.cs b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/SYSTEMHEADER.cs
new file mode 100644
index 00000000..28a6383c
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/SYSTEMHEADER.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.Help.Compiled.WinHelp.Internal
+{
+ public struct SYSTEMHEADER
+ {
+ public Version Version;
+ public DateTime GenDate;
+ public SystemHeaderFlags Flags;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/SYSTEMRECORD.cs b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/SYSTEMRECORD.cs
new file mode 100644
index 00000000..e249101c
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/SYSTEMRECORD.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.Help.Compiled.WinHelp.Internal
+{
+ public struct SYSTEMRECORD
+ {
+ public int SavePos;
+ public int Remaining;
+ public SystemRecordType RecordType;
+ public ushort DataSize;
+ public byte[] Data;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/SystemHeaderFlags.cs b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/SystemHeaderFlags.cs
new file mode 100644
index 00000000..eb868892
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/SystemHeaderFlags.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.Help.Compiled.WinHelp.Internal
+{
+ [Flags()]
+ public enum SystemHeaderFlags
+ {
+ None = 0,
+ CompressedLZ77TopicBlockSize4k = 4,
+ CompressedLZ77TopicBlockSize2k = 8
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/SystemRecordType.cs b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/SystemRecordType.cs
new file mode 100644
index 00000000..781bc593
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/SystemRecordType.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.Help.Compiled.WinHelp.Internal
+{
+ public enum SystemRecordType : ushort
+ {
+ ///
+ /// Help file title
+ ///
+ Title = 1,
+ ///
+ /// Copyright notice shown in AboutBox
+ ///
+ Copyright = 2,
+ ///
+ /// Topic offset of starting topic
+ ///
+ Contents = 3,
+ ///
+ /// All macros executed on opening
+ ///
+ Config = 4,
+ ///
+ /// See WIN31WH on icon file format
+ ///
+ Icon = 5,
+ ///
+ /// Windows defined in the HPJ-file; Viewer 2.0 Windows defined in MVP-file
+ ///
+ Window = 6,
+ ///
+ /// The Citation printed
+ ///
+ Citation = 8,
+ ///
+ /// Language ID, Windows 95 (HCW 4.00)
+ ///
+ LanguageID = 9,
+ ///
+ /// CNT file name, Windows 95 (HCW 4.00)
+ ///
+ TableOfContents = 10,
+ ///
+ /// Charset, Windows 95 (HCW 4.00)
+ ///
+ CharacterSet = 11,
+ ///
+ /// Default dialog font, Windows 95 (HCW 4.00); Multimedia Help Files dtypes
+ ///
+ DefaultDialogFontOrFTIndex = 12,
+ ///
+ /// Defined GROUPs, Multimedia Help File
+ ///
+ Groups = 13,
+ ///
+ /// Separators, Windows 95 (HCW 4.00); Multimedia Help Files
+ ///
+ IndexSeparatorsOrKeyIndex = 14,
+ ///
+ /// Defined language, Multimedia Help Files
+ ///
+ Language = 18,
+ ///
+ /// Defined DLLMAPS, Multimedia Help Files
+ ///
+ DLLMaps = 19
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/TOPICBLOCKHEADER.cs b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/TOPICBLOCKHEADER.cs
new file mode 100644
index 00000000..69368f10
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/TOPICBLOCKHEADER.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.Help.Compiled.WinHelp.Internal
+{
+ public struct TOPICBLOCKHEADER
+ {
+ ///
+ /// Points to last TOPICLINK in previous block
+ ///
+ public int LastTopicLink;
+ ///
+ /// Points to first TOPICLINK in this block
+ ///
+ public int FirstTopicLink;
+ ///
+ /// Points to TOPICLINK of last TOPICHEADER
+ ///
+ public int LastTopicHeader;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/TOPICHEADER.cs b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/TOPICHEADER.cs
new file mode 100644
index 00000000..354b2cd4
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/TOPICHEADER.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.Help.Compiled.WinHelp.Internal
+{
+ public struct TOPICHEADER
+ {
+ ///
+ /// Size of topic, including internal topic links
+ ///
+ public int BlockSize;
+ ///
+ /// Topic offset for prev topic in browse sequence
+ ///
+ public int BrowseSequencePreviousTopic;
+ ///
+ /// Topic offset for next topic in browse sequence
+ ///
+ public int BrowseSequenceNextTopic;
+ ///
+ /// Topic number
+ ///
+ public int TopicNum;
+ ///
+ /// Start of non-scrolling region (topic offset) or -1
+ ///
+ public int NonScrollingRegionOffset;
+ ///
+ /// Start of scrolling region (topic offset)
+ ///
+ public int ScrollingRegionOffset;
+ ///
+ /// Start of next type 2 record
+ ///
+ public int NextTopic;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/TOPICLINK.cs b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/TOPICLINK.cs
new file mode 100644
index 00000000..d2f6d00c
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/TOPICLINK.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.Help.Compiled.WinHelp.Internal
+{
+ public struct TOPICLINK
+ {
+ ///
+ /// Size of this link + LinkData1 + LinkData2
+ ///
+ public int BlockSize;
+ ///
+ /// Length of decompressed LinkData2
+ ///
+ public int DataLen2;
+ ///
+ /// Windows 3.0 (HC30): number of bytes the TOPICLINK of the previous block is located before this TOPICLINK, that is the block size of the previous TOPICLINK plus
+ /// eventually skipped TOPICBLOCKHEADER.
+ /// Windows 3.1 (HC31): TOPICPOS of previous TOPICLINK
+ ///
+ public int PrevBlock;
+ ///
+ /// Windows 3.0 (HC30): number of bytes the TOPICLINK of the next block is located behind this block, including skipped TOPICBLOCKHEADER.
+ /// Windows 3.1 (HC31): TOPICPOS of next TOPICLINK
+ ///
+ public int NextBlock;
+ ///
+ /// includes size of TOPICLINK
+ ///
+ public int DataLen1;
+ public TopicLinkRecordType RecordType;
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/TopicLinkRecordType.cs b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/TopicLinkRecordType.cs
new file mode 100644
index 00000000..87400f69
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/DataFormats/Help/Compiled/WinHelp/Internal/TopicLinkRecordType.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.DataFormats.Help.Compiled.WinHelp.Internal
+{
+ public enum TopicLinkRecordType : byte
+ {
+ ///
+ /// Version 3.0 displayable information
+ ///
+ Display30 = 0x01,
+ ///
+ /// Topic header information
+ ///
+ TopicHeader = 0x02,
+ ///
+ /// Version 3.1 displayable information
+ ///
+ Display31 = 0x20,
+ ///
+ /// Version 3.1 table
+ ///
+ Table31 = 0x23
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/ObjectModels/Help/Compiled/CompiledHelpObjectModel.cs b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/ObjectModels/Help/Compiled/CompiledHelpObjectModel.cs
new file mode 100644
index 00000000..24056cf5
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/ObjectModels/Help/Compiled/CompiledHelpObjectModel.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.ObjectModels.Help.Compiled
+{
+ public class CompiledHelpObjectModel : ObjectModel
+ {
+ private static ObjectModelReference _omr = null;
+ protected override ObjectModelReference MakeReferenceInternal()
+ {
+ if (_omr == null)
+ {
+ _omr = base.MakeReferenceInternal();
+ _omr.Title = "WinHelp compiled documentation file";
+ _omr.Path = new string[] { "Documentation Writer", "Compiled Documentation" };
+ }
+ return _omr;
+ }
+
+ public override void Clear()
+ {
+ }
+
+ public override void CopyTo(ObjectModel where)
+ {
+ }
+
+ private string mvarTitle = String.Empty;
+ public string Title { get { return mvarTitle; } set { mvarTitle = value; } }
+
+ private string mvarCopyright = String.Empty;
+ public string Copyright { get { return mvarCopyright; } set { mvarCopyright = value; } }
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/UniversalEditor.Plugins.Microsoft.csproj b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/UniversalEditor.Plugins.Microsoft.csproj
index d2d686de..48fdf23d 100644
--- a/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/UniversalEditor.Plugins.Microsoft.csproj
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Microsoft/UniversalEditor.Plugins.Microsoft.csproj
@@ -60,6 +60,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -67,6 +80,7 @@
+