public byte[] SaveToArray() { byte[] temp = new byte[Leo.LBAToByte(DiskType, Leo.RamStartLBA[DiskType], 3)]; Util.WriteStringN(MFS.RAM_ID, temp, 0, MFS.RAM_ID.Length); temp[0x0E] = (byte)(0 | (Attributes.isVolumeWriteProtected ? 0x20 : 0) | (Attributes.isVolumeReadProtected ? 0x40 : 0) | (Attributes.isWriteProtected ? 0x80 : 0)); temp[0x0F] = (byte)DiskType; Util.WriteStringN(Name, temp, 0x10, 0x14); Util.WriteBEU32(Date.Save(), temp, 0x24); Util.WriteBEU16(Renewal, temp, 0x28); temp[0x2A] = Country; //Save FAT Entries for (int i = 0; i < FAT.Length; i++) { Util.WriteBEU16(FAT[i], temp, 0x3C + (i * 2)); } //Save File Entries 0x16B0 for (int i = 0; i < Entries.Count; i++) { byte[] tempentry; if (Entries[i].GetType() == typeof(MFSDirectory)) { tempentry = ((MFSDirectory)Entries[i]).Save(); } else { tempentry = ((MFSFile)Entries[i]).Save(); } Array.Copy(tempentry, 0, temp, 0x16B0 + (0x30 * i), 0x30); } //Checksum uint crc = 0; for (int i = 0; i < (temp.Length / 4); i++) { crc ^= Util.ReadBEU32(temp, i * 4); } Util.WriteBEU32(crc, temp, 0x2C); return(temp); }
public static bool WriteFile(MFSDisk mfsDisk, byte[] filedata, MFSFile file) { if (CheckIfFileAlreadyExists(mfsDisk, file.Name, file.Ext, file.ParentDirectory)) { return(false); } if (GetFreeSpaceSize(mfsDisk) < filedata.Length) { return(false); } int FATentry = -1; int lastFATentry = -1; int offset = 0; for (int i = 6; i < Leo.SIZE_LBA - Leo.RamStartLBA[mfsDisk.RAMVolume.DiskType]; i++) { if (mfsDisk.RAMVolume.FAT[i] == (ushort)MFS.FAT.Unused) { if (FATentry == -1) { FATentry = i; file.FATEntry = (ushort)i; } //Write File Data Array.Copy(filedata, offset, mfsDisk.Data, mfsDisk.OffsetToMFSRAM + Leo.LBAToByte(mfsDisk.RAMVolume.DiskType, Leo.RamStartLBA[mfsDisk.RAMVolume.DiskType], i), Math.Min(Leo.LBAToByte(mfsDisk.RAMVolume.DiskType, Leo.RamStartLBA[mfsDisk.RAMVolume.DiskType] + i, 1), filedata.Length - offset)); offset += Math.Min(Leo.LBAToByte(mfsDisk.RAMVolume.DiskType, Leo.RamStartLBA[mfsDisk.RAMVolume.DiskType] + i, 1), filedata.Length - offset); if (lastFATentry != -1) { mfsDisk.RAMVolume.FAT[lastFATentry] = (ushort)i; } if (offset == filedata.Length) { mfsDisk.RAMVolume.FAT[i] = (ushort)MFS.FAT.LastFileBlock; mfsDisk.RAMVolume.Entries.Add(file); return(true); } lastFATentry = i; } } return(false); }
public static int GetCapacitySize(MFSDisk mfsDisk) { int totalsize = 0; for (int i = 6; i < Leo.SIZE_LBA - Leo.RamStartLBA[mfsDisk.RAMVolume.DiskType]; i++) { switch (mfsDisk.RAMVolume.FAT[i]) { case (ushort)MFS.FAT.Prohibited: case (ushort)MFS.FAT.DontManage: break; default: totalsize += Leo.LBAToByte(mfsDisk.RAMVolume.DiskType, Leo.RamStartLBA[mfsDisk.RAMVolume.DiskType] + i, 1); break; } } return(totalsize); }
public static byte[] ReadFile(MFSDisk mfsDisk, MFSFile file) { byte[] filedata = new byte[file.Size]; //Add FAT Entries and Copy to data to blocks ushort nextblock = file.FATEntry; uint offset = 0; uint size = file.Size; do { int blocksrc = Leo.LBAToByte(mfsDisk.RAMVolume.DiskType, Leo.RamStartLBA[mfsDisk.RAMVolume.DiskType], nextblock); int blocksize = Leo.LBAToByte(mfsDisk.RAMVolume.DiskType, Leo.RamStartLBA[mfsDisk.RAMVolume.DiskType] + nextblock, 1); Array.Copy(mfsDisk.Data, mfsDisk.OffsetToMFSRAM + blocksrc, filedata, offset, Math.Min(blocksize, size)); offset += (uint)Math.Min(blocksize, size); size -= (uint)Math.Min(blocksize, size); nextblock = mfsDisk.RAMVolume.FAT[nextblock]; }while (nextblock != (ushort)MFS.FAT.LastFileBlock); return(filedata); }
void Load(string filepath) { //Assume RAM format for now Format = MFS.DiskFormat.Invalid; if (!File.Exists(filepath)) { return; } FileStream file = new FileStream(filepath, FileMode.Open); if (file.Length >= Leo.RamSize[5]) { //Check Header file.Seek(0, SeekOrigin.Begin); byte[] test = new byte[MFS.RAM_ID.Length]; file.Read(test, 0, test.Length); if (Encoding.ASCII.GetString(test).Equals(MFS.RAM_ID)) { //It's a RAM file file.Seek(15, SeekOrigin.Begin); int DiskType = file.ReadByte(); if (DiskType >= 0 && DiskType < 6 && Leo.RamSize[DiskType] == file.Length) { file.Seek(0, SeekOrigin.Begin); OffsetToMFSRAM = 0; Data = new byte[file.Length]; file.Read(Data, 0, Data.Length); RAMVolume = new MFSRAMVolume(Data, OffsetToMFSRAM); Format = MFS.DiskFormat.RAM; } } else { //SHA256 check if N64 Cartridge Port bootloader byte[] headerTest = new byte[0xFC0]; file.Seek(0x40, SeekOrigin.Begin); file.Read(headerTest, 0, headerTest.Length); SHA256 hashHeader = SHA256.Create(); hashHeader.ComputeHash(headerTest); string hashHeaderStr = ""; foreach (byte b in hashHeader.Hash) { hashHeaderStr += b.ToString("x2"); } Console.WriteLine(hashHeaderStr); int offsetStart = 0; //SHA256 = 53c0088fb777870d0af32f0251e964030e2e8b72e830c26042fd191169508c05 if (hashHeaderStr == "53c0088fb777870d0af32f0251e964030e2e8b72e830c26042fd191169508c05") { offsetStart = 0x738C0 - 0x10E8; //Start of User LBA 0 (24 w/ System Area) } //Try every Disk Type for (int i = 0; i < 6; i++) { int offset = Leo.LBAToByte(i, 0, Leo.RamStartLBA[i]) - offsetStart; file.Seek(offset, SeekOrigin.Begin); file.Read(test, 0, test.Length); if (Encoding.ASCII.GetString(test).Equals(MFS.RAM_ID)) { OffsetToMFSRAM = offset; Data = new byte[file.Length]; file.Seek(0, SeekOrigin.Begin); file.Read(Data, 0, Data.Length); RAMVolume = new MFSRAMVolume(Data, OffsetToMFSRAM); if (offsetStart == 0) { Format = MFS.DiskFormat.SDK; } else { Format = MFS.DiskFormat.N64; } break; } } } } file.Close(); }
public static int GetFreeSpaceSize(MFSDisk mfsDisk) { int unused = Leo.RamSize[mfsDisk.RAMVolume.DiskType] - GetTotalUsedSize(mfsDisk) - Leo.LBAToByte(mfsDisk.RAMVolume.DiskType, Leo.RamStartLBA[mfsDisk.RAMVolume.DiskType], 6); return(unused); }