private bool WriteEntryData(BinaryWriter Writer, ImageEntry Entry, uint DataOffset) { if (Writer == null) { return(false); } // Check if the entry is valid before writing the data if (!CheckEntry(Entry)) { return(false); } try { long oldPos = Writer.BaseStream.Position; // Seek to the start of data Writer.BaseStream.Seek(DataOffset, SeekOrigin.Begin); // Write all the data Writer.Write(Entry.Data); Writer.BaseStream.Position = oldPos; } catch (Exception) { return(false); } return(true); }
public bool ReplaceImage(int ID, ImageEntry NewEntry) { if (Images.Count <= ID || ID < 0) { return(false); } Images[ID] = NewEntry; return(true); }
public bool CheckAddEntry(ImageEntry Entry) { if (Images.Count == 0 && Entry.Data.Length > NandSize / 2) { return(false); } if (CalculateUsage() + Entry.Data.Length > NandSize) { return(false); } return(NandImage.CheckEntry(Entry)); }
public static bool CheckEntry(ImageEntry Entry) { if (Entry.Data == null) { return(false); } if (Entry.Data.Length == 0) { return(false); } if (Entry.Name.Length >= 0x30) { return(false); } return(true); }
public bool ReadImage(Stream ImageStream) { if (ImageStream == null) { return(false); } BinaryReader reader = new BinaryReader(ImageStream); uint numImages = 0; // Prepare everything Header = new BootHeader(); if (Images != null) { Images.Clear(); } Images = new List <ImageEntry>(); // Our blocksize is 0x20000 bytes / block // Seek to the beginning of the file / memorystream for our header block // When writing, there is a copy of the entire NandLoader at 0x20000, 0x40000 and 0x60000 reader.BaseStream.Seek(0x00000, SeekOrigin.Begin); if (!ReadBootHeader(reader, out Header)) { return(false); } // Now seek to block 0 of the last nand page - 1 // When writing, there is a copy at 0x3f000, 0x5f000 and at 0x7f000 reader.BaseStream.Seek(0x1f000, SeekOrigin.Begin); try { // Now check the magic if (reader.ReadUInt32() != 0x574255aa) { return(false); } // Then read the number of images numImages = reader.ReadUInt32(); // Now skip one 32 bit word reader.BaseStream.Seek(sizeof(uint), SeekOrigin.Current); // Finally check the last magic if (reader.ReadUInt32() != 0x57425963) { return(false); } } catch (Exception) { return(false); } // Now we can read the image structs for (int image = 0; image < numImages; image++) { ImageHeader head; if (!ReadEntryHeader(reader, out head)) { return(false); } ImageEntry entry = new ImageEntry(head.ImageName, head.ImageType, head.ExecuteAddress); if (!ReadEntryData(reader, head, out entry.Data)) { return(false); } if (!CheckAddEntry(entry)) { return(false); } Images.Add(entry); } return(true); }
public bool WriteImage(Stream ImageStream) { if (Images == null || ImageStream == null) { return(false); } if (Images.Count == 0) { return(false); } try { BinaryWriter writer = new BinaryWriter(ImageStream); // Write the boot header to various locations // 0x00000, 0x20000, 0x40000 and 0x60000 for (int block = 0; block < 4; block++) { writer.BaseStream.Seek(0x20000 * block, SeekOrigin.Begin); if (!WriteBootHeader(writer, Header)) { return(false); } } // When writing the bootloader, there is a copy at 0x1f000, 0x3f000, 0x5f000 // and at 0x7f000 // Copy the headers and data over for (int copyIter = 0; copyIter < 4; copyIter++) { // Seek to the end page of the block writer.BaseStream.Seek((0x10000 + (0x20000 * copyIter)) | 0xf000, SeekOrigin.Begin); // Write the preamble // First, seek to the last page of the block try { // Now write the magic writer.Write((uint)0x574255aa); // Then write the number of images writer.Write((uint)Images.Count); // Now skip one 32 bit word writer.BaseStream.Seek(sizeof(uint), SeekOrigin.Current); // Finally write the last magic writer.Write((uint)0x57425963); } catch (Exception) { return(false); } // Write all the images ushort block = 0; for (ushort imageID = 0; imageID < Images.Count; imageID++) { // Retrieve the image ImageEntry img = Images[imageID]; ImageHeader head = new ImageHeader(); ushort numBlocks; if (!CheckEntry(img)) { return(false); } // Calculate the blocks if (imageID == 0) { numBlocks = 3; } else { numBlocks = CalculateBlocks(img.Data.Length); } // Construct the header head.ImageID = imageID; head.ImageName = img.Name; head.ImageType = img.Type; head.StartBlock = block; head.EndBlock = (ushort)(head.StartBlock + numBlocks); head.ExecuteAddress = img.ExecAddr; head.FileSize = (uint)img.Data.Length; // On the bootloader image, adjust the size if (imageID == 0) { head.FileSize += 0x20; } // Write the header if (!WriteEntryHeader(writer, head)) { return(false); } // On the first write of every image, write the data // For id 0, write it every time to a new location if (copyIter == 0 || imageID == 0) { uint offset; if (imageID == 0) { offset = (uint)((copyIter * BytesPerBlock) + 0x20); } else { offset = (uint)(block * BytesPerBlock); } if (!WriteEntryData(writer, img, offset)) { return(false); } } block += numBlocks; } } } catch (Exception) { return(false); } return(true); }