Example #1
0
File: Cell.cs Project: pszmyd/SHS
        internal Partition part; // the partition containing this cell

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Load a cell from disk into memory.
        /// </summary>
        /// <param name="part">The partition where this cell belongs</param>
        /// <param name="fileName">The name of the file holding the persisted cell</param>
        /// <exception cref="FileFormatException">The cell file is malformed</exception>
        /// <exception cref="EndOfStreamException">The cell file is too short</exception>
        internal Cell(Partition part, string fileName, bool partial)
        {
            this.part = part;
              this.fileName = fileName;
              var fileLength = new FileInfo(fileName).Length;
              using (var br = new BinaryReader(new BufferedStream(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)))) {
            this.baseUID   = br.ReadInt64();
            this.epoch     = br.ReadInt32();
            this.numUrls   = br.ReadInt64();
            this.supraUID  = this.baseUID + this.numUrls;

            this.urlCell = new UrlCell(this, br);
            this.linkCell = new LinkCell[2];
            this.linkCell[0] = new LinkCell(this, br);
            this.linkCell[1] = new LinkCell(this, br);

            long numHdrBytes = br.BaseStream.Position;
            this.urlCell.startPos = numHdrBytes;
            this.linkCell[0].startPos = this.urlCell.startPos + this.urlCell.numBytes;
            this.linkCell[1].startPos = this.linkCell[0].startPos + this.linkCell[0].numBytes;
            var expectedSize = numHdrBytes + this.urlCell.numBytes +
              (partial ? 0L : this.linkCell[0].numBytes + this.linkCell[1].numBytes);
            if (fileLength != expectedSize) {
              throw new FileFormatException(fileName + " is wrong size");
            }
              }
        }
 internal override EntityDesignerDiagram CreateDiagramHelper(Partition diagramPartition, ModelElement modelRoot)
 {
     var evm = modelRoot as EntityDesignerViewModel;
     var diagram = new EntityDesignerDiagram(diagramPartition);
     diagram.ModelElement = evm;
     return diagram;
 }
 /// <summary>
 /// Copy information from another partition.
 /// </summary>
 /// <param name="other">Partition to copy.</param>
 public Partition(Partition other)
 {
     this.partitionNumber = other.partitionNumber;
     this.size = other.size;
     this.replicas = new List<UNCPathname>();
     this.replicas.AddRange(other.replicas);
 }
    void CheckTerrain(string id, int res)
    {
        instance = GetComponent<BC2Instance>().instance;
        string terrainLocation = Util.GetField("TerrainAsset", instance).reference;
        if (terrainLocation == "" || terrainLocation == null)
        {
            Util.Log("TerrainAsset is missing from " + instance.guid);
        } else
        {

            string guid = Util.GetGuid(terrainLocation);
            terrainLocation = Util.ClearGUIDString(terrainLocation);
            terrainLoc = terrainLocation;
            partition = Util.LoadPartition(terrainLocation);
            int terrainRes;
            if (res == 0)
            {
                terrainRes = TerrainRes(terrainLocation, guid);
                fullres = terrainRes;
            } else
            {
                terrainRes = res;
            }

            int terrainHeight = TerrainHeight(terrainLocation);

            LoadTerrain(terrainLocation, terrainRes, terrainHeight, id);

        }
    }
Example #5
0
        public static void CreateNewProcessOverview(string ProcessName, ProjectItem processFile, ProjectItem diagramFile)
        {
            var store = new Store(typeof(CloudCoreArchitectProcessOverviewDomainModel));
            var partition = new Partition(store);
            var result = new SerializationResult();

            using (Transaction t = store.TransactionManager.BeginTransaction("create new process overview model"))
            {
                try
                {
                    var processOverviewSerializationHelper = CloudCoreArchitectProcessOverviewSerializationHelper.Instance;
                    Architect.ProcessOverview.Process process = processOverviewSerializationHelper.CreateModelHelper(partition);

                    SetProcessOverviewProperties(ProcessName, process);

                    var diagram = processOverviewSerializationHelper.CreateDiagramHelper(partition, process);

                    processOverviewSerializationHelper.SaveModelAndDiagram(result, process, processFile.FileNames[0], diagram, diagramFile.FileNames[0]);

                    AddAssemblyReference(ProcessName, process);

                    t.Commit();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }

        }
Example #6
0
        public void Init()
        {
            this.ListUIChildren = new List<UIComponent>();

            Ribbon.HEIGHT = (int)(0.2f * Render.ScreenHeight);
            Rec = new Rectangle(0, 0, (int)Render.ScreenWidth, Ribbon.HEIGHT);
            RecMenuBar = new Rectangle(Ribbon.MARGE + 100, 0, Rec.Width - 100 - Ribbon.MARGE * 2, 30);
            recBackground = new Rectangle(Rec.X, Rec.Y, Rec.Width, (int)((float)Rec.Height * 1.2f));
            vecTime = new Vector2(RecMenuBar.Left + MARGE * 4, RecMenuBar.Top + RecMenuBar.Height / 2 - Render.FontTextSmall.MeasureString("0").Y / 2);

            BPMMeter BPMMeter = new BPMMeter(this, this.UI, GetNewTimeSpan());
            BPMMeter.Init();
            this.ListUIChildren.Add(BPMMeter);

            Partition = new Partition(this, this.UI, GetNewTimeSpan());
            Partition.Init();
            this.ListUIChildren.Add(Partition);

            imgPlay = new ClickableImage(UI, this, GetNewTimeSpan(), "Play", Render.texPlay, Render.texPlay, new Vector2(BPMMeter.Rec.Right + MARGE * 2, Partition.Rec.Y + RecMenuBar.Height / 2 - Render.texPlay.Height / 2));
            imgPause = new ClickableImage(UI, this, GetNewTimeSpan(), "Pause", Render.texPause, Render.texPause, new Vector2(BPMMeter.Rec.Right + MARGE * 2, Partition.Rec.Y + RecMenuBar.Height / 2 - Render.texPause.Height / 2));
            imgPause.Visible = false;
            imgStop = new ClickableImage(UI, this, GetNewTimeSpan(), "Stop", Render.texStop, Render.texStop, new Vector2(BPMMeter.Rec.Right + MARGE * 3 + Render.texPlay.Width, Partition.Rec.Y + RecMenuBar.Height / 2 - Render.texStop.Height / 2));

            imgPlay.ClickImage += new ClickableImage.ClickImageHandler(imgPlay_ClickImage);
            imgPause.ClickImage += new ClickableImage.ClickImageHandler(imgPause_ClickImage);
            imgStop.ClickImage += new ClickableImage.ClickImageHandler(imgStop_ClickImage);

            this.ListUIChildren.Add(imgPlay);
            this.ListUIChildren.Add(imgPause);
            this.ListUIChildren.Add(imgStop);
        }
        private static ModelElement CreateModelElementForEFObjectType(EFObject obj, Partition partition)
        {
            ModelElement modelElement = null;
            var t = obj.GetType();
            if (t == typeof(ConceptualEntityModel))
            {
                modelElement = new EntityDesignerViewModel(partition);
            }
            else if (t == typeof(ConceptualEntityType))
            {
                modelElement = new EntityType(partition);
            }
            else if (t == typeof(ConceptualProperty))
            {
                modelElement = new ScalarProperty(partition);
            }
            else if (t == typeof(ComplexConceptualProperty))
            {
                modelElement = new ComplexProperty(partition);
            }
            else if (t == typeof(Association))
            {
                modelElement = new ViewModel.Association(partition);
            }
            else if (t == typeof(EntityTypeBaseType))
            {
                modelElement = new Inheritance(partition);
            }
            else if (t == typeof(NavigationProperty))
            {
                modelElement = new ViewModel.NavigationProperty(partition);
            }

            return modelElement;
        }
        public NodeShape(Partition partition, params PropertyAssignment[] propertyAssignments)
        	: base(partition, propertyAssignments)
        {
            bool bHandledSize = false;
            bool bHandledLocation = false;
            bool bHandledAbsoluteLocation = false;

            if (propertyAssignments != null)
                foreach (PropertyAssignment propertyAssignment in propertyAssignments)
                {
                    if (propertyAssignment.PropertyId == NodeShape.SizeDomainPropertyId)
                        bHandledSize = true;
                    else if (propertyAssignment.PropertyId == NodeShape.LocationDomainPropertyId)
                        bHandledLocation = true;
                    else if (propertyAssignment.PropertyId == NodeShape.AbsoluteLocationDomainPropertyId)
                        bHandledAbsoluteLocation = true;
                }

            if (!bHandledSize)
                this.Size = this.DefaultSize;
            if (!bHandledLocation)
                this.Location = PointD.Empty;
            if (!bHandledAbsoluteLocation)
                this.AbsoluteLocation = PointD.Empty;
        }
Example #9
0
 public WallCatalogResource(int APIversion,
     uint version,
     uint unknown2,
     Common common,
     Wall wallType,
     Partition partitionType,
     PartitionFlagsType partitionFlags,
     VerticalSpan verticalSpanType,
     PartitionsBlockedFlagsType partitionsBlockedFlags,
     PartitionsBlockedFlagsType adjacentPartitionsBlockedFlags,
     PartitionTool partitionToolMode,
     ToolUsageFlagsType toolUsageFlags,
     uint defaultPatternIndex,
     WallThickness wallThicknessType,
     TGIBlockList ltgib)
     : base(APIversion, version, common, ltgib)
 {
     this.unknown2 = unknown2;
     this.wallType = wallType;
     this.partitionType = partitionType;
     this.partitionFlags = partitionFlags;
     this.verticalSpanType = verticalSpanType;
     this.partitionsBlockedFlags = partitionsBlockedFlags;
     this.adjacentPartitionsBlockedFlags = adjacentPartitionsBlockedFlags;
     this.partitionToolMode = partitionToolMode;
     this.toolUsageFlags = toolUsageFlags;
     this.defaultPatternIndex = defaultPatternIndex;
     this.wallThicknessType = wallThicknessType;
 }
    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

        MapLoad mapLoad = (MapLoad)target;

        if(GUILayout.Button("Save as " + mapLoad.saveAs))
        {
            mapLoad.Save();
        }
        string path = "Levels/"+mapLoad.mapName;
        string minimapPath;
        if (lastMapName != mapLoad.mapName) {
            if(Util.FileExist("Resources/"+path+".xml")) {
                partition = Util.LoadPartition (path);
                foreach (Field field in Util.GetComplex ("LevelDescription", partition.instance [0]).field) {
                    if (field.name == "MinimapTexture") {
                        minimapPath = Util.ClearGUIDString (field.reference);
                        minimapPath += ".itexture";
                        texture = Util.LoadiTexture (minimapPath);

                    }
                }

            }
                lastMapName = mapLoad.mapName;
        }
        if (texture != null && !Application.isPlaying) {
            GUILayout.Label (texture, GUILayout.Width(EditorGUIUtility.currentViewWidth - 40), GUILayout.Height(EditorGUIUtility.currentViewWidth - 40));
        }
    }
 public bool DeletePartition(Partition entity)
 {
     if (entity == null) return false;
     _unitOfWork.PartitionRepository.Delete(entity);
     _unitOfWork.Save();
     return true;
 }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="partition">Partition where new element is to be created.</param>
 /// <param name="propertyAssignments">List of domain property id/value pairs to set once the element is created.</param>
 public DiagramsModel(Partition partition, params PropertyAssignment[] propertyAssignments)
 	: base(partition, propertyAssignments)
 {
     // listen to events
     this.Store.EventManagerDirectory.ElementAdded.Add(new EventHandler<ElementAddedEventArgs>(OnElementAdded));
     this.Store.EventManagerDirectory.ElementDeleted.Add(new EventHandler<ElementDeletedEventArgs>(OnElementDeleted));
 }
 public DeleteCommand(Cluster cluster, WritePolicy policy, Key key)
 {
     this.cluster = cluster;
     this.policy = policy;
     this.key = key;
     this.partition = new Partition(key);
 }
Example #14
0
 public async Task Put(string key, string value)
 {
     var now = DateTime.UtcNow;
     var versionLevel = new Partition(this.Target, key);
     await Task.WhenAll(
         versionLevel.Put((now.Ticks).ToString("d19"), value),
         this.master.Put(key, value));
 }
 public AsyncDelete(AsyncCluster cluster, WritePolicy policy, Key key, DeleteListener listener)
     : base(cluster)
 {
     this.policy = policy;
     this.listener = listener;
     this.key = key;
     this.partition = new Partition(key);
 }
		/// <summary>
		/// Initialize the serialization context on load / save
		/// </summary>
		/// <remarks>We need to supply a model bus for ModelBusReference deserialization to work</remarks>
		protected override void InitializeSerializationContext(Partition partition, SerializationContext serializationContext, bool isLoading)
		{
			Debug.Assert(partition != null, "partition should not be null");
			Debug.Assert(serializationContext != null, "serializationContext should not be null");

			IModelBus modelbus = partition.Store.GetService(typeof(SModelBus)) as IModelBus;
			serializationContext[Microsoft.VisualStudio.Modeling.Integration.ModelBusReferencePropertySerializer.ModelBusLoadContextKey] = modelbus;
		}	
        public override double Process(Partition p)
        {
            double result = 0;
            for (int i = 0; i < p.ElementsCount; i++)
                result += GetSilhouette(p, p.Set.Elements[i]);

            return result / p.ElementsCount;
        }
 public AsyncExists(AsyncCluster cluster, Policy policy, Key key, ExistsListener listener)
     : base(cluster)
 {
     this.policy = policy;
     this.listener = listener;
     this.key = key;
     this.partition = new Partition(key);
 }
        public void SetUp()
        {
            table = Storage.SetUp();

            partition = new Partition(table, "test");
            virtual1  = new Partition(table, "test|123");
            virtual2  = new Partition(table, "test|456");
        }
Example #20
0
        public Ext( Device device, MBRPartitionEntry mbr_entry )
        {
            partition = new Partition( device, mbr_entry );
            Byte[] sector = new Byte[ device.SectorSize ];
            partition.Read( sector, 1024, device.SectorSize );

            if ( sector[ 56 ] != 0x53 || sector[ 57 ] != 0xef ) throw new Exception( "Partition is not Ext2/3/4" );

            Utils.LoadLE32( out inode_count,            sector, 0 );
            Utils.LoadLE32( out total_block_count,      sector, 4 );
            Utils.LoadLE32( out reserved_block_count,   sector, 8 );
            Utils.LoadLE32( out free_block_count,       sector, 12 );
            Utils.LoadLE32( out free_inode_count,       sector, 16 );
            Utils.LoadLE32( out first_data_block,       sector, 20 );
            Utils.LoadLE32( out block_size_pow,         sector, 24 );
            Utils.LoadLE32( out blocks_per_group,       sector, 32 );
            Utils.LoadLE32( out inodes_per_group,       sector, 40 );
            Utils.LoadLE16( out minor_revision,         sector, 62 );
            Utils.LoadLE32( out revision,               sector, 76 );
            Utils.LoadLE32( out first_useable_inode,    sector, 84 );
            Utils.LoadLE16( out inode_size,             sector, 88 );
            Utils.LoadLE32( out features_compatible,    sector, 92 );
            Utils.LoadLE32( out features_incompatible,  sector, 96 );
            Utils.LoadLE32( out features_ro_compatible, sector, 100 );
            Utils.LoadLE32( out volume_id[0],           sector, 104 );
            Utils.LoadLE32( out volume_id[1],           sector, 108 );
            Utils.LoadLE32( out volume_id[2],           sector, 112 );
            Utils.LoadLE32( out volume_id[3],           sector, 116 );
            Utils.LoadString( out volume_name, 16,      sector, 120 );
            prealloc_file   = sector[204];
            prealloc_dir    = sector[205];
            Utils.LoadString( out journal_uuid, 16,     sector, 208 );
            Utils.LoadLE32( out journal_inode,          sector, 224 );
            Utils.LoadLE32( out journal_last_orphan,    sector, 232 );
            Utils.LoadLE32( out hash_seed[0],           sector, 236 );
            Utils.LoadLE32( out hash_seed[1],           sector, 240 );
            Utils.LoadLE32( out hash_seed[2],           sector, 244 );
            Utils.LoadLE32( out hash_seed[3],           sector, 248 );
            hash_version    = sector[252];
            Utils.LoadLE32( out first_meta_block_group, sector, 260 );

            ext4 =  ( ( features_ro_compatible & 0x0008 ) != 0 ) ||
                    ( ( features_ro_compatible & 0x0010 ) != 0 ) ||
                    ( ( features_ro_compatible & 0x0020 ) != 0 ) ||
                    ( ( features_ro_compatible & 0x0040 ) != 0 ) ||
                    ( ( features_incompatible & 0x0040 ) != 0 ) ||
                    ( ( features_incompatible & 0x0080 ) != 0 ) ||
                    ( ( features_incompatible & 0x0100 ) != 0 ) ||
                    ( ( features_incompatible & 0x0200 ) != 0 ) ||
                    ( ( features_incompatible & 0x0400 ) != 0 ) ||
                    ( ( features_incompatible & 0x1000 ) != 0 );

            uint block_group_count = ( total_block_count + blocks_per_group-1 )/blocks_per_group;
            for ( uint i=0; i<block_group_count; ++i )
            {
                bg_descriptors.Add( GetGroupDescriptor( i ) );
            }
        }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="partition">Partition where new element is to be created.</param>
 /// <param name="propertyAssignments">List of domain property id/value pairs to set once the element is created.</param>
 public GraphicalDependenciesDiagram(Partition partition, params PropertyAssignment[] propertyAssignments)
 	: base(partition, propertyAssignments)
 {
     if (SubscribedToDeleteEvent == false)
     {
         SubscribedToDeleteEvent = true;
         this.Store.EventManagerDirectory.ElementDeleted.Add(new EventHandler<ElementDeletedEventArgs>(OnElementDeleted));
     }
 }
 public WriteCommand(Cluster cluster, WritePolicy policy, Key key, Bin[] bins, Operation.Type operation)
 {
     this.cluster = cluster;
     this.policy = policy;
     this.key = key;
     this.partition = new Partition(key);
     this.bins = bins;
     this.operation = operation;
 }
 /// <summary>
 ///     Instantiate EntityTypeElementListCompartment so we can control FontSetting style for the list item.
 /// </summary>
 /// <returns></returns>
 public override Compartment CreateCompartment(Partition partition)
 {
     var compartment = new EntityTypeElementListCompartment(partition);
     if (IsDefaultCollapsed)
     {
         compartment.IsExpanded = false;
     }
     return compartment;
 }
 public override double Process(Partition p)
 {
     double result = 0;
     foreach (string str in p.Clusters.Keys)
     {
         result += p.Clusters[str].Count;
     }
     return result / p.ClusterCount;
 }
 /// <summary>
 /// Gets the source proto role player.
 /// </summary>
 /// <param name="partition">Partition.</param>
 /// <returns>Source proto role player.</returns>
 public ModelProtoRolePlayer GetSourceRolePlayer(Partition partition)
 {
     DomainDataDirectory domainDataDirectory = partition.Store.DomainDataDirectory;
     ModelProtoRolePlayer protoRolePlayer = rolePlayers[0];
     DomainRoleInfo domainRoleInfo = domainDataDirectory.GetDomainRole(protoRolePlayer.DomainRoleId);
     if (!domainRoleInfo.IsSource)
         protoRolePlayer = rolePlayers[1];
     return protoRolePlayer;
 }
 public AsyncWrite(AsyncCluster cluster, WritePolicy policy, WriteListener listener, Key key, Bin[] bins, Operation.Type operation)
     : base(cluster)
 {
     this.policy = policy;
     this.listener = listener;
     this.key = key;
     this.partition = new Partition(key);
     this.bins = bins;
     this.operation = operation;
 }
 public void Start()
 {
     Inst instance = transform.gameObject.GetComponent<BC2Instance>().instance;
     Field field = Util.GetField ("Name", instance);
     partition = Util.LoadPartition(field.value);
     foreach (Inst inst in partition.instance)
     {
         GeneratePosRot(inst);
         GenerateHavokItem(inst);
     }
 }
Example #28
0
 public Partition DeepCopy()
 {
     var result = new Partition();
     lock ( _entities )
     {
        foreach ( var e in _entities )
        {
       result._entities.Add( e.Key, e.Value );
        }
     }
     return result;
 }
 internal override EntityDesignerViewModel LoadModelAndDiagram(
     SerializationResult serializationResult, Partition modelPartition, string modelFileName, Partition diagramPartition,
     string diagramFileName, ISchemaResolver schemaResolver, ValidationController validationController,
     ISerializerLocator serializerLocator)
 {
     EntityDesignerViewModel evm = null;
     using (new VsUtils.HourglassHelper())
     {
         evm = LoadModel(serializationResult, modelPartition, modelFileName, schemaResolver, validationController, serializerLocator);
         var diagram = CreateDiagramHelper(diagramPartition, evm);
     }
     return evm;
 }
        public override Structuring BuildStructuring()
        {
            try
            {
                int _current = 1;
                if (IContainerProgressBar != null)
                {
                    IContainerProgressBar.ResetProgressBar(1, 1, true);
                    IContainerProgressBar.UpdateProgressBar(1, "Running Metis algorithm...", true);
                }


                if (ClustersCount <= 0)
                    throw new Exception("La cantidad de clusters debe ser mayor que cero");
                else if (ClustersCount == 1)
                {
                    Dictionary<string, Cluster> dic_clus = new Dictionary<string, Cluster>();
                    string name = "C-0";
                    List<Element> temp = new List<Element>();

                    for (int i = 0; i < Set.ElementsCount; i++)
                        temp.Add(Set[i]);

                    dic_clus.Add(name, new Cluster(name) { Elements = temp });

                    if (IContainerProgressBar != null)
                        IContainerProgressBar.FinishProgressBar();

                    Structuring = new Partition() { Clusters = dic_clus, Proximity = Proximity };
                    return Structuring;
                }
                else
                {
                    string filename = BuildInputFile(ref _current);
                    string parameters = filename + " " + ClustersCount;
                    Utils.ExecuteMetisPackage(Utils.MetisExecutableName, parameters);
                    Structuring = Utils.BuildStructuringFromOutputFile(filename, Set, ClustersCount, Proximity);

                    if (IContainerProgressBar != null)
                        IContainerProgressBar.FinishProgressBar();
                    
                    return Structuring;
                }
            }
            catch
            {
                if (IContainerProgressBar != null)
                    IContainerProgressBar.ShowError("Has Occurred an error in METIS algorithm.");
                return null;
            }
        }
Example #31
0
        public bool Identify(IMediaImage imagePlugin, Partition partition)
        {
            try
            {
                if (imagePlugin.Info.ReadableSectorTags == null)
                {
                    return(false);
                }

                if (!imagePlugin.Info.ReadableSectorTags.Contains(SectorTagType.AppleSectorTag))
                {
                    return(false);
                }

                // Minimal LisaOS disk is 3.5" single sided double density, 800 sectors
                if (imagePlugin.Info.Sectors < 800)
                {
                    return(false);
                }

                int beforeMddf = -1;

                // LisaOS searches sectors until tag tells MDDF resides there, so we'll search 100 sectors
                for (int i = 0; i < 100; i++)
                {
                    DecodeTag(imagePlugin.ReadSectorTag((ulong)i, SectorTagType.AppleSectorTag),
                              out LisaTag.PriamTag searchTag);

                    AaruConsole.DebugWriteLine("LisaFS plugin", "Sector {0}, file ID 0x{1:X4}", i, searchTag.FileId);

                    if (beforeMddf == -1 &&
                        searchTag.FileId == FILEID_LOADER_SIGNED)
                    {
                        beforeMddf = i - 1;
                    }

                    if (searchTag.FileId != FILEID_MDDF)
                    {
                        continue;
                    }

                    byte[] sector = imagePlugin.ReadSector((ulong)i);

                    var infoMddf = new MDDF
                    {
                        mddf_block                   = BigEndianBitConverter.ToUInt32(sector, 0x6C),
                        volsize_minus_one            = BigEndianBitConverter.ToUInt32(sector, 0x70),
                        volsize_minus_mddf_minus_one = BigEndianBitConverter.ToUInt32(sector, 0x74),
                        vol_size  = BigEndianBitConverter.ToUInt32(sector, 0x78),
                        blocksize = BigEndianBitConverter.ToUInt16(sector, 0x7C),
                        datasize  = BigEndianBitConverter.ToUInt16(sector, 0x7E)
                    };

                    AaruConsole.DebugWriteLine("LisaFS plugin", "Current sector = {0}", i);
                    AaruConsole.DebugWriteLine("LisaFS plugin", "mddf.mddf_block = {0}", infoMddf.mddf_block);
                    AaruConsole.DebugWriteLine("LisaFS plugin", "Disk size = {0} sectors", imagePlugin.Info.Sectors);
                    AaruConsole.DebugWriteLine("LisaFS plugin", "mddf.vol_size = {0} sectors", infoMddf.vol_size);
                    AaruConsole.DebugWriteLine("LisaFS plugin", "mddf.vol_size - 1 = {0}", infoMddf.volsize_minus_one);

                    AaruConsole.DebugWriteLine("LisaFS plugin", "mddf.vol_size - mddf.mddf_block -1 = {0}",
                                               infoMddf.volsize_minus_mddf_minus_one);

                    AaruConsole.DebugWriteLine("LisaFS plugin", "Disk sector = {0} bytes", imagePlugin.Info.SectorSize);
                    AaruConsole.DebugWriteLine("LisaFS plugin", "mddf.blocksize = {0} bytes", infoMddf.blocksize);
                    AaruConsole.DebugWriteLine("LisaFS plugin", "mddf.datasize = {0} bytes", infoMddf.datasize);

                    if (infoMddf.mddf_block != i - beforeMddf)
                    {
                        return(false);
                    }

                    if (infoMddf.vol_size > imagePlugin.Info.Sectors)
                    {
                        return(false);
                    }

                    if (infoMddf.vol_size - 1 != infoMddf.volsize_minus_one)
                    {
                        return(false);
                    }

                    if (infoMddf.vol_size - i - 1 != infoMddf.volsize_minus_mddf_minus_one - beforeMddf)
                    {
                        return(false);
                    }

                    if (infoMddf.datasize > infoMddf.blocksize)
                    {
                        return(false);
                    }

                    if (infoMddf.blocksize < imagePlugin.Info.SectorSize)
                    {
                        return(false);
                    }

                    return(infoMddf.datasize == imagePlugin.Info.SectorSize);
                }

                return(false);
            }
            catch (Exception ex)
            {
                AaruConsole.ErrorWriteLine("Exception {0}, {1}, {2}", ex.Message, ex.InnerException, ex.StackTrace);

                return(false);
            }
        }
Example #32
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = Encoding.Unicode;
            information = "";

            StringBuilder sb = new StringBuilder();

            byte[] ntfsBpb = imagePlugin.ReadSector(0 + partition.Start);

            NtfsBootBlock ntfsBb = Marshal.ByteArrayToStructureLittleEndian <NtfsBootBlock>(ntfsBpb);

            sb.AppendFormat("{0} bytes per sector", ntfsBb.bps).AppendLine();
            sb.AppendFormat("{0} sectors per cluster ({1} bytes)", ntfsBb.spc, ntfsBb.spc * ntfsBb.bps).AppendLine();
            //          sb.AppendFormat("{0} reserved sectors", ntfs_bb.rsectors).AppendLine();
            //          sb.AppendFormat("{0} FATs", ntfs_bb.fats_no).AppendLine();
            //          sb.AppendFormat("{0} entries in the root folder", ntfs_bb.root_ent).AppendLine();
            //          sb.AppendFormat("{0} sectors on volume (small)", ntfs_bb.sml_sectors).AppendLine();
            sb.AppendFormat("Media descriptor: 0x{0:X2}", ntfsBb.media).AppendLine();
            //          sb.AppendFormat("{0} sectors per FAT", ntfs_bb.spfat).AppendLine();
            sb.AppendFormat("{0} sectors per track", ntfsBb.sptrk).AppendLine();
            sb.AppendFormat("{0} heads", ntfsBb.heads).AppendLine();
            sb.AppendFormat("{0} hidden sectors before filesystem", ntfsBb.hsectors).AppendLine();
            //          sb.AppendFormat("{0} sectors on volume (big)", ntfs_bb.big_sectors).AppendLine();
            sb.AppendFormat("BIOS drive number: 0x{0:X2}", ntfsBb.drive_no).AppendLine();
            //          sb.AppendFormat("NT flags: 0x{0:X2}", ntfs_bb.nt_flags).AppendLine();
            //          sb.AppendFormat("Signature 1: 0x{0:X2}", ntfs_bb.signature1).AppendLine();
            sb.AppendFormat("{0} sectors on volume ({1} bytes)", ntfsBb.sectors, ntfsBb.sectors * ntfsBb.bps)
            .AppendLine();
            sb.AppendFormat("Cluster where $MFT starts: {0}", ntfsBb.mft_lsn).AppendLine();
            sb.AppendFormat("Cluster where $MFTMirr starts: {0}", ntfsBb.mftmirror_lsn).AppendLine();

            if (ntfsBb.mft_rc_clusters > 0)
            {
                sb.AppendFormat("{0} clusters per MFT record ({1} bytes)", ntfsBb.mft_rc_clusters,
                                ntfsBb.mft_rc_clusters * ntfsBb.bps * ntfsBb.spc).AppendLine();
            }
            else
            {
                sb.AppendFormat("{0} bytes per MFT record", 1 << -ntfsBb.mft_rc_clusters).AppendLine();
            }
            if (ntfsBb.index_blk_cts > 0)
            {
                sb.AppendFormat("{0} clusters per Index block ({1} bytes)", ntfsBb.index_blk_cts,
                                ntfsBb.index_blk_cts * ntfsBb.bps * ntfsBb.spc).AppendLine();
            }
            else
            {
                sb.AppendFormat("{0} bytes per Index block", 1 << -ntfsBb.index_blk_cts).AppendLine();
            }

            sb.AppendFormat("Volume serial number: {0:X16}", ntfsBb.serial_no).AppendLine();
            //          sb.AppendFormat("Signature 2: 0x{0:X4}", ntfs_bb.signature2).AppendLine();

            XmlFsType = new FileSystemType();

            if (ntfsBb.jump[0] == 0xEB && ntfsBb.jump[1] > 0x4E && ntfsBb.jump[1] < 0x80 && ntfsBb.signature2 == 0xAA55)
            {
                XmlFsType.Bootable = true;
                string bootChk = Sha1Context.Data(ntfsBb.boot_code, out _);
                sb.AppendLine("Volume is bootable");
                sb.AppendFormat("Boot code's SHA1: {0}", bootChk).AppendLine();
            }

            XmlFsType.ClusterSize  = (uint)(ntfsBb.spc * ntfsBb.bps);
            XmlFsType.Clusters     = (ulong)(ntfsBb.sectors / ntfsBb.spc);
            XmlFsType.VolumeSerial = $"{ntfsBb.serial_no:X16}";
            XmlFsType.Type         = "NTFS";

            information = sb.ToString();
        }
Example #33
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            // Technically everything on Plan 9 from Bell Labs is in UTF-8
            Encoding    = Encoding.UTF8;
            information = "";

            if (imagePlugin.Info.SectorSize < 512)
            {
                return;
            }

            ulong hdrSector = HEADER_POS / imagePlugin.Info.SectorSize;

            byte[] sector = imagePlugin.ReadSector(partition.Start + hdrSector);
            Header hdr    = Marshal.ByteArrayToStructureBigEndian <Header>(sector);

            AaruConsole.DebugWriteLine("Fossil plugin", "magic at 0x{0:X8} (expected 0x{1:X8})", hdr.magic,
                                       FOSSIL_HDR_MAGIC);

            var sb = new StringBuilder();

            sb.AppendLine("Fossil");
            sb.AppendFormat("Filesystem version {0}", hdr.version).AppendLine();
            sb.AppendFormat("{0} bytes per block", hdr.blockSize).AppendLine();
            sb.AppendFormat("Superblock resides in block {0}", hdr.super).AppendLine();
            sb.AppendFormat("Labels resides in block {0}", hdr.label).AppendLine();
            sb.AppendFormat("Data starts at block {0}", hdr.data).AppendLine();
            sb.AppendFormat("Volume has {0} blocks", hdr.end).AppendLine();

            ulong sbLocation = (hdr.super * (hdr.blockSize / imagePlugin.Info.SectorSize)) + partition.Start;

            XmlFsType = new FileSystemType
            {
                Type        = "Fossil filesystem",
                ClusterSize = hdr.blockSize,
                Clusters    = hdr.end
            };

            if (sbLocation <= partition.End)
            {
                sector = imagePlugin.ReadSector(sbLocation);
                SuperBlock fsb = Marshal.ByteArrayToStructureBigEndian <SuperBlock>(sector);

                AaruConsole.DebugWriteLine("Fossil plugin", "magic 0x{0:X8} (expected 0x{1:X8})", fsb.magic,
                                           FOSSIL_SB_MAGIC);

                if (fsb.magic == FOSSIL_SB_MAGIC)
                {
                    sb.AppendFormat("Epoch low {0}", fsb.epochLow).AppendLine();
                    sb.AppendFormat("Epoch high {0}", fsb.epochHigh).AppendLine();
                    sb.AppendFormat("Next QID {0}", fsb.qid).AppendLine();
                    sb.AppendFormat("Active root block {0}", fsb.active).AppendLine();
                    sb.AppendFormat("Next root block {0}", fsb.next).AppendLine();
                    sb.AppendFormat("Current root block {0}", fsb.current).AppendLine();
                    sb.AppendFormat("Volume label: \"{0}\"", StringHandlers.CToString(fsb.name, Encoding)).AppendLine();
                    XmlFsType.VolumeName = StringHandlers.CToString(fsb.name, Encoding);
                }
            }

            information = sb.ToString();
        }
Example #34
0
        /// <summary>
        ///     Traverses all known filesystems and outputs a list of all that recognized what is in the specified image and
        ///     partition
        /// </summary>
        /// <param name="imagePlugin">Media image</param>
        /// <param name="idPlugins">List of plugins recognizing the filesystem</param>
        /// <param name="partition">Partition</param>
        public static void Identify(IMediaImage imagePlugin, out List <string> idPlugins, Partition partition)
        {
            PluginBase plugins = GetPluginBase.Instance;

            idPlugins = (from plugin in plugins.PluginsList.Values
                         where plugin.Identify(imagePlugin, partition)
                         select plugin.Name.ToLower()).ToList();
        }
Example #35
0
        private static void InitAta(Ata.ControllerIdEnum aControllerID,
                                    Ata.BusPositionEnum aBusPosition)
        {
            var xIO = aControllerID == Ata.ControllerIdEnum.Primary
          ? Core.Global.BaseIOGroups.ATA1
          : Core.Global.BaseIOGroups.ATA2;
            var xATA = new AtaPio(xIO, aControllerID, aBusPosition);

            if (xATA.DriveType == AtaPio.SpecLevel.Null)
            {
                return;
            }
            if (xATA.DriveType == AtaPio.SpecLevel.ATA)
            {
                BlockDevice.BlockDevice.Devices.Add(xATA);
                Ata.AtaDebugger.Send("ATA device with speclevel ATA found.");
            }
            else
            {
                //Ata.AtaDebugger.Send("ATA device with spec level " + (int)xATA.DriveType +
                //                     " found, which is not supported!");
                return;
            }
            var xMbrData = new byte[512];

            xATA.ReadBlock(0UL, 1U, xMbrData);
            var xMBR = new MBR(xMbrData);

            if (xMBR.EBRLocation != 0)
            {
                //EBR Detected
                var xEbrData = new byte[512];
                xATA.ReadBlock(xMBR.EBRLocation, 1U, xEbrData);
                var xEBR = new EBR(xEbrData);

                for (int i = 0; i < xEBR.Partitions.Count; i++)
                {
                    //var xPart = xEBR.Partitions[i];
                    //var xPartDevice = new BlockDevice.Partition(xATA, xPart.StartSector, xPart.SectorCount);
                    //BlockDevice.BlockDevice.Devices.Add(xPartDevice);
                }
            }

            // TODO Change this to foreach when foreach is supported
            Ata.AtaDebugger.Send("Number of MBR partitions found:");
            Ata.AtaDebugger.SendNumber(xMBR.Partitions.Count);
            for (int i = 0; i < xMBR.Partitions.Count; i++)
            {
                var xPart = xMBR.Partitions[i];
                if (xPart == null)
                {
                    Console.WriteLine("Null partition found at idx: " + i);
                }
                else
                {
                    var xPartDevice = new Partition(xATA, xPart.StartSector, xPart.SectorCount);
                    BlockDevice.BlockDevice.Devices.Add(xPartDevice);
                    Console.WriteLine("Found partition at idx" + i);
                }
            }
        }
Example #36
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("iso-8859-15");
            information = "";

            if (imagePlugin.Info.SectorSize < 512)
            {
                return;
            }

            uint sbAddr = REISER_SUPER_OFFSET / imagePlugin.Info.SectorSize;

            if (sbAddr == 0)
            {
                sbAddr = 1;
            }

            uint sbSize = (uint)(Marshal.SizeOf <Superblock>() / imagePlugin.Info.SectorSize);

            if (Marshal.SizeOf <Superblock>() % imagePlugin.Info.SectorSize != 0)
            {
                sbSize++;
            }

            byte[] sector = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize);

            if (sector.Length < Marshal.SizeOf <Superblock>())
            {
                return;
            }

            Superblock reiserSb = Marshal.ByteArrayToStructureLittleEndian <Superblock>(sector);

            if (!_magic35.SequenceEqual(reiserSb.magic) &&
                !_magic36.SequenceEqual(reiserSb.magic) &&
                !_magicJr.SequenceEqual(reiserSb.magic))
            {
                return;
            }

            var sb = new StringBuilder();

            if (_magic35.SequenceEqual(reiserSb.magic))
            {
                sb.AppendLine("Reiser 3.5 filesystem");
            }
            else if (_magic36.SequenceEqual(reiserSb.magic))
            {
                sb.AppendLine("Reiser 3.6 filesystem");
            }
            else if (_magicJr.SequenceEqual(reiserSb.magic))
            {
                sb.AppendLine("Reiser Jr. filesystem");
            }

            sb.AppendFormat("Volume has {0} blocks with {1} blocks free", reiserSb.block_count, reiserSb.free_blocks).
            AppendLine();

            sb.AppendFormat("{0} bytes per block", reiserSb.blocksize).AppendLine();
            sb.AppendFormat("Root directory resides on block {0}", reiserSb.root_block).AppendLine();

            if (reiserSb.umount_state == 2)
            {
                sb.AppendLine("Volume has not been cleanly umounted");
            }

            sb.AppendFormat("Volume last checked on {0}", DateHandlers.UnixUnsignedToDateTime(reiserSb.last_check)).
            AppendLine();

            if (reiserSb.version >= 2)
            {
                sb.AppendFormat("Volume UUID: {0}", reiserSb.uuid).AppendLine();
                sb.AppendFormat("Volume name: {0}", Encoding.GetString(reiserSb.label)).AppendLine();
            }

            information = sb.ToString();

            XmlFsType = new FileSystemType();

            if (_magic35.SequenceEqual(reiserSb.magic))
            {
                XmlFsType.Type = "Reiser 3.5 filesystem";
            }
            else if (_magic36.SequenceEqual(reiserSb.magic))
            {
                XmlFsType.Type = "Reiser 3.6 filesystem";
            }
            else if (_magicJr.SequenceEqual(reiserSb.magic))
            {
                XmlFsType.Type = "Reiser Jr. filesystem";
            }

            XmlFsType.ClusterSize           = reiserSb.blocksize;
            XmlFsType.Clusters              = reiserSb.block_count;
            XmlFsType.FreeClusters          = reiserSb.free_blocks;
            XmlFsType.FreeClustersSpecified = true;
            XmlFsType.Dirty = reiserSb.umount_state == 2;

            if (reiserSb.version < 2)
            {
                return;
            }

            XmlFsType.VolumeName   = StringHandlers.CToString(reiserSb.label, Encoding);
            XmlFsType.VolumeSerial = reiserSb.uuid.ToString();
        }
        protected void OnMenuOpen(object sender, EventArgs e)
        {
            // TODO: Extensions
            var dlgOpenImage = new OpenFileDialog
            {
                Title = "Choose image to open"
            };

            DialogResult result = dlgOpenImage.ShowDialog(this);

            if(result != DialogResult.Ok)
                return;

            var     filtersList = new FiltersList();
            IFilter inputFilter = filtersList.GetFilter(dlgOpenImage.FileName);

            if(inputFilter == null)
            {
                MessageBox.Show("Cannot open specified file.", MessageBoxType.Error);

                return;
            }

            try
            {
                IMediaImage imageFormat = ImageFormat.Detect(inputFilter);

                if(imageFormat == null)
                {
                    MessageBox.Show("Image format not identified.", MessageBoxType.Error);

                    return;
                }

                DicConsole.WriteLine("Image format identified by {0} ({1}).", imageFormat.Name, imageFormat.Id);

                try
                {
                    if(!imageFormat.Open(inputFilter))
                    {
                        MessageBox.Show("Unable to open image format", MessageBoxType.Error);
                        DicConsole.ErrorWriteLine("Unable to open image format");
                        DicConsole.ErrorWriteLine("No error given");

                        return;
                    }

                    // TODO: SVG
                    Stream logo =
                        ResourceHandler.
                            GetResourceStream($"DiscImageChef.Gui.Assets.Logos.Media.{imageFormat.Info.MediaType}.png");

                    var imageGridItem = new TreeGridItem
                    {
                        Values = new object[]
                        {
                            logo == null ? null : new Bitmap(logo),
                            $"{Path.GetFileName(dlgOpenImage.FileName)} ({imageFormat.Info.MediaType})",
                            dlgOpenImage.FileName, new pnlImageInfo(dlgOpenImage.FileName, inputFilter, imageFormat),
                            inputFilter, imageFormat
                        }
                    };

                    List<Partition> partitions = Core.Partitions.GetAll(imageFormat);
                    Core.Partitions.AddSchemesToStats(partitions);

                    bool         checkraw = false;
                    List<string> idPlugins;
                    IFilesystem  plugin;
                    PluginBase   plugins = GetPluginBase.Instance;

                    if(partitions.Count == 0)
                    {
                        DicConsole.DebugWriteLine("Analyze command", "No partitions found");

                        checkraw = true;
                    }
                    else
                    {
                        DicConsole.WriteLine("{0} partitions found.", partitions.Count);

                        foreach(string scheme in partitions.Select(p => p.Scheme).Distinct().OrderBy(s => s))
                        {
                            var schemeGridItem = new TreeGridItem
                            {
                                Values = new object[]
                                {
                                    nullImage, // TODO: Add icons to partition schemes
                                    scheme
                                }
                            };

                            foreach(Partition partition in partitions.
                                                           Where(p => p.Scheme == scheme).OrderBy(p => p.Start))
                            {
                                var partitionGridItem = new TreeGridItem
                                {
                                    Values = new object[]
                                    {
                                        nullImage, // TODO: Add icons to partition schemes
                                        $"{partition.Name} ({partition.Type})", null, new pnlPartition(partition)
                                    }
                                };

                                DicConsole.WriteLine("Identifying filesystem on partition");

                                Core.Filesystems.Identify(imageFormat, out idPlugins, partition);

                                if(idPlugins.Count == 0)
                                    DicConsole.WriteLine("Filesystem not identified");
                                else
                                {
                                    DicConsole.WriteLine($"Identified by {idPlugins.Count} plugins");

                                    foreach(string pluginName in idPlugins)
                                        if(plugins.PluginsList.TryGetValue(pluginName, out plugin))
                                        {
                                            plugin.GetInformation(imageFormat, partition, out string information, null);

                                            var fsPlugin = plugin as IReadOnlyFilesystem;

                                            if(fsPlugin != null)
                                            {
                                                Errno error =
                                                    fsPlugin.Mount(imageFormat, partition, null,
                                                                   new Dictionary<string, string>(), null);

                                                if(error != Errno.NoError)
                                                    fsPlugin = null;
                                            }

                                            var filesystemGridItem = new TreeGridItem
                                            {
                                                Values = new object[]
                                                {
                                                    nullImage, // TODO: Add icons to filesystems
                                                    plugin.XmlFsType.VolumeName is null ? $"{plugin.XmlFsType.Type}"
                                                        : $"{plugin.XmlFsType.VolumeName} ({plugin.XmlFsType.Type})",
                                                    fsPlugin, new pnlFilesystem(plugin.XmlFsType, information)
                                                }
                                            };

                                            if(fsPlugin != null)
                                            {
                                                Statistics.AddCommand("ls");
                                                filesystemGridItem.Children.Add(placeholderItem);
                                            }

                                            Statistics.AddFilesystem(plugin.XmlFsType.Type);
                                            partitionGridItem.Children.Add(filesystemGridItem);
                                        }
                                }

                                schemeGridItem.Children.Add(partitionGridItem);
                            }

                            imageGridItem.Children.Add(schemeGridItem);
                        }
                    }

                    if(checkraw)
                    {
                        var wholePart = new Partition
                        {
                            Name = "Whole device", Length = imageFormat.Info.Sectors,
                            Size = imageFormat.Info.Sectors * imageFormat.Info.SectorSize
                        };

                        Core.Filesystems.Identify(imageFormat, out idPlugins, wholePart);

                        if(idPlugins.Count == 0)
                            DicConsole.WriteLine("Filesystem not identified");
                        else
                        {
                            DicConsole.WriteLine($"Identified by {idPlugins.Count} plugins");

                            foreach(string pluginName in idPlugins)
                                if(plugins.PluginsList.TryGetValue(pluginName, out plugin))
                                {
                                    plugin.GetInformation(imageFormat, wholePart, out string information, null);

                                    var fsPlugin = plugin as IReadOnlyFilesystem;

                                    if(fsPlugin != null)
                                    {
                                        Errno error = fsPlugin.Mount(imageFormat, wholePart, null,
                                                                     new Dictionary<string, string>(), null);

                                        if(error != Errno.NoError)
                                            fsPlugin = null;
                                    }

                                    var filesystemGridItem = new TreeGridItem
                                    {
                                        Values = new object[]
                                        {
                                            nullImage, // TODO: Add icons to filesystems
                                            plugin.XmlFsType.VolumeName is null ? $"{plugin.XmlFsType.Type}"
                                                : $"{plugin.XmlFsType.VolumeName} ({plugin.XmlFsType.Type})",
                                            fsPlugin, new pnlFilesystem(plugin.XmlFsType, information)
                                        }
                                    };

                                    if(fsPlugin != null)
                                    {
                                        Statistics.AddCommand("ls");
                                        filesystemGridItem.Children.Add(placeholderItem);
                                    }

                                    Statistics.AddFilesystem(plugin.XmlFsType.Type);
                                    imageGridItem.Children.Add(filesystemGridItem);
                                }
                        }
                    }

                    imagesRoot.Children.Add(imageGridItem);
                    treeImages.ReloadData();

                    Statistics.AddMediaFormat(imageFormat.Format);
                    Statistics.AddMedia(imageFormat.Info.MediaType, false);
                    Statistics.AddFilter(inputFilter.Name);
                }
Example #38
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("iso-8859-15");
            information = "";
            StringBuilder sbInformation = new StringBuilder();

            uint magic = 0;
            uint sb_size_in_sectors;

            byte[] ufs_sb_sectors;
            ulong  sb_offset     = partition.Start;
            bool   fs_type_42bsd = false;
            bool   fs_type_43bsd = false;
            bool   fs_type_44bsd = false;
            bool   fs_type_ufs   = false;
            bool   fs_type_ufs2  = false;
            bool   fs_type_sun   = false;
            bool   fs_type_sun86 = false;

            if (imagePlugin.Info.SectorSize == 2336 || imagePlugin.Info.SectorSize == 2352 ||
                imagePlugin.Info.SectorSize == 2448)
            {
                sb_size_in_sectors = block_size / 2048;
            }
            else
            {
                sb_size_in_sectors = block_size / imagePlugin.Info.SectorSize;
            }

            ulong[] locations =
            {
                sb_start_floppy,                    sb_start_boot,                       sb_start_long_boot, sb_start_piggy, sb_start_att_dsdd,
                8192 / imagePlugin.Info.SectorSize, 65536 / imagePlugin.Info.SectorSize,
                262144 / imagePlugin.Info.SectorSize
            };

            foreach (ulong loc in locations.Where(loc => partition.End > partition.Start + loc + sb_size_in_sectors))
            {
                ufs_sb_sectors = imagePlugin.ReadSectors(partition.Start + loc, sb_size_in_sectors);
                magic          = BitConverter.ToUInt32(ufs_sb_sectors, 0x055C);

                if (magic == UFS_MAGIC || magic == UFS_CIGAM || magic == UFS_MAGIC_BW || magic == UFS_CIGAM_BW ||
                    magic == UFS2_MAGIC || magic == UFS2_CIGAM || magic == UFS_BAD_MAGIC || magic == UFS_BAD_CIGAM)
                {
                    sb_offset = partition.Start + loc;
                    break;
                }

                magic = 0;
            }

            if (magic == 0)
            {
                information = "Not a UFS filesystem, I shouldn't have arrived here!";
                return;
            }

            XmlFsType = new FileSystemType();

            switch (magic)
            {
            case UFS_MAGIC:
                sbInformation.AppendLine("UFS filesystem");
                XmlFsType.Type = "UFS";
                break;

            case UFS_CIGAM:
                sbInformation.AppendLine("Big-endian UFS filesystem");
                XmlFsType.Type = "UFS";
                break;

            case UFS_MAGIC_BW:
                sbInformation.AppendLine("BorderWare UFS filesystem");
                XmlFsType.Type = "UFS";
                break;

            case UFS_CIGAM_BW:
                sbInformation.AppendLine("Big-endian BorderWare UFS filesystem");
                XmlFsType.Type = "UFS";
                break;

            case UFS2_MAGIC:
                sbInformation.AppendLine("UFS2 filesystem");
                XmlFsType.Type = "UFS2";
                break;

            case UFS2_CIGAM:
                sbInformation.AppendLine("Big-endian UFS2 filesystem");
                XmlFsType.Type = "UFS2";
                break;

            case UFS_BAD_MAGIC:
                sbInformation.AppendLine("Incompletely initialized UFS filesystem");
                sbInformation.AppendLine("BEWARE!!! Following information may be completely wrong!");
                XmlFsType.Type = "UFS";
                break;

            case UFS_BAD_CIGAM:
                sbInformation.AppendLine("Incompletely initialized big-endian UFS filesystem");
                sbInformation.AppendLine("BEWARE!!! Following information may be completely wrong!");
                XmlFsType.Type = "UFS";
                break;
            }

            // Fun with seeking follows on superblock reading!
            ufs_sb_sectors = imagePlugin.ReadSectors(sb_offset, sb_size_in_sectors);

            UFSSuperBlock ufs_sb = Marshal.ByteArrayToStructureLittleEndian <UFSSuperBlock>(ufs_sb_sectors);

            UFSSuperBlock bs_sfu = Marshal.ByteArrayToStructureBigEndian <UFSSuperBlock>(ufs_sb_sectors);

            if (bs_sfu.fs_magic == UFS_MAGIC && ufs_sb.fs_magic == UFS_CIGAM ||
                bs_sfu.fs_magic == UFS_MAGIC_BW && ufs_sb.fs_magic == UFS_CIGAM_BW ||
                bs_sfu.fs_magic == UFS2_MAGIC && ufs_sb.fs_magic == UFS2_CIGAM ||
                bs_sfu.fs_magic == UFS_BAD_MAGIC && ufs_sb.fs_magic == UFS_BAD_CIGAM)
            {
                ufs_sb = bs_sfu;
                ufs_sb.fs_old_cstotal.cs_nbfree  = Swapping.Swap(ufs_sb.fs_old_cstotal.cs_nbfree);
                ufs_sb.fs_old_cstotal.cs_ndir    = Swapping.Swap(ufs_sb.fs_old_cstotal.cs_ndir);
                ufs_sb.fs_old_cstotal.cs_nffree  = Swapping.Swap(ufs_sb.fs_old_cstotal.cs_nffree);
                ufs_sb.fs_old_cstotal.cs_nifree  = Swapping.Swap(ufs_sb.fs_old_cstotal.cs_nifree);
                ufs_sb.fs_cstotal.cs_numclusters = Swapping.Swap(ufs_sb.fs_cstotal.cs_numclusters);
                ufs_sb.fs_cstotal.cs_nbfree      = Swapping.Swap(ufs_sb.fs_cstotal.cs_nbfree);
                ufs_sb.fs_cstotal.cs_ndir        = Swapping.Swap(ufs_sb.fs_cstotal.cs_ndir);
                ufs_sb.fs_cstotal.cs_nffree      = Swapping.Swap(ufs_sb.fs_cstotal.cs_nffree);
                ufs_sb.fs_cstotal.cs_nifree      = Swapping.Swap(ufs_sb.fs_cstotal.cs_nifree);
                ufs_sb.fs_cstotal.cs_spare[0]    = Swapping.Swap(ufs_sb.fs_cstotal.cs_spare[0]);
                ufs_sb.fs_cstotal.cs_spare[1]    = Swapping.Swap(ufs_sb.fs_cstotal.cs_spare[1]);
                ufs_sb.fs_cstotal.cs_spare[2]    = Swapping.Swap(ufs_sb.fs_cstotal.cs_spare[2]);
            }

            DicConsole.DebugWriteLine("FFS plugin", "ufs_sb offset: 0x{0:X8}", sb_offset);
            DicConsole.DebugWriteLine("FFS plugin", "fs_rlink: 0x{0:X8}", ufs_sb.fs_rlink);
            DicConsole.DebugWriteLine("FFS plugin", "fs_sblkno: 0x{0:X8}", ufs_sb.fs_sblkno);
            DicConsole.DebugWriteLine("FFS plugin", "fs_cblkno: 0x{0:X8}", ufs_sb.fs_cblkno);
            DicConsole.DebugWriteLine("FFS plugin", "fs_iblkno: 0x{0:X8}", ufs_sb.fs_iblkno);
            DicConsole.DebugWriteLine("FFS plugin", "fs_dblkno: 0x{0:X8}", ufs_sb.fs_dblkno);
            DicConsole.DebugWriteLine("FFS plugin", "fs_size: 0x{0:X8}", ufs_sb.fs_size);
            DicConsole.DebugWriteLine("FFS plugin", "fs_dsize: 0x{0:X8}", ufs_sb.fs_dsize);
            DicConsole.DebugWriteLine("FFS plugin", "fs_ncg: 0x{0:X8}", ufs_sb.fs_ncg);
            DicConsole.DebugWriteLine("FFS plugin", "fs_bsize: 0x{0:X8}", ufs_sb.fs_bsize);
            DicConsole.DebugWriteLine("FFS plugin", "fs_fsize: 0x{0:X8}", ufs_sb.fs_fsize);
            DicConsole.DebugWriteLine("FFS plugin", "fs_frag: 0x{0:X8}", ufs_sb.fs_frag);
            DicConsole.DebugWriteLine("FFS plugin", "fs_minfree: 0x{0:X8}", ufs_sb.fs_minfree);
            DicConsole.DebugWriteLine("FFS plugin", "fs_bmask: 0x{0:X8}", ufs_sb.fs_bmask);
            DicConsole.DebugWriteLine("FFS plugin", "fs_fmask: 0x{0:X8}", ufs_sb.fs_fmask);
            DicConsole.DebugWriteLine("FFS plugin", "fs_bshift: 0x{0:X8}", ufs_sb.fs_bshift);
            DicConsole.DebugWriteLine("FFS plugin", "fs_fshift: 0x{0:X8}", ufs_sb.fs_fshift);
            DicConsole.DebugWriteLine("FFS plugin", "fs_maxcontig: 0x{0:X8}", ufs_sb.fs_maxcontig);
            DicConsole.DebugWriteLine("FFS plugin", "fs_maxbpg: 0x{0:X8}", ufs_sb.fs_maxbpg);
            DicConsole.DebugWriteLine("FFS plugin", "fs_fragshift: 0x{0:X8}", ufs_sb.fs_fragshift);
            DicConsole.DebugWriteLine("FFS plugin", "fs_fsbtodb: 0x{0:X8}", ufs_sb.fs_fsbtodb);
            DicConsole.DebugWriteLine("FFS plugin", "fs_sbsize: 0x{0:X8}", ufs_sb.fs_sbsize);
            DicConsole.DebugWriteLine("FFS plugin", "fs_csmask: 0x{0:X8}", ufs_sb.fs_csmask);
            DicConsole.DebugWriteLine("FFS plugin", "fs_csshift: 0x{0:X8}", ufs_sb.fs_csshift);
            DicConsole.DebugWriteLine("FFS plugin", "fs_nindir: 0x{0:X8}", ufs_sb.fs_nindir);
            DicConsole.DebugWriteLine("FFS plugin", "fs_inopb: 0x{0:X8}", ufs_sb.fs_inopb);
            DicConsole.DebugWriteLine("FFS plugin", "fs_optim: 0x{0:X8}", ufs_sb.fs_optim);
            DicConsole.DebugWriteLine("FFS plugin", "fs_id_1: 0x{0:X8}", ufs_sb.fs_id_1);
            DicConsole.DebugWriteLine("FFS plugin", "fs_id_2: 0x{0:X8}", ufs_sb.fs_id_2);
            DicConsole.DebugWriteLine("FFS plugin", "fs_csaddr: 0x{0:X8}", ufs_sb.fs_csaddr);
            DicConsole.DebugWriteLine("FFS plugin", "fs_cssize: 0x{0:X8}", ufs_sb.fs_cssize);
            DicConsole.DebugWriteLine("FFS plugin", "fs_cgsize: 0x{0:X8}", ufs_sb.fs_cgsize);
            DicConsole.DebugWriteLine("FFS plugin", "fs_ipg: 0x{0:X8}", ufs_sb.fs_ipg);
            DicConsole.DebugWriteLine("FFS plugin", "fs_fpg: 0x{0:X8}", ufs_sb.fs_fpg);
            DicConsole.DebugWriteLine("FFS plugin", "fs_fmod: 0x{0:X2}", ufs_sb.fs_fmod);
            DicConsole.DebugWriteLine("FFS plugin", "fs_clean: 0x{0:X2}", ufs_sb.fs_clean);
            DicConsole.DebugWriteLine("FFS plugin", "fs_ronly: 0x{0:X2}", ufs_sb.fs_ronly);
            DicConsole.DebugWriteLine("FFS plugin", "fs_flags: 0x{0:X2}", ufs_sb.fs_flags);
            DicConsole.DebugWriteLine("FFS plugin", "fs_magic: 0x{0:X8}", ufs_sb.fs_magic);

            if (ufs_sb.fs_magic == UFS2_MAGIC)
            {
                fs_type_ufs2 = true;
            }
            else
            {
                const uint
                    SunOSEpoch =
                    0x1A54C580;     // We are supposing there cannot be a Sun's fs created before 1/1/1982 00:00:00

                fs_type_43bsd =
                    true; // There is no way of knowing this is the version, but there is of knowing it is not.

                if (ufs_sb.fs_link > 0)
                {
                    fs_type_42bsd = true; // It was used in 4.2BSD
                    fs_type_43bsd = false;
                }

                if ((ufs_sb.fs_maxfilesize & 0xFFFFFFFF) > SunOSEpoch &&
                    DateHandlers.UnixUnsignedToDateTime(ufs_sb.fs_maxfilesize & 0xFFFFFFFF) < DateTime.Now)
                {
                    fs_type_42bsd = false;
                    fs_type_sun   = true;
                    fs_type_43bsd = false;
                }

                // This is for sure, as it is shared with a sectors/track with non-x86 SunOS, Epoch is absurdly high for that
                if (ufs_sb.fs_old_npsect > SunOSEpoch &&
                    DateHandlers.UnixToDateTime(ufs_sb.fs_old_npsect) < DateTime.Now)
                {
                    fs_type_42bsd = false;
                    fs_type_sun86 = true;
                    fs_type_sun   = false;
                    fs_type_43bsd = false;
                }

                if (ufs_sb.fs_cgrotor > 0x00000000 && (uint)ufs_sb.fs_cgrotor < 0xFFFFFFFF)
                {
                    fs_type_42bsd = false;
                    fs_type_sun   = false;
                    fs_type_sun86 = false;
                    fs_type_ufs   = true;
                    fs_type_43bsd = false;
                }

                // 4.3BSD code does not use these fields, they are always set up to 0
                fs_type_43bsd &= ufs_sb.fs_id_2 == 0 && ufs_sb.fs_id_1 == 0;

                // This is the only 4.4BSD inode format
                fs_type_44bsd |= ufs_sb.fs_old_inodefmt == 2;
            }

            if (!fs_type_ufs2)
            {
                sbInformation.AppendLine("There are a lot of variants of UFS using overlapped values on same fields");
                sbInformation
                .AppendLine("I will try to guess which one it is, but unless it's UFS2, I may be surely wrong");
            }

            if (fs_type_42bsd)
            {
                sbInformation.AppendLine("Guessed as 42BSD FFS");
            }
            if (fs_type_43bsd)
            {
                sbInformation.AppendLine("Guessed as 43BSD FFS");
            }
            if (fs_type_44bsd)
            {
                sbInformation.AppendLine("Guessed as 44BSD FFS");
            }
            if (fs_type_sun)
            {
                sbInformation.AppendLine("Guessed as SunOS FFS");
            }
            if (fs_type_sun86)
            {
                sbInformation.AppendLine("Guessed as SunOS/x86 FFS");
            }
            if (fs_type_ufs)
            {
                sbInformation.AppendLine("Guessed as UFS");
            }

            if (fs_type_42bsd)
            {
                sbInformation.AppendFormat("Linked list of filesystems: 0x{0:X8}", ufs_sb.fs_link).AppendLine();
            }
            sbInformation.AppendFormat("Superblock LBA: {0}", ufs_sb.fs_sblkno).AppendLine();
            sbInformation.AppendFormat("Cylinder-block LBA: {0}", ufs_sb.fs_cblkno).AppendLine();
            sbInformation.AppendFormat("inode-block LBA: {0}", ufs_sb.fs_iblkno).AppendLine();
            sbInformation.AppendFormat("First data block LBA: {0}", ufs_sb.fs_dblkno).AppendLine();
            sbInformation.AppendFormat("Cylinder group offset in cylinder: {0}", ufs_sb.fs_old_cgoffset).AppendLine();
            sbInformation.AppendFormat("Volume last written on {0}", DateHandlers.UnixToDateTime(ufs_sb.fs_old_time))
            .AppendLine();
            XmlFsType.ModificationDate          = DateHandlers.UnixToDateTime(ufs_sb.fs_old_time);
            XmlFsType.ModificationDateSpecified = true;
            sbInformation.AppendFormat("{0} blocks in volume ({1} bytes)", ufs_sb.fs_old_size,
                                       (long)ufs_sb.fs_old_size * ufs_sb.fs_fsize).AppendLine();
            XmlFsType.Clusters    = (ulong)ufs_sb.fs_old_size;
            XmlFsType.ClusterSize = (uint)ufs_sb.fs_fsize;
            sbInformation.AppendFormat("{0} data blocks in volume ({1} bytes)", ufs_sb.fs_old_dsize,
                                       (long)ufs_sb.fs_old_dsize * ufs_sb.fs_fsize).AppendLine();
            sbInformation.AppendFormat("{0} cylinder groups in volume", ufs_sb.fs_ncg).AppendLine();
            sbInformation.AppendFormat("{0} bytes in a basic block", ufs_sb.fs_bsize).AppendLine();
            sbInformation.AppendFormat("{0} bytes in a frag block", ufs_sb.fs_fsize).AppendLine();
            sbInformation.AppendFormat("{0} frags in a block", ufs_sb.fs_frag).AppendLine();
            sbInformation.AppendFormat("{0}% of blocks must be free", ufs_sb.fs_minfree).AppendLine();
            sbInformation.AppendFormat("{0}ms for optimal next block", ufs_sb.fs_old_rotdelay).AppendLine();
            sbInformation.AppendFormat("disk rotates {0} times per second ({1}rpm)", ufs_sb.fs_old_rps,
                                       ufs_sb.fs_old_rps * 60).AppendLine();

            /*          sbInformation.AppendFormat("fs_bmask: 0x{0:X8}", ufs_sb.fs_bmask).AppendLine();
             *          sbInformation.AppendFormat("fs_fmask: 0x{0:X8}", ufs_sb.fs_fmask).AppendLine();
             *          sbInformation.AppendFormat("fs_bshift: 0x{0:X8}", ufs_sb.fs_bshift).AppendLine();
             *          sbInformation.AppendFormat("fs_fshift: 0x{0:X8}", ufs_sb.fs_fshift).AppendLine();*/
            sbInformation.AppendFormat("{0} contiguous blocks at maximum", ufs_sb.fs_maxcontig).AppendLine();
            sbInformation.AppendFormat("{0} blocks per cylinder group at maximum", ufs_sb.fs_maxbpg).AppendLine();
            sbInformation.AppendFormat("Superblock is {0} bytes", ufs_sb.fs_sbsize).AppendLine();
            sbInformation.AppendFormat("NINDIR: 0x{0:X8}", ufs_sb.fs_nindir).AppendLine();
            sbInformation.AppendFormat("INOPB: 0x{0:X8}", ufs_sb.fs_inopb).AppendLine();
            sbInformation.AppendFormat("NSPF: 0x{0:X8}", ufs_sb.fs_old_nspf).AppendLine();
            switch (ufs_sb.fs_optim)
            {
            case 0:
                sbInformation.AppendLine("Filesystem will minimize allocation time");
                break;

            case 1:
                sbInformation.AppendLine("Filesystem will minimize volume fragmentation");
                break;

            default:
                sbInformation.AppendFormat("Unknown optimization value: 0x{0:X8}", ufs_sb.fs_optim).AppendLine();
                break;
            }

            if (fs_type_sun)
            {
                sbInformation.AppendFormat("{0} sectors/track", ufs_sb.fs_old_npsect).AppendLine();
            }
            else if (fs_type_sun86)
            {
                sbInformation.AppendFormat("Volume state on {0}", DateHandlers.UnixToDateTime(ufs_sb.fs_old_npsect))
                .AppendLine();
            }
            sbInformation.AppendFormat("Hardware sector interleave: {0}", ufs_sb.fs_old_interleave).AppendLine();
            sbInformation.AppendFormat("Sector 0 skew: {0}/track", ufs_sb.fs_old_trackskew).AppendLine();
            if (!fs_type_43bsd && ufs_sb.fs_id_1 > 0 && ufs_sb.fs_id_2 > 0)
            {
                sbInformation.AppendFormat("Volume ID: 0x{0:X8}{1:X8}", ufs_sb.fs_id_1, ufs_sb.fs_id_2).AppendLine();
            }
            else if (fs_type_43bsd && ufs_sb.fs_id_1 > 0 && ufs_sb.fs_id_2 > 0)
            {
                sbInformation.AppendFormat("{0} µsec for head switch", ufs_sb.fs_id_1).AppendLine();
                sbInformation.AppendFormat("{0} µsec for track-to-track seek", ufs_sb.fs_id_2).AppendLine();
            }

            sbInformation.AppendFormat("Cylinder group summary LBA: {0}", ufs_sb.fs_old_csaddr).AppendLine();
            sbInformation.AppendFormat("{0} bytes in cylinder group summary", ufs_sb.fs_cssize).AppendLine();
            sbInformation.AppendFormat("{0} bytes in cylinder group", ufs_sb.fs_cgsize).AppendLine();
            sbInformation.AppendFormat("{0} tracks/cylinder", ufs_sb.fs_old_ntrak).AppendLine();
            sbInformation.AppendFormat("{0} sectors/track", ufs_sb.fs_old_nsect).AppendLine();
            sbInformation.AppendFormat("{0} sectors/cylinder", ufs_sb.fs_old_spc).AppendLine();
            sbInformation.AppendFormat("{0} cylinder in volume", ufs_sb.fs_old_ncyl).AppendLine();
            sbInformation.AppendFormat("{0} cylinders/group", ufs_sb.fs_old_cpg).AppendLine();
            sbInformation.AppendFormat("{0} inodes per cylinder group", ufs_sb.fs_ipg).AppendLine();
            sbInformation.AppendFormat("{0} blocks per group", ufs_sb.fs_fpg / ufs_sb.fs_frag).AppendLine();
            sbInformation.AppendFormat("{0} directories", ufs_sb.fs_old_cstotal.cs_ndir).AppendLine();
            sbInformation.AppendFormat("{0} free blocks ({1} bytes)", ufs_sb.fs_old_cstotal.cs_nbfree,
                                       (long)ufs_sb.fs_old_cstotal.cs_nbfree * ufs_sb.fs_fsize).AppendLine();
            XmlFsType.FreeClusters          = (ulong)ufs_sb.fs_old_cstotal.cs_nbfree;
            XmlFsType.FreeClustersSpecified = true;
            sbInformation.AppendFormat("{0} free inodes", ufs_sb.fs_old_cstotal.cs_nifree).AppendLine();
            sbInformation.AppendFormat("{0} free frags", ufs_sb.fs_old_cstotal.cs_nffree).AppendLine();
            if (ufs_sb.fs_fmod == 1)
            {
                sbInformation.AppendLine("Superblock is under modification");
                XmlFsType.Dirty = true;
            }

            if (ufs_sb.fs_clean == 1)
            {
                sbInformation.AppendLine("Volume is clean");
            }
            if (ufs_sb.fs_ronly == 1)
            {
                sbInformation.AppendLine("Volume is read-only");
            }
            sbInformation.AppendFormat("Volume flags: 0x{0:X2}", ufs_sb.fs_flags).AppendLine();
            if (fs_type_ufs)
            {
                sbInformation.AppendFormat("Volume last mounted on \"{0}\"", StringHandlers.CToString(ufs_sb.fs_fsmnt))
                .AppendLine();
            }
            else if (fs_type_ufs2)
            {
                sbInformation.AppendFormat("Volume last mounted on \"{0}\"", StringHandlers.CToString(ufs_sb.fs_fsmnt))
                .AppendLine();
                sbInformation.AppendFormat("Volume name: \"{0}\"", StringHandlers.CToString(ufs_sb.fs_volname))
                .AppendLine();
                XmlFsType.VolumeName = StringHandlers.CToString(ufs_sb.fs_volname);
                sbInformation.AppendFormat("Volume ID: 0x{0:X16}", ufs_sb.fs_swuid).AppendLine();
                //xmlFSType.VolumeSerial = string.Format("{0:X16}", ufs_sb.fs_swuid);
                sbInformation.AppendFormat("Last searched cylinder group: {0}", ufs_sb.fs_cgrotor).AppendLine();
                sbInformation.AppendFormat("{0} contiguously allocated directories", ufs_sb.fs_contigdirs).AppendLine();
                sbInformation.AppendFormat("Standard superblock LBA: {0}", ufs_sb.fs_sblkno).AppendLine();
                sbInformation.AppendFormat("{0} directories", ufs_sb.fs_cstotal.cs_ndir).AppendLine();
                sbInformation.AppendFormat("{0} free blocks ({1} bytes)", ufs_sb.fs_cstotal.cs_nbfree,
                                           ufs_sb.fs_cstotal.cs_nbfree * ufs_sb.fs_fsize).AppendLine();
                XmlFsType.FreeClusters          = (ulong)ufs_sb.fs_cstotal.cs_nbfree;
                XmlFsType.FreeClustersSpecified = true;
                sbInformation.AppendFormat("{0} free inodes", ufs_sb.fs_cstotal.cs_nifree).AppendLine();
                sbInformation.AppendFormat("{0} free frags", ufs_sb.fs_cstotal.cs_nffree).AppendLine();
                sbInformation.AppendFormat("{0} free clusters", ufs_sb.fs_cstotal.cs_numclusters).AppendLine();
                sbInformation.AppendFormat("Volume last written on {0}", DateHandlers.UnixToDateTime(ufs_sb.fs_time))
                .AppendLine();
                XmlFsType.ModificationDate          = DateHandlers.UnixToDateTime(ufs_sb.fs_time);
                XmlFsType.ModificationDateSpecified = true;
                sbInformation.AppendFormat("{0} blocks ({1} bytes)", ufs_sb.fs_size, ufs_sb.fs_size * ufs_sb.fs_fsize)
                .AppendLine();
                XmlFsType.Clusters = (ulong)ufs_sb.fs_size;
                sbInformation
                .AppendFormat("{0} data blocks ({1} bytes)", ufs_sb.fs_dsize, ufs_sb.fs_dsize * ufs_sb.fs_fsize)
                .AppendLine();
                sbInformation.AppendFormat("Cylinder group summary area LBA: {0}", ufs_sb.fs_csaddr).AppendLine();
                sbInformation.AppendFormat("{0} blocks pending of being freed", ufs_sb.fs_pendingblocks).AppendLine();
                sbInformation.AppendFormat("{0} inodes pending of being freed", ufs_sb.fs_pendinginodes).AppendLine();
            }

            if (fs_type_sun)
            {
                sbInformation.AppendFormat("Volume state on {0}", DateHandlers.UnixToDateTime(ufs_sb.fs_old_npsect))
                .AppendLine();
            }
            else if (fs_type_sun86)
            {
                sbInformation.AppendFormat("{0} sectors/track", ufs_sb.fs_state).AppendLine();
            }
            else if (fs_type_44bsd)
            {
                sbInformation.AppendFormat("{0} blocks on cluster summary array", ufs_sb.fs_contigsumsize).AppendLine();
                sbInformation.AppendFormat("Maximum length of a symbolic link: {0}", ufs_sb.fs_maxsymlinklen)
                .AppendLine();
                sbInformation.AppendFormat("A file can be {0} bytes at max", ufs_sb.fs_maxfilesize).AppendLine();
                sbInformation.AppendFormat("Volume state on {0}", DateHandlers.UnixToDateTime(ufs_sb.fs_state))
                .AppendLine();
            }

            if (ufs_sb.fs_old_nrpos > 0)
            {
                sbInformation.AppendFormat("{0} rotational positions", ufs_sb.fs_old_nrpos).AppendLine();
            }
            if (ufs_sb.fs_old_rotbloff > 0)
            {
                sbInformation.AppendFormat("{0} blocks per rotation", ufs_sb.fs_old_rotbloff).AppendLine();
            }

            information = sbInformation.ToString();
        }
Example #39
0
        public bool GetInformation(IMediaImage imagePlugin, out List <Partition> partitions, ulong sectorOffset)
        {
            partitions = new List <Partition>();

            byte[] sector;
            ulong  sectsPerUnit;

            AaruConsole.DebugWriteLine("Human68k plugin", "sectorSize = {0}", imagePlugin.Info.SectorSize);

            if (sectorOffset + 4 >= imagePlugin.Info.Sectors)
            {
                return(false);
            }

            switch (imagePlugin.Info.SectorSize)
            {
            case 256:
                sector       = imagePlugin.ReadSector(4 + sectorOffset);
                sectsPerUnit = 1;

                break;

            case 512:
                sector       = imagePlugin.ReadSector(4 + sectorOffset);
                sectsPerUnit = 2;

                break;

            case 1024:
                sector       = imagePlugin.ReadSector(2 + sectorOffset);
                sectsPerUnit = 1;

                break;

            default: return(false);
            }

            X68kTable table = Marshal.ByteArrayToStructureBigEndian <X68kTable>(sector);

            AaruConsole.DebugWriteLine("Human68k plugin", "table.magic = {0:X4}", table.magic);

            if (table.magic != X68K_MAGIC)
            {
                return(false);
            }

            for (int i = 0; i < table.entries.Length; i++)
            {
                table.entries[i] = (X68kEntry)Marshal.SwapStructureMembersEndian(table.entries[i]);
            }

            AaruConsole.DebugWriteLine("Human68k plugin", "table.size = {0:X4}", table.size);
            AaruConsole.DebugWriteLine("Human68k plugin", "table.size2 = {0:X4}", table.size2);
            AaruConsole.DebugWriteLine("Human68k plugin", "table.unknown = {0:X4}", table.unknown);

            ulong counter = 0;

            foreach (X68kEntry entry in table.entries)
            {
                AaruConsole.DebugWriteLine("Human68k plugin", "entry.name = {0}",
                                           StringHandlers.CToString(entry.name, Encoding.GetEncoding(932)));

                AaruConsole.DebugWriteLine("Human68k plugin", "entry.stateStart = {0}", entry.stateStart);
                AaruConsole.DebugWriteLine("Human68k plugin", "entry.length = {0}", entry.length);

                AaruConsole.DebugWriteLine("Human68k plugin", "sectsPerUnit = {0} {1}", sectsPerUnit,
                                           imagePlugin.Info.SectorSize);

                var part = new Partition
                {
                    Start  = (entry.stateStart & 0xFFFFFF) * sectsPerUnit,
                    Length = entry.length * sectsPerUnit,
                    Type   = StringHandlers.CToString(entry.name, Encoding.GetEncoding(932)), Sequence = counter,
                    Scheme = Name
                };

                part.Offset = part.Start * (ulong)sector.Length;
                part.Size   = part.Length * (ulong)sector.Length;

                if (entry.length <= 0)
                {
                    continue;
                }

                partitions.Add(part);
                counter++;
            }

            return(true);
        }
            private static void SetBitToTrue(Partition partition, ulong ptrPosition, int bitPosition)
            {
                Debug.Assert(partition.IsEmpty == false);

                partition.Ptr[ptrPosition] |= (byte)(1 << bitPosition);
            }
Example #41
0
 public void SetUp()
 {
     table     = Storage.SetUp();
     partition = new Partition(table, "test");
 }
Example #42
0
        /// <summary>
        /// Get Virtual Servers, Pools, PoolMembers, Profiles and Certificates from Group
        /// </summary>
        /// <param name="devGroup">Group to Collect Info From</param>
        private static void GetObjectsFromDeviceGroup(SyncFailoverGroup sfog)
        {
            // Create Common Partition Holder
            Partition CommonPartition = new Partition("Blank", "Blank");

            // Attach to First Device in Device Group
            m_interfaces.initialize(sfog.DeviceList[0].Address, sfog.DeviceList[0].F5usr, sfog.DeviceList[0].F5pwd);

            if (m_interfaces.initialized)
            {
                // Get SNMP Info (Not Partition Dependant)
                // Virtual Server
                List <Variable> VirtualServerSnmpResults = SNMP.WalkSNMP(SNMP.ltmVsStatusName, sfog.DeviceList[0].Address, sfog.DeviceList[0].Port, sfog.DeviceList[0].Community);
                // Pools
                List <Variable> PoolSnmpResults = SNMP.WalkSNMP(SNMP.ltmPoolStatusName, sfog.DeviceList[0].Address, sfog.DeviceList[0].Port, sfog.DeviceList[0].Community);
                // Pool Members
                List <Variable> PoolMemberSnmpResults = SNMP.WalkSNMP(SNMP.ltmPoolMbrStatusNodeName, sfog.DeviceList[0].Address, sfog.DeviceList[0].Port, sfog.DeviceList[0].Community);
                // Client SSL Profiles
                List <Variable> ClientSslProfileSnmpResults = SNMP.WalkSNMP(SNMP.ltmClientSslName, sfog.DeviceList[0].Address, sfog.DeviceList[0].Port, sfog.DeviceList[0].Community);
                // Server SSL Profiles
                List <Variable> ServerSslProfileSnmpResults = SNMP.WalkSNMP(SNMP.ltmServerSslName, sfog.DeviceList[0].Address, sfog.DeviceList[0].Port, sfog.DeviceList[0].Community);

                // Get List of Partitions
                ManagementPartitionAuthZPartition[] partitionList = m_interfaces.ManagementPartition.get_partition_list();

                // Loop through Partitions
                foreach (ManagementPartitionAuthZPartition partition in partitionList)
                {
                    // Set Active Partition
                    m_interfaces.ManagementPartition.set_active_partition(partition.partition_name);

                    // Create Partition
                    Partition newPartition = new Partition(sfog.Key, partition.partition_name);
                    sfog.PartitionList.Add(newPartition);

                    // Get Certificates
                    ManagementKeyCertificateCertificateInformation_v2[] certs = m_interfaces.ManagementKeyCertificate.get_certificate_list_v2(ManagementKeyCertificateManagementModeType.MANAGEMENT_MODE_DEFAULT);
                    foreach (ManagementKeyCertificateCertificateInformation_v2 cert in certs)
                    {
                        Certificate newCert = new Certificate(cert, sfog, partition.partition_name);
                        newPartition.CertificateList.Add(newCert);
                    }

                    // Get Client SSL Profiles
                    // Get iControl Info
                    string[] ProfileClientSSLList                    = m_interfaces.LocalLBProfileClientSSL.get_list();
                    string[] ProfileClientSSLDescriptionList         = m_interfaces.LocalLBProfileClientSSL.get_description(ProfileClientSSLList);
                    LocalLBProfileString[] ProfileClientSSL_ca_files = m_interfaces.LocalLBProfileClientSSL.get_certificate_file_v2(ProfileClientSSLList);

                    // Loop Through All Client SSL profiles
                    for (int i = 0; i < ProfileClientSSLList.Length; i++)
                    {
                        // Create Profile
                        ProfileClientSSL newProfile = new ProfileClientSSL(sfog, partition.partition_name, ProfileClientSSLList[i], ProfileClientSSLDescriptionList[i], ProfileClientSSL_ca_files[i].value);

                        // Look for Matching Certs in This Partition
                        foreach (Certificate cert in newPartition.CertificateList)
                        {
                            if (ProfileClientSSL_ca_files[i].value == cert.SCOM_Object.Values[3].ToString())
                            {
                                newProfile.CertificateList.Add(cert);
                            }
                        }

                        // Look For Matching Certificates in Common Partition
                        if (partition.partition_name != "Common")
                        {
                            foreach (Certificate cert in CommonPartition.CertificateList)
                            {
                                if (ProfileClientSSL_ca_files[i].value == cert.SCOM_Object.Values[3].ToString())
                                {
                                    newProfile.CertificateList.Add(cert);
                                }
                            }
                        }

                        // Save ClientSslProfile
                        newPartition.ClientSslProfileList.Add(newProfile);
                    }

                    // Get Server SSL Profiles
                    string[] ProfileServerSSLList                    = m_interfaces.LocalLBProfileServerSSL.get_list();
                    string[] ProfileServerSSLDescriptionList         = m_interfaces.LocalLBProfileServerSSL.get_description(ProfileServerSSLList);
                    LocalLBProfileString[] ProfileServerSSL_ca_files = m_interfaces.LocalLBProfileServerSSL.get_certificate_file_v2(ProfileServerSSLList);
                    // Loop Through All Server SSL profiles
                    for (int i = 0; i < ProfileServerSSLList.Length; i++)
                    {
                        // Create Profile
                        ProfileServerSSL newProfile = new ProfileServerSSL(sfog, partition.partition_name, ProfileServerSSLList[i], ProfileServerSSLDescriptionList[i], ProfileServerSSL_ca_files[i].value);
                        // Look for Matching Certs in This Partition
                        foreach (Certificate cert in newPartition.CertificateList)
                        {
                            if (ProfileServerSSL_ca_files[i].value == cert.SCOM_Object.Values[3].ToString())
                            {
                                newProfile.CertificateList.Add(cert);
                            }
                        }

                        // Look For Matching Certificates in Common Partition
                        if (partition.partition_name != "Common")
                        {
                            foreach (Certificate cert in CommonPartition.CertificateList)
                            {
                                if (ProfileServerSSL_ca_files[i].value == cert.SCOM_Object.Values[3].ToString())
                                {
                                    newProfile.CertificateList.Add(cert);
                                }
                            }
                        }
                        newPartition.ServerSslProfileList.Add(newProfile);
                    }

                    // Get Virtual Servers
                    // Get iControl Info
                    string[] vipNames        = m_interfaces.LocalLBVirtualServer.get_list();
                    string[] vipDefaultPools = m_interfaces.LocalLBVirtualServer.get_default_pool_name(vipNames);
                    LocalLBVirtualServerVirtualServerType[] vipTypes = m_interfaces.LocalLBVirtualServer.get_type(vipNames);
                    CommonAddressPort[] vipAddressPorts     = m_interfaces.LocalLBVirtualServer.get_destination_v2(vipNames);
                    string[]            vipDescriptions     = m_interfaces.LocalLBVirtualServer.get_description(vipNames);
                    CommonULong64[]     vipConnectionLimits = m_interfaces.LocalLBVirtualServer.get_connection_limit(vipNames);
                    LocalLBVirtualServerVirtualServerProfileAttribute[][] vipProfiles = m_interfaces.LocalLBVirtualServer.get_profile(vipNames);

                    // Loop Through All Virtual Servers
                    for (int i = 0; i < vipNames.Length; i++)
                    {
                        // Set Address
                        string vipAddress = vipAddressPorts[i].address;
                        vipAddress = vipAddress.Substring(vipAddress.LastIndexOf("/") + 1);
                        // Get Connection Limit
                        string vipConnectionLimit = ConvertUlong(vipConnectionLimits[i]).ToString();
                        // Get Oid Suffix
                        string vipOidSuffix = GetOidSuffix(vipNames[i], SNMP.ltmVsStatusName, VirtualServerSnmpResults);
                        // Get Client SSL Profiles
                        string vipClientSSLProfiles = "";
                        string vipServerSSLProfiles = "";
                        foreach (LocalLBVirtualServerVirtualServerProfileAttribute profileAttr in vipProfiles[i])
                        {
                            if (profileAttr.profile_type == LocalLBProfileType.PROFILE_TYPE_CLIENT_SSL)
                            {
                                vipClientSSLProfiles += profileAttr.profile_name + ",";
                            }
                            if (profileAttr.profile_type == LocalLBProfileType.PROFILE_TYPE_SERVER_SSL)
                            {
                                vipServerSSLProfiles += profileAttr.profile_name + ",";
                            }
                        }
                        vipClientSSLProfiles = vipClientSSLProfiles.TrimEnd(',');
                        vipServerSSLProfiles = vipServerSSLProfiles.TrimEnd(',');
                        // Get Device Group
                        string vipDeviceGroup = sfog.Name;

                        VirtualServer vs = new VirtualServer(sfog, partition.partition_name, vipNames[i], vipAddress, vipAddressPorts[i].port.ToString(), vipDescriptions[i],
                                                             vipTypes[i].ToString(), vipDefaultPools[i], vipConnectionLimit, vipClientSSLProfiles, vipServerSSLProfiles);

                        // Look For Matching ClientSslProfiles in this Partition
                        foreach (ProfileClientSSL profile in newPartition.ClientSslProfileList)
                        {
                            if (vipClientSSLProfiles.Contains(profile.SCOM_Object.Values[0].ToString()))
                            {
                                vs.ProfileClientSslList.Add(profile);
                            }
                        }
                        // Look For Matching ClientSslProfiles in Common Partition
                        if (partition.partition_name != "Common")
                        {
                            foreach (ProfileClientSSL profile in CommonPartition.ClientSslProfileList)
                            {
                                if (vipClientSSLProfiles.Contains(profile.SCOM_Object.Values[0].ToString()))
                                {
                                    vs.ProfileClientSslList.Add(profile);
                                }
                            }
                        }
                        // Look For Matching ServerSslProfiles in this Partition
                        foreach (ProfileServerSSL profile in newPartition.ServerSslProfileList)
                        {
                            if (vipServerSSLProfiles.Contains(profile.SCOM_Object.Values[0].ToString()))
                            {
                                vs.ProfileServerSslList.Add(profile);
                            }
                        }
                        // Look For Matching ClientSslProfiles in Common Partition
                        if (partition.partition_name != "Common")
                        {
                            foreach (ProfileServerSSL profile in CommonPartition.ServerSslProfileList)
                            {
                                if (vipServerSSLProfiles.Contains(profile.SCOM_Object.Values[0].ToString()))
                                {
                                    vs.ProfileServerSslList.Add(profile);
                                }
                            }
                        }
                        // Add it to the List
                        newPartition.VirtualServerList.Add(vs);
                    }

                    // Get Pools & Pool Members
                    // Get iControl Info
                    string[] poolNames                           = m_interfaces.LocalLBPool.get_list();
                    string[] poolDescriptions                    = m_interfaces.LocalLBPool.get_description(poolNames);
                    long[]   poolActiveMemberCount               = m_interfaces.LocalLBPool.get_active_member_count(poolNames);
                    CommonAddressPort[][] poolMembers            = m_interfaces.LocalLBPool.get_member_v2(poolNames);
                    string[][]            poolMemberDescriptions = m_interfaces.LocalLBPool.get_member_description(poolNames, poolMembers);
                    // Loop Through All Pools
                    for (int i = 0; i < poolNames.Length; i++)
                    {
                        // Get Full Name
                        string sPoolName = poolNames[i];

                        // Get Node Short Name
                        string sShortPoolName = sPoolName.Substring(sPoolName.LastIndexOf("/") + 1);

                        // Ignore _auto_ Nodes
                        if (sShortPoolName.ToLower().StartsWith("_auto_"))
                        {
                            continue;
                        }

                        // Get Oid Suffix
                        string OidSuffix = GetOidSuffix(sPoolName, SNMP.ltmPoolStatusName, PoolSnmpResults);

                        // Get Monitor Rule
                        string MonitorRule = SNMP.GetSNMP(SNMP.ltmPoolMonitorRule + OidSuffix, sfog.DeviceList[0].Address, sfog.DeviceList[0].Port, sfog.DeviceList[0].Community)[0].Data.ToString();

                        // Create new Pool
                        Pool newPool = new Pool(sfog, partition.partition_name, sPoolName, sShortPoolName, poolDescriptions[i], MonitorRule, poolMembers[i].Length, poolActiveMemberCount[i]);

                        // Add Pool Members
                        for (int j = 0; j < poolMembers[i].Length; j++)
                        {
                            // Get Oid Suffix
                            string pmOidSuffix = GetOidSuffix(poolMembers[i][j].address, SNMP.ltmPoolMbrStatusNodeName, PoolMemberSnmpResults);
                            // Get Monitor Rule (using SNMP as iControl seems to Error)
                            string pmMonitorRule = SNMP.GetSNMP(SNMP.ltmPoolMemberMonitorRule + pmOidSuffix, sfog.DeviceList[0].Address, sfog.DeviceList[0].Port, sfog.DeviceList[0].Community)[0].Data.ToString();

                            // Create New Pool Member
                            PoolMember newPoolMember = new PoolMember(sfog, partition.partition_name, sPoolName, poolMembers[i][j].address, poolMemberDescriptions[i][j], poolMembers[i][j].port.ToString(), pmMonitorRule);

                            // Add to Pool
                            newPool.PoolMembers.Add(newPoolMember);
                        }

                        // Add it to the List
                        newPartition.PoolList.Add(newPool);

                        // Match To Virtual Servers (DefaultPool)
                        foreach (VirtualServer vs in newPartition.VirtualServerList)
                        {
                            if (vs.DefaultPoolName == sPoolName)
                            {
                                vs.DefaultPool = newPool;
                            }
                        }
                    }


                    // Get Nodes
                    string[] nodeNameList        = m_interfaces.LocalLBNodeAddressV2.get_list();
                    string[] nodeAddressList     = m_interfaces.LocalLBNodeAddressV2.get_address(nodeNameList);
                    string[] nodeDescriptionList = m_interfaces.LocalLBNodeAddressV2.get_description(nodeNameList);
                    for (int i = 0; i < nodeNameList.Length; i++)
                    {
                        // Get Node Full Name
                        string sNodeName = nodeNameList[i];

                        // Get Node Short Name
                        string sShortNodeName = sNodeName.Substring(sNodeName.LastIndexOf("/") + 1);

                        // Ignore _auto_ Nodes
                        if (sShortNodeName.ToLower().StartsWith("_auto_"))
                        {
                            continue;
                        }

                        string MonitorRules = "";
                        try
                        {
                            LocalLBMonitorRule[] nodeMonitorRuleList = m_interfaces.LocalLBNodeAddressV2.get_monitor_rule(new string[] { sNodeName });
                            for (int j = 0; j < nodeMonitorRuleList[0].monitor_templates.Length; j++)
                            {
                                MonitorRules += nodeMonitorRuleList[0].monitor_templates[j].ToString() + ",";
                            }
                            MonitorRules = MonitorRules.TrimEnd(',');
                        }
                        catch (Exception)
                        {
                        }

                        // Create a New Node
                        Node newNode = new Node(sfog.Key, partition.partition_name, sNodeName, sShortNodeName, nodeAddressList[i], nodeDescriptionList[i], MonitorRules);
                        newPartition.NodeList.Add(newNode);
                    }

                    // Take a Copy of Common Parition
                    if (partition.partition_name == "Common")
                    {
                        CommonPartition = newPartition;
                    }
                }
            }
        }
Example #43
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = Encoding.Unicode;
            information = "";
            if (imagePlugin.Info.SectorSize < F2FS_MIN_SECTOR || imagePlugin.Info.SectorSize > F2FS_MAX_SECTOR)
            {
                return;
            }

            uint sbAddr = F2FS_SUPER_OFFSET / imagePlugin.Info.SectorSize;

            if (sbAddr == 0)
            {
                sbAddr = 1;
            }

            uint sbSize = (uint)(Marshal.SizeOf <F2FS_Superblock>() / imagePlugin.Info.SectorSize);

            if (Marshal.SizeOf <F2FS_Superblock>() % imagePlugin.Info.SectorSize != 0)
            {
                sbSize++;
            }

            byte[] sector = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize);
            if (sector.Length < Marshal.SizeOf <F2FS_Superblock>())
            {
                return;
            }

            F2FS_Superblock f2fsSb = Marshal.ByteArrayToStructureLittleEndian <F2FS_Superblock>(sector);

            if (f2fsSb.magic != F2FS_MAGIC)
            {
                return;
            }

            StringBuilder sb = new StringBuilder();

            sb.AppendLine("F2FS filesystem");
            sb.AppendFormat("Version {0}.{1}", f2fsSb.major_ver, f2fsSb.minor_ver).AppendLine();
            sb.AppendFormat("{0} bytes per sector", 1 << (int)f2fsSb.log_sectorsize).AppendLine();
            sb.AppendFormat("{0} sectors ({1} bytes) per block", 1 << (int)f2fsSb.log_sectors_per_block,
                            1 << (int)f2fsSb.log_blocksize).AppendLine();
            sb.AppendFormat("{0} blocks per segment", f2fsSb.log_blocks_per_seg).AppendLine();
            sb.AppendFormat("{0} blocks in volume", f2fsSb.block_count).AppendLine();
            sb.AppendFormat("{0} segments per section", f2fsSb.segs_per_sec).AppendLine();
            sb.AppendFormat("{0} sections per zone", f2fsSb.secs_per_zone).AppendLine();
            sb.AppendFormat("{0} sections", f2fsSb.section_count).AppendLine();
            sb.AppendFormat("{0} segments", f2fsSb.segment_count).AppendLine();
            sb.AppendFormat("Root directory resides on inode {0}", f2fsSb.root_ino).AppendLine();
            sb.AppendFormat("Volume UUID: {0}", f2fsSb.uuid).AppendLine();
            sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(f2fsSb.volume_name, Encoding.Unicode, true))
            .AppendLine();
            sb.AppendFormat("Volume last mounted on kernel version: {0}", StringHandlers.CToString(f2fsSb.version))
            .AppendLine();
            sb.AppendFormat("Volume created on kernel version: {0}", StringHandlers.CToString(f2fsSb.init_version))
            .AppendLine();

            information = sb.ToString();

            XmlFsType = new FileSystemType
            {
                Type                   = "F2FS filesystem",
                SystemIdentifier       = Encoding.ASCII.GetString(f2fsSb.version),
                Clusters               = f2fsSb.block_count,
                ClusterSize            = (uint)(1 << (int)f2fsSb.log_blocksize),
                DataPreparerIdentifier = Encoding.ASCII.GetString(f2fsSb.init_version),
                VolumeName             = StringHandlers.CToString(f2fsSb.volume_name, Encoding.Unicode, true),
                VolumeSerial           = f2fsSb.uuid.ToString()
            };
        }
Example #44
0
        public FatFileSystem(Partition aDevice, string aRootPath)
            : base(aDevice, aRootPath)
        {
            var xBPB = mDevice.NewBlockArray(1);

            mDevice.ReadBlock(0UL, 1U, xBPB);

            ushort xSig = xBPB.ToUInt16(510);

            if (xSig != 0xAA55)
            {
                throw new Exception("FAT signature not found.");
            }

            BytesPerSector      = xBPB.ToUInt16(11);
            SectorsPerCluster   = xBPB[13];
            BytesPerCluster     = BytesPerSector * SectorsPerCluster;
            ReservedSectorCount = xBPB.ToUInt16(14);
            NumberOfFATs        = xBPB[16];
            RootEntryCount      = xBPB.ToUInt16(17);

            TotalSectorCount = xBPB.ToUInt16(19);
            if (TotalSectorCount == 0)
            {
                TotalSectorCount = xBPB.ToUInt32(32);
            }

            // FATSz
            FatSectorCount = xBPB.ToUInt16(22);
            if (FatSectorCount == 0)
            {
                FatSectorCount = xBPB.ToUInt32(36);
            }

            DataSectorCount = TotalSectorCount - (ReservedSectorCount + NumberOfFATs * FatSectorCount + ReservedSectorCount);

            // Computation rounds down.
            ClusterCount = DataSectorCount / SectorsPerCluster;
            // Determine the FAT type. Do not use another method - this IS the official and
            // proper way to determine FAT type.
            // Comparisons are purposefully < and not <=
            // FAT16 starts at 4085, FAT32 starts at 65525
            if (ClusterCount < 4085)
            {
                mFatType = FatTypeEnum.Fat12;
            }
            else if (ClusterCount < 65525)
            {
                mFatType = FatTypeEnum.Fat16;
            }
            else
            {
                mFatType = FatTypeEnum.Fat32;
            }

            if (mFatType == FatTypeEnum.Fat32)
            {
                RootCluster = xBPB.ToUInt32(44);
            }
            else
            {
                RootSector      = ReservedSectorCount + NumberOfFATs * FatSectorCount;
                RootSectorCount = (RootEntryCount * 32 + (BytesPerSector - 1)) / BytesPerSector;
            }
            DataSector = ReservedSectorCount + NumberOfFATs * FatSectorCount + RootSectorCount;

            mFats = new Fat[NumberOfFATs];
            for (ulong i = 0; i < NumberOfFATs; i++)
            {
                mFats[i] = new Fat(this, (ReservedSectorCount + i * FatSectorCount));
            }
        }
Example #45
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("iso-8859-15");
            information = "";

            var sb = new StringBuilder();

            XmlFsType = new FileSystemType();

            byte[]           vbrSector = imagePlugin.ReadSector(0 + partition.Start);
            VolumeBootRecord vbr       = Marshal.ByteArrayToStructureLittleEndian <VolumeBootRecord>(vbrSector);

            byte[] parametersSector = imagePlugin.ReadSector(9 + partition.Start);

            OemParameterTable parametersTable =
                Marshal.ByteArrayToStructureLittleEndian <OemParameterTable>(parametersSector);

            byte[]         chkSector = imagePlugin.ReadSector(11 + partition.Start);
            ChecksumSector chksector = Marshal.ByteArrayToStructureLittleEndian <ChecksumSector>(chkSector);

            sb.AppendLine("Microsoft exFAT");
            sb.AppendFormat("Partition offset: {0}", vbr.offset).AppendLine();

            sb.AppendFormat("Volume has {0} sectors of {1} bytes each for a total of {2} bytes", vbr.sectors,
                            1 << vbr.sectorShift, vbr.sectors * (ulong)(1 << vbr.sectorShift)).AppendLine();

            sb.AppendFormat("Volume uses clusters of {0} sectors ({1} bytes) each", 1 << vbr.clusterShift,
                            (1 << vbr.sectorShift) * (1 << vbr.clusterShift)).AppendLine();

            sb.AppendFormat("First FAT starts at sector {0} and runs for {1} sectors", vbr.fatOffset, vbr.fatLength).
            AppendLine();

            sb.AppendFormat("Volume uses {0} FATs", vbr.fats).AppendLine();

            sb.AppendFormat("Cluster heap starts at sector {0}, contains {1} clusters and is {2}% used",
                            vbr.clusterHeapOffset, vbr.clusterHeapLength, vbr.heapUsage).AppendLine();

            sb.AppendFormat("Root directory starts at cluster {0}", vbr.rootDirectoryCluster).AppendLine();

            sb.AppendFormat("Filesystem revision is {0}.{1:D2}", (vbr.revision & 0xFF00) >> 8, vbr.revision & 0xFF).
            AppendLine();

            sb.AppendFormat("Volume serial number: {0:X8}", vbr.volumeSerial).AppendLine();
            sb.AppendFormat("BIOS drive is {0:X2}h", vbr.drive).AppendLine();

            if (vbr.flags.HasFlag(VolumeFlags.SecondFatActive))
            {
                sb.AppendLine("2nd FAT is in use");
            }

            if (vbr.flags.HasFlag(VolumeFlags.VolumeDirty))
            {
                sb.AppendLine("Volume is dirty");
            }

            if (vbr.flags.HasFlag(VolumeFlags.MediaFailure))
            {
                sb.AppendLine("Underlying media presented errors");
            }

            int count = 1;

            foreach (OemParameter parameter in parametersTable.parameters)
            {
                if (parameter.OemParameterType == OEM_FLASH_PARAMETER_GUID)
                {
                    sb.AppendFormat("OEM Parameters {0}:", count).AppendLine();
                    sb.AppendFormat("\t{0} bytes in erase block", parameter.eraseBlockSize).AppendLine();
                    sb.AppendFormat("\t{0} bytes per page", parameter.pageSize).AppendLine();
                    sb.AppendFormat("\t{0} spare blocks", parameter.spareBlocks).AppendLine();
                    sb.AppendFormat("\t{0} nanoseconds random access time", parameter.randomAccessTime).AppendLine();
                    sb.AppendFormat("\t{0} nanoseconds program time", parameter.programTime).AppendLine();
                    sb.AppendFormat("\t{0} nanoseconds read cycle time", parameter.readCycleTime).AppendLine();
                    sb.AppendFormat("\t{0} nanoseconds write cycle time", parameter.writeCycleTime).AppendLine();
                }
                else if (parameter.OemParameterType != Guid.Empty)
                {
                    sb.AppendFormat("Found unknown parameter type {0}", parameter.OemParameterType).AppendLine();
                }

                count++;
            }

            sb.AppendFormat("Checksum 0x{0:X8}", chksector.checksum[0]).AppendLine();

            XmlFsType.ClusterSize  = (uint)((1 << vbr.sectorShift) * (1 << vbr.clusterShift));
            XmlFsType.Clusters     = vbr.clusterHeapLength;
            XmlFsType.Dirty        = vbr.flags.HasFlag(VolumeFlags.VolumeDirty);
            XmlFsType.Type         = "exFAT";
            XmlFsType.VolumeSerial = $"{vbr.volumeSerial:X8}";

            information = sb.ToString();
        }
Example #46
0
        private void Load(StructureValueCollection values, FileSegmenter segmenter)
        {
            _eofSegment = segmenter.WrapEOF((int)values.GetInteger("file size"));

            var metaOffset = (int)values.GetInteger("meta offset");

            int tagTableSize = (int)values.GetInteger("tag data offset");
            int tagDataSize  = (int)values.GetInteger("tag data size");

            var headSegment = new FileSegment(
                segmenter.DefineSegment(metaOffset, tagTableSize, 0x1000, SegmentResizeOrigin.Beginning), segmenter);

            var metaSize       = (int)values.GetInteger("meta size");
            int metaOffsetMask = (int)values.GetInteger("meta offset mask");

            var metaSegment = new FileSegment(
                segmenter.DefineSegment(metaOffset + tagTableSize, tagDataSize, 0x1000, SegmentResizeOrigin.End), segmenter);

            MetaArea = new FileSegmentGroup(new MetaOffsetConverter(headSegment, (uint)metaOffsetMask));

            IndexHeaderLocation = MetaArea.AddSegment(headSegment);
            MetaArea.AddSegment(metaSegment);

            Type = (CacheFileType)values.GetInteger("type");

            var headerGroup = new FileSegmentGroup();

            headerGroup.AddSegment(segmenter.WrapSegment(0, HeaderSize, 1, SegmentResizeOrigin.None));

            StringIDCount = (int)values.GetInteger("string table count");
            var sidDataSize = (int)values.GetInteger("string table size");

            StringIDData = segmenter.WrapSegment((int)values.GetInteger("string table offset"), sidDataSize, 1,
                                                 SegmentResizeOrigin.End);
            StringIDIndexTable = segmenter.WrapSegment((int)values.GetInteger("string index table offset"), StringIDCount * 4, 4,
                                                       SegmentResizeOrigin.End);

            FileNameCount = (int)values.GetInteger("file table count");
            var fileDataSize = (int)values.GetInteger("file table size");

            FileNameData = segmenter.WrapSegment((int)values.GetInteger("file table offset"), fileDataSize, 1,
                                                 SegmentResizeOrigin.End);
            FileNameIndexTable = segmenter.WrapSegment((int)values.GetInteger("file index table offset"), FileNameCount * 4, 4,
                                                       SegmentResizeOrigin.End);

            InternalName = values.GetString("internal name");
            ScenarioName = values.GetString("scenario name");

            StringArea = new FileSegmentGroup();
            StringArea.AddSegment(segmenter.WrapSegment((int)values.GetInteger("string block offset"), StringIDCount * 0x80, 0x80,
                                                        SegmentResizeOrigin.End));
            StringArea.AddSegment(StringIDIndexTable);
            StringArea.AddSegment(StringIDData);
            StringArea.AddSegment(FileNameIndexTable);
            StringArea.AddSegment(FileNameData);

            StringIDIndexTableLocation = SegmentPointer.FromOffset(StringIDIndexTable.Offset, StringArea);
            StringIDDataLocation       = SegmentPointer.FromOffset(StringIDData.Offset, StringArea);
            FileNameIndexTableLocation = SegmentPointer.FromOffset(FileNameIndexTable.Offset, StringArea);
            FileNameDataLocation       = SegmentPointer.FromOffset(FileNameData.Offset, StringArea);

            LocaleArea = new FileSegmentGroup();

            var rawTableOffset = (int)values.GetInteger("raw table offset");
            var rawTableSize   = (int)values.GetInteger("raw table size");

            // It is apparently possible to create a cache without a raw table, but -1 gets written as the offset
            if (rawTableOffset != -1)
            {
                RawTable = segmenter.WrapSegment(rawTableOffset, rawTableSize, 0x80, SegmentResizeOrigin.End);
            }

            Checksum = (uint)values.GetInteger("checksum");

            // Set up a bogus partition table
            Partitions    = new Partition[1];
            Partitions[0] = new Partition(SegmentPointer.FromOffset(MetaArea.Offset, MetaArea), (uint)MetaArea.Size);
        }
Example #47
0
        public void CreateStandardActions()
        {
            var csDialog = new CultureSelectDialog();

            // Import Table Wizard...:
            Add(new Action((s, m) => Governance.AllowCreate(typeof(Table)), (s, m) => ImportTablesWizard.ShowWizard(m), (s, m) => "Import Tables...", true, Context.Model | Context.Tables));
            Add(new Action((s, m) => Governance.AllowCreate(typeof(DataColumn)) && m.DataSources.Any(ds => ds.Type == DataSourceType.Provider), (s, m) => ScriptHelper.SchemaCheck(m), (s, m) => "Refresh Table Metadata...", true, Context.Model | Context.Tables));
            // Import Table Wizard...:
            Add(new Action((s, m) => Governance.AllowCreate(typeof(DataColumn)) && s.DirectCount == 1 && s.DataSource is ProviderDataSource, (s, m) => ImportTablesWizard.ShowWizard(m, s.DataSource as ProviderDataSource), (s, m) => "Import Tables...", true, Context.DataSource));

            // Schema check:
            Add(new Action((s, m) => Governance.AllowCreate(typeof(DataColumn)) && s.DirectCount == 1 && m.DataSources.Any(ds => ds.Type == DataSourceType.Provider) && s.DataSource is ProviderDataSource, (s, m) => ScriptHelper.SchemaCheck(s.DataSource as ProviderDataSource), (s, m) => "Refresh Table Metadata...", true, Context.DataSource));
            Add(new Action((s, m) => Governance.AllowCreate(typeof(DataColumn)) && s.DirectCount == 1 && m.DataSources.Any(ds => ds.Type == DataSourceType.Provider) && s.Partition.DataSource is ProviderDataSource, (s, m) => ScriptHelper.SchemaCheck(s.Partition), (s, m) => "Refresh Table Metadata...", true, Context.Partition));

            Add(new Separator());

            // "Create New Display Folder"
            Add(new Action((s, m) => Governance.AllowEditProperty(s, TOMWrapper.Properties.DISPLAYFOLDER) && s.Count >= 1,
                           (s, m) => {
                var orgDF = (s.Direct.FirstOrDefault() as IFolderObject)?.GetDisplayFolder(Handler.Tree.Culture);
                var newDF = string.IsNullOrWhiteSpace(orgDF) ? "New folder" : (orgDF + @"\New folder");;
                Folder.CreateFolder(s.Table, newDF).Edit().Expand();
                s.ReplaceFolder(orgDF, newDF, Handler.Tree.Culture);
            },
                           (s, m) => @"Create New\Display Folder", true, Context.TableObject));
            Add(new Action((s, m) => Governance.AllowCreate(typeof(CalculationItem)) && s.Count == 1, (s, m) => s.CalculationGroup.AddCalculationItem().Edit(), (s, m) => @"Create New\Calculation Item", false, Context.CalculationGroupTable));

            Add(new Separator(@"Create New"));

            // Add measure:
            Add(new Action((s, m) => Governance.AllowCreate(typeof(Measure)) && (s.Count == 1 || s.Context.HasX(Context.TableObject)), (s, m) => s.Table.AddMeasure(displayFolder: s.CurrentFolder).Vis().Edit(), (s, m) => @"Create New\Measure", true, Context.CalculationGroupTable | Context.Table | Context.TableObject, Keys.Alt | Keys.D1));

            // Add calc column:
            Add(new Action((s, m) => Governance.AllowCreate(typeof(CalculatedColumn)) && (s.Count == 1 || s.Context.HasX(Context.TableObject)), (s, m) => s.Table.AddCalculatedColumn(displayFolder: s.CurrentFolder).Vis().Edit(), (s, m) => @"Create New\Calculated Column", true, Context.CalculationGroupTable | Context.Table | Context.TableObject, Keys.Alt | Keys.D2));

            // Add calc table column:
            Add(new Action((s, m) => Governance.AllowCreate(typeof(CalculatedTableColumn)) &&
                           Handler.SourceType != ModelSourceType.Database &&
                           (s.Count == 1 || s.Context.HasX(Context.TableObject)) &&
                           (s.Table is CalculatedTable),
                           (s, m) => (s.Table as CalculatedTable).AddCalculatedTableColumn(displayFolder: s.CurrentFolder).Vis().Edit(), (s, m) => @"Create New\Calculated Table Column", true, Context.Table | Context.TableObject));

            // Add hierarchy:
            Add(new Action((s, m) => Governance.AllowCreate(typeof(Hierarchy)) && (s.Count == 1 || s.Context.HasX(Context.TableObject)),
                           (s, m) => s.Table.AddHierarchy(displayFolder: s.CurrentFolder, levels: s.Direct.OfType <Column>().ToArray()).Expand().Vis().Edit(),
                           (s, m) => @"Create New\Hierarchy", true, Context.CalculationGroupTable | Context.Table | Context.TableObject, Keys.Alt | Keys.D3));

            // Add data column:
            Add(new Action((s, m) => Governance.AllowCreate(typeof(DataColumn)) && (s.Count == 1 || s.Context.HasX(Context.TableObject)) && !(s.Table is CalculatedTable), (s, m) => s.Table.AddDataColumn(displayFolder: s.CurrentFolder).Vis().Edit(), (s, m) => @"Create New\Data Column", true, Context.CalculationGroupTable | Context.Table | Context.TableObject, Keys.Alt | Keys.D4));

            // Add KPI:
            Add(new Action((s, m) => Governance.AllowCreate(typeof(KPI)) && s.Count == 1 && !s.Folders.Any(), (s, m) => s.Measure.AddKPI().Edit(), (s, m) => @"Create New\KPI", true, Context.Measure));

            Add(new Separator(@"Create New"));

            Add(new Action(
                    (s, m) => Governance.AllowCreate(typeof(Partition)) && s.Count == 1,
                    (s, m) => Partition.CreateNew(s.Table).Edit(),
                    (s, m) => @"Create New\Partition" + (Handler.CompatibilityLevel >= 1400 ? " (Legacy)" : ""), true, Context.Table));
            Add(new Action(
                    (s, m) => Governance.AllowCreate(typeof(MPartition)) && s.Count == 1 && Handler.CompatibilityLevel >= 1400,
                    (s, m) => MPartition.CreateNew(s.Table).Edit(),
                    (s, m) => @"Create New\Partition (Power Query)", true, Context.Table));

            Add(new Action(
                    (s, m) => Governance.AllowCreate(typeof(Partition)),
                    (s, m) => Partition.CreateNew(s.Table).Edit(),
                    (s, m) => @"New Partition" + (Handler.CompatibilityLevel >= 1400 ? " (Legacy)" : ""), true, Context.PartitionCollection | Context.Partition));
            Add(new Action(
                    (s, m) => Governance.AllowCreate(typeof(MPartition)) && Handler.CompatibilityLevel >= 1400,
                    (s, m) => MPartition.CreateNew(s.Table).Edit(),
                    (s, m) => @"New Partition (Power Query)", true, Context.PartitionCollection | Context.Partition));

            Add(new Action((s, m) => Governance.AllowCreate(typeof(Table)) && m.DataSources.Any(), (s, m) => m.AddTable().Vis().Edit(), (s, m) => @"Create New\Table", false, Context.Tables | Context.Model, Keys.Alt | Keys.D5));

            Add(new Action((s, m) => Governance.AllowCreate(typeof(CalculatedTable)), (s, m) => m.AddCalculatedTable().Vis().Edit(), (s, m) => @"Create New\Calculated Table", false, Context.Tables | Context.Model, Keys.Alt | Keys.D6));
            Add(new Action((s, m) => Governance.AllowCreate(typeof(CalculationGroupTable)) && Handler.CompatibilityLevel >= 1470, (s, m) => m.AddCalculationGroup().Vis().Edit(), (s, m) => @"Create New\Calculation Group", false, Context.Tables | Context.Model, Keys.Alt | Keys.D7));

            Add(new Action((s, m) => Governance.AllowCreate(typeof(CalculationItem)) && s.Count == 1, (s, m) => s.CalculationGroup.AddCalculationItem().Edit(), (s, m) => @"New Calculation Item", false, Context.CalculationItemCollection));
            Add(new Action((s, m) => Governance.AllowCreate(typeof(CalculationItem)), (s, m) => s.CalculationItems.First().CalculationGroupTable.AddCalculationItem().Edit(), (s, m) => @"New Calculation Item", false, Context.CalculationItem));

            Add(new Action((s, m) => Governance.AllowCreate(typeof(ProviderDataSource)), (s, m) => m.AddDataSource().Edit(), (s, m) => @"Create New\Data Source (Legacy)", false, Context.DataSources | Context.Model));
            Add(new Action((s, m) => Governance.AllowCreate(typeof(StructuredDataSource)) && Handler.CompatibilityLevel >= 1400, (s, m) => m.AddStructuredDataSource().Edit(), (s, m) => @"Create New\Data Source (Power Query)", false, Context.DataSources | Context.Model));
            Add(new Action((s, m) => Governance.AllowCreate(typeof(Perspective)), (s, m) => m.AddPerspective().Edit(), (s, m) => @"Create New\Perspective", false, Context.Model | Context.Perspectives | Context.Perspective));
            Add(new Action((s, m) => Governance.AllowCreate(typeof(NamedExpression)), (s, m) => m.AddExpression().Edit(), (s, m) => @"Create New\Shared Expression", false, Context.Model | Context.Expressions | Context.Expression));
            Add(new Action((s, m) => Governance.AllowCreate(typeof(SingleColumnRelationship)) && m.Tables.Count(t => t.Columns.Any()) >= 2, (s, m) => m.AddRelationship().Edit(), (s, m) => @"Create New\Relationship", false, Context.Relationship | Context.Relationships | Context.Model));
            Add(new Action((s, m) => Governance.AllowCreate(typeof(ModelRole)), (s, m) => m.AddRole().Edit(), (s, m) => @"Create New\Role", false, Context.Model | Context.Roles | Context.Role));


            Add(new Action((s, m) => Governance.AllowCreate(typeof(Culture)), (s, m) => {
                var res = csDialog.ShowDialog();
                if (res == DialogResult.OK)
                {
                    m.AddTranslation(csDialog.SelectedCulture.Name).Edit();
                }
            }, (s, m) => @"Create New\Translation", true, Context.Model | Context.Translations | Context.Translation));

            Add(new CreateRelationshipAction(CreateRelationshipDirection.To));
            Add(new CreateRelationshipAction(CreateRelationshipDirection.From));

            // "Add to Hierarchy..."
            Add(new MultiAction((s, m, p) => Governance.AllowEditProperty(ObjectType.Hierarchy, TOMWrapper.Properties.LEVELS) && (
                                    // Action enabled only when table contains at least one hierarchy:
                                    ((p == null) && s.Table.Hierarchies.Any()) ||
                                    // ...and none of the selected columns are already present as levels in the hierarchy:
                                    ((p != null) && !(p as Hierarchy).Levels.Select(l => l.Column).Intersect(s.Columns).Any())),

                                (s, m, p) => (p as Hierarchy).AddLevels(s.Columns),
                                (s, m, p) => (p as Hierarchy).Name,
                                (s, m) => s.Table.Hierarchies.AsEnumerable(), "Add to Hierarchy...", true, Context.Column));

            Add(new Separator());

            // Relationship actions:
            Add(new Action((s, m) => Governance.AllowEditProperty(ObjectType.Relationship, TOMWrapper.Properties.ISACTIVE) && s.SingleColumnRelationships.Any(o => !o.IsActive), (s, m) => s.SingleColumnRelationships.IsActive = true, (s, m) => "Activate", true, Context.Relationship));
            Add(new Action((s, m) => Governance.AllowEditProperty(ObjectType.Relationship, TOMWrapper.Properties.ISACTIVE) && s.SingleColumnRelationships.Any(o => o.IsActive), (s, m) => s.SingleColumnRelationships.IsActive  = false, (s, m) => "Deactivate", true, Context.Relationship));
            // Reverse relationship:
            Add(new Action((s, m) => Governance.AllowEditProperty(ObjectType.Relationship, TOMWrapper.Properties.FROMCOLUMN), (s, m) => s.SingleColumnRelationships.ForEach(r => {
                var fc       = r.FromColumn; r.FromColumn = null;
                var tc       = r.ToColumn; r.ToColumn = null;
                r.FromColumn = tc;
                r.ToColumn   = fc;
            }), (s, m) => "Reverse direction", false, Context.Relationship));

            // Visibility and perspectives
            Add(new Action((s, m) => Governance.AllowEditProperty(s, TOMWrapper.Properties.ISHIDDEN) && s.OfType <IHideableObject>().Any(o => o.IsHidden), (s, m) => s.IsHidden  = false, (s, m) => "Make visible", true, Context.DataObjects, Keys.Control | Keys.U));
            Add(new Action((s, m) => Governance.AllowEditProperty(s, TOMWrapper.Properties.ISHIDDEN) && s.OfType <IHideableObject>().Any(o => !o.IsHidden), (s, m) => s.IsHidden = true, (s, m) => "Make invisible", true, Context.DataObjects, Keys.Control | Keys.I));
            Add(new Action((s, m) => Governance.AllowCreate(typeof(Perspective)) && s.OfType <ITabularPerspectiveObject>().Any(), (s, m) => s.ShowInAllPerspectives(), (s, m) => @"Show in Perspectives\All Perspectives", true, Context.DataObjects));
            Add(new Action((s, m) => Governance.AllowCreate(typeof(Perspective)) && s.OfType <ITabularPerspectiveObject>().Any(), (s, m) => s.HideInAllPerspectives(), (s, m) => @"Hide in Perspectives\All Perspectives", true, Context.DataObjects));

            Add(new Separator(@"Show in Perspectives"));
            Add(new Separator(@"Hide in Perspectives"));

            Add(new MultiAction((s, m, p) => Governance.AllowCreate(typeof(Perspective)) && s.OfType <ITabularPerspectiveObject>().Any(obj => p == null || !obj.InPerspective[p as Perspective]),
                                (s, m, p) => s.ShowInPerspective(p as Perspective),
                                (s, m, p) => (p as Perspective).Name,
                                (s, m) => m.Perspectives, "Show in Perspectives", true, Context.DataObjects));

            Add(new MultiAction((s, m, p) => Governance.AllowCreate(typeof(Perspective)) && s.OfType <ITabularPerspectiveObject>().Any(obj => p == null || obj.InPerspective[p as Perspective]),
                                (s, m, p) => s.HideInPerspective(p as Perspective),
                                (s, m, p) => (p as Perspective).Name,
                                (s, m) => m.Perspectives, "Hide in Perspectives", true, Context.DataObjects));

            // Rename Dialogs
            Add(new Separator());

            // "Duplicate Table Object";
            Add(new Action((s, m) => Governance.AllowCreate(s),
                           (s, m) => s.ForEach(i =>
            {
                var obj = (i as IClonableObject).Clone(includeTranslations: i is ITranslatableObject && Preferences.Current.Copy_IncludeTranslations);
                if (s.Count == 1)
                {
                    obj.Edit();                   // Focuses the cloned item in the tree, and lets the user edit its name
                }
            }),
                           (s, m) => "Duplicate " + s.Summary(), true, Context.TableObject | Context.Partition | Context.CalculationItem));

            // "Duplicate Table";
            Add(new Action((s, m) => Governance.AllowCreate(s) && s.Count == 1, (s, m) => s.Table.Clone().Edit(), (s, m) => "Duplicate Table", true, Context.Table));
            Add(new Action((s, m) => Governance.AllowCreate(typeof(CalculationGroupTable)) && s.Count == 1, (s, m) => s.CalculationGroup.Clone().Edit(), (s, m) => "Duplicate Calculation Group", true, Context.CalculationGroupTable));

            // "Duplicate Translation";
            Add(new Action((s, m) => Governance.AllowCreate(typeof(Culture)) && s.Count == 1,
                           (s, m) => s.ForEach(i =>
            {
                var res = csDialog.ShowDialog();
                if (res == DialogResult.OK)
                {
                    (i as IClonableObject).Clone(csDialog.SelectedCulture.Name, false).Edit();
                }
            }),
                           (s, m) => "Duplicate " + s.Summary(), true, Context.Translation));

            // "Duplicate Role / Perspective":
            Add(new Action((s, m) => Governance.AllowCreate(typeof(Perspective)) && s.Count == 1, (s, m) => s.ForEach(i => (i as IClonableObject).Clone(null, Preferences.Current.Copy_IncludeTranslations).Edit()), (s, m) => "Duplicate Perspective", true, Context.Perspective));
            Add(new Action((s, m) => Governance.AllowCreate(typeof(ModelRole)) && s.Count == 1, (s, m) => s.ForEach(i => (i as IClonableObject).Clone(null, Preferences.Current.Copy_IncludeTranslations).Edit()), (s, m) => "Duplicate Role", true, Context.Role));

            // Batch Rename
            Add(new Action((s, m) => Governance.AllowEditProperty(s, TOMWrapper.Properties.NAME) && s.DirectCount > 1, (s, m) =>
            {
                var form  = Dialogs.ReplaceForm.Singleton;
                form.Text = "Batch Rename - (" + s.Summary() + " selected)";
                var res   = form.ShowDialog();
                if (res == DialogResult.Cancel)
                {
                    return;
                }
                // TODO: Add options for match case and whole word only
                s.Rename(form.Pattern, form.ReplaceWith, form.RegEx, form.IncludeTranslations);
            }, (s, m) => "Batch Rename...", true, Context.DataObjects | Context.Level | Context.CalculationItem | Context.Partition, Keys.F2)
            {
                ToolTip = "Opens a dialog that lets you rename all the selected objects at once. Folders are not renamed, but objects inside folders are."
            });

            // Batch Rename Children
            Add(new Action((s, m) => Governance.AllowEditProperty(new[] { ObjectType.Measure, ObjectType.Column, ObjectType.Hierarchy, ObjectType.Level }, TOMWrapper.Properties.NAME) &&
                           (s.Context == Context.Table || s.Direct.Any(i => i is Folder) || s.Context == Context.PartitionCollection), (s, m) =>
            {
                var form = Dialogs.ReplaceForm.Singleton;
                var sel  = new UISelectionList <ITabularNamedObject>(
                    s.Direct.OfType <ITabularObjectContainer>().SelectMany(t => t.GetChildren())
                    .Concat(s.Hierarchies.SelectMany(t => t.Levels))
                    .OfType <ITabularNamedObject>());
                form.Text = "Batch Rename - (" + sel.Summary() + ")";
                var res   = form.ShowDialog();
                if (res == DialogResult.Cancel)
                {
                    return;
                }
                // TODO: Add options for match case and whole word only
                sel.Rename(form.Pattern, form.ReplaceWith, form.RegEx, form.IncludeTranslations);
            }, (s, m) => "Batch Rename Children...", true, Context.DataObjects | Context.PartitionCollection, Keys.Shift | Keys.F2)
            {
                ToolTip = "Opens a dialog that lets you rename all children of the selected objects at once. Folders are not renamed, but objects inside folders are."
            });

            // Delete Action
            Delete = new Action((s, m) => Governance.AllowDelete(s) && s.Count >= 1,
                                (s, m) => {
                if (s.Count == 1)
                {
                    // Handle single-object deletion:
                    string message;
                    if (!s.First().CanDelete(out message))
                    {
                        MessageBox.Show(message, s.Summary() + " cannot be deleted.", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                        return;
                    }
                    else if (!string.IsNullOrEmpty(message))
                    {
                        var mr = MessageBox.Show(message, "Confirm deletion", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
                        if (mr == DialogResult.Cancel)
                        {
                            return;
                        }
                    }
                }
                else
                {
                    // Handle multi-object deletion:
                    string message;
                    if (s.Any(o => !o.CanDelete(out message)))
                    {
                        var mr = MessageBox.Show("One or more of the selected objects cannot be deleted. Proceed?", "Unable to delete one or more objects.", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
                        if (mr == DialogResult.Cancel)
                        {
                            return;
                        }
                    }
                    else
                    {
                        // Confirm deletion of multiple objects just in case...
                        var mr = MessageBox.Show("Are you sure you want to delete the selected objects?", s.Summary(), MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
                        if (mr == DialogResult.Cancel)
                        {
                            return;
                        }
                    }
                }

                s.Delete();
            }, (s, m) => "Delete " + s.Summary() + "...", true, Context.SingularObjects ^ Context.Model);
            Add(Delete);

            Add(new Separator());

            // Select Columns (aka. Import Table Wizard) and Refresh Table Metadata:
            Add(new Action((s, m) => Governance.AllowCreate(typeof(DataColumn)) && s.DirectCount == 1 && s.Table.Partitions[0].DataSource is ProviderDataSource, (s, m) => ImportTablesWizard.ShowWizard(s.Table), (s, m) => "Select Columns...", true, Context.Table));
            Add(new Action((s, m) => Governance.AllowCreate(typeof(DataColumn)) && s.DirectCount == 1 && m.DataSources.Any(ds => ds.Type == DataSourceType.Provider) && s.Table.Partitions.Count > 0 && s.Table.Partitions[0].DataSource is ProviderDataSource, (s, m) => ScriptHelper.SchemaCheck(s.Table), (s, m) => "Refresh Table Metadata...", true, Context.Table));

            Add(new Separator());
            Add(new Action((s, m) => m.Cultures.Count > 0, (s, m) => UIController.Current.Translations_ExportAll(), (s, m) => "Export translations...", false, Context.Translations | Context.Tool));
            Add(new Action((s, m) => Governance.AllowCreate(typeof(Culture)) && true, (s, m) => UIController.Current.Translations_Import(), (s, m) => "Import translations...", true, Context.Translations | Context.Tool));
            Add(new Action((s, m) => true, (s, m) => UIController.Current.Translations_ExportSelected(), (s, m) => string.Format("Export {0} translation{1}...", s.Count, s.Count == 1 ? "" : "s"), true, Context.Translation));

            // Table actions:
            Add(new Action((s, m) => Governance.AllowEditProperty(ObjectType.Column, TOMWrapper.Properties.ISKEY) && Governance.AllowEditProperty(ObjectType.Column, TOMWrapper.Properties.DATACATEGORY) && s.DirectCount == 1 && s.Table.Columns.Any(c => c.DataType == DataType.DateTime), (s, m) => UIController.Current.MarkAsDateTableDialog.Go(s.Table), (s, m) => "Mark as Date Table...", true, Context.Table));

            // Show dependencies...
            Add(new Action((s, m) => s.DirectCount == 1 && s.Direct.First() is IDaxObject, (s, m) =>
            {
                UIController.Current.ShowDependencies(s.Direct.First() as IDaxObject);
            }, (s, m) => @"Show &dependencies...", true, Context.Table | Context.TableObject | Context.CalculationItem, Keys.F3));

            // Filter related...
            // TODO

            /*Add(new Action((s, m) => s.DirectCount == 1, (s, m) => UIController.Current.ApplyFilter(":RelatedTables.Any(Name = \"" + s.Table.Name + "\")"),
             *  (s, m) => @"Filter &related", true, Context.Table));*/


            // Script actions:
            Add(new Action((s, m) => s.DirectCount == 1, (s, m) => Clipboard.SetText(Scripter.ScriptCreateOrReplace(s.OfType <TabularNamedObject>().FirstOrDefault())), (s, m) => @"Script\Create or Replace\To clipboard", true, Context.Scriptable));
            Add(new Action((s, m) => s.DirectCount == 1, (s, m) => Clipboard.SetText(Scripter.ScriptCreate(s.OfType <TabularNamedObject>().FirstOrDefault())), (s, m) => @"Script\Create\To clipboard", true, Context.Scriptable));
            Add(new Action((s, m) => s.DirectCount == 1, (s, m) => Clipboard.SetText(Scripter.ScriptAlter(s.OfType <TabularNamedObject>().FirstOrDefault())), (s, m) => @"Script\Alter\To clipboard", true, Context.Scriptable));
            Add(new Action((s, m) => s.DirectCount == 1, (s, m) => Clipboard.SetText(Scripter.ScriptDelete(s.OfType <TabularNamedObject>().FirstOrDefault())), (s, m) => @"Script\Delete\To clipboard", true, Context.Scriptable));
            Add(new Action((s, m) => s.DirectCount == 1, (s, m) => SaveScriptToFile(Scripter.ScriptCreateOrReplace(s.OfType <TabularNamedObject>().FirstOrDefault())), (s, m) => @"Script\Create or Replace\To file...", true, Context.Scriptable));
            Add(new Action((s, m) => s.DirectCount == 1, (s, m) => SaveScriptToFile(Scripter.ScriptCreate(s.OfType <TabularNamedObject>().FirstOrDefault())), (s, m) => @"Script\Create\To file...", true, Context.Scriptable));
            Add(new Action((s, m) => s.DirectCount == 1, (s, m) => SaveScriptToFile(Scripter.ScriptAlter(s.OfType <TabularNamedObject>().FirstOrDefault())), (s, m) => @"Script\Alter\To file...", true, Context.Scriptable));
            Add(new Action((s, m) => s.DirectCount == 1, (s, m) => SaveScriptToFile(Scripter.ScriptDelete(s.OfType <TabularNamedObject>().FirstOrDefault())), (s, m) => @"Script\Delete\To file...", true, Context.Scriptable));

            Add(new Action((s, m) => s.DirectCount > 1, (s, m) => Clipboard.SetText(Scripter.ScriptMergePartitions(s.OfType <Partition>().ToList())), (s, m) => @"Script\Merge Partitions\To clipboard", true, Context.Partition));
            Add(new Action((s, m) => s.DirectCount > 1, (s, m) => SaveScriptToFile(Scripter.ScriptMergePartitions(s.OfType <Partition>().ToList())), (s, m) => @"Script\Merge Partitions\To file...", true, Context.Partition));

            Add(new RefreshAction(true));
            Add(new RefreshAction(false));
        }
Example #48
0
        public Errno Mount(IMediaImage imagePlugin, Partition partition, Encoding encoding,
                           Dictionary <string, string> options, string @namespace)
        {
            // TODO: Find correct default encoding
            Encoding = Encoding.ASCII;

            if (options == null)
            {
                options = GetDefaultOptions();
            }
            if (options.TryGetValue("debug", out string debugString))
            {
                bool.TryParse(debugString, out debug);
            }

            byte[] sbSector = imagePlugin.ReadSector(0 + partition.Start);

            SuperBlock sb = Marshal.ByteArrayToStructureBigEndian <SuperBlock>(sbSector);

            if (sb.record_type != 1 || sb.record_version != 1)
            {
                return(Errno.InvalidArgument);
            }
            if (Encoding.ASCII.GetString(sb.sync_bytes) != SYNC)
            {
                return(Errno.InvalidArgument);
            }

            if (imagePlugin.Info.SectorSize == 2336 || imagePlugin.Info.SectorSize == 2352 ||
                imagePlugin.Info.SectorSize == 2448)
            {
                volumeBlockSizeRatio = sb.block_size / 2048;
            }
            else
            {
                volumeBlockSizeRatio = sb.block_size / imagePlugin.Info.SectorSize;
            }

            XmlFsType = new FileSystemType
            {
                Type         = "Opera",
                VolumeName   = StringHandlers.CToString(sb.volume_label, Encoding),
                ClusterSize  = sb.block_size,
                Clusters     = sb.block_count,
                Bootable     = true,
                VolumeSerial = $"{sb.volume_id:X8}"
            };

            statfs = new FileSystemInfo
            {
                Blocks         = sb.block_count,
                FilenameLength = MAX_NAME,
                FreeBlocks     = 0,
                Id             = new FileSystemId {
                    IsInt = true, Serial32 = sb.volume_id
                },
                PluginId = Id,
                Type     = "Opera"
            };

            image = imagePlugin;
            int firstRootBlock = BigEndianBitConverter.ToInt32(sbSector, Marshal.SizeOf <SuperBlock>());

            rootDirectoryCache = DecodeDirectory(firstRootBlock);
            directoryCache     = new Dictionary <string, Dictionary <string, DirectoryEntryWithPointers> >();
            mounted            = true;

            return(Errno.NoError);
        }
Example #49
0
 /// <summary>
 ///   Returns a string that represents the current object.
 /// </summary>
 /// <returns>A string that represents the current object.</returns>
 public override string ToString() => $"{nameof(Partition)}: {Partition?.ToString()}, {nameof(Key)}: {Key?.ToString()}, {nameof(UtcExpiry)}: {UtcExpiry.ToString()}";
Example #50
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding = encoding ?? Encoding.UTF8;
            byte[] sector = imagePlugin.ReadSector(partition.Start);
            uint   magic  = BitConverter.ToUInt32(sector, 0x00);

            SquashSuperBlock sqSb         = new SquashSuperBlock();
            bool             littleEndian = true;

            switch (magic)
            {
            case SQUASH_MAGIC:
                IntPtr sqSbPtr = Marshal.AllocHGlobal(Marshal.SizeOf(sqSb));
                Marshal.Copy(sector, 0, sqSbPtr, Marshal.SizeOf(sqSb));
                sqSb = (SquashSuperBlock)Marshal.PtrToStructure(sqSbPtr, typeof(SquashSuperBlock));
                Marshal.FreeHGlobal(sqSbPtr);
                break;

            case SQUASH_CIGAM:
                sqSb         = BigEndianMarshal.ByteArrayToStructureBigEndian <SquashSuperBlock>(sector);
                littleEndian = false;
                break;
            }

            StringBuilder sbInformation = new StringBuilder();

            sbInformation.AppendLine("Squash file system");
            sbInformation.AppendLine(littleEndian ? "Little-endian" : "Big-endian");
            sbInformation.AppendFormat("Volume version {0}.{1}", sqSb.s_major, sqSb.s_minor).AppendLine();
            sbInformation.AppendFormat("Volume has {0} bytes", sqSb.bytes_used).AppendLine();
            sbInformation.AppendFormat("Volume has {0} bytes per block", sqSb.block_size).AppendLine();
            sbInformation.AppendFormat("Volume created on {0}", DateHandlers.UnixUnsignedToDateTime(sqSb.mkfs_time))
            .AppendLine();
            sbInformation.AppendFormat("Volume has {0} inodes", sqSb.inodes).AppendLine();
            switch (sqSb.compression)
            {
            case (ushort)SquashCompression.Lz4:
                sbInformation.AppendLine("Volume is compressed using LZ4");
                break;

            case (ushort)SquashCompression.Lzo:
                sbInformation.AppendLine("Volume is compressed using LZO");
                break;

            case (ushort)SquashCompression.Lzma:
                sbInformation.AppendLine("Volume is compressed using LZMA");
                break;

            case (ushort)SquashCompression.Xz:
                sbInformation.AppendLine("Volume is compressed using XZ");
                break;

            case (ushort)SquashCompression.Zlib:
                sbInformation.AppendLine("Volume is compressed using GZIP");
                break;

            case (ushort)SquashCompression.Zstd:
                sbInformation.AppendLine("Volume is compressed using Zstandard");
                break;

            default:
                sbInformation.AppendFormat("Volume is compressed using unknown algorithm {0}", sqSb.compression)
                .AppendLine();
                break;
            }

            information = sbInformation.ToString();

            XmlFsType = new FileSystemType
            {
                Type                  = "Squash file system",
                CreationDate          = DateHandlers.UnixUnsignedToDateTime(sqSb.mkfs_time),
                CreationDateSpecified = true,
                Clusters              =
                    (long)((partition.End - partition.Start + 1) * imagePlugin.Info.SectorSize / sqSb.block_size),
                ClusterSize           = (int)sqSb.block_size,
                Files                 = sqSb.inodes,
                FilesSpecified        = true,
                FreeClusters          = 0,
                FreeClustersSpecified = true
            };
        }
Example #51
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("iso-8859-15");
            information = "";
            StringBuilder sb          = new StringBuilder();
            uint          bootSectors = JFS_BOOT_BLOCKS_SIZE / imagePlugin.Info.SectorSize;

            byte[] sector = imagePlugin.ReadSector(partition.Start + bootSectors);
            if (sector.Length < 512)
            {
                return;
            }

            JfsSuperBlock jfsSb = Marshal.ByteArrayToStructureLittleEndian <JfsSuperBlock>(sector);

            sb.AppendLine("JFS filesystem");
            sb.AppendFormat("Version {0}", jfsSb.s_version).AppendLine();
            sb.AppendFormat("{0} blocks of {1} bytes", jfsSb.s_size, jfsSb.s_bsize).AppendLine();
            sb.AppendFormat("{0} blocks per allocation group", jfsSb.s_agsize).AppendLine();

            if (jfsSb.s_flags.HasFlag(JfsFlags.Unicode))
            {
                sb.AppendLine("Volume uses Unicode for directory entries");
            }
            if (jfsSb.s_flags.HasFlag(JfsFlags.RemountRO))
            {
                sb.AppendLine("Volume remounts read-only on error");
            }
            if (jfsSb.s_flags.HasFlag(JfsFlags.Continue))
            {
                sb.AppendLine("Volume continues on error");
            }
            if (jfsSb.s_flags.HasFlag(JfsFlags.Panic))
            {
                sb.AppendLine("Volume panics on error");
            }
            if (jfsSb.s_flags.HasFlag(JfsFlags.UserQuota))
            {
                sb.AppendLine("Volume has user quotas enabled");
            }
            if (jfsSb.s_flags.HasFlag(JfsFlags.GroupQuota))
            {
                sb.AppendLine("Volume has group quotas enabled");
            }
            if (jfsSb.s_flags.HasFlag(JfsFlags.NoJournal))
            {
                sb.AppendLine("Volume is not using any journal");
            }
            if (jfsSb.s_flags.HasFlag(JfsFlags.Discard))
            {
                sb.AppendLine("Volume sends TRIM/UNMAP commands to underlying device");
            }
            if (jfsSb.s_flags.HasFlag(JfsFlags.GroupCommit))
            {
                sb.AppendLine("Volume commits in groups of 1");
            }
            if (jfsSb.s_flags.HasFlag(JfsFlags.LazyCommit))
            {
                sb.AppendLine("Volume commits lazy");
            }
            if (jfsSb.s_flags.HasFlag(JfsFlags.Temporary))
            {
                sb.AppendLine("Volume does not commit to log");
            }
            if (jfsSb.s_flags.HasFlag(JfsFlags.InlineLog))
            {
                sb.AppendLine("Volume has log withing itself");
            }
            if (jfsSb.s_flags.HasFlag(JfsFlags.InlineMoving))
            {
                sb.AppendLine("Volume has log withing itself and is moving it out");
            }
            if (jfsSb.s_flags.HasFlag(JfsFlags.BadSAIT))
            {
                sb.AppendLine("Volume has bad current secondary ait");
            }
            if (jfsSb.s_flags.HasFlag(JfsFlags.Sparse))
            {
                sb.AppendLine("Volume supports sparse files");
            }
            if (jfsSb.s_flags.HasFlag(JfsFlags.DASDEnabled))
            {
                sb.AppendLine("Volume has DASD limits enabled");
            }
            if (jfsSb.s_flags.HasFlag(JfsFlags.DASDPrime))
            {
                sb.AppendLine("Volume primes DASD on boot");
            }
            if (jfsSb.s_flags.HasFlag(JfsFlags.SwapBytes))
            {
                sb.AppendLine("Volume is in a big-endian system");
            }
            if (jfsSb.s_flags.HasFlag(JfsFlags.DirIndex))
            {
                sb.AppendLine("Volume has presistent indexes");
            }
            if (jfsSb.s_flags.HasFlag(JfsFlags.Linux))
            {
                sb.AppendLine("Volume supports Linux");
            }
            if (jfsSb.s_flags.HasFlag(JfsFlags.DFS))
            {
                sb.AppendLine("Volume supports DCE DFS LFS");
            }
            if (jfsSb.s_flags.HasFlag(JfsFlags.OS2))
            {
                sb.AppendLine("Volume supports OS/2, and is case insensitive");
            }
            if (jfsSb.s_flags.HasFlag(JfsFlags.AIX))
            {
                sb.AppendLine("Volume supports AIX");
            }
            if (jfsSb.s_state != 0)
            {
                sb.AppendLine("Volume is dirty");
            }
            sb.AppendFormat("Volume was last updated on {0}",
                            DateHandlers.UnixUnsignedToDateTime(jfsSb.s_time.tv_sec, jfsSb.s_time.tv_nsec))
            .AppendLine();
            if (jfsSb.s_version == 1)
            {
                sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(jfsSb.s_fpack, Encoding)).AppendLine();
            }
            else
            {
                sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(jfsSb.s_label, Encoding)).AppendLine();
            }
            sb.AppendFormat("Volume UUID: {0}", jfsSb.s_uuid).AppendLine();

            XmlFsType = new FileSystemType
            {
                Type        = "JFS filesystem",
                Clusters    = jfsSb.s_size,
                ClusterSize = jfsSb.s_bsize,
                Bootable    = true,
                VolumeName  =
                    StringHandlers.CToString(jfsSb.s_version == 1 ? jfsSb.s_fpack : jfsSb.s_label, Encoding),
                VolumeSerial     = $"{jfsSb.s_uuid}",
                ModificationDate =
                    DateHandlers.UnixUnsignedToDateTime(jfsSb.s_time.tv_sec, jfsSb.s_time.tv_nsec),
                ModificationDateSpecified = true
            };
            if (jfsSb.s_state != 0)
            {
                XmlFsType.Dirty = true;
            }

            information = sb.ToString();
        }
Example #52
0
File: PCFX.cs Project: paulyc/Aaru
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            // Always Shift-JIS
            Encoding    = Encoding.GetEncoding("shift_jis");
            information = "";

            byte[] sector = imagePlugin.ReadSectors(partition.Start, 2);
            Header header = Marshal.ByteArrayToStructureLittleEndian <Header>(sector);

            string   date;
            DateTime dateTime = DateTime.MinValue;

            try
            {
                date = Encoding.GetString(header.date);
                int year  = int.Parse(date.Substring(0, 4));
                int month = int.Parse(date.Substring(4, 2));
                int day   = int.Parse(date.Substring(6, 2));
                dateTime = new DateTime(year, month, day);
            }
            catch
            {
                date = null;
            }

            var sb = new StringBuilder();

            sb.AppendLine("PC-FX executable:");
            sb.AppendFormat("Identifier: {0}", StringHandlers.CToString(header.signature, Encoding)).AppendLine();
            sb.AppendFormat("Copyright: {0}", StringHandlers.CToString(header.copyright, Encoding)).AppendLine();
            sb.AppendFormat("Title: {0}", StringHandlers.CToString(header.title, Encoding)).AppendLine();
            sb.AppendFormat("Maker ID: {0}", StringHandlers.CToString(header.makerId, Encoding)).AppendLine();
            sb.AppendFormat("Maker name: {0}", StringHandlers.CToString(header.makerName, Encoding)).AppendLine();
            sb.AppendFormat("Volume number: {0}", header.volumeNumber).AppendLine();
            sb.AppendFormat("Country code: {0}", header.country).AppendLine();
            sb.AppendFormat("Version: {0}.{1}", header.minorVersion, header.majorVersion).AppendLine();

            if (date != null)
            {
                sb.AppendFormat("Dated {0}", dateTime).AppendLine();
            }

            sb.AppendFormat("Load {0} sectors from sector {1}", header.loadCount, header.loadOffset).AppendLine();

            sb.AppendFormat("Load at 0x{0:X8} and jump to 0x{1:X8}", header.loadAddress, header.entryPoint).
            AppendLine();

            information = sb.ToString();

            XmlFsType = new FileSystemType
            {
                Type                  = "PC-FX",
                Clusters              = partition.Length,
                ClusterSize           = 2048,
                Bootable              = true,
                CreationDate          = dateTime,
                CreationDateSpecified = date != null,
                PublisherIdentifier   = StringHandlers.CToString(header.makerName, Encoding),
                VolumeName            = StringHandlers.CToString(header.title, Encoding),
                SystemIdentifier      = "PC-FX"
            };
        }
Example #53
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
            StringBuilder sbInformation = new StringBuilder();

            XmlFsType   = new FileSystemType();
            information = "";

            ulong sbSectorOff  = 0x10000 / imagePlugin.Info.SectorSize;
            uint  sbSectorSize = 0x1000 / imagePlugin.Info.SectorSize;

            byte[] sector = imagePlugin.ReadSectors(sbSectorOff + partition.Start, sbSectorSize);

            SuperBlock btrfsSb = Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(sector);

            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.checksum = {0}", btrfsSb.checksum);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.uuid = {0}", btrfsSb.uuid);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.pba = {0}", btrfsSb.pba);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.flags = {0}", btrfsSb.flags);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.magic = {0}", btrfsSb.magic);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.generation = {0}", btrfsSb.generation);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.root_lba = {0}", btrfsSb.root_lba);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.chunk_lba = {0}", btrfsSb.chunk_lba);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.log_lba = {0}", btrfsSb.log_lba);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.log_root_transid = {0}", btrfsSb.log_root_transid);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.total_bytes = {0}", btrfsSb.total_bytes);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.bytes_used = {0}", btrfsSb.bytes_used);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.root_dir_objectid = {0}", btrfsSb.root_dir_objectid);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.num_devices = {0}", btrfsSb.num_devices);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.sectorsize = {0}", btrfsSb.sectorsize);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.nodesize = {0}", btrfsSb.nodesize);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.leafsize = {0}", btrfsSb.leafsize);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.stripesize = {0}", btrfsSb.stripesize);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.n = {0}", btrfsSb.n);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.chunk_root_generation = {0}",
                                      btrfsSb.chunk_root_generation);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.compat_flags = 0x{0:X16}", btrfsSb.compat_flags);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.compat_ro_flags = 0x{0:X16}", btrfsSb.compat_ro_flags);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.incompat_flags = 0x{0:X16}", btrfsSb.incompat_flags);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.csum_type = {0}", btrfsSb.csum_type);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.root_level = {0}", btrfsSb.root_level);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.chunk_root_level = {0}", btrfsSb.chunk_root_level);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.log_root_level = {0}", btrfsSb.log_root_level);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.id = 0x{0:X16}", btrfsSb.dev_item.id);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.bytes = {0}", btrfsSb.dev_item.bytes);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.used = {0}", btrfsSb.dev_item.used);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.optimal_align = {0}",
                                      btrfsSb.dev_item.optimal_align);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.optimal_width = {0}",
                                      btrfsSb.dev_item.optimal_width);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.minimal_size = {0}",
                                      btrfsSb.dev_item.minimal_size);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.type = {0}", btrfsSb.dev_item.type);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.generation = {0}", btrfsSb.dev_item.generation);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.start_offset = {0}",
                                      btrfsSb.dev_item.start_offset);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.dev_group = {0}", btrfsSb.dev_item.dev_group);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.seek_speed = {0}", btrfsSb.dev_item.seek_speed);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.bandwitdh = {0}", btrfsSb.dev_item.bandwitdh);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.device_uuid = {0}",
                                      btrfsSb.dev_item.device_uuid);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.uuid = {0}", btrfsSb.dev_item.uuid);
            DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.label = {0}", btrfsSb.label);

            sbInformation.AppendLine("B-tree filesystem");
            sbInformation.AppendFormat("UUID: {0}", btrfsSb.uuid).AppendLine();
            sbInformation.AppendFormat("This superblock resides on physical block {0}", btrfsSb.pba).AppendLine();
            sbInformation.AppendFormat("Root tree starts at LBA {0}", btrfsSb.root_lba).AppendLine();
            sbInformation.AppendFormat("Chunk tree starts at LBA {0}", btrfsSb.chunk_lba).AppendLine();
            sbInformation.AppendFormat("Log tree starts at LBA {0}", btrfsSb.log_lba).AppendLine();
            sbInformation.AppendFormat("Volume has {0} bytes spanned in {1} devices", btrfsSb.total_bytes,
                                       btrfsSb.num_devices).AppendLine();
            sbInformation.AppendFormat("Volume has {0} bytes used", btrfsSb.bytes_used).AppendLine();
            sbInformation.AppendFormat("{0} bytes/sector", btrfsSb.sectorsize).AppendLine();
            sbInformation.AppendFormat("{0} bytes/node", btrfsSb.nodesize).AppendLine();
            sbInformation.AppendFormat("{0} bytes/leaf", btrfsSb.leafsize).AppendLine();
            sbInformation.AppendFormat("{0} bytes/stripe", btrfsSb.stripesize).AppendLine();
            sbInformation.AppendFormat("Flags: 0x{0:X}", btrfsSb.flags).AppendLine();
            sbInformation.AppendFormat("Compatible flags: 0x{0:X}", btrfsSb.compat_flags).AppendLine();
            sbInformation.AppendFormat("Read-only compatible flags: 0x{0:X}", btrfsSb.compat_ro_flags).AppendLine();
            sbInformation.AppendFormat("Incompatible flags: 0x{0:X}", btrfsSb.incompat_flags).AppendLine();
            sbInformation.AppendFormat("Device's UUID: {0}", btrfsSb.dev_item.uuid).AppendLine();
            sbInformation.AppendFormat("Volume label: {0}", btrfsSb.label).AppendLine();

            information = sbInformation.ToString();

            XmlFsType = new FileSystemType
            {
                Clusters              = btrfsSb.total_bytes / btrfsSb.sectorsize,
                ClusterSize           = btrfsSb.sectorsize,
                FreeClustersSpecified = true,
                VolumeName            = btrfsSb.label,
                VolumeSerial          = $"{btrfsSb.uuid}",
                VolumeSetIdentifier   = $"{btrfsSb.dev_item.device_uuid}",
                Type = Name
            };
            XmlFsType.FreeClusters = XmlFsType.Clusters - btrfsSb.bytes_used / btrfsSb.sectorsize;
        }
Example #54
0
 public bool Contains(Partition p)
 {
     return(this.partitions.Contains(p));
 }
Example #55
0
        public override void Read(IO.EndianReader s)
        {
            int k_local_sizeof = Blam.CacheFile.ValidateHeader(s, kSizeOfBeta, kSizeOf);

            s.Seek(4);
            version = s.ReadInt32();
            if (version != 11 && version != 12)
            {
                throw new InvalidCacheFileException(s.FileName);
            }
            fileLength = s.ReadInt32();
            s.ReadInt32();
            tagIndexAddress    = s.ReadUInt32();
            memoryBufferOffset = s.ReadInt32();
            memoryBufferSize   = s.ReadInt32();

            sourceFile = s.ReadAsciiString(256);
            build      = s.ReadTagString();
            cacheType  = (Blam.CacheType)s.ReadInt16();
            sharedType = (Cache.SharedType)s.ReadInt16();

            s.ReadBool();
            s.ReadBool();             // false if it belongs to a untracked build
            s.ReadBool();
            s.ReadByte();             // appears to be an ODST-only field

            s.ReadInt32(); s.ReadInt32();
            s.ReadInt32(); s.ReadInt32(); s.ReadInt32();

            #region string id table
            // 0x158
            stringIdsCount        = s.ReadInt32();
            stringIdsBufferSize   = s.ReadInt32();
            stringIdIndicesOffset = s.ReadInt32();
            stringIdsBufferOffset = s.ReadInt32();
            #endregion

            #region filetimes?
            // pretty sure this is a flags field
            // used to tell which of the following 64bit values
            // are used. Damn sure this are FILETIME structures, but
            // hex workshop doesn't like them so I can't be for sure...
            needsShared             = s.ReadInt32() != 0; // just a little 'hack' if you will. if zero, the map is self reliant, so no worries
            Filetime.dwHighDateTime = s.ReadInt32();
            Filetime.dwLowDateTime  = s.ReadInt32();
            if (s.ReadInt32() != 0)
            {
                flags.Add(Halo3.CacheHeaderFlags.DependsOnMainMenu);
            }
            s.ReadInt32();
            if (s.ReadInt32() != 0)
            {
                flags.Add(Halo3.CacheHeaderFlags.DependsOnShared);
            }
            s.ReadInt32();
            if (s.ReadInt32() != 0)
            {
                flags.Add(Halo3.CacheHeaderFlags.DependsOnCampaign);
            }
            s.ReadInt32();
            #endregion

            name = s.ReadTagString();
            s.ReadInt32();
            scenarioPath = s.ReadAsciiString(256);
            s.ReadInt32();             // minor version, normally not used

            #region tag paths
            tagNamesCount        = s.ReadInt32();
            tagNamesBufferOffset = s.ReadInt32();           // cstring buffer
            tagNamesBufferSize   = s.ReadInt32();           // cstring buffer total size in bytes
            tagNameIndicesOffset = s.ReadInt32();
            #endregion

            checksum = s.ReadUInt32();                // 0x2C4
            s.Seek(32, System.IO.SeekOrigin.Current); // these bytes are always the same

            baseAddress = s.ReadUInt32();             // expected base address
            xdkVersion  = s.ReadInt32();              // xdk version

            #region memory partitions
            // 0x2F0

            // memory partitions
            memoryPartitions = new Partition[6];
            memoryPartitions[0].BaseAddress = s.ReadUInt32();             // cache resource buffer
            memoryPartitions[0].Size        = s.ReadInt32();

            // readonly
            memoryPartitions[1].BaseAddress = s.ReadUInt32();             // cache gestalt resource buffer
            memoryPartitions[1].Size        = s.ReadInt32();

            memoryPartitions[2].BaseAddress = s.ReadUInt32();             // global tags buffer (cache sound tags likes this memory space too)
            memoryPartitions[2].Size        = s.ReadInt32();
            memoryPartitions[3].BaseAddress = s.ReadUInt32();             // shared tag blocks? (havok data likes this memory space too)
            memoryPartitions[3].Size        = s.ReadInt32();
            memoryPartitions[4].BaseAddress = s.ReadUInt32();             // address
            memoryPartitions[4].Size        = s.ReadInt32();

            // readonly
            memoryPartitions[5].BaseAddress = s.ReadUInt32();             // map tags buffer
            memoryPartitions[5].Size        = s.ReadInt32();
            #endregion

            int count = s.ReadInt32();
            s.Seek(4 + 8, System.IO.SeekOrigin.Current);             // these bytes are always the same
            // if there is a hash in the header, this is the ONLY
            // place where it can be
            s.Seek(20 /*SHA1*/ + 40 + 256 /*RSA*/, System.IO.SeekOrigin.Current);             // ???

            // 0x46C
            cacheInterop.Read(s);
            cacheInterop.PostprocessForCacheRead(k_local_sizeof);

            s.Seek(16, System.IO.SeekOrigin.Current);             // GUID?, these bytes are always the same. ODST is different from Halo 3

            #region blah 1
            // 0x4AC

            // campaign has a shit load of these
            // but shared doesn't nor mainmenu
            // I compared the sc110 french and english and both have the SAME counts and element data. So
            // I don't think this is a hash or something. At least, if it is, it's not runtime relative so
            // nothing we have to worry about

            s.ReadInt16();             // I've only seen this be two different values (besides zero).
            count = s.ReadInt16();     // I think the above specifies the size of the structure this count represents?
            s.ReadInt32();             // seems to always be zero
            CompressionGuid = new Guid(s.ReadBytes(16));

            s.Seek(count * 28, System.IO.SeekOrigin.Current);             // seek past the elements
            // dword
            // long
            // buffer [0x14] (probably a sha1 hash)
            s.Seek((320 - count) * 28, System.IO.SeekOrigin.Current);             // seek past the unused elements
            #endregion

            // this shit has changed. f**k you.
            #region blah 2
#if false
            {
                // 0x27C4
                // This on the other hand, sc110 french and english had MINOR differences. Those differences were in
                // DWORDs @ 0x4 and 0x8

                // going to punt and just assume there is a max count of 10 of these possible

                // maybe related to bsp\'zones'?
                const int blah2_sizeof = 180;

                count = (int)(s.ReadUInt32() >> 24);                               // did someone forget to f*****g byte swap something?
                s.Seek(count * blah2_sizeof, System.IO.SeekOrigin.Current);        // seek past the elements
                s.Seek((10 - count) * blah2_sizeof, System.IO.SeekOrigin.Current); // seek past the unused elements
            }
#endif
            #endregion

            //s.Seek(300 + sizeof(uint), System.IO.SeekOrigin.Current); // zero
            s.Seek(6200 + sizeof(uint), System.IO.SeekOrigin.Current);


            ReadPostprocessForInterop();

            ReadPostprocessForBaseAddresses(s);
        }
Example #56
0
 public override int GetHashCode()
 {
     return(Topic.GetHashCode() & Partition.GetHashCode() ^ 33333);
 }
Example #57
0
        public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
                                   Encoding encoding)
        {
            Encoding    = encoding ?? Encoding.GetEncoding("iso-8859-1");
            information = "";

            var sb = new StringBuilder();

            byte[] hbSector = imagePlugin.ReadSector(1 + partition.Start);

            OdsHomeBlock homeblock = Marshal.ByteArrayToStructureLittleEndian <OdsHomeBlock>(hbSector);

            // Optical disc
            if (imagePlugin.Info.XmlMediaType == XmlMediaType.OpticalDisc &&
                StringHandlers.CToString(homeblock.format) != "DECFILE11A  " &&
                StringHandlers.CToString(homeblock.format) != "DECFILE11B  ")
            {
                if (hbSector.Length < 0x400)
                {
                    return;
                }

                byte[] tmp = imagePlugin.ReadSector(partition.Start);
                hbSector = new byte[0x200];
                Array.Copy(tmp, 0x200, hbSector, 0, 0x200);

                homeblock = Marshal.ByteArrayToStructureLittleEndian <OdsHomeBlock>(hbSector);

                if (StringHandlers.CToString(homeblock.format) != "DECFILE11A  " &&
                    StringHandlers.CToString(homeblock.format) != "DECFILE11B  ")
                {
                    return;
                }
            }

            if ((homeblock.struclev & 0xFF00) != 0x0200 ||
                (homeblock.struclev & 0xFF) != 1 ||
                StringHandlers.CToString(homeblock.format) != "DECFILE11B  ")
            {
                sb.AppendLine("The following information may be incorrect for this volume.");
            }

            if (homeblock.resfiles < 5 ||
                homeblock.devtype != 0)
            {
                sb.AppendLine("This volume may be corrupted.");
            }

            sb.AppendFormat("Volume format is {0}", StringHandlers.SpacePaddedToString(homeblock.format, Encoding)).
            AppendLine();

            sb.AppendFormat("Volume is Level {0} revision {1}", (homeblock.struclev & 0xFF00) >> 8,
                            homeblock.struclev & 0xFF).AppendLine();

            sb.AppendFormat("Lowest structure in the volume is Level {0}, revision {1}",
                            (homeblock.lowstruclev & 0xFF00) >> 8, homeblock.lowstruclev & 0xFF).AppendLine();

            sb.AppendFormat("Highest structure in the volume is Level {0}, revision {1}",
                            (homeblock.highstruclev & 0xFF00) >> 8, homeblock.highstruclev & 0xFF).AppendLine();

            sb.AppendFormat("{0} sectors per cluster ({1} bytes)", homeblock.cluster, homeblock.cluster * 512).
            AppendLine();

            sb.AppendFormat("This home block is on sector {0} (VBN {1})", homeblock.homelbn, homeblock.homevbn).
            AppendLine();

            sb.AppendFormat("Secondary home block is on sector {0} (VBN {1})", homeblock.alhomelbn,
                            homeblock.alhomevbn).AppendLine();

            sb.AppendFormat("Volume bitmap starts in sector {0} (VBN {1})", homeblock.ibmaplbn, homeblock.ibmapvbn).
            AppendLine();

            sb.AppendFormat("Volume bitmap runs for {0} sectors ({1} bytes)", homeblock.ibmapsize,
                            homeblock.ibmapsize * 512).AppendLine();

            sb.AppendFormat("Backup INDEXF.SYS;1 is in sector {0} (VBN {1})", homeblock.altidxlbn, homeblock.altidxvbn).
            AppendLine();

            sb.AppendFormat("{0} maximum files on the volume", homeblock.maxfiles).AppendLine();
            sb.AppendFormat("{0} reserved files", homeblock.resfiles).AppendLine();

            if (homeblock.rvn > 0 &&
                homeblock.setcount > 0 &&
                StringHandlers.CToString(homeblock.strucname) != "            ")
            {
                sb.AppendFormat("Volume is {0} of {1} in set \"{2}\".", homeblock.rvn, homeblock.setcount,
                                StringHandlers.SpacePaddedToString(homeblock.strucname, Encoding)).AppendLine();
            }

            sb.AppendFormat("Volume owner is \"{0}\" (ID 0x{1:X8})",
                            StringHandlers.SpacePaddedToString(homeblock.ownername, Encoding), homeblock.volowner).
            AppendLine();

            sb.AppendFormat("Volume label: \"{0}\"", StringHandlers.SpacePaddedToString(homeblock.volname, Encoding)).
            AppendLine();

            sb.AppendFormat("Drive serial number: 0x{0:X8}", homeblock.serialnum).AppendLine();
            sb.AppendFormat("Volume was created on {0}", DateHandlers.VmsToDateTime(homeblock.credate)).AppendLine();

            if (homeblock.revdate > 0)
            {
                sb.AppendFormat("Volume was last modified on {0}", DateHandlers.VmsToDateTime(homeblock.revdate)).
                AppendLine();
            }

            if (homeblock.copydate > 0)
            {
                sb.AppendFormat("Volume copied on {0}", DateHandlers.VmsToDateTime(homeblock.copydate)).AppendLine();
            }

            sb.AppendFormat("Checksums: 0x{0:X4} and 0x{1:X4}", homeblock.checksum1, homeblock.checksum2).AppendLine();
            sb.AppendLine("Flags:");
            sb.AppendFormat("Window: {0}", homeblock.window).AppendLine();
            sb.AppendFormat("Cached directores: {0}", homeblock.lru_lim).AppendLine();
            sb.AppendFormat("Default allocation: {0} blocks", homeblock.extend).AppendLine();

            if ((homeblock.volchar & 0x01) == 0x01)
            {
                sb.AppendLine("Readings should be verified");
            }

            if ((homeblock.volchar & 0x02) == 0x02)
            {
                sb.AppendLine("Writings should be verified");
            }

            if ((homeblock.volchar & 0x04) == 0x04)
            {
                sb.AppendLine("Files should be erased or overwritten when deleted");
            }

            if ((homeblock.volchar & 0x08) == 0x08)
            {
                sb.AppendLine("Highwater mark is to be disabled");
            }

            if ((homeblock.volchar & 0x10) == 0x10)
            {
                sb.AppendLine("Classification checks are enabled");
            }

            sb.AppendLine("Volume permissions (r = read, w = write, c = create, d = delete)");
            sb.AppendLine("System, owner, group, world");

            // System
            sb.Append((homeblock.protect & 0x1000) == 0x1000 ? "-" : "r");
            sb.Append((homeblock.protect & 0x2000) == 0x2000 ? "-" : "w");
            sb.Append((homeblock.protect & 0x4000) == 0x4000 ? "-" : "c");
            sb.Append((homeblock.protect & 0x8000) == 0x8000 ? "-" : "d");

            // Owner
            sb.Append((homeblock.protect & 0x100) == 0x100 ? "-" : "r");
            sb.Append((homeblock.protect & 0x200) == 0x200 ? "-" : "w");
            sb.Append((homeblock.protect & 0x400) == 0x400 ? "-" : "c");
            sb.Append((homeblock.protect & 0x800) == 0x800 ? "-" : "d");

            // Group
            sb.Append((homeblock.protect & 0x10) == 0x10 ? "-" : "r");
            sb.Append((homeblock.protect & 0x20) == 0x20 ? "-" : "w");
            sb.Append((homeblock.protect & 0x40) == 0x40 ? "-" : "c");
            sb.Append((homeblock.protect & 0x80) == 0x80 ? "-" : "d");

            // World (other)
            sb.Append((homeblock.protect & 0x1) == 0x1 ? "-" : "r");
            sb.Append((homeblock.protect & 0x2) == 0x2 ? "-" : "w");
            sb.Append((homeblock.protect & 0x4) == 0x4 ? "-" : "c");
            sb.Append((homeblock.protect & 0x8) == 0x8 ? "-" : "d");

            sb.AppendLine();

            sb.AppendLine("Unknown structures:");
            sb.AppendFormat("Security mask: 0x{0:X8}", homeblock.sec_mask).AppendLine();
            sb.AppendFormat("File protection: 0x{0:X4}", homeblock.fileprot).AppendLine();
            sb.AppendFormat("Record protection: 0x{0:X4}", homeblock.recprot).AppendLine();

            XmlFsType = new FileSystemType
            {
                Type         = "FILES-11", ClusterSize = (uint)(homeblock.cluster * 512),
                Clusters     = partition.Size / (ulong)(homeblock.cluster * 512),
                VolumeName   = StringHandlers.SpacePaddedToString(homeblock.volname, Encoding),
                VolumeSerial = $"{homeblock.serialnum:X8}"
            };

            if (homeblock.credate > 0)
            {
                XmlFsType.CreationDate          = DateHandlers.VmsToDateTime(homeblock.credate);
                XmlFsType.CreationDateSpecified = true;
            }

            if (homeblock.revdate > 0)
            {
                XmlFsType.ModificationDate          = DateHandlers.VmsToDateTime(homeblock.revdate);
                XmlFsType.ModificationDateSpecified = true;
            }

            information = sb.ToString();
        }
Example #58
0
        public void PartitionInit()
        {
            var p = new Partition();

            p.Dispose();
        }
Example #59
0
        /// <summary>
        ///     Mounts an Apple Lisa filesystem
        /// </summary>
        public Errno Mount(IMediaImage imagePlugin, Partition partition, Encoding encoding,
                           Dictionary <string, string> options, string @namespace)
        {
            XmlFsType = new FileSystemType();
            if (options == null)
            {
                options = GetDefaultOptions();
            }
            if (options.TryGetValue("debug", out string debugString))
            {
                bool.TryParse(debugString, out debug);
            }

            // Default namespace
            if (@namespace is null)
            {
                @namespace = "ecs";
            }

            switch (@namespace.ToLowerInvariant())
            {
            case "dos":
                this.@namespace = Namespace.Dos;
                break;

            case "nt":
                this.@namespace = Namespace.Nt;
                break;

            case "os2":
                this.@namespace = Namespace.Os2;
                break;

            case "ecs":
                this.@namespace = Namespace.Ecs;
                break;

            case "lfn":
                this.@namespace = Namespace.Lfn;
                break;

            case "human":
                this.@namespace = Namespace.Human;
                break;

            default: return(Errno.InvalidArgument);
            }

            DicConsole.DebugWriteLine("FAT plugin", "Reading BPB");

            uint sectorsPerBpb = imagePlugin.Info.SectorSize < 512 ? 512 / imagePlugin.Info.SectorSize : 1;

            byte[] bpbSector = imagePlugin.ReadSectors(0 + partition.Start, sectorsPerBpb);

            BpbKind bpbKind = DetectBpbKind(bpbSector, imagePlugin, partition,
                                            out BiosParameterBlockEbpb fakeBpb,
                                            out HumanParameterBlock humanBpb, out AtariParameterBlock atariBpb,
                                            out byte minBootNearJump, out bool andosOemCorrect,
                                            out bool bootable);

            fat12              = false;
            fat16              = false;
            fat32              = false;
            useFirstFat        = true;
            XmlFsType.Bootable = bootable;

            statfs = new FileSystemInfo
            {
                Blocks         = XmlFsType.Clusters,
                FilenameLength = 11,
                Files          = 0, // Requires traversing all directories
                FreeFiles      = 0,
                PluginId       = Id,
                FreeBlocks     = 0 // Requires traversing the FAT
            };

            // This is needed because for FAT16, GEMDOS increases bytes per sector count instead of using big_sectors field.
            uint sectorsPerRealSector = 1;
            // This is needed because some OSes don't put volume label as first entry in the root directory
            uint sectorsForRootDirectory = 0;
            uint rootDirectoryCluster    = 0;

            switch (bpbKind)
            {
            case BpbKind.DecRainbow:
            case BpbKind.Hardcoded:
            case BpbKind.Msx:
            case BpbKind.Apricot:
                fat12 = true;
                break;

            case BpbKind.ShortFat32:
            case BpbKind.LongFat32:
            {
                fat32 = true;
                Fat32ParameterBlock fat32Bpb =
                    Marshal.ByteArrayToStructureLittleEndian <Fat32ParameterBlock>(bpbSector);
                Fat32ParameterBlockShort shortFat32Bpb =
                    Marshal.ByteArrayToStructureLittleEndian <Fat32ParameterBlockShort>(bpbSector);

                rootDirectoryCluster = fat32Bpb.root_cluster;

                // This is to support FAT partitions on hybrid ISO/USB images
                if (imagePlugin.Info.XmlMediaType == XmlMediaType.OpticalDisc)
                {
                    fat32Bpb.bps       *= 4;
                    fat32Bpb.spc       /= 4;
                    fat32Bpb.big_spfat /= 4;
                    fat32Bpb.hsectors  /= 4;
                    fat32Bpb.sptrk     /= 4;
                }

                XmlFsType.Type = fat32Bpb.version != 0 ? "FAT+" : "FAT32";

                if (fat32Bpb.oem_name != null && (fat32Bpb.oem_name[5] != 0x49 || fat32Bpb.oem_name[6] != 0x48 ||
                                                  fat32Bpb.oem_name[7] != 0x43))
                {
                    XmlFsType.SystemIdentifier = StringHandlers.CToString(fat32Bpb.oem_name);
                }

                sectorsPerCluster     = fat32Bpb.spc;
                XmlFsType.ClusterSize = (uint)(fat32Bpb.bps * fat32Bpb.spc);
                reservedSectors       = fat32Bpb.rsectors;
                if (fat32Bpb.big_sectors == 0 && fat32Bpb.signature == 0x28)
                {
                    XmlFsType.Clusters = shortFat32Bpb.huge_sectors / shortFat32Bpb.spc;
                }
                else
                {
                    XmlFsType.Clusters = fat32Bpb.big_sectors / fat32Bpb.spc;
                }

                sectorsPerFat          = fat32Bpb.big_spfat;
                XmlFsType.VolumeSerial = $"{fat32Bpb.serial_no:X8}";
                statfs.Id = new FileSystemId {
                    IsInt = true, Serial32 = fat32Bpb.serial_no
                };

                if ((fat32Bpb.flags & 0xF8) == 0x00)
                {
                    if ((fat32Bpb.flags & 0x01) == 0x01)
                    {
                        XmlFsType.Dirty = true;
                    }
                }

                if ((fat32Bpb.mirror_flags & 0x80) == 0x80)
                {
                    useFirstFat = (fat32Bpb.mirror_flags & 0xF) != 1;
                }

                if (fat32Bpb.signature == 0x29)
                {
                    XmlFsType.VolumeName = Encoding.ASCII.GetString(fat32Bpb.volume_label);
                }

                // Check that jumps to a correct boot code position and has boot signature set.
                // This will mean that the volume will boot, even if just to say "this is not bootable change disk"......
                XmlFsType.Bootable =
                    fat32Bpb.jump[0] == 0xEB && fat32Bpb.jump[1] >= minBootNearJump && fat32Bpb.jump[1] < 0x80 ||
                    fat32Bpb.jump[0] == 0xE9 && fat32Bpb.jump.Length >= 3 &&
                    BitConverter.ToUInt16(fat32Bpb.jump, 1) >= minBootNearJump &&
                    BitConverter.ToUInt16(fat32Bpb.jump, 1) <= 0x1FC;

                sectorsPerRealSector = fat32Bpb.bps / imagePlugin.Info.SectorSize;
                sectorsPerCluster   *= sectorsPerRealSector;

                // First root directory sector
                firstClusterSector =
                    (ulong)(fat32Bpb.big_spfat * fat32Bpb.fats_no + fat32Bpb.rsectors) * sectorsPerRealSector -
                    2 * sectorsPerCluster;

                if (fat32Bpb.fsinfo_sector + partition.Start <= partition.End)
                {
                    byte[]       fsinfoSector = imagePlugin.ReadSector(fat32Bpb.fsinfo_sector + partition.Start);
                    FsInfoSector fsInfo       =
                        Marshal.ByteArrayToStructureLittleEndian <FsInfoSector>(fsinfoSector);

                    if (fsInfo.signature1 == FSINFO_SIGNATURE1 && fsInfo.signature2 == FSINFO_SIGNATURE2 &&
                        fsInfo.signature3 == FSINFO_SIGNATURE3)
                    {
                        if (fsInfo.free_clusters < 0xFFFFFFFF)
                        {
                            XmlFsType.FreeClusters          = fsInfo.free_clusters;
                            XmlFsType.FreeClustersSpecified = true;
                        }
                    }
                }

                break;
            }

            // Some fields could overflow fake BPB, those will be handled below
            case BpbKind.Atari:
            {
                ushort sum = 0;
                for (int i = 0; i < bpbSector.Length; i += 2)
                {
                    sum += BigEndianBitConverter.ToUInt16(bpbSector, i);
                }

                // TODO: Check this
                if (sum == 0x1234)
                {
                    XmlFsType.Bootable = true;
                }

                break;
            }

            case BpbKind.Human:
                // If not debug set Human68k namespace and ShiftJIS codepage as defaults
                if (!debug)
                {
                    this.@namespace = Namespace.Human;
                    encoding        = Encoding.GetEncoding("shift_jis");
                }

                XmlFsType.Bootable = true;
                break;
            }

            Encoding = encoding ?? (bpbKind == BpbKind.Human
                                        ? Encoding.GetEncoding("shift_jis")
                                        : Encoding.GetEncoding("IBM437"));

            ulong firstRootSector = 0;

            if (!fat32)
            {
                // This is to support FAT partitions on hybrid ISO/USB images
                if (imagePlugin.Info.XmlMediaType == XmlMediaType.OpticalDisc)
                {
                    fakeBpb.bps      *= 4;
                    fakeBpb.spc      /= 4;
                    fakeBpb.spfat    /= 4;
                    fakeBpb.hsectors /= 4;
                    fakeBpb.sptrk    /= 4;
                    fakeBpb.rsectors /= 4;

                    if (fakeBpb.spc == 0)
                    {
                        fakeBpb.spc = 1;
                    }
                }

                // This assumes no sane implementation will violate cluster size rules
                // However nothing prevents this to happen
                // If first file on disk uses only one cluster there is absolutely no way to differentiate between FAT12 and FAT16,
                // so let's hope implementations use common sense?
                if (!fat12 && !fat16)
                {
                    ulong clusters;

                    if (fakeBpb.sectors == 0)
                    {
                        clusters = fakeBpb.spc == 0 ? fakeBpb.big_sectors : fakeBpb.big_sectors / fakeBpb.spc;
                    }
                    else
                    {
                        clusters = fakeBpb.spc == 0 ? fakeBpb.sectors : (ulong)fakeBpb.sectors / fakeBpb.spc;
                    }

                    if (clusters < 4089)
                    {
                        fat12 = true;
                    }
                    else
                    {
                        fat16 = true;
                    }
                }

                if (fat12)
                {
                    XmlFsType.Type = "FAT12";
                }
                else if (fat16)
                {
                    XmlFsType.Type = "FAT16";
                }

                if (bpbKind == BpbKind.Atari)
                {
                    if (atariBpb.serial_no[0] != 0x49 || atariBpb.serial_no[1] != 0x48 || atariBpb.serial_no[2] != 0x43)
                    {
                        XmlFsType.VolumeSerial =
                            $"{atariBpb.serial_no[0]:X2}{atariBpb.serial_no[1]:X2}{atariBpb.serial_no[2]:X2}";
                        statfs.Id = new FileSystemId
                        {
                            IsInt    = true,
                            Serial32 = (uint)((atariBpb.serial_no[0] << 16) + (atariBpb.serial_no[1] << 8) +
                                              atariBpb.serial_no[2])
                        };
                    }

                    XmlFsType.SystemIdentifier = StringHandlers.CToString(atariBpb.oem_name);
                    if (string.IsNullOrEmpty(XmlFsType.SystemIdentifier))
                    {
                        XmlFsType.SystemIdentifier = null;
                    }
                }
                else if (fakeBpb.oem_name != null)
                {
                    if (fakeBpb.oem_name[5] != 0x49 || fakeBpb.oem_name[6] != 0x48 || fakeBpb.oem_name[7] != 0x43)
                    {
                        // Later versions of Windows create a DOS 3 BPB without OEM name on 8 sectors/track floppies
                        // OEM ID should be ASCII, otherwise ignore it
                        if (fakeBpb.oem_name[0] >= 0x20 && fakeBpb.oem_name[0] <= 0x7F && fakeBpb.oem_name[1] >= 0x20 &&
                            fakeBpb.oem_name[1] <= 0x7F && fakeBpb.oem_name[2] >= 0x20 && fakeBpb.oem_name[2] <= 0x7F &&
                            fakeBpb.oem_name[3] >= 0x20 && fakeBpb.oem_name[3] <= 0x7F && fakeBpb.oem_name[4] >= 0x20 &&
                            fakeBpb.oem_name[4] <= 0x7F && fakeBpb.oem_name[5] >= 0x20 && fakeBpb.oem_name[5] <= 0x7F &&
                            fakeBpb.oem_name[6] >= 0x20 && fakeBpb.oem_name[6] <= 0x7F && fakeBpb.oem_name[7] >= 0x20 &&
                            fakeBpb.oem_name[7] <= 0x7F)
                        {
                            XmlFsType.SystemIdentifier = StringHandlers.CToString(fakeBpb.oem_name);
                        }
                        else if (fakeBpb.oem_name[0] < 0x20 && fakeBpb.oem_name[1] >= 0x20 &&
                                 fakeBpb.oem_name[1] <= 0x7F && fakeBpb.oem_name[2] >= 0x20 &&
                                 fakeBpb.oem_name[2] <= 0x7F && fakeBpb.oem_name[3] >= 0x20 &&
                                 fakeBpb.oem_name[3] <= 0x7F && fakeBpb.oem_name[4] >= 0x20 &&
                                 fakeBpb.oem_name[4] <= 0x7F && fakeBpb.oem_name[5] >= 0x20 &&
                                 fakeBpb.oem_name[5] <= 0x7F && fakeBpb.oem_name[6] >= 0x20 &&
                                 fakeBpb.oem_name[6] <= 0x7F && fakeBpb.oem_name[7] >= 0x20 &&
                                 fakeBpb.oem_name[7] <= 0x7F)
                        {
                            XmlFsType.SystemIdentifier = StringHandlers.CToString(fakeBpb.oem_name, Encoding, start: 1);
                        }
                    }

                    if (fakeBpb.signature == 0x28 || fakeBpb.signature == 0x29)
                    {
                        XmlFsType.VolumeSerial = $"{fakeBpb.serial_no:X8}";
                        statfs.Id = new FileSystemId {
                            IsInt = true, Serial32 = fakeBpb.serial_no
                        };
                    }
                }

                if (bpbKind != BpbKind.Human)
                {
                    if (fakeBpb.sectors == 0)
                    {
                        XmlFsType.Clusters = fakeBpb.spc == 0 ? fakeBpb.big_sectors : fakeBpb.big_sectors / fakeBpb.spc;
                    }
                    else
                    {
                        XmlFsType.Clusters =
                            (ulong)(fakeBpb.spc == 0 ? fakeBpb.sectors : fakeBpb.sectors / fakeBpb.spc);
                    }
                }
                else
                {
                    XmlFsType.Clusters = humanBpb.clusters == 0 ? humanBpb.big_clusters : humanBpb.clusters;
                }

                sectorsPerCluster     = fakeBpb.spc;
                XmlFsType.ClusterSize = (uint)(fakeBpb.bps * fakeBpb.spc);
                reservedSectors       = fakeBpb.rsectors;
                sectorsPerFat         = fakeBpb.spfat;

                if (fakeBpb.signature == 0x28 || fakeBpb.signature == 0x29 || andosOemCorrect)
                {
                    if ((fakeBpb.flags & 0xF8) == 0x00)
                    {
                        if ((fakeBpb.flags & 0x01) == 0x01)
                        {
                            XmlFsType.Dirty = true;
                        }
                    }

                    if (fakeBpb.signature == 0x29 || andosOemCorrect)
                    {
                        XmlFsType.VolumeName = Encoding.ASCII.GetString(fakeBpb.volume_label);
                    }
                }

                // Workaround that PCExchange jumps into "FAT16   "...
                if (XmlFsType.SystemIdentifier == "PCX 2.0 ")
                {
                    fakeBpb.jump[1] += 8;
                }

                // Check that jumps to a correct boot code position and has boot signature set.
                // This will mean that the volume will boot, even if just to say "this is not bootable change disk"......
                if (XmlFsType.Bootable == false && fakeBpb.jump != null)
                {
                    XmlFsType.Bootable |=
                        fakeBpb.jump[0] == 0xEB && fakeBpb.jump[1] >= minBootNearJump && fakeBpb.jump[1] < 0x80 ||
                        fakeBpb.jump[0] == 0xE9 && fakeBpb.jump.Length >= 3 &&
                        BitConverter.ToUInt16(fakeBpb.jump, 1) >= minBootNearJump &&
                        BitConverter.ToUInt16(fakeBpb.jump, 1) <= 0x1FC;
                }

                // First root directory sector
                firstRootSector = (ulong)(fakeBpb.spfat * fakeBpb.fats_no + fakeBpb.rsectors) * sectorsPerRealSector +
                                  partition.Start;
                sectorsForRootDirectory = (uint)(fakeBpb.root_ent * 32 / imagePlugin.Info.SectorSize);

                sectorsPerRealSector = fakeBpb.bps / imagePlugin.Info.SectorSize;
                sectorsPerCluster   *= sectorsPerRealSector;
            }

            firstClusterSector += partition.Start;

            image = imagePlugin;

            if (fat32)
            {
                fatEntriesPerSector = imagePlugin.Info.SectorSize / 4;
            }
            else if (fat16)
            {
                fatEntriesPerSector = imagePlugin.Info.SectorSize / 2;
            }
            else
            {
                fatEntriesPerSector = imagePlugin.Info.SectorSize * 2 / 3;
            }
            fatFirstSector = partition.Start + reservedSectors * sectorsPerRealSector;

            rootDirectoryCache = new Dictionary <string, CompleteDirectoryEntry>();
            byte[] rootDirectory = null;

            if (!fat32)
            {
                firstClusterSector = firstRootSector + sectorsForRootDirectory - sectorsPerCluster * 2;
                rootDirectory      = imagePlugin.ReadSectors(firstRootSector, sectorsForRootDirectory);

                if (bpbKind == BpbKind.DecRainbow)
                {
                    MemoryStream rootMs = new MemoryStream();
                    foreach (byte[] tmp in from ulong rootSector in new[] { 0x17, 0x19, 0x1B, 0x1D, 0x1E, 0x20 }
                             select imagePlugin.ReadSector(rootSector))
                    {
                        rootMs.Write(tmp, 0, tmp.Length);
                    }

                    rootDirectory = rootMs.ToArray();
                }
            }
            else
            {
                if (rootDirectoryCluster == 0)
                {
                    return(Errno.InvalidArgument);
                }

                MemoryStream rootMs = new MemoryStream();
                uint[]       rootDirectoryClusters = GetClusters(rootDirectoryCluster);

                foreach (uint cluster in rootDirectoryClusters)
                {
                    byte[] buffer =
                        imagePlugin.ReadSectors(firstClusterSector + cluster * sectorsPerCluster, sectorsPerCluster);

                    rootMs.Write(buffer, 0, buffer.Length);
                }

                rootDirectory = rootMs.ToArray();

                // OS/2 FAT32.IFS uses LFN instead of .LONGNAME
                if (this.@namespace == Namespace.Os2)
                {
                    this.@namespace = Namespace.Os2;
                }
            }

            if (rootDirectory is null)
            {
                return(Errno.InvalidArgument);
            }

            byte[] lastLfnName     = null;
            byte   lastLfnChecksum = 0;

            for (int i = 0; i < rootDirectory.Length; i += Marshal.SizeOf <DirectoryEntry>())
            {
                DirectoryEntry entry =
                    Marshal.ByteArrayToStructureLittleEndian <DirectoryEntry>(rootDirectory, i,
                                                                              Marshal.SizeOf <DirectoryEntry>());

                if (entry.filename[0] == DIRENT_FINISHED)
                {
                    break;
                }

                if (entry.attributes.HasFlag(FatAttributes.LFN))
                {
                    if (this.@namespace != Namespace.Lfn && this.@namespace != Namespace.Ecs)
                    {
                        continue;
                    }

                    LfnEntry lfnEntry =
                        Marshal.ByteArrayToStructureLittleEndian <LfnEntry>(rootDirectory, i,
                                                                            Marshal.SizeOf <LfnEntry>());

                    int lfnSequence = lfnEntry.sequence & LFN_MASK;

                    if ((lfnEntry.sequence & LFN_ERASED) > 0)
                    {
                        continue;
                    }

                    if ((lfnEntry.sequence & LFN_LAST) > 0)
                    {
                        lastLfnName     = new byte[lfnSequence * 26];
                        lastLfnChecksum = lfnEntry.checksum;
                    }

                    if (lastLfnName is null)
                    {
                        continue;
                    }
                    if (lfnEntry.checksum != lastLfnChecksum)
                    {
                        continue;
                    }

                    lfnSequence--;

                    Array.Copy(lfnEntry.name1, 0, lastLfnName, lfnSequence * 26, 10);
                    Array.Copy(lfnEntry.name2, 0, lastLfnName, lfnSequence * 26 + 10, 12);
                    Array.Copy(lfnEntry.name3, 0, lastLfnName, lfnSequence * 26 + 22, 4);

                    continue;
                }

                // Not a correct entry
                if (entry.filename[0] < DIRENT_MIN && entry.filename[0] != DIRENT_E5)
                {
                    continue;
                }

                // Self
                if (Encoding.GetString(entry.filename).TrimEnd() == ".")
                {
                    continue;
                }

                // Parent
                if (Encoding.GetString(entry.filename).TrimEnd() == "..")
                {
                    continue;
                }

                // Deleted
                if (entry.filename[0] == DIRENT_DELETED)
                {
                    continue;
                }

                string filename;

                if (entry.attributes.HasFlag(FatAttributes.VolumeLabel))
                {
                    byte[] fullname = new byte[11];
                    Array.Copy(entry.filename, 0, fullname, 0, 8);
                    Array.Copy(entry.extension, 0, fullname, 8, 3);
                    string volname = Encoding.GetString(fullname).Trim();
                    if (!string.IsNullOrEmpty(volname))
                    {
                        XmlFsType.VolumeName =
                            entry.caseinfo.HasFlag(CaseInfo.AllLowerCase) && this.@namespace == Namespace.Nt
                                ? volname.ToLower()
                                : volname;
                    }

                    if (entry.ctime > 0 && entry.cdate > 0)
                    {
                        XmlFsType.CreationDate = DateHandlers.DosToDateTime(entry.cdate, entry.ctime);
                        if (entry.ctime_ms > 0)
                        {
                            XmlFsType.CreationDate = XmlFsType.CreationDate.AddMilliseconds(entry.ctime_ms * 10);
                        }
                        XmlFsType.CreationDateSpecified = true;
                    }

                    if (entry.mtime > 0 && entry.mdate > 0)
                    {
                        XmlFsType.ModificationDate          = DateHandlers.DosToDateTime(entry.mdate, entry.mtime);
                        XmlFsType.ModificationDateSpecified = true;
                    }

                    continue;
                }

                CompleteDirectoryEntry completeEntry = new CompleteDirectoryEntry {
                    Dirent = entry
                };

                if ((this.@namespace == Namespace.Lfn || this.@namespace == Namespace.Ecs) && lastLfnName != null)
                {
                    byte calculatedLfnChecksum = LfnChecksum(entry.filename, entry.extension);

                    if (calculatedLfnChecksum == lastLfnChecksum)
                    {
                        filename = StringHandlers.CToString(lastLfnName, Encoding.Unicode, true);

                        completeEntry.Lfn = filename;
                        lastLfnName       = null;
                        lastLfnChecksum   = 0;
                    }
                }

                if (entry.filename[0] == DIRENT_E5)
                {
                    entry.filename[0] = DIRENT_DELETED;
                }

                string name      = Encoding.GetString(entry.filename).TrimEnd();
                string extension = Encoding.GetString(entry.extension).TrimEnd();

                if (this.@namespace == Namespace.Nt)
                {
                    if (entry.caseinfo.HasFlag(CaseInfo.LowerCaseExtension))
                    {
                        extension = extension.ToLower(CultureInfo.CurrentCulture);
                    }

                    if (entry.caseinfo.HasFlag(CaseInfo.LowerCaseBasename))
                    {
                        name = name.ToLower(CultureInfo.CurrentCulture);
                    }
                }

                if (extension != "")
                {
                    filename = name + "." + extension;
                }
                else
                {
                    filename = name;
                }

                completeEntry.Shortname = filename;

                if (this.@namespace == Namespace.Human)
                {
                    HumanDirectoryEntry humanEntry =
                        Marshal.ByteArrayToStructureLittleEndian <HumanDirectoryEntry>(rootDirectory, i,
                                                                                       Marshal
                                                                                       .SizeOf <HumanDirectoryEntry
                                                                                                >());

                    completeEntry.HumanDirent = humanEntry;

                    name      = StringHandlers.CToString(humanEntry.name1, Encoding).TrimEnd();
                    extension = StringHandlers.CToString(humanEntry.extension, Encoding).TrimEnd();
                    string name2 = StringHandlers.CToString(humanEntry.name2, Encoding).TrimEnd();

                    if (extension != "")
                    {
                        filename = name + name2 + "." + extension;
                    }
                    else
                    {
                        filename = name + name2;
                    }

                    completeEntry.HumanName = filename;
                }

                if (!fat32 && filename == "EA DATA. SF")
                {
                    eaDirEntry      = entry;
                    lastLfnName     = null;
                    lastLfnChecksum = 0;

                    if (debug)
                    {
                        rootDirectoryCache[completeEntry.ToString()] = completeEntry;
                    }

                    continue;
                }

                rootDirectoryCache[completeEntry.ToString()] = completeEntry;
                lastLfnName     = null;
                lastLfnChecksum = 0;
            }

            XmlFsType.VolumeName = XmlFsType.VolumeName?.Trim();
            statfs.Blocks        = XmlFsType.Clusters;

            switch (bpbKind)
            {
            case BpbKind.Hardcoded:
                statfs.Type = $"Microsoft FAT{(fat16 ? "16" : "12")}";
                break;

            case BpbKind.Atari:
                statfs.Type = $"Atari FAT{(fat16 ? "16" : "12")}";
                break;

            case BpbKind.Msx:
                statfs.Type = $"MSX FAT{(fat16 ? "16" : "12")}";
                break;

            case BpbKind.Dos2:
            case BpbKind.Dos3:
            case BpbKind.Dos32:
            case BpbKind.Dos33:
            case BpbKind.ShortExtended:
            case BpbKind.Extended:
                statfs.Type = $"Microsoft FAT{(fat16 ? "16" : "12")}";
                break;

            case BpbKind.ShortFat32:
            case BpbKind.LongFat32:
                statfs.Type = XmlFsType.Type == "FAT+" ? "FAT+" : "Microsoft FAT32";
                break;

            case BpbKind.Andos:
                statfs.Type = $"ANDOS FAT{(fat16 ? "16" : "12")}";
                break;

            case BpbKind.Apricot:
                statfs.Type = $"Apricot FAT{(fat16 ? "16" : "12")}";
                break;

            case BpbKind.DecRainbow:
                statfs.Type = $"DEC FAT{(fat16 ? "16" : "12")}";
                break;

            case BpbKind.Human:
                statfs.Type = $"Human68k FAT{(fat16 ? "16" : "12")}";
                break;

            default: throw new ArgumentOutOfRangeException();
            }

            bytesPerCluster = sectorsPerCluster * imagePlugin.Info.SectorSize;

            if (fat12)
            {
                byte[] fatBytes =
                    imagePlugin.ReadSectors(fatFirstSector + (useFirstFat ? 0 : sectorsPerFat), sectorsPerFat);

                fatEntries = new ushort[statfs.Blocks];

                int pos = 0;
                for (int i = 0; i + 3 < fatBytes.Length && pos < fatEntries.Length; i += 3)
                {
                    fatEntries[pos++] = (ushort)(((fatBytes[i + 1] & 0xF) << 8) + fatBytes[i + 0]);
                    fatEntries[pos++] = (ushort)(((fatBytes[i + 1] & 0xF0) >> 4) + (fatBytes[i + 2] << 4));
                }
            }
            else if (fat16)
            {
                DicConsole.DebugWriteLine("FAT plugin", "Reading FAT16");

                byte[] fatBytes =
                    imagePlugin.ReadSectors(fatFirstSector + (useFirstFat ? 0 : sectorsPerFat), sectorsPerFat);

                DicConsole.DebugWriteLine("FAT plugin", "Casting FAT");
                fatEntries = MemoryMarshal.Cast <byte, ushort>(fatBytes).ToArray();
            }

            // TODO: Check how this affects international filenames
            cultureInfo    = new CultureInfo("en-US", false);
            directoryCache = new Dictionary <string, Dictionary <string, CompleteDirectoryEntry> >();

            // Check it is really an OS/2 EA file
            if (eaDirEntry.start_cluster != 0)
            {
                CacheEaData();
                ushort eamagic = BitConverter.ToUInt16(cachedEaData, 0);

                if (eamagic != EADATA_MAGIC)
                {
                    eaDirEntry   = new DirectoryEntry();
                    cachedEaData = null;
                }
                else
                {
                    eaCache = new Dictionary <string, Dictionary <string, byte[]> >();
                }
            }
            else if (fat32)
            {
                eaCache = new Dictionary <string, Dictionary <string, byte[]> >();
            }

            // Check OS/2 .LONGNAME
            if (eaCache != null && (this.@namespace == Namespace.Os2 || this.@namespace == Namespace.Ecs))
            {
                List <KeyValuePair <string, CompleteDirectoryEntry> > rootFilesWithEas =
                    rootDirectoryCache.Where(t => t.Value.Dirent.ea_handle != 0).ToList();

                foreach (KeyValuePair <string, CompleteDirectoryEntry> fileWithEa in rootFilesWithEas)
                {
                    Dictionary <string, byte[]> eas = GetEas(fileWithEa.Value.Dirent.ea_handle);

                    if (eas is null)
                    {
                        continue;
                    }

                    if (!eas.TryGetValue("com.microsoft.os2.longname", out byte[] longnameEa))
 public DeleteCommand(Cluster cluster, WritePolicy policy, Key key)
 {
     this.policy    = policy;
     this.key       = key;
     this.partition = Partition.Write(cluster, policy, key);
 }