Example #1
0
 public PrimaryVolumeDescriptor(Hardware.Devices.DiskDevice disk, uint startBlock, uint numBlocks, byte[] data)
     : base(disk, startBlock, numBlocks, data)
 {
     SystemIdentifier                  = ByteConverter.GetASCIIStringFromASCII(data, 8, 32);
     VolumeIdentifier                  = ByteConverter.GetASCIIStringFromASCII(data, 40, 32);
     VolumeSpaceSize                   = ByteConverter.ToUInt32(data, 80);
     VolumeSetSize                     = ByteConverter.ToUInt16(data, 120);
     VolumeSequenceNumber              = ByteConverter.ToUInt16(data, 124);
     LogicalBlockSize                  = ByteConverter.ToUInt16(data, 128);
     PathTableSize                     = ByteConverter.ToUInt32(data, 132);
     Location_PathTable_TypeL          = ByteConverter.ToUInt32(data, 140);
     Location_PathTable_Optional_TypeL = ByteConverter.ToUInt32(data, 144);
     RootDirectory                     = new DirectoryRecord(data, 156, true);
     VolumeSetIdentifier               = ByteConverter.GetASCIIStringFromASCII(data, 190, 128);
     PublisherIdentifier               = ByteConverter.GetASCIIStringFromASCII(data, 318, 128);
     DataPreparerIdentifier            = ByteConverter.GetASCIIStringFromASCII(data, 446, 128);
     ApplicationIdentifier             = ByteConverter.GetASCIIStringFromASCII(data, 574, 128);
     CopyrightFileIdentifier           = ByteConverter.GetASCIIStringFromASCII(data, 702, 38);
     AbstractFileIdentifier            = ByteConverter.GetASCIIStringFromASCII(data, 740, 36);
     BibliographicFileIdentifier       = ByteConverter.GetASCIIStringFromASCII(data, 776, 37);
     VolumeCreationDateTime            = new DateTime(data, 813);
     VolumeModificationDateTime        = new DateTime(data, 830);
     VolumeExpirationDateTime          = new DateTime(data, 847);
     VolumeEffectiveDateTime           = new DateTime(data, 864);
     FileStructureVersion              = data[881];
 }
Example #2
0
        private void InsertRecord(DirectoryRecord record)
        {
            // add value to directory
            lock (_directory) {
                _directory[record.Name] = record;
            }

            // check if value has an expiration time
            if (record.HasExpiration)
            {
                TimerFactory.New(record.Expiration, OnExpire, record.Name, TaskEnv.New());
            }

            SaveToFileSystem(record.Name, record.Value);

            // notify event channel
            XDoc notify = new XDoc("insert").Attr("name", record.Name);

            if (record.HasExpiration)
            {
                notify.Attr("expire", record.Expiration);
            }
            notify.Add(record.Value);
            _events.Post(notify, new Result <DreamMessage>(TimeSpan.MaxValue));
        }
Example #3
0
        public IsoFileWrapper(MountInfo minfo, DirectoryRecord ff)
        {
            MountInfo = minfo;
            Reader    = minfo.Reader;
            record    = ff;
            DirectoryRecord rec = ff;
            StringBuilder   sb  = new StringBuilder();

            while (rec != null)
            {
                if (rec == Reader.Pvds.Last().RootDir)
                {
                    break;
                }
                if (rec.IsFile)
                {
                    sb.Insert(0, rec.Name);
                }
                else
                {
                    sb.Insert(0, rec.Name + "\\");
                }
                rec = rec.Parent;
            }
            fullName = sb.ToString().Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).First();
            name     = Path.GetFileName(fullName);
            ext      = Path.GetExtension(fullName);
        }
Example #4
0
        public void SelectedItemChanged(ItemsControl viewControl, DirectoryRecord SelectedItem)
        {
            DirectoryRecord item = SelectedItem;

            foreach (var file in item.Files)
            {
                if (file.Extension == ".meta")
                {
                    continue;
                }
                FileRecord rec = null;
                if (fileSources.ContainsKey(file.FullName))
                {
                    rec = fileSources[file.FullName];
                }
                else
                {
                    rec = new FileRecord();
                    fileSources[file.FullName] = rec;
                    rec.ShowText     = file.Name;
                    rec.FileFullName = file.FullName.Substring(file.FullName.IndexOf("Asset") + 6);
                    rec.DragText     = rec.FileFullName;
                    rec.Name         = rec.FileFullName;
                    rec.FileName     = file.Name;
                    implFileIcon(file, rec);
                }
                viewControl.Items.Add(rec);
                showAtlas(file, rec);
            }
        }
Example #5
0
        private void fileTreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs <object> e)
        {
            DirectoryRecord item = folderTreeView.SelectedItem as DirectoryRecord;

            fileView.Items.Clear();
            viewModel.SelectedItemChanged(fileView, item);
        }
Example #6
0
        /// <param name="filePath">Path to Content.ggpk</param>
        public GGPK(string filePath)
        {
            // Open File
            FileStream = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);

            // Read ROOT Directory Record
            BaseRecord ggpk;

            while ((ggpk = ReadRecord()) is not GGPKRecord)
            {
                ;
            }
            GgpkRecord = (GGPKRecord)ggpk;
            Root       = (DirectoryRecord)ReadRecord(GgpkRecord.RootDirectoryOffset);
            Root.Name  = "ROOT";

            // Build Linked FreeRecord List
            FreeRecords = new();
            var NextFreeOffset = GgpkRecord.FirstFreeRecordOffset;

            while (NextFreeOffset > 0)
            {
                var current = (FreeRecord)ReadRecord(NextFreeOffset);
                FreeRecords.AddLast(current);
                NextFreeOffset = current.NextFreeOffset;
            }
        }
Example #7
0
        private GgpkDirectory GetRootDirectory()
        {
            RecordHeader ggpkHeader;

            do
            {
                ggpkHeader = Stream.ReadRecordHeader();
            } while (ggpkHeader.Type != RecordType.Ggpk);

            var             ggpk      = new GgpkRecord(Stream, ggpkHeader.Length);
            DirectoryRecord?dirRecord = default;

            foreach (var offset in ggpk.RecordOffsets)
            {
                Stream.Position = offset;
                RecordHeader header = Stream.ReadRecordHeader();
                if (header.Type == RecordType.Directory)
                {
                    dirRecord = new DirectoryRecord(Stream, header.Length);
                    break;
                }
            }

            return(dirRecord switch
            {
                not null => GgpkDirectory.CreateRootDirectory(dirRecord, this),
                _ => throw ParseException.GgpkParseFailure,
            });
Example #8
0
        private void LoadRecordsFromFileSystem()
        {
            string storagePath = Config["filestorage-path"].AsText;

            if (string.IsNullOrEmpty(storagePath))
            {
                return;
            }

            if (!System.IO.Directory.Exists(storagePath))
            {
                return;
            }

            string[] files =
                System.IO.Directory.GetFiles(storagePath, "*.xml", System.IO.SearchOption.TopDirectoryOnly);

            if (files != null)
            {
                foreach (string file in files)
                {
                    try {
                        DirectoryRecord record = new DirectoryRecord();
                        record.Name             = System.IO.Path.GetFileNameWithoutExtension(file);
                        record.Value            = XDocFactory.LoadFrom(file, MimeType.XML);
                        _directory[record.Name] = record;
                    }
                    catch (Exception) {
                        System.IO.File.Delete(file);
                    }
                }
            }
        }
Example #9
0
        private void SetVolumeDescriptor(byte[] systemId, byte[] volumeId, ulong volumeSpaceSize, ulong pathTableSize,
                                         uint typeLPathTable, uint typeMPathTable, DirectoryRecord rootDirRecord,
                                         AsciiDateRecord creationDate, AsciiDateRecord modificationDate,
                                         AsciiDateRecord expirationDate, AsciiDateRecord effectiveDate)
        {
            if (m_volumeDescriptor == null)
            {
                m_volumeDescriptor = new VolumeDescriptor();
            }

            m_volumeDescriptor.VolumeDescType = (byte)m_volumeDescriptorType;

            systemId.CopyTo(m_volumeDescriptor.SystemId, 0);
            volumeId.CopyTo(m_volumeDescriptor.VolumeId, 0);
            m_volumeDescriptor.VolumeSpaceSize = volumeSpaceSize;
            m_volumeDescriptor.PathTableSize   = pathTableSize;
            m_volumeDescriptor.TypeLPathTable  = typeLPathTable;
            m_volumeDescriptor.TypeMPathTable  = typeMPathTable;

            m_volumeDescriptor.RootDirRecord = rootDirRecord;
            m_rootDirRecord = new DirectoryRecordWrapper(rootDirRecord);

            m_volumeDescriptor.CreationDate = creationDate;
            m_creationDate = new DateWrapper(creationDate);

            m_volumeDescriptor.ModificationDate = modificationDate;
            m_modificationDate = new DateWrapper(modificationDate);

            m_volumeDescriptor.ExpirationDate = expirationDate;
            m_expirationDate = new DateWrapper(expirationDate);

            m_volumeDescriptor.EffectiveDate = effectiveDate;
            m_effectiveDate = new DateWrapper(effectiveDate);
        }
Example #10
0
        private void toolStripButton2_Click_1(object sender, EventArgs e)
        {
            if (pvdd == null)
            {
                MessageBox.Show("load image first"); return;
            }
            string dummyFileName = "Save Here";

            SaveFileDialog sf = new SaveFileDialog();

            sf.FileName = dummyFileName;

            if (sf.ShowDialog() == DialogResult.OK)
            {
                string savePath = Path.GetDirectoryName(sf.FileName);
                var    ret      = DirectoryRecord.GetAllRecords(pvdd.RootDir);

                foreach (var directoryRecord in ret)
                {
                    throw new NotImplementedException();
                    //get path ,create dirs, save files
                    //var pp=Path.Combine   (path,)
                }
            }
        }
Example #11
0
        private void ParseCd(DiscDirectoryInfo pathDir = null)
        {
            if (pathDir == null)
            {
                pathDir = GetDirectoryInfo("\\");
                Range <long, long> r = PathToClusters("\\").First();
                directoryMembers.Add(new DirectoryMemberInformation(pathDir.FullName, r.Offset, r.Count.RoundToSector(),
                                                                    0, false)
                {
                    Added = true
                });
            }

            foreach (DiscDirectoryInfo dir in pathDir.GetDirectories())
            {
                DirectoryRecord rec    = dir.Entry.Record;
                long            offset = rec.LocationOfExtent;
                long            count  = rec.DataLength;
                directoryMembers.Add(new DirectoryMemberInformation(dir.FullName, offset, count.RoundToSector(), 0, false));
                ParseCd(dir);
            }
            foreach (DiscFileInfo f in pathDir.GetFiles())
            {
                ReaderDirectory rdr = f.Entry.Parent;

                // Fetch all cluster information from the parent
                IEnumerable <ReaderDirEntry> entries = rdr.GetEntriesByName(f.Entry.FileName);

                long offset = f.Entry.Record.LocationOfExtent;
                long count  = entries.Sum(e => e.Record.DataLength);

                directoryMembers.Add(new DirectoryMemberInformation(f.FullName, offset, count.RoundToSector(), count, true));
            }
        }
Example #12
0
            public DirectoryDataCluster(byte numDirectoryRecords)
            {
                nextFileDataClusterIndex = -1;
                _directoryRecords        = new DirectoryRecord[numDirectoryRecords];

                for (int i = 0; i < _directoryRecords.Length; i++)
                {
                    _directoryRecords[i] = new DirectoryRecord(FREE_INODE_ID);
                }
            }
Example #13
0
 public bool FileExist(string path)
 {
     using (var fs = new FileStream(IsoFileInfo.FullName, FileMode.Open, FileAccess.Read))
     {
         IsoReader reader = new IsoReader();
         reader.Parse(fs);
         var ret = DirectoryRecord.GetAllRecords(reader.WorkPvd.RootDir);
         return(ret.Any(x => x.IsFile && (x.FullPath.ToLower() == path.ToLower() || Path.Combine(mountInfo.MountTarget.FullName, x.FullPath).ToLower() == path.ToLower())));
     }
 }
Example #14
0
        /// <summary>
        /// Load GGPK
        /// </summary>
        /// <param name="path">Path to GGPK file</param>
        public GGPKContainer(string path, bool BundleMode = false)
        {
            // Open File
            fileStream = File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
            Reader     = new BinaryReader(fileStream);
            Writer     = new BinaryWriter(fileStream);

            // Read ROOT Directory Record
            BaseRecord ggpk;

            while (!((ggpk = GetRecord()) is GGPKRecord))
            {
                ;
            }
            ggpkRecord         = ggpk as GGPKRecord;
            rootDirectory      = GetRecord(ggpkRecord.RootDirectoryOffset) as DirectoryRecord;
            rootDirectory.Name = "ROOT";

            // Build Linked FreeRecord List
            long NextFreeOffset = ggpkRecord.FirstFreeRecordOffset;

            while (NextFreeOffset > 0)
            {
                FreeRecord current = GetRecord(NextFreeOffset) as FreeRecord;
                LinkedFreeRecords.AddLast(current);
                NextFreeOffset = current.NextFreeOffset;
            }

            if (BundleMode)
            {
                return;
            }
            // Read Bundles
            var Bundles2DirectoryNameHash = MurmurHash2Unsafe.Hash("bundles2", 0);

            OriginalBundles2 = rootDirectory.Children.First(d => d.GetNameHash() == Bundles2DirectoryNameHash) as DirectoryRecord;
            if (OriginalBundles2.Children.FirstOrDefault(r => r.Name == "_.index.bin") is FileRecord _index)
            {
                IndexRecord = _index;
                fileStream.Seek(_index.DataBegin, SeekOrigin.Begin);
                Index        = new IndexContainer(Reader);
                FakeBundles2 = new BundleDirectoryNode("Bundles2", "", MurmurHash2Unsafe.Hash("bundles2", 0), (int)OriginalBundles2.Offset, OriginalBundles2.Length, this);
                rootDirectory.Children.Remove(OriginalBundles2);
                rootDirectory.Children.Add(FakeBundles2);
                foreach (var f in Index.Files)
                {
                    BuildBundleTree(f, FakeBundles2);
                }
            }
            foreach (var br in Index.Bundles)
            {
                RecordOfBundle[br] = (FileRecord)FindRecord(br.Name, OriginalBundles2);
            }
        }
Example #15
0
 public DirectoryRecordViewModel(DirectoryRecord directoryRecord)
 {
     _directoryRecord = directoryRecord;
     if (_directoryRecord.IsDriver)
     {
         DirectoryName = string.Format(LocalizedStrings.LocalDisk, _directoryRecord.Info.Name.Substring(0, 1));
     }
     else
     {
         DirectoryName = _directoryRecord.Info.Name;
     }
 }
Example #16
0
        public void UpdateList(DirectoryRecord record)
        {
            listView1.Items.Clear();
            if (record.Parent != null)
            {
                listView1.Items.Add(new ListViewItem(new string[] { ".." })
                {
                    Tag = record.Parent, BackColor = Color.LightBlue
                });
            }
            foreach (var directoryRecord in record.Records.OrderByDescending(z => z.IsDirectory))
            {
                if (directoryRecord.LBA == record.LBA)
                {
                    continue;
                }
                if (record.Parent != null && directoryRecord.LBA == record.Parent.LBA)
                {
                    continue;
                }

                if (string.IsNullOrEmpty(directoryRecord.Name))
                {
                    continue;
                }
                ListViewItem lvi = null;
                if (directoryRecord.IsDirectory)
                {
                    lvi = new ListViewItem(
                        new string[] { directoryRecord.Name })
                    {
                        Tag = directoryRecord
                    };
                }
                else
                {
                    lvi = new ListViewItem(
                        new string[] { directoryRecord.Name,
                                       Stuff.GetUserFriendlyFileSize(directoryRecord.DataLength) })
                    {
                        Tag = directoryRecord
                    };
                }


                listView1.Items.Add(lvi);
                if (directoryRecord.IsDirectory)
                {
                    lvi.BackColor = Color.LightBlue;
                }
            }
        }
Example #17
0
        private void extractVideoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNode node = this.tvSectors.SelectedNode;

            if (node != null && node.Parent.Name == "nodeDirectoryRecords")
            {
                DirectoryRecord dr = (DirectoryRecord)node.Tag;
                folderBrowserDialog1.SelectedPath = "C:\\Temp";
                if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
                {
                    discimg.ExtractVideo(dr, folderBrowserDialog1.SelectedPath);
                }
            }
        }
Example #18
0
        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNode node = this.tvSectors.SelectedNode;

            if (node != null && node.Parent.Name == "nodeDirectoryRecords")
            {
                DirectoryRecord dr = (DirectoryRecord)node.Tag;
                saveFileDialog1.FileName = dr.FileIdentifier;
                if (saveFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    discimg.ExtractDirectoryRecord(dr, saveFileDialog1.FileName);
                }
            }
        }
Example #19
0
        protected void UpdateHarvesterRecord(Action <string> logMessage, IEnumerable <DirectoryObjectMetadata> sourceFiles, string sourceName, RepositoryArgumentsBase harvesterArgs)
        {
            using (IDatabaseRepository <IHarvesterDataContext> harvester = RepositoryFactory.CreateHarvesterRepository(harvesterArgs))
            {
                logMessage($"Connected to database '{harvester.Name}' ({harvester.ConnectionString})");

                int insertedRecords = 0;

                Entities.Repository repository = harvester.DataContext.Repositories.First(y => y.Name == sourceName);

                if (OperationID == 0)
                {
                    logMessage("Warning: OperationID was not set properly. Correcting this.");
                    OperationID = harvester.DataContext.Operations.First(d => d.Name == Name).ID;
                }

                Dictionary <String, DirectoryRecord> dictionary = harvester.DataContext.DirectoryRecords.Where(d => d.OperationID == OperationID && d.RepositoryID == repository.ID).ToDictionary(d => d.FilePath);

                foreach (DirectoryObjectMetadata file in sourceFiles)
                {
                    if (!dictionary.ContainsKey(file.Path))
                    {
                        harvester.DataContext.DirectoryRecords.InsertOnSubmit(new DirectoryRecord
                        {
                            OperationID      = OperationID,
                            RepositoryID     = repository.ID,
                            FilePath         = file.Path,
                            FileModifiedDate = file.ModifiedDate,
                            CreationDate     = DateTime.Now,
                            ModifiedDate     = DateTime.Now
                        });
                        insertedRecords++;
                    }
                    else
                    {
                        DirectoryRecord element = dictionary[file.Path];

                        if (file.ModifiedDate > element.FileModifiedDate)
                        {
                            element.FileModifiedDate = file.ModifiedDate;
                            element.ModifiedDate     = DateTime.Now;
                        }
                    }
                }

                harvester.DataContext.SubmitChanges();
                logMessage("Inserted " + insertedRecords + " successful files into DirectoryRecords");
            }
        }
        public IsoDirectoryInfoWrapper(MountInfo minfo, DirectoryRecord ff)
        {
            MountInfo = minfo;

            Reader = minfo.Reader;
            if (ff == minfo.Reader.WorkPvd.RootDir)
            {
                _name = minfo.IsoPath.Name;
            }
            else
            {
                _name = ff.Name;
            }
            record = ff;
        }
Example #21
0
 private void tvSectors_AfterSelect(object sender, TreeViewEventArgs e)
 {
     if (e.Node.Parent != null && e.Node.Parent.Name == "nodeVolumeDescriptors")
     {
         this.pnlPrimaryVolumeDescriptor.Controls.Clear();
         VolumeDescriptor        vd     = (VolumeDescriptor)e.Node.Tag;
         VolumeDescriptorControl pvdctl = new VolumeDescriptorControl(vd);
         this.pnlPrimaryVolumeDescriptor.Controls.Add(pvdctl);
     }
     else if (e.Node.Parent != null && e.Node.Parent.Name == "nodeDirectoryRecords")
     {
         this.pnlDirectoryRecord.Controls.Clear();
         DirectoryRecord        dr    = (DirectoryRecord)e.Node.Tag;
         DirectoryRecordControl drctl = new DirectoryRecordControl(dr);
         this.pnlDirectoryRecord.Controls.Add(drctl);
     }
 }
Example #22
0
 public IFileInfo GetFile(string path)
 {
     using (var fs = new FileStream(IsoFileInfo.FullName, FileMode.Open, FileAccess.Read))
     {
         IsoReader reader = new IsoReader();
         reader.Parse(fs);
         var ret = DirectoryRecord.GetAllRecords(reader.WorkPvd.RootDir);
         var aa  = ret.First(x => x.IsFile && x.FullPath.ToLower() == path.ToLower());
         return(new IsoFileWrapper(new MountInfo()
         {
             IsoPath = IsoFileInfo
         }, aa)
         {
             Filesystem = this
         });
     }
 }
Example #23
0
        public Yield PutRecord(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            DirectoryRecord record = new DirectoryRecord();

            record.Name  = context.GetSuffix(0, UriPathFormat.Normalized);
            record.Value = request.ToDocument();
            int ttl = context.GetParam <int>(TIME_TO_LIVE, -1);

            if (ttl >= 0)
            {
                record.Expiration = DateTime.UtcNow.AddSeconds(ttl);
            }

            // add value to directory
            InsertRecord(record);
            response.Return(DreamMessage.Ok());
            yield break;
        }
Example #24
0
        public string ReadAllText(string fullName)
        {
            using (var fs = new FileStream(IsoFileInfo.FullName, FileMode.Open, FileAccess.Read))
            {
                IsoReader reader = new IsoReader();
                reader.Parse(fs);
                var ret = DirectoryRecord.GetAllRecords(reader.WorkPvd.RootDir);


                var fr = ret.First(x => x.IsFile && x.FullPath.ToLower() == fullName.ToLower());


                var          dat = fr.GetFileData(fs, reader.WorkPvd);
                MemoryStream ms  = new MemoryStream(dat);
                var          rdr = new StreamReader(ms);
                return(rdr.ReadToEnd());
            }
        }
Example #25
0
        internal GgpkDirectory(DirectoryRecord record, IDirectory parent,
                               GgpkFileSystem root)
        {
            Parent = parent;
            Root   = root;

            Name = record.Name;
            var records = record.Entries.ToRecords(root.Records).ToArray();

            _directories = records.OfType <DirectoryRecord>()
                           .Select(c => new GgpkDirectory(c, this, root)).ToList <IDirectory>();

            _files = records.OfType <FileRecord>().Select(c => new GgpkFile(c, this, root))
                     .ToList <IFile>();

            _indexDict = new Lazy <Dictionary <string, IFileSystemEntry> >(() =>
            {
                return(_directories.Union(_files.Cast <IFileSystemEntry>())
                       .ToDictionary(c => c.Name));
            });
        }
Example #26
0
        public Yield Update(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            XDoc update = request.ToDocument();

            switch (update.Name.ToLowerInvariant())
            {
            case "insert":
                DirectoryRecord record = new DirectoryRecord();
                record.Name       = update["@name"].Contents;
                record.Expiration = update["@expire"].AsDate ?? DateTime.MaxValue;
                record.Value      = update[0];
                InsertRecord(record);
                break;

            case "delete":
                string name = update["@name"].Contents;
                DeleteRecord(name);
                break;
            }
            response.Return(DreamMessage.Ok());
            yield break;
        }
Example #27
0
        private void SetDirectoryRecord(UInt64 extentLocation, UInt64 dataLength, BinaryDateRecord date, sbyte timeZone, byte fileFlags, byte[] fileIdentifier)
        {
            if (m_record == null)
            {
                m_record = new DirectoryRecord();
            }

            m_record.ExtentLocation = extentLocation;
            m_record.DataLength     = dataLength;

            m_record.Date = date;

            m_record.TimeZone  = timeZone;
            m_record.FileFlags = fileFlags;

            m_record.LengthOfFileIdentifier = (byte)fileIdentifier.Length;
            m_record.FileIdentifier         = fileIdentifier;

            m_record.Length = (byte)(m_record.LengthOfFileIdentifier + 33);
            if (m_record.Length % 2 == 1)
            {
                m_record.Length++;
            }

            if (fileIdentifier.Length > 255 ||
                m_record.LengthOfFileIdentifier + 33 > 255)
            {
                throw new Exception("Depasire!");
            }

            if (m_volumeDescriptorType == VolumeType.Suplementary &&
                ((fileFlags & 2) == 0 ||
                 fileIdentifier.Length != 1 || fileIdentifier[0] > 1))
            {
                m_volumeDescriptorType    = VolumeType.Primary;
                this.VolumeDescriptorType = VolumeType.Suplementary;
            }
        }
Example #28
0
        private TreeListNode CreateNode(DirectoryRecord directoryRecord)
        {
            var node = new TreeListNode();

            var recordType = directoryRecord.DirectoryRecordType.ToUpper();

            if (recordType == "PATIENT")
            {
                node.ImageIndex = 1;
                node.Text       = string.Format("{0} : {1}, {2}", directoryRecord.DirectoryRecordType,
                                                directoryRecord.Elements.GetSafeString(t.PatientName),
                                                directoryRecord.Elements.GetSafeString(t.PatientID));
            }
            else if (recordType == "STUDY")
            {
                node.ImageIndex = 2;
                node.Text       = string.Format("{0} : {1}, {2} ({3})", directoryRecord.DirectoryRecordType,
                                                directoryRecord.Elements.GetSafeString(t.StudyDate),
                                                directoryRecord.Elements.GetSafeString(t.StudyTime), directoryRecord.Elements.GetSafeString(t.StudyDescription));
            }
            else if (recordType == "SERIES")
            {
                node.ImageIndex = 3;
                node.Text       = string.Format("{0} : {1}, {2}", directoryRecord.DirectoryRecordType, directoryRecord.Elements.GetSafeString(t.Modality),
                                                directoryRecord.Elements.GetSafeString(t.SeriesNumber));
            }
            else if (recordType == "IMAGE" || recordType == "SR DOCUMENT")
            {
                node.ImageIndex = 4;
                node.Text       = string.Format("{0} : {1}, {2}", directoryRecord.DirectoryRecordType, directoryRecord.Elements.GetSafeString(t.InstanceNumber),
                                                directoryRecord.Elements.GetSafeString(t.ReferencedSOPInstanceUIDinFile));
                node.AdditionalData = directoryRecord.Elements[t.ReferencedFileID];
            }

            return(node);
        }
Example #29
0
        public Errno Mount(IMediaImage imagePlugin, Partition partition, Encoding encoding,
                           Dictionary <string, string> options, string @namespace)
        {
            Encoding = encoding ?? Encoding.GetEncoding(1252);
            byte[] vdMagic = new byte[5]; // Volume Descriptor magic "CD001"
            //byte[] hsMagic = new byte[5]; // Volume Descriptor magic "CDROM"

            options ??= GetDefaultOptions();

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

            if (options.TryGetValue("use_path_table", out string usePathTableString))
            {
                bool.TryParse(usePathTableString, out _usePathTable);
            }

            if (options.TryGetValue("use_trans_tbl", out string useTransTblString))
            {
                bool.TryParse(useTransTblString, out _useTransTbl);
            }

            if (options.TryGetValue("use_evd", out string useEvdString))
            {
                bool.TryParse(useEvdString, out _useEvd);
            }

            // Default namespace
            @namespace ??= "joliet";

            switch (@namespace.ToLowerInvariant())
            {
            case "normal":
                _namespace = Namespace.Normal;

                break;

            case "vms":
                _namespace = Namespace.Vms;

                break;

            case "joliet":
                _namespace = Namespace.Joliet;

                break;

            case "rrip":
                _namespace = Namespace.Rrip;

                break;

            case "romeo":
                _namespace = Namespace.Romeo;

                break;

            default: return(Errno.InvalidArgument);
            }

            PrimaryVolumeDescriptor?pvd      = null;
            PrimaryVolumeDescriptor?jolietvd = null;

            //BootRecord?                        bvd      = null;
            //HighSierraPrimaryVolumeDescriptor? hsvd     = null;
            //FileStructureVolumeDescriptor?     fsvd     = null;

            // ISO9660 is designed for 2048 bytes/sector devices
            if (imagePlugin.Info.SectorSize < 2048)
            {
                return(Errno.InvalidArgument);
            }

            // ISO9660 Primary Volume Descriptor starts at sector 16, so that's minimal size.
            if (partition.End < 16)
            {
                return(Errno.InvalidArgument);
            }

            ulong counter = 0;

            byte[] vdSector = imagePlugin.ReadSector(16 + counter + partition.Start);
            int    xaOff    = vdSector.Length == 2336 ? 8 : 0;
            //Array.Copy(vdSector, 0x009 + xaOff, hsMagic, 0, 5);
            //_highSierra = Encoding.GetString(hsMagic) == HIGH_SIERRA_MAGIC;
            int hsOff = 0;

            //if(_highSierra)
            //    hsOff = 8;

            //_cdi = false;
            List <ulong> bvdSectors = new List <ulong>();
            List <ulong> pvdSectors = new List <ulong>();
            List <ulong> svdSectors = new List <ulong>();
            List <ulong> evdSectors = new List <ulong>();
            List <ulong> vpdSectors = new List <ulong>();

            while (true)
            {
                AaruConsole.DebugWriteLine("ISO9660 plugin", "Processing VD loop no. {0}", counter);

                // Seek to Volume Descriptor
                AaruConsole.DebugWriteLine("ISO9660 plugin", "Reading sector {0}", 16 + counter + partition.Start);
                byte[] vdSectorTmp = imagePlugin.ReadSector(16 + counter + partition.Start);
                vdSector = new byte[vdSectorTmp.Length - xaOff];
                Array.Copy(vdSectorTmp, xaOff, vdSector, 0, vdSector.Length);

                byte vdType = vdSector[0 + hsOff]; // Volume Descriptor Type, should be 1 or 2.
                AaruConsole.DebugWriteLine("ISO9660 plugin", "VDType = {0}", vdType);

                if (vdType == 255) // Supposedly we are in the PVD.
                {
                    if (counter == 0)
                    {
                        return(Errno.InvalidArgument);
                    }

                    break;
                }

                Array.Copy(vdSector, 0x001, vdMagic, 0, 5);
                //Array.Copy(vdSector, 0x009, hsMagic, 0, 5);

                if (Encoding.GetString(vdMagic) != ISO_MAGIC) // Recognized, it is an ISO9660, now check for rest of data.
                {
                    if (counter == 0)
                    {
                        return(Errno.InvalidArgument);
                    }

                    break;
                }

                //_cdi |= Encoding.GetString(vdMagic) == CDI_MAGIC;

                switch (vdType)
                {
                case 0:
                {
                    if (_debug)
                    {
                        bvdSectors.Add(16 + counter + partition.Start);
                    }

                    break;
                }

                case 1:
                {
                    pvd = Marshal.ByteArrayToStructureLittleEndian <PrimaryVolumeDescriptor>(vdSector);

                    if (_debug)
                    {
                        pvdSectors.Add(16 + counter + partition.Start);
                    }

                    break;
                }

                case 2:
                {
                    PrimaryVolumeDescriptor svd =
                        Marshal.ByteArrayToStructureLittleEndian <PrimaryVolumeDescriptor>(vdSector);

                    // TODO: Other escape sequences
                    // Check if this is Joliet
                    if (svd.version == 1)
                    {
                        if (svd.escape_sequences[0] == '%' &&
                            svd.escape_sequences[1] == '/')
                        {
                            if (svd.escape_sequences[2] == '@' ||
                                svd.escape_sequences[2] == 'C' ||
                                svd.escape_sequences[2] == 'E')
                            {
                                jolietvd = svd;
                            }
                            else
                            {
                                AaruConsole.DebugWriteLine("ISO9660 plugin",
                                                           "Found unknown supplementary volume descriptor");
                            }
                        }

                        if (_debug)
                        {
                            svdSectors.Add(16 + counter + partition.Start);
                        }
                    }
                    else
                    {
                        if (_debug)
                        {
                            evdSectors.Add(16 + counter + partition.Start);
                        }

                        if (_useEvd)
                        {
                            // Basically until escape sequences are implemented, let the user chose the encoding.
                            // This is the same as user choosing Romeo namespace, but using the EVD instead of the PVD
                            _namespace = Namespace.Romeo;
                            pvd        = svd;
                        }
                    }

                    break;
                }

                case 3:
                {
                    if (_debug)
                    {
                        vpdSectors.Add(16 + counter + partition.Start);
                    }

                    break;
                }
                }

                counter++;
            }

            DecodedVolumeDescriptor decodedVd;
            var decodedJolietVd = new DecodedVolumeDescriptor();

            //XmlFsType = new FileSystemType();

            if (pvd == null) //&& hsvd == null &&fsvd == null)
            {
                AaruConsole.ErrorWriteLine("ERROR: Could not find primary volume descriptor");

                return(Errno.InvalidArgument);
            }

            decodedVd = DecodeVolumeDescriptor(pvd.Value);

            if (jolietvd != null)
            {
                decodedJolietVd = DecodeJolietDescriptor(jolietvd.Value);
            }

            if (_namespace != Namespace.Romeo)
            {
                Encoding = Encoding.ASCII;
            }

            string fsFormat;

            byte[] pathTableData;

            uint pathTableMsbLocation;
            uint pathTableLsbLocation = 0; // Initialize to 0 as ignored in CD-i

            _image = imagePlugin;

            _blockSize = pvd.Value.logical_block_size;

            pathTableData = ReadSingleExtent(pvd.Value.path_table_size, Swapping.Swap(pvd.Value.type_m_path_table));

            fsFormat = "ISO9660";

            pathTableMsbLocation = pvd.Value.type_m_path_table;
            pathTableLsbLocation = pvd.Value.type_l_path_table;


            _pathTable = DecodePathTable(pathTableData);

            if (jolietvd is null &&
                _namespace == Namespace.Joliet)
            {
                _namespace = Namespace.Normal;
            }

            uint rootLocation;
            uint rootSize;
            byte rootXattrLength = 0;


            rootLocation = pvd.Value.root_directory_record.extent;

            rootXattrLength = pvd.Value.root_directory_record.xattr_len;

            rootSize = pvd.Value.root_directory_record.size;

            if (pathTableData.Length > 1 &&
                rootLocation != _pathTable[0].Extent)
            {
                AaruConsole.DebugWriteLine("ISO9660 plugin",
                                           "Path table and PVD do not point to the same location for the root directory!");

                byte[] firstRootSector = ReadSector(rootLocation);

                bool pvdWrongRoot = false;

                {
                    DirectoryRecord rootEntry =
                        Marshal.ByteArrayToStructureLittleEndian <DirectoryRecord>(firstRootSector);

                    if (rootEntry.extent != rootLocation)
                    {
                        pvdWrongRoot = true;
                    }
                }

                if (pvdWrongRoot)
                {
                    AaruConsole.DebugWriteLine("ISO9660 plugin",
                                               "PVD does not point to correct root directory, checking path table...");

                    bool pathTableWrongRoot = false;

                    rootLocation = _pathTable[0].Extent;

                    firstRootSector = ReadSector(_pathTable[0].Extent);

                    {
                        DirectoryRecord rootEntry =
                            Marshal.ByteArrayToStructureLittleEndian <DirectoryRecord>(firstRootSector);

                        if (rootEntry.extent != rootLocation)
                        {
                            pathTableWrongRoot = true;
                        }
                    }

                    if (pathTableWrongRoot)
                    {
                        AaruConsole.ErrorWriteLine("Cannot find root directory...");

                        return(Errno.InvalidArgument);
                    }

                    _usePathTable = true;
                }
            }

            if (_usePathTable && pathTableData.Length == 1)
            {
                _usePathTable = false;
            }

            if (_usePathTable)
            {
                rootLocation = _pathTable[0].Extent;

                byte[] firstRootSector = ReadSector(rootLocation);

                {
                    DirectoryRecord rootEntry =
                        Marshal.ByteArrayToStructureLittleEndian <DirectoryRecord>(firstRootSector);

                    rootSize = rootEntry.size;
                }

                rootXattrLength = _pathTable[0].XattrLength;
            }

            try
            {
                _ = ReadSingleExtent(rootSize, rootLocation);
            }
            catch
            {
                return(Errno.InvalidArgument);
            }

            if (_namespace == Namespace.Joliet ||
                _namespace == Namespace.Rrip)
            {
                _usePathTable = false;
                _useTransTbl  = false;
            }

            // Cannot traverse path table if we substitute the names for the ones in TRANS.TBL
            if (_useTransTbl)
            {
                _usePathTable = false;
            }

            if (_namespace != Namespace.Joliet)
            {
                _rootDirectoryCache = DecodeIsoDirectory(rootLocation + rootXattrLength, rootSize);
            }

            if (jolietvd != null &&
                (_namespace == Namespace.Joliet || _namespace == Namespace.Rrip))
            {
                rootLocation    = jolietvd.Value.root_directory_record.extent;
                rootXattrLength = jolietvd.Value.root_directory_record.xattr_len;

                rootSize = jolietvd.Value.root_directory_record.size;

                _joliet = true;

                _rootDirectoryCache = DecodeIsoDirectory(rootLocation + rootXattrLength, rootSize);

                decodedVd = decodedJolietVd;
            }

            if (_debug)
            {
                _rootDirectoryCache.Add("$", new DecodedDirectoryEntry
                {
                    Extents = new List <(uint extent, uint size)>
                    {
                        (rootLocation, rootSize)
                    },
                    Filename  = "$",
                    Size      = rootSize,
                    Timestamp = decodedVd.CreationTime
                });
Example #30
0
        /// <summary>
        /// Записывает информацию о новом созданном файле на диск.
        /// </summary>
        /// <param name="fileName">Имя файла.</param>
        /// <param name="fileExtension">Расширение файла.</param>
        /// <param name="freeDirectoryRecordAddress">Адрес свободной записи в родительском каталоге.</param>
        /// <param name="freeInodeAddress">Адрес свободного индексного дескриптора.</param>
        /// <param name="freeInodeId">ID свободного индексного дескриптора.</param>
        /// <param name="freeDataClusterIndex">Индекс свободного блока данных.</param>
        private void FlushNewFile(string fileName, string fileExtension, int freeDirectoryRecordAddress, int freeInodeAddress, int freeInodeId, int freeDataClusterIndex)
        {
            DirectoryRecord newDirectoryRecord = new DirectoryRecord();
            newDirectoryRecord.fileName = fileName;
            newDirectoryRecord.fileExtension = fileExtension;
            newDirectoryRecord.fileInodeId = freeInodeId;

            Inode newFileInode = new Inode();
            newFileInode.fileType = FILE_INODE_TYPE;
            newFileInode.inodeId = freeInodeId;
            newFileInode.userId = UserId;
            newFileInode.groupId = GroupId;
            newFileInode.permissions = new AccessRights(true, true, false, true, false, false, true, false, false).ToInt16();
            Attributes attributes = new Attributes();
            attributes.hidden = false;
            attributes.readOnly = false;
            attributes.system = false;
            newFileInode.attributes = attributes.ToByte();
            newFileInode.fileSize = 0;
            newFileInode.datetimeFileCreated = Utils.GetTimestamp();
            newFileInode.datetimeFileModified = Utils.GetTimestamp();
            newFileInode.datetimeInodeModified = Utils.GetTimestamp();
            newFileInode.firstClusterIndex = freeDataClusterIndex;

            FileStream.Seek(freeDirectoryRecordAddress, SeekOrigin.Begin);
            WriteStruct(FileStream, newDirectoryRecord);
            FileStream.Seek(freeInodeAddress, SeekOrigin.Begin);
            WriteStruct(FileStream, newFileInode);
            FileStream.Seek(_superblock.dataAddress + (freeDataClusterIndex - 1) * CLUSTER_SIZE, SeekOrigin.Begin);

            // Записать один кластер файла
            FileStream.Write(BitConverter.GetBytes(LAST_CLUSTER_ID), 0, sizeof(int));
        }
Example #31
0
            public DirectoryDataCluster(byte numDirectoryRecords)
            {
                nextFileDataClusterIndex = -1;
                _directoryRecords = new DirectoryRecord[numDirectoryRecords];

                for (int i = 0; i < _directoryRecords.Length; i++)
                {
                    _directoryRecords[i] = new DirectoryRecord(FREE_INODE_ID);
                }
            }
Example #32
0
        /// <summary>
        /// Load GGPK
        /// </summary>
        /// <param name="path">Path to GGPK file</param>
        public GGPKContainer(string path, bool BundleMode = false, bool SteamMode = false, bool BuildTree = true)
        {
            // Steam Mode (No GGPK)
            if (SteamMode)
            {
                if (BundleMode)
                {
                    throw new NotSupportedException("BundleMode and SteamMode cannot be both true");
                }
                Environment.CurrentDirectory = Directory.GetParent(path).FullName;
                Index = new IndexContainer(path);
                if (BuildTree)
                {
                    rootDirectory = FakeBundles2 = new BundleDirectoryNode("Bundles2", "", MurmurHash2Unsafe.Hash("bundles2", 0), 0, 0, this);
                    foreach (var f in Index.Files)
                    {
                        BuildBundleTree(f, rootDirectory);
                    }
                }
                return;
            }

            // Open File
            fileStream = File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
            Reader     = new BinaryReader(fileStream);
            Writer     = new BinaryWriter(fileStream);

            // Read ROOT Directory Record
            BaseRecord ggpk;

            while ((ggpk = GetRecord()) is not GGPKRecord)
            {
                ;
            }
            ggpkRecord         = ggpk as GGPKRecord;
            rootDirectory      = GetRecord(ggpkRecord.RootDirectoryOffset) as DirectoryRecord;
            rootDirectory.Name = "ROOT";

            // Build Linked FreeRecord List
            LinkedFreeRecords = new LinkedList <FreeRecord>();
            var NextFreeOffset = ggpkRecord.FirstFreeRecordOffset;

            while (NextFreeOffset > 0)
            {
                FreeRecord current = GetRecord(NextFreeOffset) as FreeRecord;
                LinkedFreeRecords.AddLast(current);
                NextFreeOffset = current.NextFreeOffset;
            }

            // Read Bundles
            OriginalBundles2 = rootDirectory.Children.FirstOrDefault(d => d.GetNameHash() == MurmurHash2Unsafe.Hash("bundles2", 0)) as DirectoryRecord;
            if (OriginalBundles2?.Children.FirstOrDefault(r => r.Name == "_.index.bin") is FileRecord _index)
            {
                IndexRecord = _index;
                if (BundleMode)
                {
                    return;
                }
                fileStream.Seek(_index.DataBegin, SeekOrigin.Begin);
                Index = new IndexContainer(Reader);
                if (BuildTree)
                {
                    FakeBundles2 = new BundleDirectoryNode("Bundles2", "", MurmurHash2Unsafe.Hash("bundles2", 0), (int)OriginalBundles2.Offset, OriginalBundles2.Length, this);
                    rootDirectory.Children.Remove(OriginalBundles2);
                    rootDirectory.Children.Add(FakeBundles2);
                    foreach (var f in Index.Files)
                    {
                        BuildBundleTree(f, FakeBundles2);
                    }
                }
                _RecordOfBundle = new Dictionary <LibBundle.Records.BundleRecord, FileRecord>(Index.Bundles.Length);
            } // else BundleMode = true;
        }
Example #33
0
        /// <summary>
        /// Записывает информацию о новом созданном каталоге на диск.
        /// </summary>
        /// <param name="direcoryName">Имя каталога.</param>
        /// <param name="freeDirectoryRecordAddress">Адрес свободной записи в родительском каталоге.</param>
        /// <param name="freeInodeAddress">Адрес свободного индексного дескриптора.</param>
        /// <param name="freeInodeId">ID свободного индексного дескриптора.</param>
        /// <param name="parentInodeId">ID индексного дескриптора родительского каталога.</param>
        /// <param name="freeDataClusterIndex">Индекс свободного блока данных.</param>
        private void FlushNewDirectory(string direcoryName, int freeDirectoryRecordAddress, int freeInodeAddress, int freeInodeId, int parentInodeId, int freeDataClusterIndex)
        {
            DirectoryRecord newDirectoryRecord = new DirectoryRecord();
            newDirectoryRecord.fileName = direcoryName;
            newDirectoryRecord.fileExtension = string.Empty;
            newDirectoryRecord.fileInodeId = freeInodeId;

            Inode newDirectoryInode = new Inode();
            newDirectoryInode.fileType = DIRECTORY_INODE_TYPE;
            newDirectoryInode.inodeId = freeInodeId;
            newDirectoryInode.userId = UserId;
            newDirectoryInode.groupId = GroupId;
            newDirectoryInode.permissions = new AccessRights(true, true, true, true, false, true, true, false, true).ToInt16();
            Attributes attributes = new Attributes();
            attributes.hidden = false;
            attributes.readOnly = false;
            attributes.system = false;
            newDirectoryInode.attributes = attributes.ToByte();
            newDirectoryInode.fileSize = _superblock.clusterFactor * DISK_BYTES_PER_SECTOR;
            newDirectoryInode.datetimeFileCreated = Utils.GetTimestamp();
            newDirectoryInode.datetimeFileModified = Utils.GetTimestamp();
            newDirectoryInode.datetimeInodeModified = Utils.GetTimestamp();
            newDirectoryInode.firstClusterIndex = freeDataClusterIndex;

            FileStream.Seek(freeDirectoryRecordAddress, SeekOrigin.Begin);
            WriteStruct(FileStream, newDirectoryRecord);
            FileStream.Seek(freeInodeAddress, SeekOrigin.Begin);
            WriteStruct(FileStream, newDirectoryInode);
            FileStream.Seek(_superblock.dataAddress + (freeDataClusterIndex - 1) * CLUSTER_SIZE, SeekOrigin.Begin);

            // Записать один кластер каталога
            FileStream.Write(BitConverter.GetBytes(LAST_CLUSTER_ID), 0, sizeof(int));
            DirectoryRecord current = new DirectoryRecord();
            current.fileName = ".";
            current.fileExtension = "";
            current.fileInodeId = freeInodeId;
            DirectoryRecord parent = new DirectoryRecord();
            parent.fileName = "..";
            parent.fileExtension = "";
            parent.fileInodeId = parentInodeId;
            WriteStruct(FileStream, current);
            WriteStruct(FileStream, parent);

            int upperBound = (CLUSTER_SIZE - sizeof(int)) / Marshal.SizeOf(typeof(DirectoryRecord)) - 2;
            for (int i = 0; i < upperBound; i++)
            {
                DirectoryRecord directoryRecord = new DirectoryRecord();
                directoryRecord.fileInodeId = FREE_DIRECTORY_RECORD;
                directoryRecord.fileName = "";
                directoryRecord.fileExtension = "";
                WriteStruct(FileStream, directoryRecord);
            }
        }
Example #34
0
        /// <summary>
        /// Удаляет запись из родительского каталога объекта и освобождает индексный дескриптор.
        /// </summary>
        /// <param name="path">Путь к каталогу или файлу, который необходимо удалить.</param>
        private void DeleteFileOrDirectory(string path)
        {
            Utils.CheckPath(path);
            string fullPath = Utils.GetFullPath(path, CurrentDirectory.FullPath);
            string fileName = Utils.GetFileNameWithoutExtension(path);
            string fileExtension = Utils.GetExtension(path);
            string fullFileName = Utils.GetFileName(path);
            string directoryPath = Utils.GetDirectoryName(fullPath);
            Directory directory = OpenDirectory(directoryPath);

            //AccessRights ar = directory.AccessRights;
            if (!Utils.GetAccessRightsGroup(UserId, GroupId, directory.UserId, directory.GroupId, directory.AccessRights).canWrite)
            {
                throw new UnauthorizedAccessException("Текущий пользователь не имеет доступа к изменению этого каталога!");
            }

            MetaFile metaFile = directory.Find(fullFileName);

            if (metaFile == null)
            {
                throw new FileNotFoundException("Ошибка удаления файла! Указанный файл не существует.", fullFileName);
            }

            // Удалить всё содержимое, если это каталог.
            if (metaFile is Directory)
            {
                Directory deletingDirectory = ReadDirectoryClusters(metaFile.FirstClusterIndex, directory.FullPath + (directory.FullPath != "/" ? "/" : string.Empty) + metaFile.FullName);

                for (int i = 2; i < deletingDirectory.Count; i++)
                {
                    DeleteFileOrDirectory(deletingDirectory.FullPath + "/" + deletingDirectory[i].FullName);
                }
            }

            long address = (metaFile.FirstClusterIndex == 0 ? _superblock.rootAddress : _superblock.dataAddress + (metaFile.FirstClusterIndex - 1) * CLUSTER_SIZE);
            List<int> usedClustersIndexes = new List<int>();
            usedClustersIndexes.Add(metaFile.FirstClusterIndex);
            FileStream.Seek(address, SeekOrigin.Begin);
            int nextClusterIndex = -1;
            while ((nextClusterIndex = (int)ReadStruct(FileStream, typeof(int))) != LAST_CLUSTER_ID)
            {
                usedClustersIndexes.Add(nextClusterIndex);
                FileStream.Seek(_superblock.dataAddress + (nextClusterIndex - 1) * CLUSTER_SIZE, SeekOrigin.Begin);
            }

            for (int i = 0; i < usedClustersIndexes.Count; i++)
            {
                _bitMap.SetClusterState(usedClustersIndexes[i], BitMap.ClusterState.Free);
            }

            FileStream.Seek(metaFile.DiskRecordAddress, SeekOrigin.Begin);
            DirectoryRecord directoryRecord = new DirectoryRecord();
            directoryRecord.fileInodeId = FREE_DIRECTORY_RECORD;
            WriteStruct(FileStream, directoryRecord);
            _superblock.numFreeClusters += usedClustersIndexes.Count;

            // Перейти к заданному индексному дескриптору
            int sizeOfInode = Marshal.SizeOf(typeof(Inode));
            FileStream.Seek(_superblock.inodeArrayAddress + (metaFile.InodeId - 1) * sizeOfInode, SeekOrigin.Begin);
            Inode inode = new Inode();
            inode.fileType = FREE_INODE_TYPE;
            inode.inodeId = metaFile.InodeId;
            WriteStruct(FileStream, inode);
            _superblock.numFreeInode++;

            FlushAll();
        }
Example #35
0
        public Yield PutRecord(DreamContext context, DreamMessage request, Result<DreamMessage> response)
        {
            DirectoryRecord record = new DirectoryRecord();
            record.Name = context.GetSuffix(0, UriPathFormat.Normalized);
            record.Value = request.ToDocument();
            int ttl = context.GetParam<int>(TIME_TO_LIVE, -1);
            if(ttl >= 0) {
                record.Expiration = DateTime.UtcNow.AddSeconds(ttl);
            }

            // add value to directory
            InsertRecord(record);
            response.Return(DreamMessage.Ok());
            yield break;
        }
Example #36
0
 public Yield Update(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     XDoc update = request.ToDocument();
     switch(update.Name.ToLowerInvariant()) {
     case "insert":
         DirectoryRecord record = new DirectoryRecord();
         record.Name = update["@name"].Contents;
         record.Expiration = update["@expire"].AsDate ?? DateTime.MaxValue;
         record.Value = update[0];
         InsertRecord(record);
         break;
     case "delete":
         string name = update["@name"].Contents;
         DeleteRecord(name);
         break;
     }
     response.Return(DreamMessage.Ok());
     yield break;
 }
Example #37
0
 public PrimaryVolumeDescriptor(Hardware.Devices.DiskDevice disk, uint startBlock, uint numBlocks, byte[] data)
     : base(disk, startBlock, numBlocks, data)
 {
     SystemIdentifier = ByteConverter.GetASCIIStringFromASCII(data, 8, 32);
     VolumeIdentifier = ByteConverter.GetASCIIStringFromASCII(data, 40, 32);
     VolumeSpaceSize = ByteConverter.ToUInt32(data, 80);
     VolumeSetSize = ByteConverter.ToUInt16(data, 120);
     VolumeSequenceNumber = ByteConverter.ToUInt16(data, 124);
     LogicalBlockSize = ByteConverter.ToUInt16(data, 128);
     PathTableSize = ByteConverter.ToUInt32(data, 132);
     Location_PathTable_TypeL = ByteConverter.ToUInt32(data, 140);
     Location_PathTable_Optional_TypeL = ByteConverter.ToUInt32(data, 144);
     RootDirectory = new DirectoryRecord(data, 156, true);
     VolumeSetIdentifier = ByteConverter.GetASCIIStringFromASCII(data, 190, 128);
     PublisherIdentifier = ByteConverter.GetASCIIStringFromASCII(data, 318, 128);
     DataPreparerIdentifier = ByteConverter.GetASCIIStringFromASCII(data, 446, 128);
     ApplicationIdentifier = ByteConverter.GetASCIIStringFromASCII(data, 574, 128);
     CopyrightFileIdentifier = ByteConverter.GetASCIIStringFromASCII(data, 702, 38);
     AbstractFileIdentifier = ByteConverter.GetASCIIStringFromASCII(data, 740, 36);
     BibliographicFileIdentifier = ByteConverter.GetASCIIStringFromASCII(data, 776, 37);
     VolumeCreationDateTime = new DateTime(data, 813);
     VolumeModificationDateTime = new DateTime(data, 830);
     VolumeExpirationDateTime = new DateTime(data, 847);
     VolumeEffectiveDateTime = new DateTime(data, 864);
     FileStructureVersion = data[881];
 }
Example #38
0
        /// <summary>
        /// Считывает каталог из кластеров данных, сохраняя информацию о списке содержимого и сведения о каждом элементе.
        /// </summary>
        /// <param name="clusterIndex">Номер первого кластера каталога.</param>
        /// <param name="fullPath">Абсолютный путь к считываемому каталогу.</param>
        /// <param name="rootDirectory">Является ли считываемый каталог корневым.</param>
        /// <returns></returns>
        private Directory ReadDirectoryClusters(int clusterIndex, string fullPath, bool rootDirectory = false, Directory directoryToFill = null)
        {
            Directory result = (directoryToFill == null ? new Directory() : directoryToFill);

            if (directoryToFill != null)
            {
                result.ClearRecords();
            }

            if (rootDirectory)
            {
                result.FullPath = "/";
                //result.InodeId = 1;
                //result.StreamAddress = _superblock.rootAddress;
                //result.UserId = 1;

                FileStream.Seek(_superblock.inodeArrayAddress, SeekOrigin.Begin);
                Inode inode = (Inode)ReadStruct(FileStream, typeof(Inode));

                result.CreationTime = inode.datetimeFileCreated;
                result.Extension = string.Empty;
                result.Name = "/";
                result.GroupId = inode.groupId;
                result.InodeId = inode.inodeId;
                result.InodeModificationTime = inode.datetimeInodeModified;
                result.ModificationTime = inode.datetimeFileModified;
                result.Size = inode.fileSize;
                result.FirstClusterIndex = inode.firstClusterIndex;
                result.StreamAddress = _superblock.rootAddress;
                result.DiskRecordAddress = -1;
                result.UserId = inode.userId;
                result.AccessRights = new AccessRights(inode.permissions);
                result.Attributes = new Attributes(inode.attributes);
            }
            else
            {
                Utils.CheckPath(fullPath, true);
                result.FullPath = fullPath;
                result.StreamAddress = _superblock.dataAddress + (clusterIndex - 1) * CLUSTER_SIZE;
            }

            long address = rootDirectory ? _superblock.rootAddress : _superblock.dataAddress + (clusterIndex - 1) * CLUSTER_SIZE;
            long directoryRecordsBeginAddress;

            int nextClusterIndex = LAST_CLUSTER_ID;

            do
            {
                FileStream.Seek(address, SeekOrigin.Begin);
                directoryRecordsBeginAddress = address + sizeof(int);
                //if (!rootDirectory)
                //{
                nextClusterIndex = (int)ReadStruct(FileStream, typeof(int));
                //}

                int sizeOfDirectoryRecord = Marshal.SizeOf(typeof(DirectoryRecord));
                DirectoryRecord[] directoryRecords = new DirectoryRecord[(CLUSTER_SIZE - (!rootDirectory ? sizeof(int) : /*0*/sizeof(int))) / sizeOfDirectoryRecord];
                //int upperBound = (int)(address + CLUSTER_SIZE);
                for (int j = 0; j < directoryRecords.Length; j++)
                {
                    directoryRecords[j] = (DirectoryRecord)ReadStruct(FileStream, typeof(DirectoryRecord));
                    //FileStream.Seek(sizeOfDirectoryRecord, SeekOrigin.Current);
                }

                int fileInodeId;
                address = _superblock.inodeArrayAddress;
                FileStream.Seek(address, SeekOrigin.Begin);
                int sizeOfInode = Marshal.SizeOf(typeof(Inode));
                Inode inode;
                MetaFile metaFile;
                for (int i = 0; i < directoryRecords.Length; i++)
                {
                    fileInodeId = directoryRecords[i].fileInodeId;

                    if (fileInodeId != FREE_DIRECTORY_RECORD)
                    {
                        FileStream.Seek(address + (fileInodeId - 1) * sizeOfInode, SeekOrigin.Begin);
                        inode = (Inode)ReadStruct(FileStream, typeof(Inode));

                        switch (inode.fileType)
                        {
                            case INODE_FILE_TYPE:
                                metaFile = new File();
                                break;
                            case INODE_DIRECTORY_TYPE:
                                metaFile = new Directory();
                                break;
                            default:
                                throw new InvalidDataException("Данные индексного дескриптора повреждены! Неизвестный тип записи в каталоге.");
                        }

                        metaFile.CreationTime = inode.datetimeFileCreated;
                        metaFile.Extension = directoryRecords[i].fileExtension;
                        metaFile.Name = directoryRecords[i].fileName;
                        metaFile.GroupId = inode.groupId;
                        metaFile.InodeId = inode.inodeId;
                        metaFile.InodeModificationTime = inode.datetimeInodeModified;
                        metaFile.ModificationTime = inode.datetimeFileModified;
                        metaFile.Size = inode.fileSize;
                        metaFile.FirstClusterIndex = inode.firstClusterIndex;
                        metaFile.StreamAddress = (inode.firstClusterIndex == 0 ? _superblock.rootAddress : _superblock.dataAddress + (inode.firstClusterIndex - 1) * CLUSTER_SIZE);
                        metaFile.DiskRecordAddress = directoryRecordsBeginAddress + (i * sizeOfDirectoryRecord);
                        metaFile.UserId = inode.userId;

                        metaFile.AccessRights = new AccessRights(inode.permissions);
                        metaFile.Attributes = new Attributes(inode.attributes);

                        result.AddRecord(metaFile);
                    }
                }

                address = _superblock.dataAddress + (nextClusterIndex - 1) * CLUSTER_SIZE;
            } while (nextClusterIndex != LAST_CLUSTER_ID);

            return result;
        }
Example #39
0
 public DirectoryEntry(DirectoryHeader header, DirectoryRecord record)
 {
     _header = header;
     _record = record;
 }
Example #40
0
        private void InsertRecord(DirectoryRecord record)
        {
            // add value to directory
            lock(_directory) {
                _directory[record.Name] = record;
            }

            // check if value has an expiration time
            if(record.HasExpiration) {
                TimerFactory.New(record.Expiration, OnExpire, record.Name, TaskEnv.New());
            }

            SaveToFileSystem(record.Name, record.Value);

            // notify event channel
            XDoc notify = new XDoc("insert").Attr("name", record.Name);
            if(record.HasExpiration) {
                notify.Attr("expire", record.Expiration);
            }
            notify.Add(record.Value);
            _events.Post(notify, new Result<DreamMessage>(TimeSpan.MaxValue));
        }
Example #41
0
        private void LoadRecordsFromFileSystem()
        {
            string storagePath = Config["filestorage-path"].AsText;

            if (string.IsNullOrEmpty(storagePath))
                return;

            if (!System.IO.Directory.Exists(storagePath))
                return;

            string[] files =
                System.IO.Directory.GetFiles(storagePath, "*.xml", System.IO.SearchOption.TopDirectoryOnly);

            if (files != null) {
                foreach (string file in files) {
                    try {
                        DirectoryRecord record = new DirectoryRecord();
                        record.Name = System.IO.Path.GetFileNameWithoutExtension(file);
                        record.Value = XDocFactory.LoadFrom(file, MimeType.XML);
                        _directory[record.Name] = record;
                    }
                    catch (Exception) {
                        System.IO.File.Delete(file);
                    }
                }
            }
        }