Add support for Microsoft Cabinet (MSCF) archives (untested)
This commit is contained in:
parent
6769504274
commit
c202ad453d
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<UniversalEditor Version="4.0">
|
||||
<Associations>
|
||||
<Association>
|
||||
<Filters>
|
||||
<Filter Title="Microsoft Cabinet archive">
|
||||
<FileNameFilters>
|
||||
<FileNameFilter>*.cab</FileNameFilter>
|
||||
</FileNameFilters>
|
||||
<MagicByteSequences>
|
||||
<MagicByteSequence>
|
||||
<MagicByte Type="String">MSCF</MagicByte>
|
||||
</MagicByteSequence>
|
||||
</MagicByteSequences>
|
||||
</Filter>
|
||||
</Filters>
|
||||
<ObjectModels>
|
||||
<ObjectModel TypeName="UniversalEditor.ObjectModels.FileSystem.FileSystemObjectModel" />
|
||||
</ObjectModels>
|
||||
<DataFormats>
|
||||
<DataFormat TypeName="UniversalEditor.DataFormats.FileSystem.Microsoft.Cabinet.CABDataFormat" />
|
||||
</DataFormats>
|
||||
</Association>
|
||||
</Associations>
|
||||
</UniversalEditor>
|
||||
@ -111,6 +111,7 @@
|
||||
<Content Include="Extensions\FileSystem\Associations\IZArc.xml" />
|
||||
<Content Include="Extensions\FileSystem\Associations\LHA.xml" />
|
||||
<Content Include="Extensions\FileSystem\Associations\Microsoft\CompoundDocument.xml" />
|
||||
<Content Include="Extensions\FileSystem\Associations\Microsoft\Cabinet.xml" />
|
||||
<Content Include="Extensions\FileSystem\Associations\Microsoft\MSCompressed.xml" />
|
||||
<Content Include="Extensions\FileSystem\Associations\NeroDiscImage.xml" />
|
||||
<Content Include="Extensions\FileSystem\Associations\PKZip.xml" />
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace UniversalEditor.DataFormats.FileSystem.Microsoft.Cabinet
|
||||
{
|
||||
public enum CABCompressionMethod : ushort
|
||||
{
|
||||
None = 0,
|
||||
MSZIP = 1,
|
||||
LZX = 5379
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,375 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UniversalEditor.Accessors;
|
||||
using UniversalEditor.Compression;
|
||||
using UniversalEditor.IO;
|
||||
using UniversalEditor.ObjectModels.FileSystem;
|
||||
|
||||
namespace UniversalEditor.DataFormats.FileSystem.Microsoft.Cabinet
|
||||
{
|
||||
public class CABDataFormat : DataFormat
|
||||
{
|
||||
private static DataFormatReference _dfr = null;
|
||||
protected override DataFormatReference MakeReferenceInternal()
|
||||
{
|
||||
if (_dfr == null)
|
||||
{
|
||||
_dfr = base.MakeReferenceInternal();
|
||||
_dfr.Capabilities.Add(typeof(FileSystemObjectModel), DataFormatCapabilities.All);
|
||||
_dfr.Sources.Add("http://msdn.microsoft.com/en-us/library/bb267310.aspx#struct_spec");
|
||||
|
||||
_dfr.ExportOptions.Add(new CustomOptionNumber("CabinetReservedAreaSize", "Per-&cabinet reserved area size:", 0, 0, UInt16.MaxValue));
|
||||
_dfr.ExportOptions.Add(new CustomOptionNumber("FolderReservedAreaSize", "Per-&folder reserved area size:", 0, 0, Byte.MaxValue));
|
||||
_dfr.ExportOptions.Add(new CustomOptionNumber("DatablockReservedAreaSize", "Per-&datablock reserved area size:", 0, 0, Byte.MaxValue));
|
||||
|
||||
_dfr.ExportOptions.Add(new CustomOptionText("NextCabinetName", "&Next cabinet file name:"));
|
||||
_dfr.ExportOptions.Add(new CustomOptionText("NextDiskName", "Ne&xt cabinet disk name:"));
|
||||
_dfr.ExportOptions.Add(new CustomOptionText("PreviousCabinetName", "&Previous cabinet file name:"));
|
||||
_dfr.ExportOptions.Add(new CustomOptionText("PreviousDiskName", "Pre&vious cabinet disk name:"));
|
||||
}
|
||||
return _dfr;
|
||||
}
|
||||
|
||||
private ushort mvarCabinetReservedAreaSize = 0;
|
||||
public ushort CabinetReservedAreaSize { get { return mvarCabinetReservedAreaSize; } set { mvarCabinetReservedAreaSize = value; } }
|
||||
|
||||
private byte mvarFolderReservedAreaSize = 0;
|
||||
public byte FolderReservedAreaSize { get { return mvarFolderReservedAreaSize; } set { mvarFolderReservedAreaSize = value; } }
|
||||
|
||||
private byte mvarDatablockReservedAreaSize = 0;
|
||||
public byte DatablockReservedAreaSize { get { return mvarDatablockReservedAreaSize; } set { mvarDatablockReservedAreaSize = value; } }
|
||||
|
||||
private string mvarNextCabinetName = String.Empty;
|
||||
public string NextCabinetName { get { return mvarNextCabinetName; } set { mvarNextCabinetName = value; } }
|
||||
|
||||
private string mvarNextDiskName = String.Empty;
|
||||
public string NextDiskName { get { return mvarNextDiskName; } set { mvarNextDiskName = value; } }
|
||||
|
||||
private string mvarPreviousCabinetName = String.Empty;
|
||||
public string PreviousCabinetName { get { return mvarPreviousCabinetName; } set { mvarPreviousCabinetName = value; } }
|
||||
|
||||
private string mvarPreviousDiskName = String.Empty;
|
||||
public string PreviousDiskName { get { return mvarPreviousDiskName; } set { mvarPreviousDiskName = value; } }
|
||||
|
||||
protected override void LoadInternal(ref ObjectModel objectModel)
|
||||
{
|
||||
FileSystemObjectModel fsom = (objectModel as FileSystemObjectModel);
|
||||
|
||||
Reader br = base.Accessor.Reader;
|
||||
|
||||
Internal.CFHEADER cfheader = ReadCFHEADER(br);
|
||||
mvarCabinetReservedAreaSize = cfheader.cabinetReservedAreaSize;
|
||||
mvarDatablockReservedAreaSize = cfheader.datablockReservedAreaSize;
|
||||
mvarFolderReservedAreaSize = cfheader.folderReservedAreaSize;
|
||||
|
||||
List<Internal.CFFOLDER> folders = new List<Internal.CFFOLDER>();
|
||||
for (ushort cfFolderID = 0; cfFolderID < cfheader.folderCount; cfFolderID++)
|
||||
{
|
||||
Internal.CFFOLDER cffolder = ReadCFFOLDER(br, cfheader);
|
||||
folders.Add(cffolder);
|
||||
}
|
||||
for (ushort cfFileID = 0; cfFileID < cfheader.fileCount; cfFileID++)
|
||||
{
|
||||
Internal.CFFILE cffile = ReadCFFILE(br);
|
||||
File file = fsom.AddFile(cffile.name);
|
||||
file.Size = cffile.decompressedSize;
|
||||
file.Properties.Add("DecompressedSize", cffile.decompressedSize);
|
||||
file.Properties.Add("offset", cffile.offset);
|
||||
file.Properties.Add("folder", folders[cffile.folderIndex]);
|
||||
file.Properties.Add("reader", br);
|
||||
file.DataRequest += file_DataRequest;
|
||||
}
|
||||
}
|
||||
|
||||
private Internal.CFHEADER ReadCFHEADER(Reader br)
|
||||
{
|
||||
Internal.CFHEADER cfheader = new Internal.CFHEADER();
|
||||
cfheader.signature = br.ReadFixedLengthString(4); // cabinet file signature
|
||||
if (cfheader.signature != "MSCF") throw new InvalidDataFormatException("File does not begin with \"MSCF\"");
|
||||
|
||||
cfheader.reserved1 = br.ReadUInt32(); // reserved
|
||||
cfheader.cabinetFileSize = br.ReadUInt32(); // size of this cabinet file in bytes
|
||||
if (br.Accessor.Length != cfheader.cabinetFileSize) throw new DataCorruptedException("Stored cabinet length does not match actual file length");
|
||||
|
||||
cfheader.reserved2 = br.ReadUInt32(); // reserved
|
||||
cfheader.firstFileOffset = br.ReadUInt32(); // offset of the first CFFILE entry
|
||||
cfheader.reserved3 = br.ReadUInt32(); // reserved
|
||||
|
||||
cfheader.versionMinor = br.ReadByte(); // cabinet file format version, minor
|
||||
cfheader.versionMajor = br.ReadByte(); // cabinet file format version, major
|
||||
|
||||
cfheader.folderCount = br.ReadUInt16(); // number of CFFOLDER entries in this cabinet
|
||||
cfheader.fileCount = br.ReadUInt16(); // number of CFFILE entries in this cabinet
|
||||
|
||||
cfheader.flags = (CABFlags)br.ReadUInt16(); // cabinet file option indicators:
|
||||
|
||||
cfheader.setID = br.ReadUInt16(); // must be the same for all cabinets in a set
|
||||
cfheader.iCabinet = br.ReadUInt16(); // number of this cabinet file in a set
|
||||
|
||||
if ((cfheader.flags & CABFlags.HasReservedArea) == CABFlags.HasReservedArea)
|
||||
{
|
||||
cfheader.cabinetReservedAreaSize = br.ReadUInt16(); // (optional) size of per-cabinet reserved area
|
||||
cfheader.folderReservedAreaSize = br.ReadByte(); // (optional) size of per-folder reserved area
|
||||
cfheader.datablockReservedAreaSize = br.ReadByte(); // (optional) size of per-datablock reserved area
|
||||
}
|
||||
|
||||
cfheader.reservedArea = br.ReadBytes(mvarCabinetReservedAreaSize); // (optional) per-cabinet reserved area
|
||||
|
||||
if ((cfheader.flags & CABFlags.HasPreviousCabinet) == CABFlags.HasPreviousCabinet)
|
||||
{
|
||||
cfheader.previousCabinetName = br.ReadNullTerminatedString(); /* (optional) name of previous cabinet file */
|
||||
cfheader.previousDiskName = br.ReadNullTerminatedString(); /* (optional) name of previous disk */
|
||||
}
|
||||
if ((cfheader.flags & CABFlags.HasNextCabinet) == CABFlags.HasNextCabinet)
|
||||
{
|
||||
cfheader.nextCabinetName = br.ReadNullTerminatedString(); /* (optional) name of next cabinet file */
|
||||
cfheader.nextDiskName = br.ReadNullTerminatedString(); /* (optional) name of next disk */
|
||||
}
|
||||
return cfheader;
|
||||
}
|
||||
private Internal.CFFILE ReadCFFILE(Reader br)
|
||||
{
|
||||
Internal.CFFILE cffile = new Internal.CFFILE();
|
||||
|
||||
cffile.decompressedSize = br.ReadUInt32();
|
||||
cffile.offset = br.ReadUInt32();
|
||||
cffile.folderIndex = br.ReadUInt16();
|
||||
|
||||
cffile.date = br.ReadUInt16();
|
||||
cffile.time = br.ReadUInt16();
|
||||
|
||||
cffile.attribs = br.ReadUInt16();
|
||||
cffile.name = br.ReadNullTerminatedString();
|
||||
return cffile;
|
||||
}
|
||||
private Internal.CFFOLDER ReadCFFOLDER(Reader br, Internal.CFHEADER cfheader)
|
||||
{
|
||||
Internal.CFFOLDER cffolder = new Internal.CFFOLDER();
|
||||
cffolder.firstDataBlockOffset = br.ReadUInt32(); // offset of the first CFDATA block in this folder
|
||||
cffolder.dataBlockCount = br.ReadUInt16(); // number of CFDATA blocks in this folder
|
||||
cffolder.compressionMethod = (CABCompressionMethod)br.ReadUInt16(); // compression type indicator
|
||||
if ((cfheader.flags & CABFlags.HasReservedArea) == CABFlags.HasReservedArea)
|
||||
{
|
||||
cffolder.reservedArea = br.ReadBytes(mvarFolderReservedAreaSize); // (optional) per-folder reserved area
|
||||
}
|
||||
return cffolder;
|
||||
}
|
||||
private Internal.CFDATA ReadCFDATA(Reader br)
|
||||
{
|
||||
Internal.CFDATA data = new Internal.CFDATA();
|
||||
data.checksum = br.ReadUInt32();
|
||||
data.compressedLength = br.ReadUInt16();
|
||||
data.decompressedLength = br.ReadUInt16();
|
||||
data.reservedArea = br.ReadBytes(mvarDatablockReservedAreaSize);
|
||||
data.data = br.ReadBytes(data.compressedLength);
|
||||
return data;
|
||||
}
|
||||
|
||||
private void file_DataRequest(object sender, DataRequestEventArgs e)
|
||||
{
|
||||
File file = (sender as File);
|
||||
uint decompressedSize = (uint)file.Properties["DecompressedSize"];
|
||||
uint offset = (uint)file.Properties["offset"];
|
||||
Reader br = (Reader)file.Properties["reader"];
|
||||
|
||||
Internal.CFFOLDER cffolder = (Internal.CFFOLDER)file.Properties["folder"];
|
||||
br.Accessor.Position = cffolder.firstDataBlockOffset;
|
||||
|
||||
byte[] decompressedData = new byte[decompressedSize];
|
||||
int j = 0;
|
||||
for (int i = 0; i < cffolder.dataBlockCount; i++)
|
||||
{
|
||||
Internal.CFDATA data = ReadCFDATA(br);
|
||||
switch (cffolder.compressionMethod)
|
||||
{
|
||||
case CABCompressionMethod.None:
|
||||
{
|
||||
// no compression
|
||||
file.Properties["CompressionMethod"] = CompressionMethod.None;
|
||||
Array.Copy(data.data, offset, decompressedData, j, decompressedData.Length);
|
||||
j += decompressedData.Length;
|
||||
break;
|
||||
}
|
||||
case CABCompressionMethod.MSZIP:
|
||||
{
|
||||
Reader br1 = new Reader(new MemoryAccessor(data.data));
|
||||
byte mszipSig1 = br1.ReadByte();
|
||||
byte mszipSig2 = br1.ReadByte();
|
||||
|
||||
byte[] rest = br1.ReadToEnd();
|
||||
byte[] decompressedDataLocal = CompressionModule.FromKnownCompressionMethod(CompressionMethod.Deflate).Decompress(rest);
|
||||
Array.Copy(decompressedDataLocal, offset, decompressedData, j, decompressedData.Length);
|
||||
j += decompressedDataLocal.Length;
|
||||
break;
|
||||
}
|
||||
case CABCompressionMethod.LZX:
|
||||
{
|
||||
file.Properties["CompressionMethod"] = Compression.CompressionMethod.LZX;
|
||||
decompressedData = CompressionModule.FromKnownCompressionMethod(CompressionMethod.LZX).Decompress(data.data);
|
||||
|
||||
// no compression
|
||||
Array.Copy(data.data, 0, decompressedData, j, data.data.Length);
|
||||
j += data.data.Length;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new InvalidOperationException("unknown compression method");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
e.Data = decompressedData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#region Save
|
||||
private ushort PackDate(DateTime value)
|
||||
{
|
||||
return (ushort)(((value.Year - 1980) << 9) + (value.Month << 5) + value.Day);
|
||||
}
|
||||
private ushort PackTime(DateTime value)
|
||||
{
|
||||
return (ushort)((value.Hour << 11) + (value.Minute << 5) + (value.Second / 2));
|
||||
}
|
||||
|
||||
|
||||
private void WriteCFHEADER(Writer bw, Internal.CFHEADER cfheader)
|
||||
{
|
||||
bw.WriteFixedLengthString(cfheader.signature, 4);
|
||||
|
||||
bw.WriteUInt32(cfheader.reserved1); // reserved
|
||||
bw.WriteUInt32(cfheader.cabinetFileSize); // size of this cabinet file in bytes
|
||||
|
||||
bw.WriteUInt32(cfheader.reserved2); // reserved
|
||||
bw.WriteUInt32(cfheader.firstFileOffset); // offset of the first CFFILE entry
|
||||
bw.WriteUInt32(cfheader.reserved3); // reserved
|
||||
|
||||
bw.WriteByte(cfheader.versionMinor); // cabinet file format version, minor
|
||||
bw.WriteByte(cfheader.versionMajor); // cabinet file format version, major
|
||||
|
||||
bw.WriteUInt16(cfheader.folderCount); // number of CFFOLDER entries in this cabinet
|
||||
bw.WriteUInt16(cfheader.fileCount); // number of CFFILE entries in this cabinet
|
||||
|
||||
bw.WriteUInt16((ushort)cfheader.flags); // cabinet file option indicators
|
||||
|
||||
bw.WriteUInt16(cfheader.setID); // must be the same for all cabinets in a set
|
||||
bw.WriteUInt16(cfheader.iCabinet); // number of this cabinet file in a set
|
||||
|
||||
if ((cfheader.flags & CABFlags.HasReservedArea) == CABFlags.HasReservedArea)
|
||||
{
|
||||
bw.WriteUInt16(cfheader.cabinetReservedAreaSize); // (optional) size of per-cabinet reserved area
|
||||
bw.WriteByte(cfheader.folderReservedAreaSize); // (optional) size of per-folder reserved area
|
||||
bw.WriteByte(cfheader.datablockReservedAreaSize); // (optional) size of per-datablock reserved area
|
||||
}
|
||||
|
||||
bw.WriteFixedLengthBytes(cfheader.reservedArea, cfheader.cabinetReservedAreaSize);
|
||||
|
||||
if ((cfheader.flags & CABFlags.HasPreviousCabinet) == CABFlags.HasPreviousCabinet)
|
||||
{
|
||||
bw.WriteNullTerminatedString(cfheader.previousCabinetName); // (optional) name of previous cabinet file
|
||||
bw.WriteNullTerminatedString(cfheader.previousDiskName); // (optional) name of previous disk
|
||||
}
|
||||
if ((cfheader.flags & CABFlags.HasNextCabinet) == CABFlags.HasNextCabinet)
|
||||
{
|
||||
bw.WriteNullTerminatedString(cfheader.nextCabinetName); // (optional) name of next cabinet file
|
||||
bw.WriteNullTerminatedString(cfheader.nextDiskName); // (optional) name of next disk
|
||||
}
|
||||
}
|
||||
private void WriteCFFILE(Writer bw, Internal.CFFILE cffile)
|
||||
{
|
||||
bw.WriteUInt32(cffile.decompressedSize);
|
||||
bw.WriteUInt32(cffile.offset);
|
||||
bw.WriteUInt16(cffile.folderIndex);
|
||||
bw.WriteUInt16(cffile.date);
|
||||
bw.WriteUInt16(cffile.time);
|
||||
bw.WriteUInt16(cffile.attribs);
|
||||
bw.WriteNullTerminatedString(cffile.name);
|
||||
}
|
||||
private void WriteCFFOLDER(Writer bw, Internal.CFFOLDER cffolder, Internal.CFHEADER cfheader)
|
||||
{
|
||||
bw.WriteUInt32(cffolder.firstDataBlockOffset);
|
||||
bw.WriteUInt16(cffolder.dataBlockCount);
|
||||
bw.WriteUInt16((ushort)cffolder.compressionMethod);
|
||||
if ((cfheader.flags & CABFlags.HasReservedArea) == CABFlags.HasReservedArea)
|
||||
{
|
||||
bw.WriteFixedLengthBytes(cffolder.reservedArea, cfheader.folderReservedAreaSize);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void SaveInternal(ObjectModel objectModel)
|
||||
{
|
||||
FileSystemObjectModel fsom = (objectModel as FileSystemObjectModel);
|
||||
Writer bw = base.Accessor.Writer;
|
||||
|
||||
// go through and build a list of files
|
||||
File[] files = fsom.GetAllFiles();
|
||||
|
||||
List<Internal.CFFILE> cffiles = new List<Internal.CFFILE>();
|
||||
List<Internal.CFFOLDER> cffolders = new List<Internal.CFFOLDER>();
|
||||
|
||||
Internal.CFHEADER cfheader = new Internal.CFHEADER();
|
||||
cfheader.signature = "MSCF";
|
||||
cfheader.cabinetFileSize = 0;
|
||||
|
||||
foreach (File file in files)
|
||||
{
|
||||
Internal.CFFILE cffile = new Internal.CFFILE();
|
||||
cffile.name = file.Name;
|
||||
cffile.decompressedSize = (uint)file.Size;
|
||||
cffile.offset = 0; // TODO: how to get the offset of the file?
|
||||
cffile.folderIndex = 0;
|
||||
cfheader.cabinetFileSize += cffile.decompressedSize;
|
||||
cffiles.Add(cffile);
|
||||
}
|
||||
|
||||
#region cffolder
|
||||
{
|
||||
Internal.CFFOLDER cffolder = new Internal.CFFOLDER();
|
||||
cffolder.compressionMethod = CABCompressionMethod.None;
|
||||
cffolder.dataBlockCount = 1;
|
||||
cffolder.firstDataBlockOffset = 0;
|
||||
cffolders.Add(cffolder);
|
||||
}
|
||||
#endregion
|
||||
|
||||
cfheader.firstFileOffset = 0;
|
||||
|
||||
cfheader.versionMajor = 3;
|
||||
cfheader.versionMinor = 1;
|
||||
|
||||
cfheader.folderCount = (ushort)cffolders.Count;
|
||||
cfheader.fileCount = (ushort)cffiles.Count;
|
||||
|
||||
cfheader.setID = 12345;
|
||||
cfheader.iCabinet = 0;
|
||||
|
||||
cfheader.cabinetReservedAreaSize = mvarCabinetReservedAreaSize;
|
||||
cfheader.folderReservedAreaSize = mvarFolderReservedAreaSize;
|
||||
cfheader.datablockReservedAreaSize = mvarDatablockReservedAreaSize;
|
||||
|
||||
cfheader.nextCabinetName = mvarNextCabinetName;
|
||||
cfheader.nextDiskName = mvarNextDiskName;
|
||||
cfheader.previousCabinetName = mvarPreviousCabinetName;
|
||||
cfheader.previousDiskName = mvarPreviousDiskName;
|
||||
|
||||
if (cfheader.cabinetReservedAreaSize != 0 || cfheader.folderReservedAreaSize != 0 || cfheader.datablockReservedAreaSize != 0) cfheader.flags |= CABFlags.HasReservedArea;
|
||||
if (!String.IsNullOrEmpty(cfheader.nextCabinetName) || !String.IsNullOrEmpty(cfheader.nextDiskName)) cfheader.flags |= CABFlags.HasNextCabinet;
|
||||
if (!String.IsNullOrEmpty(cfheader.previousCabinetName) || !String.IsNullOrEmpty(cfheader.previousCabinetName)) cfheader.flags |= CABFlags.HasPreviousCabinet;
|
||||
|
||||
WriteCFHEADER(bw, cfheader);
|
||||
|
||||
foreach (Internal.CFFOLDER cffolder in cffolders)
|
||||
{
|
||||
WriteCFFOLDER(bw, cffolder, cfheader);
|
||||
}
|
||||
foreach (Internal.CFFILE cffile in cffiles)
|
||||
{
|
||||
WriteCFFILE(bw, cffile);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace UniversalEditor.DataFormats.FileSystem.Microsoft.Cabinet
|
||||
{
|
||||
[Flags()]
|
||||
public enum CABFlags
|
||||
{
|
||||
HasPreviousCabinet = 0x0001,
|
||||
HasNextCabinet = 0x0002,
|
||||
HasReservedArea = 0x0004
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace UniversalEditor.DataFormats.FileSystem.Microsoft.Cabinet.Internal
|
||||
{
|
||||
internal struct CFDATA
|
||||
{
|
||||
/// <summary>
|
||||
/// checksum of this CFDATA entry
|
||||
/// </summary>
|
||||
public uint checksum;
|
||||
/// <summary>
|
||||
/// number of compressed bytes in this block
|
||||
/// </summary>
|
||||
public ushort compressedLength;
|
||||
/// <summary>
|
||||
/// number of uncompressed bytes in this block
|
||||
/// </summary>
|
||||
public ushort decompressedLength;
|
||||
/// <summary>
|
||||
/// (optional) per-datablock reserved area
|
||||
/// </summary>
|
||||
public byte[] reservedArea;
|
||||
/// <summary>
|
||||
/// compressed data bytes
|
||||
/// </summary>
|
||||
public byte[] data;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace UniversalEditor.DataFormats.FileSystem.Microsoft.Cabinet.Internal
|
||||
{
|
||||
internal struct CFFILE
|
||||
{
|
||||
/// <summary>
|
||||
/// uncompressed size of this file in bytes
|
||||
/// </summary>
|
||||
public uint decompressedSize;
|
||||
/// <summary>
|
||||
/// uncompressed offset of this file in the folder
|
||||
/// </summary>
|
||||
public uint offset;
|
||||
/// <summary>
|
||||
/// index into the CFFOLDER area
|
||||
/// </summary>
|
||||
public ushort folderIndex;
|
||||
/// <summary>
|
||||
/// date stamp for this file
|
||||
/// </summary>
|
||||
public ushort date;
|
||||
/// <summary>
|
||||
/// time stamp for this file
|
||||
/// </summary>
|
||||
public ushort time;
|
||||
/// <summary>
|
||||
/// attribute flags for this file
|
||||
/// </summary>
|
||||
public ushort attribs;
|
||||
/// <summary>
|
||||
/// name of this file
|
||||
/// </summary>
|
||||
public string name;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace UniversalEditor.DataFormats.FileSystem.Microsoft.Cabinet.Internal
|
||||
{
|
||||
internal struct CFFOLDER
|
||||
{
|
||||
/// <summary>
|
||||
/// offset of the first CFDATA block in this folder
|
||||
/// </summary>
|
||||
public uint firstDataBlockOffset;
|
||||
/// <summary>
|
||||
/// number of CFDATA blocks in this folder
|
||||
/// </summary>
|
||||
public ushort dataBlockCount;
|
||||
/// <summary>
|
||||
/// compression type indicator
|
||||
/// </summary>
|
||||
public CABCompressionMethod compressionMethod;
|
||||
/// <summary>
|
||||
/// (optional) per-folder reserved area
|
||||
/// </summary>
|
||||
public byte[] reservedArea;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace UniversalEditor.DataFormats.FileSystem.Microsoft.Cabinet.Internal
|
||||
{
|
||||
internal struct CFHEADER
|
||||
{
|
||||
public string signature;
|
||||
public uint reserved1;
|
||||
public uint cabinetFileSize;
|
||||
public uint reserved2;
|
||||
public uint firstFileOffset;
|
||||
public uint reserved3;
|
||||
public byte versionMinor;
|
||||
public byte versionMajor;
|
||||
|
||||
public ushort folderCount;
|
||||
public ushort fileCount;
|
||||
public CABFlags flags;
|
||||
|
||||
public ushort setID;
|
||||
public ushort iCabinet;
|
||||
|
||||
public ushort cabinetReservedAreaSize;
|
||||
public byte folderReservedAreaSize;
|
||||
public byte datablockReservedAreaSize;
|
||||
|
||||
public byte[] reservedArea;
|
||||
|
||||
public string previousCabinetName;
|
||||
public string previousDiskName;
|
||||
|
||||
public string nextCabinetName;
|
||||
public string nextDiskName;
|
||||
}
|
||||
}
|
||||
@ -37,6 +37,13 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="DataFormats\DataLink\UniversalDataLink\UDLDataFormat.cs" />
|
||||
<Compile Include="DataFormats\FileSystem\Microsoft\Cabinet\Internal\CFDATA.cs" />
|
||||
<Compile Include="DataFormats\FileSystem\Microsoft\Cabinet\Internal\CFFILE.cs" />
|
||||
<Compile Include="DataFormats\FileSystem\Microsoft\Cabinet\Internal\CFFOLDER.cs" />
|
||||
<Compile Include="DataFormats\FileSystem\Microsoft\Cabinet\Internal\CFHEADER.cs" />
|
||||
<Compile Include="DataFormats\FileSystem\Microsoft\Cabinet\CABCompressionMethod.cs" />
|
||||
<Compile Include="DataFormats\FileSystem\Microsoft\Cabinet\CABDataFormat.cs" />
|
||||
<Compile Include="DataFormats\FileSystem\Microsoft\Cabinet\CABFlags.cs" />
|
||||
<Compile Include="DataFormats\FileSystem\Microsoft\CompoundDocument\CompoundDocumentDataFormat.cs" />
|
||||
<Compile Include="DataFormats\FileSystem\Microsoft\CompoundDocument\CompoundDocumentKnownSectorID.cs" />
|
||||
<Compile Include="DataFormats\FileSystem\Microsoft\MSCompressed\MSCompressedCompressionMethod.cs" />
|
||||
@ -53,6 +60,10 @@
|
||||
<Compile Include="DataFormats\Text\Formatted\XPS\XPSDataFormat.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Libraries\UniversalEditor.Compression\UniversalEditor.Compression.csproj">
|
||||
<Project>{3f664673-7e22-4486-9ad0-fc81861d0b78}</Project>
|
||||
<Name>UniversalEditor.Compression</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Libraries\UniversalEditor.Core\UniversalEditor.Core.csproj">
|
||||
<Project>{2D4737E6-6D95-408A-90DB-8DFF38147E85}</Project>
|
||||
<Name>UniversalEditor.Core</Name>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user