public void ClearFATChain(uint[] Chain)
        {
            Streams.Reader r          = Parent.Drive.Reader();
            Streams.Writer w          = new CLKsFATXLib.Streams.Writer(r.BaseStream);
            long           buffersize = 0x1000;
            long           lastoffset = 0;//VariousFunctions.BlockToFATOffset(Chain[0], Parent).DownToNearestCluster(buffersize);

            byte[] Buffer = new byte[buffersize];
            for (int i = 0; i < Chain.Length; i++)
            {
                // Read the chain buffer
                if (lastoffset != VariousFunctions.BlockToFATOffset(Chain[i], Parent).DownToNearestCluster(0x1000))
                {
                    if (i != 0)
                    {
                        w.BaseStream.Position = lastoffset;
                        w.Write(Buffer);
                    }
                    lastoffset            = VariousFunctions.BlockToFATOffset(Chain[i], Parent).DownToNearestCluster(0x1000);
                    r.BaseStream.Position = lastoffset;
                    Buffer = r.ReadBytes((int)buffersize);
                }

                // Write the chain
                Streams.Writer mem = new CLKsFATXLib.Streams.Writer(new System.IO.MemoryStream(Buffer));
                mem.BaseStream.Position = VariousFunctions.BlockToFATOffset(Chain[i], Parent) - VariousFunctions.BlockToFATOffset(Chain[i], Parent).DownToNearestCluster(0x1000);
                byte[] writing = new byte[0];
                switch (Parent.PartitionInfo.EntrySize)
                {
                case 2:
                    writing = BitConverter.GetBytes((ushort)0);
                    break;

                case 4:
                    writing = BitConverter.GetBytes(0);
                    break;
                }
                mem.Write(writing);
                mem.Close();
                if (i == Chain.Length - 1)
                {
                    w.BaseStream.Position = lastoffset;
                    w.Write(Buffer);
                }
            }
        }
 public long GetNewEntryOffset(Folder Destination)
 {
     // Go to the last block since we want to speed things up and not have to go
     // through all of them
     EntryData[] Entries = EntryDataFromBlock(Destination.BlocksOccupied[Destination.BlocksOccupied.Length - 1]);
     if (Entries.Length == 0)
     {
         return(Destination.StartingOffset);
     }
     // If there isn't the maximum amount of entries for a cluster...
     if (Entries.Length < Destination.PartitionInfo.ClusterSize / 0x40)
     {
         foreach (EntryData e in Entries)
         {
             if (e.NameSize == 0xE5)
             {
                 return(e.EntryOffset);
             }
         }
         return(Entries[Entries.Length - 1].EntryOffset + 0x40);
     }
     // Max amount of entries, let's add another cluster to our parent...
     else
     {
         uint[] NewBlocks = new uint[Destination.BlocksOccupied.Length + 1];
         Array.Copy(Destination.BlocksOccupied, NewBlocks, Destination.BlocksOccupied.Length);
         NewBlocks[NewBlocks.Length - 1] = Destination.Drive.GetFreeBlocks((Folder)Destination, 1, 0, 0, false)[0];
         byte[] FF = new byte[Destination.PartitionInfo.ClusterSize];
         for (int i = 0; i < FF.Length; i++)
         {
             FF[i] = 0xFF;
         }
         Streams.Writer w = Destination.Drive.Writer();
         w.BaseStream.Position = VariousFunctions.BlockToFATOffset(NewBlocks[NewBlocks.Length - 1], Destination);
         w.Write(FF);
         Destination.BlocksOccupied = NewBlocks;
         return(VariousFunctions.BlockToFATOffset(NewBlocks[NewBlocks.Length - 1], Destination));
     }
 }
Beispiel #3
0
        /// <summary>
        /// Returns an array of free blocks based off of the number of blocks needed
        /// </summary>
        public uint[] GetFreeBlocks(Folder Partition, int blocksNeeded, uint StartBlock, long end, bool SecondLoop)
        {
            int  Clustersize = 0x10000;
            uint Block       = StartBlock;

            if (end == 0)
            {
                end = Partition.PartitionInfo.FATOffset + Partition.PartitionInfo.FATSize;
            }
            List <uint> BlockList = new List <uint>();

            // Create our reader for the drive
            Streams.Reader br = Reader();
            // Create our reader for the memory stream
            Streams.Reader mr = null;
            for (long i = VariousFunctions.DownToNearest200(VariousFunctions.BlockToFATOffset(StartBlock, Partition)); i < end; i += Clustersize)
            {
                //Set our position to i
                br.BaseStream.Position = i;
                byte[] buffer = new byte[0];
                if ((end - i) < Clustersize)
                {
                    buffer = VariousFunctions.ReadBytes(ref br, end - i);
                }
                else
                {
                    //Read our buffer
                    buffer = br.ReadBytes(Clustersize);
                }
                try
                {
                    mr.Close();
                }
                catch { }
                mr = new Streams.Reader(new System.IO.MemoryStream(buffer));
                //Re-open our binary reader using the buffer/memory stream
                for (int j = 0; j < buffer.Length; j += (int)Partition.PartitionInfo.EntrySize, Block += (uint)Partition.PartitionInfo.EntrySize)
                {
                    mr.BaseStream.Position = j;
                    //If we've gotten all of our requested blocks...
                    if (BlockList.Count == blocksNeeded)
                    {
                        //Close our reader -> break the loop
                        mr.Close();
                        break;
                    }
                    //Read the next block entry
                    byte[] reading = mr.ReadBytes((int)Partition.PartitionInfo.EntrySize);
                    //For each byte in our reading
                    for (int k = 0; k < reading.Length; k++)
                    {
                        //If the byte isn't null (if the block isn't open)
                        if (reading[k] != 0x00)
                        {
                            //Break
                            break;
                        }
                        //If we've reached the end of the array, and the last byte
                        //is 0x00, then the block is free
                        if (k == reading.Length - 1 && reading[k] == 0x00)
                        {
                            //Do some maths to get the block numbah
                            long fOff          = Partition.PartitionInfo.FATOffset;
                            long blockPosition = (long)i + j;
                            uint block         = (uint)(blockPosition - fOff) / (uint)Partition.PartitionInfo.EntrySize;
                            BlockList.Add(block);
                        }
                    }
                }
                //We're putting in one last check so that we don't loop more than we need to
                if (BlockList.Count == blocksNeeded)
                {
                    break;
                }
            }
            //If we found the required amount of free blocks - return our list
            if (BlockList.Count == blocksNeeded)
            {
                return(BlockList.ToArray());
            }
            //If we didn't find the amount of blocks required, but we started from a
            //block other than the first one...
            if (BlockList.Count < blocksNeeded && SecondLoop == false)
            {
                BlockList.AddRange(GetFreeBlocks(Partition, blocksNeeded - BlockList.Count, 1, VariousFunctions.DownToNearest200(VariousFunctions.BlockToFATOffset(StartBlock, Partition)), true));
                return(BlockList.ToArray());
            }
            //We didn't find the amount of free blocks required, meaning we're ref of
            //disk space
            if (BlockList.Count != blocksNeeded)
            {
                throw new Exception("Out of Xbox 360 hard disk space");
            }
            return(BlockList.ToArray());
        }
        public uint[] GetBlocksOccupied()
        {
            List <uint> Blocks = new List <uint>();

            Streams.Reader r = Parent.Drive.Reader();
            Blocks.Add(Parent.StartingCluster);
            byte[] Buffer     = new byte[0x1000];
            int    buffersize = 0x1000;
            long   lastoffset = 0;

            for (int i = 0; i < Blocks.Count; i++)
            {
                r.BaseStream.Position = VariousFunctions.BlockToFATOffset(Blocks[i], Parent).DownToNearestCluster(0x1000);
                // We use this so that we aren't reading the same buffer
                // a zillion times
                if (r.BaseStream.Position != lastoffset)
                {
                    lastoffset = r.BaseStream.Position;
                    Buffer     = r.ReadBytes(buffersize);
                }

                Streams.Reader r1             = new CLKsFATXLib.Streams.Reader(new System.IO.MemoryStream(Buffer));
                int            OffsetInBuffer = (int)(VariousFunctions.BlockToFATOffset(Blocks[i], Parent) - VariousFunctions.BlockToFATOffset(Blocks[i], Parent).DownToNearestCluster(0x1000));
                r1.BaseStream.Position = OffsetInBuffer;
                switch (Parent.PartitionInfo.EntrySize)
                {
                case 2:
                    ushort Value = r1.ReadUInt16();
                    if (Value != 0xFFFF && Value != 0xFFF8)
                    {
                        if (Value == 0)
                        {
                            EntryData ed = Parent.EntryData;
                            ed.NameSize = 0xE5;
                            CreateNewEntry(ed);
                            if (Blocks.Count > 0)
                            {
                                ClearFATChain(Blocks.ToArray());
                            }
                            throw new Exception(string.Format("Bad FAT chain in file or folder {0}\r\nEntry Offset: 0x{1}\r\nLast block in FAT: 0x{2}\r\nEntry marked as deleted to avoid further errors!  Please reload this device", Parent.FullPath, Parent.EntryOffset.ToString("X"), Blocks.Last().ToString("X")));
                        }
                        Blocks.Add(Value);
                    }
                    break;

                case 4:
                    uint Value2 = r1.ReadUInt32();
                    if (Value2 != 0xFFFFFFFF && Value2 != 0xFFFFFFF8)
                    {
                        if (Value2 == 0)
                        {
                            EntryData ed = Parent.EntryData;
                            ed.NameSize = 0xE5;
                            CreateNewEntry(ed);
                            if (Blocks.Count > 0)
                            {
                                ClearFATChain(Blocks.ToArray());
                            }
                            throw new Exception(string.Format("Bad FAT chain in file or folder {0}\r\nEntry Offset: 0x{1}\r\nLast block in FAT: 0x{2}\r\nEntry marked as deleted to avoid further errors!  Please reload this device", Parent.FullPath, Parent.EntryOffset.ToString("X"), Blocks.Last().ToString("X")));
                        }
                        Blocks.Add(Value2);
                    }
                    break;
                }
                r1.Close();
            }
            return(Blocks.ToArray());
        }