various fixes, improvements, and features
This commit is contained in:
parent
1a793c3f38
commit
b02488345b
@ -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 />
|
||||
|
||||
@ -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>
|
||||
|
||||
BIN
Documentation/FileSystem/Microsoft/FAT/fatspec.pdf
Normal file
BIN
Documentation/FileSystem/Microsoft/FAT/fatspec.pdf
Normal file
Binary file not shown.
3671
Documentation/FileSystem/Microsoft/NTFS/NTFS.asciidoc
Normal file
3671
Documentation/FileSystem/Microsoft/NTFS/NTFS.asciidoc
Normal file
File diff suppressed because it is too large
Load Diff
134097
Documentation/FileSystem/Microsoft/NTFS/NTFS.pdf
Normal file
134097
Documentation/FileSystem/Microsoft/NTFS/NTFS.pdf
Normal file
File diff suppressed because it is too large
Load Diff
@ -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)
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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))
|
||||
});
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
|
||||
@ -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">
|
||||
|
||||
@ -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++)
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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; }
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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:
|
||||
/// " * / : < > ? \ |
|
||||
/// 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:
|
||||
/// " * + , / : ; < = > ? \
|
||||
/// </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
|
||||
}
|
||||
}
|
||||
@ -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">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user