Microsoft B+ (WinHelp) file system improvements

This commit is contained in:
Michael Becker 2020-08-13 22:11:42 -04:00
parent adcad4354a
commit b05224dbdd
No known key found for this signature in database
GPG Key ID: 506F54899E2BFED7
5 changed files with 87 additions and 5 deletions

View File

@ -13,6 +13,16 @@
</MagicByteSequence>
</MagicByteSequences>
</Filter>
<Filter Title="Microsoft Media Viewer book">
<FileNameFilters>
<FileNameFilter>*.mvb</FileNameFilter>
</FileNameFilters>
<MagicByteSequences>
<MagicByteSequence>
<MagicByte Type="HexString">3F5F0300</MagicByte>
</MagicByteSequence>
</MagicByteSequences>
</Filter>
</Filters>
<ObjectModels>
<ObjectModel TypeName="UniversalEditor.ObjectModels.Help.Compiled.CompiledHelpObjectModel" />
@ -23,5 +33,22 @@
<!-- <DataFormat TypeName="UniversalEditor.DataFormats.FileSystem.BPlus.BPlusFileSystemDataFormat" /> -->
</DataFormats>
</Association>
<Association>
<Filters>
<Filter Title="Microsoft WinHelp B+ FileSystem">
<MagicByteSequences>
<MagicByteSequence>
<MagicByte Type="HexString">3F5F0300</MagicByte>
</MagicByteSequence>
</MagicByteSequences>
</Filter>
</Filters>
<ObjectModels>
<ObjectModel TypeName="UniversalEditor.ObjectModels.FileSystem.FileSystemObjectModel" />
</ObjectModels>
<DataFormats>
<DataFormat TypeName="UniversalEditor.DataFormats.FileSystem.BPlus.BPlusFileSystemDataFormat" />
</DataFormats>
</Association>
</Associations>
</UniversalEditor>

View File

@ -0,0 +1,35 @@
//
// BPlusFileFlags.cs - indicates the flags for a file in a BPlus file system
//
// Author:
// Michael Becker <alcexhim@gmail.com>
//
// Copyright (c) 2020 Mike Becker's Software
//
// 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 3 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, see <http://www.gnu.org/licenses/>.
using System;
namespace UniversalEditor.DataFormats.FileSystem.BPlus
{
/// <summary>
/// Indicates the flags for a file in a BPlus file system.
/// </summary>
[Flags()]
public enum BPlusFileFlags
{
Default = 0x0002,
Directory = 0x0400
}
}

View File

@ -60,6 +60,9 @@ namespace UniversalEditor.DataFormats.FileSystem.BPlus
int directoryStart = br.ReadInt32(); // offset of FILEHEADER of internal directory
int firstFreeBlock = br.ReadInt32(); // offset of FREEHEADER or -1L if no free list
int entireFileSize = br.ReadInt32(); // size of entire help file in bytes
if (Accessor.Length != entireFileSize)
{
}
// At offset DirectoryStart the FILEHEADER of the internal directory is located
br.Accessor.Position = directoryStart;
@ -82,9 +85,9 @@ namespace UniversalEditor.DataFormats.FileSystem.BPlus
ushort magic1 = brFile.ReadUInt16();
if (magic1 != 0x293B) throw new InvalidDataFormatException("Could not read internal directory file");
ushort flags = brFile.ReadUInt16(); // bit 0x0002 always 1, bit 0x0400 1 if directory
bool bit0x0002 = ((flags & 0x0002) == 0x0002);
bool bit0x0400 = ((flags & 0x0400) == 0x0400);
BPlusFileFlags flags = (BPlusFileFlags)brFile.ReadUInt16(); // bit 0x0002 always 1, bit 0x0400 1 if directory
bool bit0x0002 = ((flags & BPlusFileFlags.Default) == BPlusFileFlags.Default);
bool bit0x0400 = ((flags & BPlusFileFlags.Directory) == BPlusFileFlags.Directory);
ushort PageSize = brFile.ReadUInt16(); // 0x0400=1k if directory, 0x0800=2k else, or 4k
string Structure = brFile.ReadFixedLengthString(16); // string describing format of data
@ -97,6 +100,7 @@ namespace UniversalEditor.DataFormats.FileSystem.BPlus
short NLevels = brFile.ReadInt16(); // number of levels of B+ tree
int TotalBPlusTreeEntries = brFile.ReadInt32(); // number of entries in B+ tree
Internal.DIRECTORYINDEXENTRY[][] directoryIndexEntries = new Internal.DIRECTORYINDEXENTRY[NLevels - 1][];
for (int i = 0; i < NLevels - 1; i++)
{
#region Index page
@ -110,10 +114,11 @@ namespace UniversalEditor.DataFormats.FileSystem.BPlus
// at FileName, but less than the next FileName. PreviousPage gets you to the
// next page if the desired FileName is lexically before the first FileName.
Internal.BTREEINDEXHEADER indexHeader = ReadBTreeIndexHeader(brFile);
directoryIndexEntries[i] = new Internal.DIRECTORYINDEXENTRY[indexHeader.PageEntriesCount];
for (short j = 0; j < indexHeader.PageEntriesCount; j++)
{
// this is the structure of directory index-pages
Internal.DIRECTORYINDEXENTRY entry = ReadDirectoryIndexEntry(brFile);
directoryIndexEntries[i][j] = ReadDirectoryIndexEntry(brFile);
}
#endregion
}
@ -131,6 +136,11 @@ namespace UniversalEditor.DataFormats.FileSystem.BPlus
{
// this is the structure of directory index-pages
Internal.DIRECTORYLEAFENTRY entry = ReadDirectoryLeafEntry(brFile);
// HACK: prevent crashing because we're running out of @#*$
if (entry.FileOffset == 0)
break;
entries.Add(entry);
}
#endregion
@ -156,7 +166,11 @@ namespace UniversalEditor.DataFormats.FileSystem.BPlus
int UsedSpace = br.ReadInt32();
fileHeader.FileFlags = br.ReadByte();
fileHeader.FileContent = br.ReadBytes(UsedSpace);
fileHeader.FreeSpace = new byte[fileHeader.ReservedSpace - UsedSpace - 9];
int t = fileHeader.ReservedSpace - UsedSpace - 9;
if (t < 0) t = 0;
fileHeader.FreeSpace = new byte[t];
return fileHeader;
}
private Internal.DIRECTORYLEAFENTRY ReadDirectoryLeafEntry(IO.Reader br)
@ -178,6 +192,10 @@ namespace UniversalEditor.DataFormats.FileSystem.BPlus
private Internal.DIRECTORYINDEXENTRY ReadDirectoryIndexEntry(IO.Reader br)
{
Internal.DIRECTORYINDEXENTRY entry = new Internal.DIRECTORYINDEXENTRY();
// HACK: see if we really need this or not???
ushort unknown1 = br.ReadUInt16();
entry.FileName = br.ReadNullTerminatedString();
entry.PageNumber = br.ReadInt16();
return entry;

View File

@ -250,6 +250,7 @@
<Compile Include="DataFormats\FileSystem\WinRAR\VM\RARVMFlags.cs" />
<Compile Include="DataFormats\FileSystem\WinRAR\VM\RAROpcodeFlags.cs" />
<Compile Include="DataFormats\FileSystem\WinRAR\VM\RARVMFunctions.cs" />
<Compile Include="DataFormats\FileSystem\BPlus\BPlusFileFlags.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Libraries\UniversalEditor.Core\UniversalEditor.Core.csproj">

View File

@ -107,6 +107,7 @@ namespace UniversalEditor.DataFormats.Help.Compiled.WinHelp
{
// help file title follows SYSTEMHEADER
string helpFileTitle = readerSystem.ReadNullTerminatedString();
help.Title = helpFileTitle;
}
else
{