// Do not feel like recoding this function. public void CreateNewEntry(EntryData Edata) { Streams.Reader br = Parent.Drive.Reader(); //Set our position so that we can read the entry location br.BaseStream.Position = VariousFunctions.DownToNearest200(Edata.EntryOffset); byte[] buffer = br.ReadBytes(0x200); //Create our binary writer Streams.Writer bw = new Streams.Writer(new System.IO.MemoryStream(buffer)); //Set our position to where the entry is long EntryOffset = Edata.EntryOffset - VariousFunctions.DownToNearest200(Edata.EntryOffset); bw.BaseStream.Position = EntryOffset; //Write our entry bw.Write(Edata.NameSize); bw.Write(Edata.Flags); bw.Write(Encoding.ASCII.GetBytes(Edata.Name)); if (Edata.NameSize != 0xE5) { int FFLength = 0x2A - Edata.NameSize; byte[] FF = new byte[FFLength]; for (int i = 0; i < FFLength; i++) { FF[i] = 0xFF; } bw.Write(FF); } else { bw.BaseStream.Position += 0x2A - Edata.Name.Length; } //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 ref the creation date/time 3 times byte[] CreationDate = BitConverter.GetBytes(Edata.CreationDate); byte[] CreationTime = BitConverter.GetBytes(Edata.CreationTime); byte[] AccessDate = BitConverter.GetBytes(Edata.AccessDate); byte[] AccessTime = BitConverter.GetBytes(Edata.AccessTime); byte[] ModifiedDate = BitConverter.GetBytes(Edata.ModifiedDate); byte[] ModifiedTime = BitConverter.GetBytes(Edata.ModifiedTime); Array.Reverse(CreationDate); Array.Reverse(CreationTime); Array.Reverse(AccessDate); Array.Reverse(AccessTime); Array.Reverse(ModifiedDate); Array.Reverse(ModifiedTime); bw.Write(CreationDate); bw.Write(CreationTime); bw.Write(AccessDate); bw.Write(AccessTime); bw.Write(ModifiedDate); bw.Write(ModifiedTime); //Close our writer bw.Close(); //Get our IO bw = Parent.Drive.Writer(); bw.BaseStream.Position = VariousFunctions.DownToNearest200(Edata.EntryOffset); //Write ref our buffer bw.Write(buffer); }
/* AUTOMATICALLY CREATES SHIT */ public EntryData GetNewEntry(Folder Destination, uint Size, Geometry.Flags[] Flags, string EntryName) { if (!VariousFunctions.CheckFileName(EntryName)) { throw new ArgumentException("Invalid name: \"" + EntryName + "\"", "EntryName"); } EntryData newEntryData = new EntryData(); newEntryData.EntryOffset = GetNewEntryOffset(Destination); ushort Date = VariousFunctions.DateTimeToFATShort(DateTime.Now, true); ushort Time = VariousFunctions.DateTimeToFATShort(DateTime.Now, false); newEntryData.CreationDate = Date; newEntryData.CreationTime = Time; newEntryData.ModifiedDate = Date; newEntryData.ModifiedTime = Time; newEntryData.AccessDate = Date; newEntryData.AccessTime = Time; if (Flags.Length != 0) { newEntryData.Flags = VariousFunctions.FlagsToByte(Flags); } else { newEntryData.Flags = 0; } newEntryData.Size = Size; newEntryData.Name = EntryName; newEntryData.NameSize = (byte)EntryName.Length; if ((Size == 0 && Flags.Contains(Geometry.Flags.Directory)) || (Size != 0 && Flags.Length == 0)) { newEntryData.StartingCluster = Destination.Drive.GetFreeBlocks(Destination, 1, 0, 0, false)[0]; } else { newEntryData.StartingCluster = 0; } WriteFATChain(new uint[] { newEntryData.StartingCluster }); CreateNewEntry(newEntryData); return newEntryData; }
public EntryData[] EntryDataFromBlock(uint Block) { bool Break = false; List<EntryData> eList = new List<EntryData>(); // Get our binary reader Streams.Reader r1 = Parent.Drive.Reader(); r1.BaseStream.Position = VariousFunctions.GetBlockOffset(Block, Parent); /* Parent.PartitionInfo.Clusters / 0x40 / 0x8 because if each * entry is 0x40 in length and the cluster is filled to the * max with cluster entries, then we can do division to get * the number of entries that would be in that cluster * the 0x8 part is because on drives we have to read in intervals * of 0x200 right? So if Parent.PartitionInfo.Clusters / 0x40 = 0x100, * then that means that there are 0x100 entries per cluster... * divide that by 8 (the number of clusters within a 0x200 interval) and * that's how many shits we have to go forward */ for (int j = 0; j < Parent.PartitionInfo.ClusterSize / 0x1000; j++) { // Increment our position // Open another reader using a memory stream long r1Position = r1.BaseStream.Position; Streams.Reader r = new CLKsFATXLib.Streams.Reader(new System.IO.MemoryStream(r1.ReadBytes(0x1000))); for (int k = 0; k < (0x1000 / 0x40); k++) { // Check to see if we've passed the last entry... uint val = r.ReadUInt32(); if (val == 0x0 || val == 0xFFFFFFFF) { Break = true; break; } // Go back four bytes because we just checked the next four... r.BaseStream.Position -= 4; long StartOffset = r.BaseStream.Position; EntryData e = new EntryData(); e.EntryOffset = r.BaseStream.Position + r1Position; e.NameSize = r.ReadByte(); e.Flags = r.ReadByte(); /* Because some f*****g smart guy decided to put the * deleted flag in the name size field, we have to check * if it's deleted or not...*/ if (e.NameSize == 0xE5) { // Fuckers e.Name = Encoding.ASCII.GetString(r.ReadBytes(0x2A)); } else { e.Name = Encoding.ASCII.GetString(r.ReadBytes(e.NameSize)); } r.BaseStream.Position = StartOffset + 0x2C; e.StartingCluster = r.ReadUInt32(); e.Size = r.ReadUInt32(); e.CreationDate = r.ReadUInt16(); e.CreationTime = r.ReadUInt16(); e.AccessDate = r.ReadUInt16(); e.AccessTime = r.ReadUInt16(); e.ModifiedDate = r.ReadUInt16(); e.ModifiedTime = r.ReadUInt16(); eList.Add(e); } r.Close(); if (Break) { break; } } return eList.ToArray(); }
public File(PartitionInfo Partition, EntryData EntryData, Drive Drive) : base(Partition, EntryData, Drive) { }
public Entry(PartitionInfo Partition, EntryData EntryData, Drive Drive) { this.PartitionInfo = Partition; this.Drive = Drive; this.EntryData = EntryData; }
/// <summary> /// Default constructor for the folder class /// </summary> /// <param name="Partition">Partition information to which this folder belongs to</param> /// <param name="EntryData">The entry data for this folder</param> /// <param name="Drive">Drive which this folder belongs to</param> public Folder(PartitionInfo Partition, EntryData EntryData, Drive Drive) : base(Partition, EntryData, Drive) { ReturnDeletedEntries = false; }