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"); }
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 bool DeleteInternal(Folder f, ref long progressUpdate, ref long progressMax, ref string CurrentFile) { uint[] Occupied = f.BlocksOccupied; //Set the max progress progressMax = Occupied.Length; foreach (File g in f.Files(false)) { progressMax += (uint)g.BlocksOccupied.Length; } foreach (Folder g in f.SubFolders(false)) { progressMax += (uint)g.BlocksOccupied.Length; } //Set progress update progressUpdate = 0; //Mark the blocks as empty ClearFATChain(Occupied, f); progressUpdate++; foreach (Folder g in f.SubFolders(false)) { DeleteInternal(g, ref progressUpdate, ref progressMax, ref CurrentFile); } foreach (File g in f.Files(false)) { ClearFATChain(g.BlocksOccupied, g); progressUpdate++; } return true; }
public bool WriteNewFile(Folder Root, string FilePath) { int Garbage=0; int Garbage2=0; return WriteNewFile(Root, FilePath, ref Garbage, ref Garbage2); }
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; } }
public bool Delete(Folder f, ref long ProgressUpdate, ref long ProgressMax, ref string CurrentEntry) { return DeleteInternal(f, ref ProgressUpdate, ref ProgressMax, ref CurrentEntry); }
public bool NewFolder(string name, Folder root) { //If the file name is valid if (m.CheckFileName(name)) { EntryData EData = GetNewEntryData(root, name); Folder f = new Folder(ourDrive, root.PartInfo); f.EData = EData; CreateNewEntry(EData); WriteFATChain(f.BlocksOccupied, f); //root.ReloadData(); return true; } return false; }
public bool Delete(Folder f) { long max = 0; long update= 0; string s = ""; return Delete(f, ref update, ref max, ref s); }
/// <summary> /// Provides partition/FAT information /// </summary> public FATStuff(FATXDrive Drive, Folder partition) { ourDrive = Drive; Partition = partition.PartInfo; }
/// <summary> /// Returns a folder when given a path /// </summary> /// <param name="path">The path to the folder</param> //public Folder GetFolder(string path) //{ // //Create our folder for the root // string[] FolderNames = path.Split('\\'); // Folder PartitionEntries = new Folder(DeviceID, Partition); // PartitionEntries.EData.StartingCluster = 1; // //Call to our function that will return our folder // return GetOurFolder(PartitionEntries, FolderNames, 0); //} //private Folder GetOurFolder(Folder f, string[] names, int startIndex) //{ // //Create our array of subfolders // Folder[] subs = f.SubFolders(); // //Loop for each folder in our subfolder // foreach (Folder g in subs) // { // //If the subfolder name matches the name for our desired index // if (g.Name == names[startIndex]) // { // //If we're not at the end of our name array... // if (!(startIndex == names.Length - 1)) // { // //Loop again for the next in the index // GetOurFolder(g, names, startIndex++); // } // //If we ARE in the end of our name array // else // { // //Return our folder // return g; // } // } // } // //The folder was not found, return null // return null; //} /// <summary> /// Returns an array of files and folders for a folder /// </summary> /// <param name="block">The block to read from</param> public object[] LoadEntries(Folder f, bool ShowDeletedEntries) { //Build our list of entry data List<EntryData> eList = new List<EntryData>(); //Build our list for files List<File> fileList = new List<File>(); //Build our list for folders List<Folder> folderList = new List<Folder>(); //For each block this shit occupies for (int i = 0; i < f.BlocksOccupied.Length; i++) { //Builds our list of entry data eList.AddRange(GetEntries(f.BlocksOccupied[i])); } //For each entry in our entry data EntryData[] eArray = eList.ToArray(); foreach (EntryData e in eArray) { //If the entry is a folder if (e.Size == 0) { Folder folder = new Folder(xDrive, Partition); folder.Drive = xDrive; folder.EData = e; folder.PartInfo = ((Folder)Holder).PartInfo; if (e.FileNameSize == 0xE5) { folder.IsDeleted = true; folder.EData.FileName = folder.EData.FileName.Remove(folder.EData.FileName.IndexOf('?')); } folderList.Add(folder); } //If the shit is a file else if (e.FileNameSize > 0x00) { //If the entry is a folder if (e.Flags == 0x10) { //Do nothing } else if (e.Size == 0 && e.StartingCluster == 0) { File file = new File(xDrive, Partition); file.Drive = xDrive; file.EData = e; file.PartInfo = ((Folder)Holder).PartInfo; if (e.FileNameSize == 0xE5) { file.IsDeleted = true; file.EData.FileName = file.EData.FileName.Remove(file.EData.FileName.IndexOf('?')); } fileList.Add(file); } else { File file = new File(xDrive, Partition); file.Drive = xDrive; file.EData = e; file.PartInfo = ((Folder)Holder).PartInfo; if (e.FileNameSize == 0xE5) { file.IsDeleted = true; file.EData.FileName = file.EData.FileName.Remove(file.EData.FileName.IndexOf('?')); } fileList.Add(file); } } } return new object[] { folderList.ToArray(), fileList.ToArray() }; }
/// <summary> /// Returns an array of folders for the specified block /// </summary> /// <param name="block">Block to read from</param> public Folder[] Folders(uint block) { List<Folder> fList = new List<Folder>(); foreach (EntryData data in GetEntries(block)) { //If the entry is a folder if (data.FileNameSize != 0xE5 && data.Size == 0 && data.StartingCluster != 0) { Folder folder = new Folder(xDrive, Partition); folder.Drive = xDrive; folder.EData = data; folder.PartInfo = ((Folder)Holder).PartInfo; fList.Add(folder); } } return fList.ToArray(); }
/// <summary> /// Returns the readable partitions as folders on the drive /// </summary> public Folder[] Get(FATXDrive xDrive) { List<Folder> PIList = new List<Folder>(); if (xDrive.DriveType == Info.DriveType.HDD | xDrive.DriveType == Info.DriveType.Backup) { foreach (Info.HDDFATX.Partitions e in Enum.GetValues(typeof(Info.HDDFATX.Partitions))) { if (e == Info.HDDFATX.Partitions.Data | e == Info.HDDFATX.Partitions.Compatibility) { FATStuff FS = new FATStuff(xDrive, e); if (FS.Magic() == "XTAF") { PartitionInfo PI = new PartitionInfo(); PI.ClusterSize = FS.ClusterSize(); PI.DataOffset = FS.DataOffset(); PI.FATCopies = FS.FATCopies(); PI.FATOffset = FS.FATOffset; PI.FATSize = FS.FATSize(); PI.ID = FS.PartitionID(); PI.Magic = FS.Magic(); PI.Name = e.ToString(); PI.Offset = (long)e; PI.SectorsPerCluster = FS.SectorsPerCluster(); PI.EntrySize = FS.bit; PI.Size = FS.PartitionSize(); Folder f = new Folder(xDrive, PI); f.EData.StartingCluster = 0; PIList.Add(f); } } } if (PIList.Count == 0) { FATStuff FS = new FATStuff(xDrive, (long)0); if (FS.Magic() == "XTAF") { PartitionInfo PI = new PartitionInfo(); PI.ClusterSize = FS.ClusterSize(); PI.DataOffset = FS.DataOffset(); PI.FATCopies = FS.FATCopies(); PI.FATOffset = FS.FATOffset; PI.FATSize = FS.FATSize(); PI.ID = FS.PartitionID(); PI.Magic = FS.Magic(); PI.Name = "Root"; PI.Offset = 0x0; PI.SectorsPerCluster = FS.SectorsPerCluster(); PI.EntrySize = FS.bit; PI.Size = xDrive.DriveSize; Folder f = new Folder(xDrive, PI); PIList.Add(f); } } } else if (xDrive.DriveType == Info.DriveType.USB) { foreach (Info.USBOffsets e in Enum.GetValues(typeof(Info.USBOffsets))) { FATStuff FS = new FATStuff(xDrive, (long)e); if (FS.Magic() == "XTAF") { PartitionInfo PI = new PartitionInfo(); PI.ClusterSize = FS.ClusterSize(); PI.DataOffset = FS.DataOffset(); PI.FATCopies = FS.FATCopies(); PI.FATOffset = FS.FATOffset; PI.FATSize = FS.FATSize(); PI.ID = FS.PartitionID(); PI.Magic = FS.Magic(); PI.Name = e.ToString(); PI.Offset = (long)e; PI.SectorsPerCluster = FS.SectorsPerCluster(); PI.EntrySize = FS.bit; PI.Size = FS.PartitionSize(); Folder f = new Folder(xDrive, PI); f.EData.StartingCluster = 0; PIList.Add(f); } } } else if (PIList.Count == 0) { if (System.Windows.Forms.MessageBox.Show("No partitions were found. Would you like to use the Manual Partition tool to set the offset yourself?", "No Partitions Found", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes) { PartitionInfo PI = new PartitionInfo(); Manual_Partition mp = new Manual_Partition(ref PI); if (mp.ShowDialog() == System.Windows.Forms.DialogResult.OK) { PI = mp.ReturnInfo; FATStuff FS = new FATStuff(xDrive, PI.Offset); if (FS.Magic() == "XTAF") { PI.ClusterSize = FS.ClusterSize(); PI.DataOffset = FS.DataOffset(); PI.FATCopies = FS.FATCopies(); PI.FATOffset = FS.FATOffset; PI.FATSize = FS.FATSize(); PI.ID = FS.PartitionID(); PI.Magic = FS.Magic(); PI.Name = "Root"; PI.SectorsPerCluster = FS.SectorsPerCluster(); PI.EntrySize = FS.bit; PI.Size = FS.PartitionSize(); Folder f = new Folder(xDrive, PI); f.EData.StartingCluster = 0; PIList.Add(f); } } } } return PIList.ToArray(); }