Пример #1
0
        public void ExpandFile(long TotalLength)
        {
            // If the total size is larger than uint32.maxvalue...
            if (TotalLength > UInt32.MaxValue)
            {
                throw new Exception("Filesize too large!");
            }
            // We'll be adding clusters here, so first thing we need to do is figure out
            // how many clusters we need
            long Difference = TotalLength - Size;
            // Now that we have the difference, let's see if we don't have to allocate
            // any more clusters
            if (Size.UpToNearestCluster(PartitionInfo.ClusterSize) ==
                TotalLength.UpToNearestCluster(PartitionInfo.ClusterSize))
            {
                // We don't have to do anything except write the new size! Yay
                Structs.EntryData newEd = EntryData;
                newEd.Size = (uint)TotalLength;
                new EntryFunctions(this).CreateNewEntry(newEd);
                EntryData = newEd;
                return;
            }
            // Looks like we'll be adding clusters...
            else if (Size.UpToNearestCluster(PartitionInfo.ClusterSize) >
                TotalLength.UpToNearestCluster(PartitionInfo.ClusterSize) || (Size == 0))
            {
                int ClustersToAdd = (int)(TotalLength.UpToNearestCluster(PartitionInfo.ClusterSize) / PartitionInfo.ClusterSize);
                // Subtract the total clusters from the number clusters we already have
                ClustersToAdd -= BlocksOccupied.Length;
                // Get the new clusters!
                uint[] FreeClusters = Drive.GetFreeBlocks(Drive.FolderFromPath(FullPath.Remove(FullPath.IndexOf("\\"))),
                    ClustersToAdd,
                    1,
                    0,
                    false);
                // Add those to our current chain
                List<uint> Current = BlocksOccupied.ToList();
                Current.AddRange(FreeClusters);
                EntryFunctions ef = new EntryFunctions(this);
                // Write the cluster chain
                ef.WriteFATChain(Current.ToArray());

                // Subtract some of the space remaining on the drive
                if (Drive.Remaining != ~0UL)
                {
                    Drive.Remaining -= (ulong)(ClustersToAdd * PartitionInfo.ClusterSize);
                }

                // Replace the currently loaded clusters in the file
                BlocksOccupied = Current.ToArray();
                // Overwrite the size in the entry data
                Structs.EntryData ed = EntryData;
                ed.Size = (uint)TotalLength;
                if (Size == 0)
                {
                    ed.StartingCluster = Current[0];
                }
                // Write the new entry data
                ef.CreateNewEntry(ed);
                EntryData = ed;
                return;
            }
            // TotalLength might be smaller, throw an exception
            throw new Exception("Can not shrink file!");
        }
Пример #2
0
 public void TruncateFile(long TotalLength)
 {
     if (TotalLength < 0)
     {
         throw new Exception("File size must be non-negative number");
     }
     if (Size == 0)
     {
         return;
     }
     long Difference = Size - TotalLength;
     if (VariousFunctions.DownToNearestCluster(Difference, PartitionInfo.ClusterSize) != VariousFunctions.DownToNearestCluster(Size, PartitionInfo.ClusterSize))
     {
         // Looks like we have to remove part of the cluster chain...
         if (TotalLength == 0)
         {
             new EntryFunctions(this).ClearFATChain(this.BlocksOccupied);
             this.BlocksOccupied = new uint[0];
         }
         else
         {
             List<uint> Chain = this.BlocksOccupied.ToList();
             // Number of clusters to remove
             int ClustersToRemove = Chain.Count - (int)((TotalLength > PartitionInfo.ClusterSize) ? 1 :
                 (VariousFunctions.UpToNearestCluster(TotalLength, PartitionInfo.ClusterSize) / PartitionInfo.ClusterSize));
             EntryFunctions ef = new EntryFunctions(this);
             // Clear the cluster chain
             ef.ClearFATChain(Chain.ToArray());
             Chain.RemoveRange((int)((TotalLength > PartitionInfo.ClusterSize) ? 1 :
                 (VariousFunctions.UpToNearestCluster(TotalLength, PartitionInfo.ClusterSize) / PartitionInfo.ClusterSize)),
                 ClustersToRemove);
             // Re-write the cluster chain
             ef.WriteFATChain(Chain.ToArray());
             BlocksOccupied = Chain.ToArray();
         }
     }
     {
         EntryData newE = this.EntryData;
         newE.Size = (uint)TotalLength;
         if (TotalLength == 0)
         {
             newE.StartingCluster = 0;
         }
         EntryFunctions ef = new EntryFunctions(this);
         ef.CreateNewEntry(newE);
         this.EntryData = newE;
     }
 }
Пример #3
0
        /// <summary>
        /// Creates a new folder
        /// </summary>
        /// <param name="Name">New folder name</param>
        /// <returns>The existing file or folder will be returned if applicable, otherwise returns null (no problems encountered)</returns>
        public Structs.WriteResult CreateNewFolder(string Name)
        {
            WriteResult Result = new WriteResult();
            Folders();
            Console.WriteLine("Getting folders... comparing names");
            for (int i = 0; i < cachedFolders.Count; i++)
            {
                if (cachedFolders[i].Name.ToLower() == Name.ToLower())
                {
                    Result.CouldNotWrite = true;
                    Result.Entry = cachedFolders[i];
                    Result.ConflictingEntryPath = Result.Entry.FullPath;
                    return Result;
                }
            }

            Console.WriteLine("Getting files... comparing names");
            for (int i = 0; i < cachedFiles.Count; i++)
            {
                if (cachedFiles[i].Name.ToLower() == Name.ToLower())
                {
                    Result.CouldNotWrite = true;
                    Result.Entry = cachedFiles[i];
                    Result.ConflictingEntryPath = Result.Entry.FullPath;
                    return Result;
                }
            }

            EntryFunctions ef = new EntryFunctions(this);
            Console.WriteLine("Creating new folder");
            Folder f = new Folder(this.PartitionInfo,
                ef.GetNewEntry(this, 0, new Geometry.Flags[] { Geometry.Flags.Directory }, Name),
                this.Drive);
            // Check if the new folder was created on a new cluster
            if (f.EntryOffset >= VariousFunctions.GetBlockOffset(this.BlocksOccupied[BlocksOccupied.Length - 1], this) + this.PartitionInfo.ClusterSize)
            {
                List<uint> blocks = this.BlocksOccupied.ToList();
                blocks.Add(VariousFunctions.GetBlockFromOffset(f.EntryOffset, this.PartitionInfo));
                this.BlocksOccupied = blocks.ToArray();
            }
            Console.WriteLine("Writing FAT chain");
            ef.WriteFATChain(new uint[] { f.EntryData.StartingCluster });
            f.FullPath = this.FullPath + "\\" + f.Name;
            f.Parent = this;
            Streams.Writer w = this.Drive.Writer();
            w.BaseStream.Position = f.StartingOffset;
            byte[] FF = new byte[PartitionInfo.ClusterSize];
            for (int i = 0; i < FF.Length; i++)
            {
                FF[i] = 0xFF;
            }
            Console.WriteLine("Writing FF");
            w.Write(FF);
            //Console.WriteLine("Closing stream");
            //w.Close();
            this.cachedFolders.Add(f);

            EntryEventArgs eea = new EntryEventArgs();
            eea.FullParentPath = FullPath;
            eea.ModifiedEntry = f;
            eea.ParentFolder = this;
            OnEntryEvent(ref eea);

            Console.WriteLine("Updating entry modified time");
            UpdateModifiedTime();

            Result.Entry = f;
            return Result;
        }