various fixes, improvements, and features

This commit is contained in:
Michael Becker 2023-07-01 21:26:37 -04:00
parent 1a793c3f38
commit b02488345b
18 changed files with 138176 additions and 49 deletions

View File

@ -9,6 +9,11 @@
<Command ID="PartitionedFileSystemEditor_tvPartitions_ContextMenu_CopyTo" Title="_Copy To..." />
<Command ID="PartitionedFileSystemEditor_tvPartitions_ContextMenu_Unselected" Title="PartitionedFileSystemEditor tvPartitions ContextMenu Unselected">
<Items>
<CommandReference CommandID="FileProperties" />
</Items>
</Command>
<Command ID="PartitionedFileSystemEditor_tvPartitions_ContextMenu_Selected" Title="PartitionedFileSystemEditor tvPartitions ContextMenu Unselected">
<Items>
<CommandReference CommandID="PartitionedFileSystemEditor_tvPartitions_ContextMenu_CopyTo" />
<Separator />

View File

@ -22,6 +22,8 @@
<column type="gchararray"/>
<!-- column-name colPartitionFlags -->
<column type="gchararray"/>
<!-- column-name colPartitionColorImage -->
<column type="GdkPixbuf"/>
</columns>
</object>
<object class="GtkWindow">
@ -55,7 +57,9 @@
<property name="can-focus">True</property>
<property name="model">tmPartitions</property>
<child internal-child="selection">
<object class="GtkTreeSelection"/>
<object class="GtkTreeSelection">
<property name="mode">multiple</property>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="tvcPartitionDevice">
@ -91,6 +95,15 @@
<property name="title" translatable="yes">File System</property>
<property name="clickable">True</property>
<property name="reorderable">True</property>
<child>
<object class="GtkCellRendererPixbuf">
<property name="width">16</property>
<property name="height">16</property>
</object>
<attributes>
<attribute name="pixbuf">9</attribute>
</attributes>
</child>
<child>
<object class="GtkCellRendererText"/>
<attributes>

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -136,14 +136,16 @@ namespace UniversalEditor.DataFormats.PartitionedFileSystem.MBR
{
switch (partitionType)
{
case MBRPartitionType.Ext4: return PartitionType.Ext4;
case MBRPartitionType.FAT12: return PartitionType.FAT12;
case MBRPartitionType.FAT32LBA: return PartitionType.FAT32LBA;
case MBRPartitionType.IFS_HPFS_NTFS_exFAT_QNX: return PartitionType.IFS_HPFS_NTFS_exFAT_QNX;
case MBRPartitionType.IFS_HPFS_NTFS_exFAT_QNX: return PartitionType.IFS_HPFS_NTFS_exFAT_QNX;
case MBRPartitionType.None: return PartitionType.None;
case MBRPartitionType.XenixRoot: return PartitionType.XenixRoot;
case MBRPartitionType.XenixUsr: return PartitionType.XenixUsr;
}
throw new ArgumentOutOfRangeException();
Console.Error.WriteLine("unknown partition type {0}", partitionType);
return PartitionType.Unknown;
}
private MBRPartitionEntry ReadMBRPartitionEntry(Reader r)

View File

@ -40,6 +40,8 @@ namespace UniversalEditor.DataFormats.PartitionedFileSystem.MBR
IFS_HPFS_NTFS_exFAT_QNX = 0x07,
Ext4 = 0x83,
/// <summary>
/// FAT32 with Logical Block Addressing (LBA)
/// </summary>

View File

@ -23,7 +23,9 @@ namespace UniversalEditor.ObjectModels.PartitionedFileSystem
{
public enum PartitionType
{
Unknown = -1,
None = 0,
Ext4,
/// <summary>
/// FAT12 as primary partition in first physical 32 MB of disk or as
/// logical drive anywhere on disk (else use 06h instead)

View File

@ -706,11 +706,19 @@ namespace UniversalEditor.Editors.FileSystem
else if (fso is File)
{
File f = (fso as File);
string fileExtension = null;
if (f.Name.Contains("."))
{
fileExtension = System.IO.Path.GetExtension(f.Name);
if (fileExtension.StartsWith("."))
fileExtension = fileExtension.Substring(1);
}
r = new TreeModelRow(new TreeModelRowColumn[]
{
new TreeModelRowColumn(tm.Columns[0], f.Name),
new TreeModelRowColumn(tm.Columns[1], UserInterface.Common.FileInfo.FormatSize(f.Size)),
new TreeModelRowColumn(tm.Columns[2], f.Name.Contains(".") ? String.Format("{0} file", System.IO.Path.GetExtension(f.Name).Substring(1)) : "File"),
new TreeModelRowColumn(tm.Columns[2], !String.IsNullOrEmpty(fileExtension) ? String.Format("{0} file", fileExtension) : "File"),
new TreeModelRowColumn(tm.Columns[3], f.ModificationTimestamp.ToString()),
new TreeModelRowColumn(tm.Columns[4], Image.FromStock(StockType.File, 16))
});

View File

@ -0,0 +1,49 @@
//
// PartitionGuiInfo.cs
//
// Author:
// beckermj <>
//
// Copyright (c) 2023 ${CopyrightHolder}
//
// 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;
using MBS.Framework.Drawing;
using MBS.Framework.UserInterface.Drawing;
using UniversalEditor.ObjectModels.PartitionedFileSystem;
namespace UniversalEditor.Editors.PartitionedFileSystem
{
public struct PartitionGuiInfo
{
public string Name { get; }
public PartitionType PartitionType { get; }
public Color Color { get; }
public Image ColorImage { get; }
public PartitionGuiInfo(PartitionType type, string name, Color color)
{
Name = name;
PartitionType = type;
Color = color;
Image image = Image.Create(16, 16);
Graphics g = Graphics.FromImage(image);
//g.Clear(color);
g.FillRectangle(new SolidBrush(color), new Rectangle(0, 0, 16, 16));
ColorImage = image;
}
}
}

View File

@ -19,10 +19,15 @@
// 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;
using System.Collections.Generic;
using MBS.Framework;
using MBS.Framework.Drawing;
using MBS.Framework.UserInterface;
using MBS.Framework.UserInterface.Controls.ListView;
using MBS.Framework.UserInterface.Dialogs;
using MBS.Framework.UserInterface.Drawing;
using MBS.Framework.UserInterface.Drawing.Drawing2D;
using MBS.Framework.UserInterface.Input.Mouse;
using UniversalEditor.ObjectModels.PartitionedFileSystem;
using UniversalEditor.UserInterface;
@ -34,6 +39,139 @@ namespace UniversalEditor.Editors.PartitionedFileSystem
private CustomControl cnvPartitions;
private ListViewControl tvPartitions;
private Partition _SelectedPartition = null;
public Partition SelectedPartition
{
get { return _SelectedPartition; }
set
{
_SelectedPartition = value;
_InhibitSelectedRowsChanged = true;
tvPartitions.SelectedRows.Clear();
foreach (TreeModelRow row in tvPartitions.Model.Rows)
{
if (row.GetExtraData<Partition>("part") == value)
{
tvPartitions.SelectedRows.Add(row);
}
}
_InhibitSelectedRowsChanged = false;
Context.Commands["PartitionedFileSystemEditor_tvPartitions_ContextMenu_CopyTo"].Enabled = _SelectedPartition != null;
cnvPartitions.Refresh();
}
}
private bool _InhibitSelectedRowsChanged = false;
private Partition PartitionHitTest(Vector2D loc)
{
PartitionedFileSystemObjectModel disk = ObjectModel as PartitionedFileSystemObjectModel;
if (disk == null)
return null;
double totalSize = 0;
double x = 0, y = 0;
foreach (Partition p in disk.Partitions)
{
totalSize += (p.SectorCount * disk.SectorSize);
}
foreach (Partition p in disk.Partitions)
{
double width = 0;
width = ((p.SectorCount * disk.SectorSize) / totalSize) * this.Size.Width;
if (loc.X >= x && loc.X <= x + width)
{
return p;
}
x += width;
}
return null;
}
[EventHandler(nameof(cnvPartitions), nameof(Control.MouseDown))]
private void cnvPartitions_MouseDown(object sender, MouseEventArgs e)
{
Partition p = PartitionHitTest(e.Location);
if (p != null)
{
SelectedPartition = p;
}
}
[EventHandler(nameof(cnvPartitions), nameof(Control.BeforeContextMenu))]
private void cnvPartitions_BeforeContextMenu(object sender, EventArgs e)
{
if (tvPartitions.SelectedRows.Count > 0)
{
cnvPartitions.ContextMenuCommandID = "PartitionedFileSystemEditor_tvPartitions_ContextMenu_Selected";
}
else
{
cnvPartitions.ContextMenuCommandID = "PartitionedFileSystemEditor_tvPartitions_ContextMenu_Unselected";
}
}
private DashStyle dsLongDash = new DashStyle(new double[] { 4, 4 });
private Dictionary<PartitionType, PartitionGuiInfo> _partitionGuiInfo = new Dictionary<PartitionType, PartitionGuiInfo>();
[EventHandler(nameof(cnvPartitions), nameof(Control.Paint))]
private void cnvPartitions_Paint(object sender, PaintEventArgs e)
{
PartitionedFileSystemObjectModel disk = ObjectModel as PartitionedFileSystemObjectModel;
if (disk == null)
return;
double totalSize = 0;
foreach (Partition p in disk.Partitions)
{
totalSize += (p.SectorCount * disk.SectorSize);
}
double x = 0;
bool f = false;
foreach (Partition p in disk.Partitions)
{
double partitionSize = (p.SectorCount * disk.SectorSize);
double pctWidth = partitionSize / totalSize;
double width = 0;
width = (pctWidth * cnvPartitions.Size.Width) - 8;
double usedSize = 0.3 * totalSize;
double usedWidth = ((usedSize / partitionSize) * width) - 8;
Rectangle partRect = new Rectangle(x + 4, 4, width - 4, cnvPartitions.Size.Height - 8);
e.Graphics.FillRectangle(new SolidBrush(Color.FromRGBADouble(1.0, 1.0, 1.0, 0.1)), partRect);
e.Graphics.FillRectangle(new SolidBrush(SystemColors.HighlightBackground.Alpha(0.4)), new Rectangle(partRect.X, partRect.Y, usedWidth, partRect.Height));
Pen pen = new Pen(Colors.DarkGray, new Measurement(4, MeasurementUnit.Pixel));
if (_partitionGuiInfo.ContainsKey(p.PartitionType))
{
PartitionGuiInfo info = _partitionGuiInfo[p.PartitionType];
pen.Color = info.Color;
}
e.Graphics.DrawRectangle(pen, partRect);
e.Graphics.DrawText(String.Format("{0}\n{1}", String.Format("@dev@{0}", disk.Partitions.IndexOf(p)), UserInterface.Common.FileInfo.FormatSize(disk.CalculatePartitionSize(p))), Font.FromFont(SystemFonts.MenuFont, new Measurement(12, MeasurementUnit.Pixel)), partRect, new SolidBrush(SystemColors.WindowForeground), HorizontalAlignment.Center, VerticalAlignment.Middle);
if (p == SelectedPartition)
{
Pen pen2 = new Pen(SystemColors.HighlightBackground, new Measurement(4, MeasurementUnit.Pixel), dsLongDash, LineCapStyles.Flat);
e.Graphics.DrawRectangle(pen2, partRect);
}
x += width + 8;
f = true;
}
}
private static EditorReference _er = null;
public override EditorReference MakeReference()
{
@ -58,11 +196,25 @@ namespace UniversalEditor.Editors.PartitionedFileSystem
{
base.OnCreated(e);
InitializePartitionGuiInfo();
OnObjectModelChanged(e);
Context.AttachCommandEventHandler("PartitionedFileSystemEditor_tvPartitions_ContextMenu_CopyTo", PartitionedFileSystemEditor_tvPartitions_ContextMenu_CopyTo);
}
private void InitializePartitionGuiInfo(PartitionGuiInfo info)
{
_partitionGuiInfo.Add(info.PartitionType, info);
}
private void InitializePartitionGuiInfo()
{
InitializePartitionGuiInfo(new PartitionGuiInfo(PartitionType.Ext4, "ext4", Color.Parse("#314e6c")));
InitializePartitionGuiInfo(new PartitionGuiInfo(PartitionType.FAT12, "fat12", Color.Parse("#00ff00")));
InitializePartitionGuiInfo(new PartitionGuiInfo(PartitionType.FAT32LBA, "fat32", Color.Parse("#46a046")));
InitializePartitionGuiInfo(new PartitionGuiInfo(PartitionType.IFS_HPFS_NTFS_exFAT_QNX, "ntfs", Color.Parse("#70d2b1")));
}
private void PartitionedFileSystemEditor_tvPartitions_ContextMenu_CopyTo(object sender, EventArgs e)
{
PartitionedFileSystemObjectModel disk = ObjectModel as PartitionedFileSystemObjectModel;
@ -105,12 +257,30 @@ namespace UniversalEditor.Editors.PartitionedFileSystem
[EventHandler(nameof(tvPartitions), nameof(Control.BeforeContextMenu))]
private void tvPartitions_BeforeContextMenu(object sender, EventArgs e)
{
tvPartitions.ContextMenuCommandID = "PartitionedFileSystemEditor_tvPartitions_ContextMenu_Unselected";
if (tvPartitions.SelectedRows.Count > 0)
{
cnvPartitions.ContextMenuCommandID = "PartitionedFileSystemEditor_tvPartitions_ContextMenu_Selected";
}
else
{
cnvPartitions.ContextMenuCommandID = "PartitionedFileSystemEditor_tvPartitions_ContextMenu_Unselected";
}
}
[EventHandler(nameof(tvPartitions), nameof(ListViewControl.SelectionChanged))]
private void tvPartitions_SelectionChanged(object sender, EventArgs e)
{
Context.Commands["PartitionedFileSystemEditor_tvPartitions_ContextMenu_CopyTo"].Enabled = (tvPartitions.SelectedRows.Count == 1);
if (tvPartitions.SelectedRows.Count == 1)
{
SelectedPartition = tvPartitions.SelectedRows[0].GetExtraData<Partition>("part");
}
else if (tvPartitions.SelectedRows.Count > 1)
{
}
else
{
SelectedPartition = null;
}
}
protected override void OnObjectModelChanged(EventArgs e)
@ -130,14 +300,14 @@ namespace UniversalEditor.Editors.PartitionedFileSystem
{
new TreeModelRowColumn(tvPartitions.Model.Columns[0], String.Format("@dev@{0}", i)),
new TreeModelRowColumn(tvPartitions.Model.Columns[1], String.Empty /* Name */),
new TreeModelRowColumn(tvPartitions.Model.Columns[2], String.Empty /* File System */),
new TreeModelRowColumn(tvPartitions.Model.Columns[2], _partitionGuiInfo.ContainsKey(disk.Partitions[i].PartitionType) ? _partitionGuiInfo[disk.Partitions[i].PartitionType].Name : disk.Partitions[i].PartitionType.ToString() /* File System */),
new TreeModelRowColumn(tvPartitions.Model.Columns[3], String.Empty /* Mount Point */),
new TreeModelRowColumn(tvPartitions.Model.Columns[4], String.Empty /* Label */),
new TreeModelRowColumn(tvPartitions.Model.Columns[5], UserInterface.Common.FileInfo.FormatSize(disk.CalculatePartitionSize(disk.Partitions[i]))),
new TreeModelRowColumn(tvPartitions.Model.Columns[6], UserInterface.Common.FileInfo.FormatSize(0) /* Used */),
new TreeModelRowColumn(tvPartitions.Model.Columns[7], UserInterface.Common.FileInfo.FormatSize(0) /* Unused */),
new TreeModelRowColumn(tvPartitions.Model.Columns[8], Flagstr(disk.Partitions[i]))
new TreeModelRowColumn(tvPartitions.Model.Columns[8], Flagstr(disk.Partitions[i])),
new TreeModelRowColumn(tvPartitions.Model.Columns[9], _partitionGuiInfo.ContainsKey(disk.Partitions[i].PartitionType) ? _partitionGuiInfo[disk.Partitions[i].PartitionType].ColorImage : null)
});
rowPartition.SetExtraData<Partition>("part", disk.Partitions[i]);
tvPartitions.Model.Rows.Add(rowPartition);

View File

@ -142,6 +142,7 @@
<Compile Include="Editors\Text\Formatted\FormattedTextEditor.cs" />
<Compile Include="Panels\OutputWindowPanel.cs" />
<Compile Include="Editors\PartitionedFileSystem\PartitionedFileSystemEditor.cs" />
<Compile Include="Editors\PartitionedFileSystem\PartitionGuiInfo.cs" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">

View File

@ -151,6 +151,7 @@ namespace UniversalEditor.Plugins.Microsoft.Multimedia.DataFormats.Font.Bitmap
byte b = 0, bits = 0;
b = ma.Reader.ReadByte();
long pos = ma.Position;
for (y = 0; y < pic.Height; y++)
{
for (x = 0; x < pic.Width; x++)
@ -174,9 +175,10 @@ namespace UniversalEditor.Plugins.Microsoft.Multimedia.DataFormats.Font.Bitmap
bits = 0;
b = ma.Reader.ReadByte();
}
ma.Reader.Align(4);
}
ma.Reader.Align(4);
long dwpos = ma.Position;
ma.Reader.Align(dfWidthBytes);
}
/*
for (int column = 0; column < pk; column++)

View File

@ -30,6 +30,7 @@ namespace UniversalEditor.DataFormats.FileSystem.Microsoft.NTFS.Attributes
public long AllocatedSize { get; set; }
public long ActualSize { get; set; }
public NTFSFileNameNamespace FileNameNamespace { get; set; } = NTFSFileNameNamespace.Windows;
public string FileName { get; set; } = null;
}
}

View File

@ -23,8 +23,9 @@ namespace UniversalEditor.DataFormats.FileSystem.Microsoft.NTFS.Attributes
{
public class NTFSStandardInformationAttribute : NTFSAttribute
{
public NTFSStandardInformationAttribute()
{
}
public DateTime CreationDateTime { get; internal set; }
public DateTime ModificationDateTime { get; internal set; }
public DateTime MftModificationDateTime { get; internal set; }
public DateTime ReadDateTime { get; internal set; }
}
}

View File

@ -21,6 +21,7 @@
using System;
using System.Collections.Generic;
using UniversalEditor.Accessors;
using UniversalEditor.DataFormats.FileSystem.Microsoft.NTFS.Attributes;
using UniversalEditor.IO;
using UniversalEditor.ObjectModels.FileSystem;
@ -154,11 +155,18 @@ namespace UniversalEditor.DataFormats.FileSystem.Microsoft.NTFS
break;
}
if (attr is NTFSFileNameAttribute)
if (attr is NTFSFileNameAttribute attName)
{
NTFSFileNameAttribute att = (attr as NTFSFileNameAttribute);
file.Name = att.FileName;
file.Size = att.AllocatedSize;
file.Name = attName.FileName;
file.Size = attName.ActualSize;
}
else if (attr is NTFSStandardInformationAttribute attStandard)
{
file.ModificationTimestamp = attStandard.ModificationDateTime;
}
else if (attr is NTFSDataAttribute attData)
{
file.SetData(attData.Data);
}
if (!keepgoing)
@ -173,12 +181,12 @@ namespace UniversalEditor.DataFormats.FileSystem.Microsoft.NTFS
private bool ReadAttribute(Reader reader, out NTFSMftKnownAttribute type, out NTFSAttribute attr)
{
long thisoffset = reader.Accessor.Position;
attr = null;
NTFSMftKnownAttribute attributeId = (NTFSMftKnownAttribute)reader.ReadInt32();
type = attributeId;
if (attributeId == NTFSMftKnownAttribute.End)
{
attr = null;
return false;
}
@ -195,45 +203,57 @@ namespace UniversalEditor.DataFormats.FileSystem.Microsoft.NTFS
ushort contentOffset = reader.ReadUInt16();
reader.Seek(thisoffset + contentOffset, SeekOrigin.Begin);
byte[] attributeData = reader.ReadBytes(contentSize);
MemoryAccessor ma = new MemoryAccessor(attributeData);
switch (attributeId)
{
case NTFSMftKnownAttribute.StandardInformation:
{
NTFSStandardInformationAttribute att = new NTFSStandardInformationAttribute();
long creationDateTime = reader.ReadInt64();
long modificationDateTime = reader.ReadInt64();
long mftModificationDateTime = reader.ReadInt64();
long readDateTime = reader.ReadInt64();
int dosFilePermissions = reader.ReadInt32();
int maxVersionCount = reader.ReadInt32();
int versionNumber = reader.ReadInt32();
int classId = reader.ReadInt32();
int ownerId = reader.ReadInt32();
int securityId = reader.ReadInt32();
long quotaCharged = reader.ReadInt64();
long updateSequenceNumber = reader.ReadInt64();
long creationDateTime = ma.Reader.ReadInt64();
att.CreationDateTime = new DateTime(creationDateTime);
long modificationDateTime = ma.Reader.ReadInt64();
att.ModificationDateTime = new DateTime(modificationDateTime);
long mftModificationDateTime = ma.Reader.ReadInt64();
att.MftModificationDateTime = new DateTime(mftModificationDateTime);
long readDateTime = ma.Reader.ReadInt64();
att.ReadDateTime = new DateTime(readDateTime);
int dosFilePermissions = ma.Reader.ReadInt32();
int maxVersionCount = ma.Reader.ReadInt32();
int versionNumber = ma.Reader.ReadInt32();
int classId = ma.Reader.ReadInt32();
if (!ma.Reader.EndOfStream)
{
int ownerId = ma.Reader.ReadInt32();
int securityId = ma.Reader.ReadInt32();
long quotaCharged = ma.Reader.ReadInt64();
long updateSequenceNumber = ma.Reader.ReadInt64();
}
attr = att;
break;
}
case NTFSMftKnownAttribute.FileName:
{
NTFSFileNameAttribute att = new NTFSFileNameAttribute();
long parentDirectoryFileref = reader.ReadInt64();
long creationDateTime = reader.ReadInt64();
long parentDirectoryFileref = ma.Reader.ReadInt64();
long creationDateTime = ma.Reader.ReadInt64();
att.CreationDateTime = new DateTime(creationDateTime);
long modificationDateTime = reader.ReadInt64();
long modificationDateTime = ma.Reader.ReadInt64();
att.ModificationDateTime = new DateTime(modificationDateTime);
long mftModificationDateTime = reader.ReadInt64();
long readDateTime = reader.ReadInt64();
long mftModificationDateTime = ma.Reader.ReadInt64();
long readDateTime = ma.Reader.ReadInt64();
att.AccessDateTime = new DateTime(readDateTime);
att.AllocatedSize = reader.ReadInt64();
att.ActualSize = reader.ReadInt64();
int fileNameFlags = reader.ReadInt32();
int reparse = reader.ReadInt32();
att.AllocatedSize = ma.Reader.ReadInt64();
att.ActualSize = ma.Reader.ReadInt64();
int fileNameFlags = ma.Reader.ReadInt32();
int reparse = ma.Reader.ReadInt32();
// int securityId = reader.ReadInt32();
byte fileNameLength = reader.ReadByte();
byte fileNameNamespace = reader.ReadByte();
string fileNameUnicode = reader.ReadFixedLengthString(fileNameLength * 2, Encoding.UTF16LittleEndian);
byte fileNameLength = ma.Reader.ReadByte();
NTFSFileNameNamespace fileNameNamespace = (NTFSFileNameNamespace)ma.Reader.ReadByte();
att.FileNameNamespace = fileNameNamespace;
string fileNameUnicode = ma.Reader.ReadFixedLengthString(fileNameLength * 2, Encoding.UTF16LittleEndian);
att.FileName = fileNameUnicode;
attr = att;
@ -242,7 +262,7 @@ namespace UniversalEditor.DataFormats.FileSystem.Microsoft.NTFS
case NTFSMftKnownAttribute.Data:
{
NTFSDataAttribute att = new NTFSDataAttribute();
att.Data = reader.ReadBytes(attributeLength);
att.Data = attributeData;
attr = att;
break;
}
@ -260,18 +280,47 @@ namespace UniversalEditor.DataFormats.FileSystem.Microsoft.NTFS
}
else
{
long runlistStartingVirtualClusterNumber = reader.ReadInt64();
long runlistEndingVirtualClusterNumber = reader.ReadInt64();
ushort runlistOffset = reader.ReadUInt16();
long startingVirtualClusterNumber = reader.ReadInt64();
long endingVirtualClusterNumber = reader.ReadInt64();
ushort runlistOffset = reader.ReadUInt16(); // relative from start of attribute
ushort compressionUnitSize = reader.ReadUInt16();
uint unused = reader.ReadUInt32();
ulong attributeContentAllocatedSize = reader.ReadUInt64();
ulong attributeContentActualSize = reader.ReadUInt64();
ulong attributeContentInitializedSize = reader.ReadUInt64();
SeekToCluster(runlistStartingVirtualClusterNumber);
Accessor.Seek(thisoffset + runlistOffset, SeekOrigin.Begin);
attr = null;
while (true)
{
byte clusterBlockValueSize = reader.ReadByte();
if (clusterBlockValueSize == 0x00)
break;
byte nClusterBlocksValueSize = (byte)clusterBlockValueSize.GetBits(0, 4);
byte clusterBlockNumberValueSize = (byte)clusterBlockValueSize.GetBits(4, 4);
byte[] clusterBlocksValue = reader.ReadBytes(nClusterBlocksValueSize);
byte[] clusterBlockNumberValue = reader.ReadBytes(clusterBlockNumberValueSize);
}
Accessor.SavePosition();
SeekToCluster(startingVirtualClusterNumber);
byte[] data = reader.ReadBytes(attributeContentActualSize);
Accessor.LoadPosition();
if (attributeId == NTFSMftKnownAttribute.Data)
{
attr = new NTFSDataAttribute();
((NTFSDataAttribute)attr).Data = data;
}
else
{
}
}
long remaining = (thisoffset + attributeLength) - reader.Accessor.Position;

View File

@ -0,0 +1,53 @@
//
// NTFSFileNameNamespace.cs
//
// Author:
// beckermj <>
//
// Copyright (c) 2023 ${CopyrightHolder}
//
// 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.Microsoft.NTFS
{
public enum NTFSFileNameNamespace : byte
{
/// <summary>
/// Case sensitive character set that consists of all Unicode
/// characters except for: \0 (zero character), / (forward slash).
/// The : (colon) is valid for NTFS but not for Windows.
/// </summary>
POSIX = 0,
/// <summary>
/// A case insensitive sub set of the <see cref="POSIX" /> character
/// set that consists of all Unicode characters except for:
/// " * / : &lt; &gt; ? \ |
/// Note that names cannot end with a . (dot) or ' ' (space).
/// </summary>
Windows = 1,
/// <summary>
/// A case insensitive sub set of the <see cref="Windows" />
/// character set that consists of all upper case ASCII characters
/// except for:
/// " * + , / : ; &lt; = &gt; ? \
/// </summary>
DOS = 2,
/// <summary>
/// Both the <see cref="DOS" /> and <see cref="Windows" /> names are
/// identical. Which is the same as the DOS character set, with the
/// exception that lower case is used as well.
/// </summary>
DOSWindows = 3
}
}

View File

@ -160,6 +160,7 @@
<Compile Include="DataFormats\CompoundDocument\SummaryInformation\PropertySetInfo.cs" />
<Compile Include="DataFormats\CompoundDocument\SummaryInformation\PropertyInfo.cs" />
<Compile Include="DataFormats\CompoundDocument\SummaryInformation\PropertySetPropertyType.cs" />
<Compile Include="DataFormats\FileSystem\Microsoft\NTFS\NTFSFileNameNamespace.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Libraries\UniversalEditor.Compression\UniversalEditor.Compression.csproj">