public bool WriteNewFile(Folder Root, string FilePath, ref int Progress, ref int BlocksToWrite) { FATX_Browser.FATX.IOReader br = null; //Do a try... try { //Get our entry EntryData EData = GetNewEntryData(Root, new System.IO.FileInfo(FilePath).Name); //Create our entry in the folder CreateNewEntry(EData); //Create our new fatstuff to get our free blocks FATStuff fs = new FATStuff(Root); //Get our free blocks uint[] blocks = fs.GetFreeBlocks((int)(m.UpToNearestCluster(new System.IO.FileInfo(FilePath).Length, Root.PartInfo.ClusterSize) / Root.PartInfo.ClusterSize), EData.StartingCluster, 0, false); //Make a new list for the blocks... List<uint> COCKS = blocks.ToList<uint>(); //Insert the beginning block at the 0 index COCKS.Insert(0, EData.StartingCluster); //Make the cocks an array blocks = COCKS.ToArray(); //Write the FAT chain WriteFATChain(blocks, Root); //Create our binary reader to read our file br = new FATX_Browser.FATX.IOReader(new System.IO.FileStream(FilePath, System.IO.FileMode.Open)); for (int i = 0; i < blocks.Length; i++) { WriteToCluster(m.GetBlockOffset(blocks[i], Root), br.ReadBytes(0x200)); } br.Close(); return true; } catch(Exception e) { try { br.Close(); } catch { } throw e; } }
/// <summary> /// Partition ID /// </summary> public uint PartitionID() { uint rVal = 0; Misc m = new Misc(); //Open our binary reader FATX_Browser.FATX.IOReader br = ourDrive.GetIO(); //Seek to the data partition offset br.BaseStream.Position = Partition.Offset; //Read our buffer FATX_Browser.FATX.IOReader mem = new FATX_Browser.FATX.IOReader(new System.IO.MemoryStream(br.ReadBytes(0x200))); br.Close(); mem.BaseStream.Position = 0x4; rVal = m.ReadUInt32(ref mem); mem.Close(); return rVal; }
public bool OverWriteFile(File FileToOverwrite, string FilePath, ref int Progress, ref int BlocksToWrite) { FATX_Browser.FATX.IOReader br = null; //Do a try... try { //Create our new fatstuff to get our free blocks FATStuff fs = new FATStuff(FileToOverwrite); //Get our blocks needed int BlocksNeeded = (int)(m.UpToNearestCluster(new System.IO.FileInfo(FilePath).Length, FileToOverwrite.PartInfo.ClusterSize) / FileToOverwrite.PartInfo.ClusterSize); //Create our block array for the blocks we do have uint[] BlocksWeHave = FileToOverwrite.BlocksOccupied; //If we have more blocks than we need already... if ((int)FileToOverwrite.BlocksOccupied.Length > BlocksNeeded) { //Get our blocks that we're going to clear... List<uint> BlocksList = FileToOverwrite.BlocksOccupied.ToList<uint>(); //Remove the blocks we need from the list of blocks to overwrite BlocksList.RemoveRange(0x0, (int)((int)FileToOverwrite.BlocksOccupied.Length - BlocksNeeded)); //Finalize uint[] BlocksToFree = BlocksList.ToArray(); //Clears the blocks. ClearFATChain(BlocksToFree, FileToOverwrite); //Make the final block in the series the ending block by writing 0xFFFF to it uint EndBlock = FileToOverwrite.BlocksOccupied[(FileToOverwrite.BlocksOccupied.Length - 1) - BlocksNeeded]; if (FileToOverwrite.PartInfo.EntrySize == Info.PartitionBit.FATX16) { WriteBlock(EndBlock, new byte[] { 0xFF, 0xFF }, FileToOverwrite); } else { WriteBlock(EndBlock, new byte[] { 0xFF, 0xFF, 0xFF, 0xFF }, FileToOverwrite); } BlocksList = FileToOverwrite.BlocksOccupied.ToList<uint>(); BlocksList.RemoveRange(0x0, (FileToOverwrite.BlocksOccupied.Length - 1) - BlocksNeeded); BlocksWeHave = BlocksList.ToArray(); } else if ((int)FileToOverwrite.BlocksOccupied.Length < BlocksNeeded) { //Get the number of blocks we REALLY need int RealBlocksNeeded = BlocksNeeded - FileToOverwrite.BlocksOccupied.Length; //Write out the FAT chain from that last block List<uint> bl = new List<uint>(); bl.Add(FileToOverwrite.BlocksOccupied[FileToOverwrite.BlocksOccupied.Length - 1]); uint[] newBlocks = new FATStuff(FileToOverwrite).GetFreeBlocks(RealBlocksNeeded, bl[0], 0, false); bl.AddRange(newBlocks); //Set the BlocksWeHave BlocksWeHave = bl.ToArray(); } //Create our binary reader to read our file br = new FATX_Browser.FATX.IOReader(new System.IO.FileStream(FilePath, System.IO.FileMode.Open)); for (int i = 0; i < BlocksWeHave.Length; i++) { WriteToCluster(m.GetBlockOffset(BlocksWeHave[i], FileToOverwrite), br.ReadBytes(0x200)); } br.Close(); return true; } catch (Exception e) { try { br.Close(); } catch { } throw e; } }
/// <summary> /// Returns an array of free blocks based off of the number of blocks needed /// </summary> public uint[] GetFreeBlocks(int blocksNeeded, uint StartBlock, long end, bool SecondLoop) { int Clustersize = 0x1000; uint Block = StartBlock; if (end == 0) { end = DataOffset(); } List<uint> BlockList = new List<uint>(); Misc m = new Misc(); for (long i = m.DownToNearest200(m.BlockToFATOffset(StartBlock, Partition)); i < end; i += Clustersize) { //Create our reader FATX_Browser.FATX.IOReader br = ourDrive.GetIO(); //Set our position to i br.BaseStream.Position = i; //Read our buffer byte[] buffer = br.ReadBytes(Clustersize); br.Close(); //Re-open our binary reader using the buffer/memory stream for (int j = 0; j < Clustersize; j+= (int)Partition.EntrySize, Block += (uint)Partition.EntrySize) { br = new FATX_Browser.FATX.IOReader(new System.IO.MemoryStream(buffer)); br.BaseStream.Position = j; //If we've gotten all of our requested blocks... if (BlockList.ToArray().Length == blocksNeeded) { //Close our reader -> break the loop br.Close(); break; } //Read the next block entry byte[] reading = br.ReadBytes((int)Partition.EntrySize); //Close our reader - it's no longer needed br.Close(); //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 = FATOffset; long blockPosition = (long)i + j; uint block = (uint)(blockPosition - fOff) / (uint)EntrySize; BlockList.Add(block); } } } //We're putting in one last check so that we don't loop more than we need to if (BlockList.ToArray().Length == 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(blocksNeeded - BlockList.ToArray().Length, 1, m.DownToNearest200(m.BlockToFATOffset(StartBlock, Partition)), true)); } //We didn't find the amount of free blocks required, meaning we're out of //disk space throw new Exception("Out of Xbox 360 hard disk space"); }
/// <summary> /// Number of File Allocation Tables /// </summary> public uint FATCopies() { uint rVal = 0; Misc m = new Misc(); //Open our binary reader FATX_Browser.FATX.IOReader br = ourDrive.GetIO(); //Seek to the data partition offset + 0xC (where the FATCopies int is) br.BaseStream.Position = Partition.Offset; //Create our mem reader / buffer FATX_Browser.FATX.IOReader mem = new FATX_Browser.FATX.IOReader(new System.IO.MemoryStream(br.ReadBytes(0x200))); br.Close(); mem.BaseStream.Position = 0xC; //Get our value (uses outside class for bigendian) rVal = m.ReadUInt32(ref mem); mem.Close(); return rVal; }
//For reading a single block private byte[] GetOccupiedBlock(uint baseBlock) { //Create our list of our Misc m = new Misc(); //Create our binary reader FATX_Browser.FATX.IOReader br = xDrive.GetIO(); //Read our buffer to load in to the memory stream long BufferOffset = m.BlockToFATOffset(baseBlock, Holder); BufferOffset = BufferOffset - (BufferOffset % 0x200); long BlockOffsetInBuffer = m.BlockToFATOffset(baseBlock, Holder) - BufferOffset; //Go to the buffer we're reading's offset br.BaseStream.Position = BufferOffset; //Read our buffer byte[] buffer = br.ReadBytes(0x200); br.Close(); //Re-open our reader using the memorystream this time FATX_Browser.FATX.IOReader mem = new FATX_Browser.FATX.IOReader(new System.IO.MemoryStream(buffer)); //Close our reader mem.BaseStream.Position = BlockOffsetInBuffer; byte[] rVal = mem.ReadBytes(EntrySize); //The following checks to see if the next block in the sequence is uint nextBlock; if (EntrySize == 4) { byte[] blockCopy = rVal; nextBlock = BitConverter.ToUInt32(blockCopy, 0x0); } else { byte[] blockCopy = rVal; nextBlock = BitConverter.ToUInt16(blockCopy, 0x0); } mem.Close(); return rVal; }
/// <summary> /// Returns an array of EntryData for a specified block /// </summary> /// <param name="block">The block to read from</param> public EntryData[] GetEntries(uint block) { FATX_Browser.FATX.IOReader br = xDrive.GetIO(); //Get the block offset Misc r = new Misc(); br.BaseStream.Position = r.GetBlockOffset(block, Holder.PartInfo); long position = br.BaseStream.Position; //Create another binary reader that will hold our 0x200 bytes to read //(we can not seek to something that's not a multiple of 0x200) long OOFFSET = br.BaseStream.Position; byte[] buffer = br.ReadBytes(0x200); //Our placeholder for the bytes in the buffer read int bufferRead = 0; List<EntryData> l = new List<EntryData>(); for (uint i = 1; i <= 100; i++) { //If we've reached the end of the buffer if (bufferRead == 0x200) { OOFFSET = br.BaseStream.Position; //Read the next 0x200 bytes buffer = br.ReadBytes(0x200); bufferRead = 0; } //Create our stream for the reader FATX_Browser.FATX.IOReader mem = new FATX_Browser.FATX.IOReader(new System.IO.MemoryStream(buffer)); mem.BaseStream.Position = bufferRead; //Make sure that we're not at the end of the block byte[] end = mem.ReadBytes(2); if (EOF(end, true)) { break; } //We have to reset the reader back to the beginning of the block mem.BaseStream.Position -= 0x2; l.Add(GetEData(OOFFSET, mem, i, block)); position += 0x40; bufferRead += 0x40; br.BaseStream.Position = position; mem.Close(); } br.Close(); return l.ToArray(); }
//For getting an array of blocks occupied /// <summary> /// Returns an array of blocks that a file/folder entry occupies /// </summary> /// <param name="baseBlock">The base block to read from the FAT chain (the root)</param> public uint[] GetBlocksOccupied(uint baseBlock) { //Create our list to hold the uints List<uint> l = new List<uint>(); l.Add(baseBlock); //Create a new byte array with random input byte[] ourReturn = { 0xAA, 0xAA }; //Increase the number of blocks - keep the loop going until we've //reached the end of the blocks (0xFFFF or equal) for (int i = 0; !EOF(ourReturn, false); i++) { uint CurrentBlock = l.ToArray()[i]; //Get our next block in the series //Create our list of our Misc m = new Misc(); //Create our binary reader FATX_Browser.FATX.IOReader br = xDrive.GetIO(); //Read our buffer to load in to the memory stream long BufferOffset = m.BlockToFATOffset(CurrentBlock, Holder); BufferOffset = BufferOffset - (BufferOffset % 0x200); long BlockOffsetInBuffer = m.BlockToFATOffset(CurrentBlock, Holder) - BufferOffset; //Go to the buffer we're reading's offset br.BaseStream.Position = BufferOffset; //Read our buffer byte[] buffer = br.ReadBytes(0x200); br.Close(); //Re-open our reader using the memorystream this time FATX_Browser.FATX.IOReader mem = new FATX_Browser.FATX.IOReader(new System.IO.MemoryStream(buffer)); //Close our reader mem.BaseStream.Position = BlockOffsetInBuffer; ourReturn = mem.ReadBytes(EntrySize); mem.Close(); //If the block is the ending block if (EOF(ourReturn, false)) { //Break break; } //The block isn't the ending block, reverse the array so we can //convert it to big endian uintxx Array.Reverse(ourReturn); //Create our value to add to the list uint addVal; if (bit == Info.PartitionBit.FATX32) { addVal = BitConverter.ToUInt32(ourReturn, 0); } else { addVal = BitConverter.ToUInt16(ourReturn, 0); } //Add our value to the list l.Add(addVal); Array.Reverse(ourReturn); if (BufferOffset == (long)(m.DownToNearest200(m.BlockToFATOffset(addVal, Holder)))) { object[] stuff = CheckBlock(ref buffer, ourReturn, BufferOffset); l.AddRange(((List<uint>)stuff[1]).ToArray()); i += ((List<uint>)stuff[1]).Count; if ((bool)stuff[0] == true) { break; } } } return l.ToArray(); }