/* Create Recursive */ static MfsEntry CreateRecursive(MfsDisk mDisk, SafeFileHandle hDisk, UInt32 DirBucket, String pPath) { /* Sanity, if start with "/" skip */ String mPath = pPath; if (mPath.StartsWith("/")) mPath = mPath.Substring(1, mPath.Length - 1); if (mPath.EndsWith("/")) mPath = mPath.Substring(0, mPath.Length - 1); /* Get token */ int iDex = mPath.IndexOf("/"); String LookFor = mPath.Substring(0, iDex == -1 ? mPath.Length : iDex); /* EoP */ if (String.IsNullOrEmpty(LookFor) || iDex == -1) { /* List files */ UInt32 IteratorBucket = DirBucket; UInt32 PrevItrBucket = 0; int End = 0; while (End == 0) { UInt64 Sector = IteratorBucket * mDisk.BucketSize; /* Gogo */ Byte[] fBuffer = ReadDisk(mDisk, hDisk, Sector, mDisk.BucketSize); for (int i = 0; i < (mDisk.BucketSize * mDisk.BytesPerSector); i++) { /* EoC? */ if (fBuffer[i] == 0) { End = 1; break; } /* Woah, parse */ int Len = 0; while (fBuffer[i + 76 + Len] != 0) Len++; String Name = System.Text.Encoding.UTF8.GetString(fBuffer, i + 76, Len); UInt16 Flags = BitConverter.ToUInt16(fBuffer, i + 2); if (Name.ToLower() == LookFor.ToLower()) return null; /* Next */ i += 1023; } /* Sanity */ if (End == 1) break; /* Get next bucket */ UInt32 DirBucketLength = 0; PrevItrBucket = IteratorBucket; if (End == 0) IteratorBucket = GetNextBucket(mDisk, hDisk, IteratorBucket, out DirBucketLength); /* End of list? */ if (IteratorBucket == 0xFFFFFFFF) End = 1; } /* We must reach this point */ MfsEntry nEntry = new MfsEntry(); nEntry.DirBucket = IteratorBucket == 0xFFFFFFFF ? PrevItrBucket : IteratorBucket; nEntry.DirIndex = 0; /* Done */ return nEntry; } else { /* Find LookFor in DirBucket */ UInt32 IteratorBucket = DirBucket; int End = 0; while (End == 0) { UInt64 Sector = IteratorBucket * mDisk.BucketSize; /* Gogo */ Byte[] fBuffer = ReadDisk(mDisk, hDisk, Sector, mDisk.BucketSize); for (int i = 0; i < (mDisk.BucketSize * mDisk.BytesPerSector); i++) { /* EoC? */ if (fBuffer[i] == 0) { End = 1; break; } /* Woah, parse */ int Len = 0; while (fBuffer[i + 76 + Len] != 0) Len++; String Name = System.Text.Encoding.UTF8.GetString(fBuffer, i + 76, Len); UInt16 Flags = BitConverter.ToUInt16(fBuffer, i + 2); if (Name.ToLower() == LookFor.ToLower()) { /* More sanity */ if (!((MfsEntryFlags)Flags).HasFlag(MfsEntryFlags.MFS_DIRECTORY)) { Console.WriteLine(LookFor + " is not a directory"); return null; } /* Match */ MfsEntry nEntry = new MfsEntry(); nEntry.Name = Name; nEntry.Size = BitConverter.ToUInt64(fBuffer, i + 60); nEntry.AllocatedSize = BitConverter.ToUInt64(fBuffer, i + 68); nEntry.Bucket = BitConverter.ToUInt32(fBuffer, i + 4); nEntry.BucketLength = BitConverter.ToUInt32(fBuffer, i + 8); nEntry.DirBucket = IteratorBucket; nEntry.DirIndex = (uint)i; /* Sanity */ if (nEntry.Bucket == 0xFFFFFFFF) { Byte[] Mbr = ReadDisk(mDisk, hDisk, 0, 1); /* Find MB Ptr */ UInt64 MbSector = BitConverter.ToUInt64(Mbr, 28); UInt64 MbMirrorSector = BitConverter.ToUInt64(Mbr, 36); /* Find Root Ptr in MB */ Byte[] Mb = ReadDisk(mDisk, hDisk, MbSector, 1); UInt32 FreeBucket = BitConverter.ToUInt32(Mb, 8); /* Allocate */ nEntry.Bucket = FreeBucket; UInt32 InitialBucketSize = 0; UInt32 NextFree = AllocateBucket(mDisk, hDisk, FreeBucket, 1, out InitialBucketSize); /* Update Mb */ Mb[8] = (Byte)(NextFree & 0xFF); Mb[9] = (Byte)((NextFree >> 8) & 0xFF); Mb[10] = (Byte)((NextFree >> 16) & 0xFF); Mb[11] = (Byte)((NextFree >> 24) & 0xFF); /* Write Mb */ WriteDisk(mDisk, hDisk, MbSector, Mb); WriteDisk(mDisk, hDisk, MbMirrorSector, Mb); /* Update Dir */ fBuffer[i + 4] = (Byte)(nEntry.Bucket & 0xFF); fBuffer[i + 5] = (Byte)((nEntry.Bucket >> 8) & 0xFF); fBuffer[i + 6] = (Byte)((nEntry.Bucket >> 16) & 0xFF); fBuffer[i + 7] = (Byte)((nEntry.Bucket >> 24) & 0xFF); fBuffer[i + 8] = 0x01; fBuffer[i + 9] = 0x00; fBuffer[i + 10] = 0x00; fBuffer[i + 11] = 0x00; WriteDisk(mDisk, hDisk, Sector, fBuffer); /* Wipe bucket */ Byte[] Wipe = new Byte[mDisk.BucketSize * mDisk.BytesPerSector]; for (int g = 0; g < Wipe.Length; g++) Wipe[g] = 0; WriteDisk(mDisk, hDisk, (nEntry.Bucket * mDisk.BucketSize), Wipe); } /* Done */ return CreateRecursive(mDisk, hDisk, nEntry.Bucket, mPath.Substring(LookFor.Length)); } /* Next */ i += 1023; } /* Get next bucket */ UInt32 DirBucketLength = 0; if (End == 0) IteratorBucket = GetNextBucket(mDisk, hDisk, IteratorBucket, out DirBucketLength); /* CAN not be end of list? */ if (IteratorBucket == 0xFFFFFFFF) End = 1; } } return null; }
/* Recursive List */ static MfsEntry ListRecursive(MfsDisk mDisk, SafeFileHandle hDisk, UInt32 DirBucket, String pPath) { /* Sanity, if start with "/" skip */ String mPath = pPath; if (mPath.StartsWith("/")) mPath = mPath.Substring(1, mPath.Length - 1); /* Get token */ int iDex = mPath.IndexOf("/"); String LookFor = mPath.Substring(0, iDex == -1 ? mPath.Length : iDex); /* EoP */ if (String.IsNullOrEmpty(LookFor) || LookFor.Contains(".")) { /* List files */ UInt32 IteratorBucket = DirBucket; int End = 0; while (End == 0) { UInt64 Sector = IteratorBucket * mDisk.BucketSize; /* Gogo */ Byte[] fBuffer = ReadDisk(mDisk, hDisk, Sector, mDisk.BucketSize); for (int i = 0; i < (mDisk.BucketSize * mDisk.BytesPerSector); i++) { /* EoC? */ if (fBuffer[i] == 0) { End = 1; break; } /* Woah, parse */ int Len = 0; while (fBuffer[i + 76 + Len] != 0) Len++; String Name = System.Text.Encoding.UTF8.GetString(fBuffer, i + 76, Len); UInt16 Flags = BitConverter.ToUInt16(fBuffer, i + 2); if (LookFor.Contains(".") && Name.ToLower() == LookFor.ToLower()) { /* Match */ MfsEntry nEntry = new MfsEntry(); nEntry.Name = Name; nEntry.Size = BitConverter.ToUInt64(fBuffer, i + 60); nEntry.AllocatedSize = BitConverter.ToUInt64(fBuffer, i + 68); nEntry.Bucket = BitConverter.ToUInt32(fBuffer, i + 4); nEntry.BucketLength = BitConverter.ToUInt32(fBuffer, i + 8); nEntry.DirBucket = IteratorBucket; nEntry.DirIndex = (uint)i; /* Done */ return nEntry; } else { if (((MfsEntryFlags)Flags).HasFlag(MfsEntryFlags.MFS_DIRECTORY)) Console.WriteLine("Dir: " + Name); else Console.WriteLine("File: " + Name + " (" + BitConverter.ToUInt64(fBuffer, i + 60).ToString() + " Bytes)"); } /* Next */ i += 1023; } /* Get next bucket */ UInt32 DirBuckLength = 0; if (End == 0) IteratorBucket = GetNextBucket(mDisk, hDisk, IteratorBucket, out DirBuckLength); /* End of list? */ if (IteratorBucket == 0xFFFFFFFF) End = 1; } /* Done */ return null; } else { /* Find LookFor in DirBucket */ UInt32 IteratorBucket = DirBucket; int End = 0; while (End == 0) { UInt64 Sector = IteratorBucket * mDisk.BucketSize; /* Gogo */ Byte[] fBuffer = ReadDisk(mDisk, hDisk, Sector, mDisk.BucketSize); for (int i = 0; i < (mDisk.BucketSize * mDisk.BytesPerSector); i++) { /* EoC? */ if (fBuffer[i] == 0) { End = 1; break; } /* Woah, parse */ int Len = 0; while (fBuffer[i + 76 + Len] != 0) Len++; String Name = System.Text.Encoding.UTF8.GetString(fBuffer, i + 76, Len); UInt16 Flags = BitConverter.ToUInt16(fBuffer, i + 2); if (Name.ToLower() == LookFor.ToLower()) { /* More sanity */ if (!((MfsEntryFlags)Flags).HasFlag(MfsEntryFlags.MFS_DIRECTORY)) { Console.WriteLine(LookFor + " is not a directory"); return null; } /* Match */ MfsEntry nEntry = new MfsEntry(); nEntry.Name = Name; nEntry.Size = BitConverter.ToUInt64(fBuffer, i + 60); nEntry.AllocatedSize = BitConverter.ToUInt64(fBuffer, i + 68); nEntry.Bucket = BitConverter.ToUInt32(fBuffer, i + 4); nEntry.BucketLength = BitConverter.ToUInt32(fBuffer, i + 8); nEntry.DirBucket = IteratorBucket; nEntry.DirIndex = (uint)i; /* Sanity */ if (nEntry.Bucket == 0xFFFFFFFF) return null; /* Done */ return ListRecursive(mDisk, hDisk, nEntry.Bucket, mPath.Substring(LookFor.Length)); } /* Next */ i += 1023; } /* Get next bucket */ UInt32 DirBuckLength = 0; if (End == 0) IteratorBucket = GetNextBucket(mDisk, hDisk, IteratorBucket, out DirBuckLength); /* End of list? */ if (IteratorBucket == 0xFFFFFFFF) End = 1; } } return null; }