public bool CreateNewEntry(EntryData Edata) { FATX_Browser.FATX.IOReader br = ourDrive.GetIO(); //Set our position so that we can read the entry location br.BaseStream.Position = m.DownToNearest200(Edata.EntryOffset); byte[] buffer = br.ReadBytes(0x200); br.Close(); //Create our binary writer FATX_Browser.FATX.IOWriter bw = new FATX_Browser.FATX.IOWriter(new System.IO.MemoryStream(buffer)); //Set our position to where the entry is long EntryOffset = Edata.EntryOffset - m.DownToNearest200(Edata.EntryOffset); bw.BaseStream.Position = EntryOffset; //Write our entry bw.Write(Edata.FileNameSize); bw.Write(Edata.Flags); bw.Write(Encoding.ASCII.GetBytes(Edata.FileName)); bw.BaseStream.Position = EntryOffset + 0x2C; //Right here, we need to make everything a byte array, as it feels like writing //everything in little endian for some reason... byte[] StartingCluster = BitConverter.GetBytes(Edata.StartingCluster); Array.Reverse(StartingCluster); bw.Write(StartingCluster); byte[] Size = BitConverter.GetBytes(Edata.Size); Array.Reverse(Size); bw.Write(Size); //Write out the creation date 6 times byte[] CreationDate = BitConverter.GetBytes(Edata.CreationDate); byte[] CreationTime = BitConverter.GetBytes(Edata.CreationTime); Array.Reverse(CreationDate); Array.Reverse(CreationTime); for (int i = 0; i < 3; i++) { bw.Write(CreationDate); bw.Write(CreationTime); } //Close our writer bw.Close(); //Get our IO bw = ourDrive.GetWriterIO(); bw.BaseStream.Position = m.DownToNearest200(Edata.EntryOffset); //Write out our buffer bw.Write(buffer); return true; }
private object[] CheckIfBlocksNeeded(Folder f) { //Create our object array that will hold our Bool and Entry for if //we need an open block, and if there's a deleted file //Create our entry reader so that we can get a return of entries... Entries e = new Entries(f); //Get our entries in the last block EntryData[] eData = e.GetEntries(f.BlocksOccupied[f.BlocksOccupied.Length - 1]); //Files span upon multiple blocks... Here we go to the last block that it occupies //(the most recent block created), and check if it has any open entries //Check for deleted entries foreach (EntryData E in eData) { if (E.FileNameSize == (byte)Info.FileFlags.Deleted) { return new object[] { true, E }; } } //We didn't find a deleted entry, but we have room in the last block of the folder //for a new entry if (eData.Length < 100) { EntryData newEntry = new EntryData(); newEntry.EntryOffset = eData[eData.Length - 1].EntryOffset + 0x40; newEntry.StartingCluster = eData[eData.Length - 1].StartingCluster; return new object[] { false, newEntry }; } //We don't have any deleted entries, and don't have enough room in the last block, //so let's create a new block, add it to the FAT chain, etc. //Get our new block... uint nextBlock = new FATStuff(f).GetFreeBlocks(1, f.BlocksOccupied[f.BlocksOccupied.Length - 1], 0, false)[0]; //Write the fat chain WriteFATChain(new uint[] { f.BlocksOccupied[f.BlocksOccupied.Length - 1], nextBlock}, f); //Create our new entrydata EntryData EntryNew = new EntryData(); EntryNew.EntryOffset = m.GetBlockOffset(nextBlock, f); return new object[] { false, EntryNew }; }
private EntryData GetNewEntryData(Folder root, string Name) { if (m.CheckFileName(Name)) { EntryData EData = new EntryData(); object[] ourObject = CheckIfBlocksNeeded(root); //If we need to create a new entry... if (!(bool)ourObject[0]) { //Create our new entrydata that will serve as the EData for the new folder Int32 timeStamp = m.FatTimeInt(DateTime.Now); byte[] ourArray = BitConverter.GetBytes(timeStamp); byte[] CD = new byte[] { ourArray[2], ourArray[3] }; byte[] CT = new byte[] { ourArray[0], ourArray[1] }; EData.CreationDate = BitConverter.ToUInt16(CD, 0); EData.CreationTime = BitConverter.ToUInt16(CT, 0); EData.FileName = Name; EData.FileNameSize = (byte)Name.Length; EData.Flags = 0x10; EData.Size = 0x0; //Uint for our blocks.. uint[] Blocks = new FATStuff(root).GetFreeBlocks(1, ((EntryData)ourObject[1]).StartingCluster, 0, false); //Set our starting cluster using the "GetFreeBlocks" method - tell it we need one block, and the starting block is the block of the previous entry EData.StartingCluster = Blocks[0]; //If we're using a block that we just created (the current block for the parent folder //has free space EData.EntryOffset = ((EntryData)ourObject[1]).EntryOffset; //Create a new folder Folder f = new Folder(ourDrive, root.PartInfo); f.EData = EData; f.BlocksOccupied = Blocks; CreateNewEntry(EData); WriteFATChain(f.BlocksOccupied, f); } //We are using a deleted entry else { Int32 timeStamp = m.FatTimeInt(DateTime.Now); byte[] ourArray = BitConverter.GetBytes(timeStamp); byte[] CD = new byte[] { ourArray[0], ourArray[1] }; Array.Reverse(CD); byte[] CT = new byte[] { ourArray[2], ourArray[3] }; Array.Reverse(CT); EData.CreationDate = BitConverter.ToUInt16(CD, 0); EData.CreationTime = BitConverter.ToUInt16(CT, 0); EData.FileName = Name; EData.FileNameSize = (byte)Name.Length; EData.Flags = 0x10; EData.Size = 0x0; EData.StartingCluster = new FATStuff(root).GetFreeBlocks(1, ((EntryData)ourObject[1]).StartingCluster, 0, false)[0]; EData.EntryOffset = ((EntryData)ourObject[1]).EntryOffset; Folder f = new Folder(ourDrive, root.PartInfo); f.EData = EData; CreateNewEntry(EData); WriteFATChain(f.BlocksOccupied, f); } return EData; } throw new Exception("File name not valid"); }
/// <summary> /// Returns EntryData for an entry in a block /// </summary> /// <param name="br">The binary reader to use</param> /// <param name="EntryBlock">The entry in the block to read</param> /// <param name="Block">The block to read from</param> internal EntryData GetEData(long originalOffset, FATX_Browser.FATX.IOReader br, uint EntryBlock, uint Block) { Misc r = new Misc(); //br.BaseStream.Position = 0x131229000;//(r.GetBlockOffset(Block, Partition, DeviceID)) + (0x40 * EntryBlock); //Create our return EntryData data = new EntryData(); //Read our variables data.EntryOffset = originalOffset + br.BaseStream.Position; data.FileNameSize = br.ReadByte(); data.Flags = br.ReadByte(); data.FileName = Encoding.ASCII.GetString(br.ReadBytes((int)data.FileNameSize)); //Go to the end of the name to continue reading the variables br.BaseStream.Position += (0x2A - (int)data.FileNameSize); data.StartingCluster = r.ReadUInt32(ref br); data.Size = r.ReadUInt32(ref br); data.CreationDate = r.ReadUInt16(ref br); data.CreationTime = r.ReadUInt16(ref br); data.AccessDate = r.ReadUInt16(ref br); data.AccessTime = r.ReadUInt16(ref br); data.ModifiedDate = r.ReadUInt16(ref br); data.ModifiedTime = r.ReadUInt16(ref br); //br.BaseStream.Position += 0xC; br.Close(); return data; //TODO: Datetime conversion from FAT to DateTime }