All pastes #733319 Raw Edit

romldr

public cpp v1 · immutable
·published 2007-10-11 18:37 UTC
rendered paste body
#pragma once#include "flags.h"namespace RomLDR {	using namespace System;	using namespace System::IO;	using namespace System::Runtime::InteropServices;	using namespace System::Collections::Generic;	#define DIR_OUT            "OUT\\"	#define DIR_MOD            "MODULES\\"	#define DIR_FIL            "FILES\\"	#define DIR_MODULES        DIR_OUT"MODULES\\"	#define DIR_FILES          DIR_OUT"FILES\\"	#define FIL_PRTHDR         DIR_OUT"PARTHDR.txt"	#define FIL_ROMHDR         DIR_OUT"ROMHDR.txt"	#define FIL_MAP            DIR_OUT"MAP.txt"	#define FIL_MAP_P          DIR_OUT"MAP.physical.txt"	#define STR_FROM64   "   {0,-23}{1:X16}"	#define STR_FROMAT   "   {0,-23}{1:X8}"	#define STR_FROM_K   "   {0,-22}({1:X8})"	#define STR_F_IS_P   "   {0,-21}P={1:X8}"	#define STR_FROM_P   "   {0,-21}P+{1:X8}"	#define STR_F_IS_R   "   {0,-21}R={1:X8}"	#define STR_FROM_R   "   {0,-21}R+{1:X8}"	#define STR_F_IS_V   "   {0,-21}V={1:X8}"	#define STR_FROM_V   "   {0,-21}V+{1:X8}"	#define STR_F_IS_D   "   {0,-21}D={1:X8}"	#define STR_FROM_D   "   {0,-21}D+{1:X8}"	#define STR_FROM_Z   "   {0,-21}0+{1:X8}"	[StructLayout(LayoutKind::Sequential, Size=16)]	ref struct COPYentry {		unsigned int ulSource;               // copy source address		unsigned int ulDest;                 // copy destination address		unsigned int ulCopyLen;              // copy length		unsigned int ulDestLen;              // copy destination length (zero fill to end if > ulCopyLen)		virtual String^ ToString() override {			return String::Format("copyent {0:x8} L{1:x8} -> {2:x8} L{3:x8}", ulSource, ulCopyLen, ulDest, ulDestLen);		}		static property unsigned int RomSize {			unsigned int get() {				return Marshal::SizeOf(COPYentry::typeid);			}		}	};	array<Byte>^ GetData(BinaryReader^ br, unsigned int offset, unsigned int size) {		Int64 position = br->BaseStream->Position;		br->BaseStream->Seek(offset, SeekOrigin::Begin);		array<Byte>^ data = br->ReadBytes(size);		br->BaseStream->Seek(position, System::IO::SeekOrigin::Begin);		return data;	}	#pragma region ROM Header Structure	[StructLayout(LayoutKind::Sequential, Pack=1, Size=84)]	ref struct ROMHDR {		unsigned int dllfirst;               // first DLL address		unsigned int dlllast;                // last DLL address		unsigned int physfirst;              // first physical address		unsigned int physlast;               // highest physical address		unsigned int nummods;                // number of TOCentry's		unsigned int ulRAMStart;             // start of RAM		unsigned int ulRAMFree;              // start of RAM free space		unsigned int ulRAMEnd;               // end of RAM		unsigned int ulCopyEntries;          // number of copy section entries		unsigned int ulCopyOffset;           // offset to copy section		unsigned int ulProfileLen;           // length of PROFentries RAM 		unsigned int ulProfileOffset;        // offset to PROFentries		unsigned int numfiles;               // number of FILES		unsigned int ulKernelFlags;          // optional kernel flags from ROMFLAGS .bib config option		unsigned int ulFSRamPercent;         // Percentage of RAM used for filesystem 		unsigned int ulDrivglobStart;        // device driver global starting address		unsigned int ulDrivglobLen;          // device driver global length		unsigned short usCPUType;            // CPU (machine) Type		unsigned short usMiscFlags;          // Miscellaneous flags		unsigned int pExtensions;            // pointer to ROM Header extensions		unsigned int ulTrackingStart;        // tracking memory starting address		unsigned int ulTrackingLen;          // tracking memory ending address		void WriteToText() {			TextWriter^ tw = gcnew StreamWriter(File::Create(FIL_ROMHDR));			tw->WriteLine(String::Format(STR_F_IS_D, "dllfirst:",        dllfirst));			tw->WriteLine(String::Format(STR_FROMAT, "dlllast:",         dlllast));			tw->WriteLine(String::Format(STR_F_IS_P, "physfirst:",       physfirst));			tw->WriteLine(String::Format(STR_FROMAT, "physlast:",        physlast));			tw->WriteLine(String::Format(STR_FROM_K, "nummods:",         nummods));			tw->WriteLine(String::Format(STR_F_IS_R, "ulRAMStart:",      ulRAMStart));			tw->WriteLine(String::Format(STR_FROMAT, "ulRAMFree:",       ulRAMFree));			tw->WriteLine(String::Format(STR_FROMAT, "ulRAMEnd:",        ulRAMEnd));			tw->WriteLine(String::Format(STR_FROM_K, "ulCopyEntries:",   ulCopyEntries));			tw->WriteLine(String::Format(STR_FROM_P, "ulCopyOffset:",    ulCopyOffset - physfirst));			tw->WriteLine(String::Format(STR_FROMAT, "ulProfileLen:",    ulProfileLen));			tw->WriteLine(String::Format(STR_FROMAT, "ulProfileOffset:", ulProfileOffset));			tw->WriteLine(String::Format(STR_FROM_K, "numfiles:",        numfiles));			tw->WriteLine(String::Format(STR_FROMAT, "ulKernelFlags:",   ulKernelFlags));			tw->WriteLine(String::Format(STR_FROMAT, "ulFSRamPercent:",  ulFSRamPercent));			tw->WriteLine(String::Format(STR_FROMAT, "ulDrivglobStart:", ulDrivglobStart));			tw->WriteLine(String::Format(STR_FROMAT, "ulDrivglobLen:",   ulDrivglobLen));			tw->WriteLine(String::Format(STR_FROMAT, "usCPUType:",       usCPUType));			tw->WriteLine(String::Format(STR_FROMAT, "usMiscFlags:",     usMiscFlags));			tw->WriteLine(String::Format(STR_FROM_P, "pExtensions:",     pExtensions - physfirst));			tw->WriteLine(String::Format(STR_FROMAT, "ulTrackingStart:", ulTrackingStart));			tw->WriteLine(String::Format(STR_FROMAT, "ulTrackingLen:",   ulTrackingLen));			tw->Close();		}		void ReadFromText(String^ file) {			TextReader^ tr = gcnew StreamReader(File::OpenRead(file));			dllfirst        = GetInt32(tr);			dlllast         = GetInt32(tr);			physfirst       = GetInt32(tr);			physlast        = GetInt32(tr);			nummods         = GetInt32(tr);			ulRAMStart      = GetInt32(tr);			ulRAMFree       = GetInt32(tr);			ulRAMEnd        = GetInt32(tr);			ulCopyEntries   = GetInt32(tr);			ulCopyOffset    = GetInt32(tr);			ulProfileLen    = GetInt32(tr);			ulProfileOffset = GetInt32(tr);			numfiles        = GetInt32(tr);			ulKernelFlags   = GetInt32(tr);			ulFSRamPercent  = GetInt32(tr);			ulDrivglobStart = GetInt32(tr);			ulDrivglobLen   = GetInt32(tr);			usCPUType       = GetInt32(tr);			usMiscFlags     = GetInt32(tr);			pExtensions     = GetInt32(tr);			ulTrackingStart = GetInt32(tr);			ulTrackingLen   = GetInt32(tr);			tr->Close();		}		unsigned int GetInt32(TextReader^ tr) {			return GetInt32(tr, 0);		}		unsigned int GetInt32(TextReader^ tr, int v) {			String^ line = tr->ReadLine();			unsigned int value = UInt32::Parse(line->Substring(26, 8), System::Globalization::NumberStyles::HexNumber);			String^ add = line->Substring(24, 2);			if(add==" (") return 0;			if(add=="P+") value += physfirst;			if(add=="R+") value += ulRAMStart;			if(add=="D+") value += dllfirst;			if(add=="V+") value += v;			return value;		}		__int64 GetInt64(TextReader^ tr) {			String^ line = tr->ReadLine();			return UInt64::Parse(line->Substring(26, 16), System::Globalization::NumberStyles::HexNumber);		}		unsigned short GetInt16(TextReader^ tr) {			String^ line = tr->ReadLine();			return UInt16::Parse(line->Substring(30, 4), System::Globalization::NumberStyles::HexNumber);		}		bool IsPhys(unsigned int value) {			if(physfirst <= value && value < physlast) return true;			return false;		}		bool IsDll(unsigned int value) {			if(dllfirst <= value && value < dlllast) return true;			return false;		}		bool IsRAM(unsigned int value) {			if(ulRAMStart <= value && value < ulRAMEnd) return true;			return false;		}		property unsigned int CopyOffset[int] {			unsigned int get(int index) {				return ulCopyOffset - physfirst + index * Marshal::SizeOf(COPYentry::typeid);			}		}		property unsigned int CopyEntriesCount {			unsigned int get() {				return ulCopyEntries;			}			void set(unsigned int value) {				 ulCopyEntries = value;			}		}		property unsigned int ModulesCount {			unsigned int get() {				return nummods;			}			void set(unsigned int value) {				nummods = value;			}		}				property unsigned int FilesCount {			unsigned int get() {				return numfiles;			}			void set(unsigned int value) {				numfiles = value;			}		}		virtual String^ ToString () override {			return String::Format("rom_00 header: dlls={0:x8}-{1:x8} phys={2:x8}-{3:x8}, {4} modules, {5} files, {6} copyentries ext={7:x8}  ram={8:x8}-{9:x8} cputype={10:x8}", dllfirst, dlllast, physfirst, physlast, nummods, numfiles, ulCopyEntries, pExtensions, ulRAMStart, ulRAMEnd, usCPUType);		}		#pragma region static property unsigned int RomSize {get()}		static property unsigned int RomSize {			unsigned int get() {				return Marshal::SizeOf(ROMHDR::typeid);			}		}		#pragma endregion	};	#pragma endregion	ref struct G {		static ROMHDR^ ROMHDR;	};	#pragma region o32_rom	[StructLayout(LayoutKind::Sequential, Size=24)]	ref class o32_rom {		unsigned long o32_vsize;      /* Virtual memory size              */		unsigned long o32_rva;        /* Object relative virtual address  */		unsigned long o32_psize;      /* Physical file size of init. data */		unsigned long o32_dataptr;    /* Image pages offset               */		unsigned long o32_realaddr;   /* pointer to actual                */		unsigned long o32_flags;      /* Attribute flags for the object   */	public:		#pragma region property unsigned long vsize    {get(), set()}		property unsigned long vsize {			unsigned long get() {				return o32_vsize;			}			void set(unsigned long value) {				o32_vsize = value;			}		}		#pragma endregion		#pragma region property unsigned long rva      {get(), set()}		property unsigned long rva {			unsigned long get() {				return o32_rva;			}			void set(unsigned long value) {				o32_rva = value;			}		}		#pragma endregion		#pragma region property unsigned long psize    {get(), set()}		property unsigned long psize {			unsigned long get() {				return o32_psize;			}			void set(unsigned long value) {				o32_psize = value;			}		}		#pragma endregion		#pragma region property unsigned long dataptr  {get(), set()}		property unsigned long dataptr {			unsigned long get() {				return o32_dataptr;			}			void set(unsigned long value) {				if(o32_dataptr == o32_realaddr) o32_realaddr = value;				o32_dataptr = value;			}		}		#pragma endregion		#pragma region property unsigned long realaddr {get(), set()}		property unsigned long realaddr {			unsigned long get() {				return o32_realaddr;			}			void set(unsigned long value) {				o32_realaddr = value;			}		}		#pragma endregion		#pragma region property unsigned long flags    {get(), set()}		property unsigned long flags {			unsigned long get() {				return o32_flags;			}			void set(unsigned long value) {				o32_flags = value;			}		}		#pragma endregion		#pragma region property unsigned long DataOffset  {get()}		property unsigned long DataOffset {			unsigned long get() {				if(o32_dataptr == 0) return 0;				return o32_dataptr - G::ROMHDR->physfirst;			}		}		#pragma endregion		#pragma region property unsigned long DataSize    {get()}		property unsigned long DataSize {			unsigned long get() {				if(o32_vsize >= o32_psize) return o32_psize;				return o32_vsize;			}		}		#pragma endregion		#pragma region String^ ToString (String^ name, int index)		String^ ToString (String^ name, int index) {			return String::Format("o32 region_{0} rva={1:x8} vsize={2:x8} real={3:x8} psize={4:x8} f={5:x8} for {6}", index, o32_rva, o32_vsize, o32_realaddr, o32_psize, o32_flags, name);		}		#pragma endregion		#pragma region static property unsigned int RomSize {get()}		static property unsigned int RomSize {			unsigned int get() {				return Marshal::SizeOf(o32_rom::typeid);			}		}		#pragma endregion	};	#pragma endregion	#pragma region e32_rom	#define ROM_EXTRA 9	[StructLayout(LayoutKind::Sequential)]	value struct info {       /* Extra information header block      */		Int32 rva;            /* Virtual relative address of info    */		Int32 size;           /* Size of information block           */	};	[StructLayout(LayoutKind::Sequential, Size= ROM_EXTRA * 2 * 4 + 5 * 2 + 6 * 4)]	ref class e32_rom {		unsigned short e32_objcnt;     /* Number of memory objects            */		unsigned short e32_imageflags; /* Image flags                         */		unsigned long  e32_entryrva;   /* Relative virt. addr. of entry point */		unsigned long  e32_vbase;      /* Virtual base address of module      */		unsigned short e32_subsysmajor;/* The subsystem major version number  */		unsigned short e32_subsysminor;/* The subsystem minor version number  */		unsigned long  e32_stackmax;   /* Maximum stack size                  */		unsigned long  e32_vsize;      /* Virtual size of the entire image    */		unsigned long  e32_sect14rva;  /* section 14 rva */		unsigned long  e32_sect14size; /* section 14 size */		[MarshalAs(UnmanagedType::ByValArray, SizeConst=ROM_EXTRA)]		array<info>^   e32_unit;       /* Array of extra info units           */		unsigned short e32_subsys;     /* The subsystem type                  */	public:		#pragma region property unsigned short objcnt      {get()}		property unsigned short objcnt {			unsigned short get() {				return e32_objcnt;			}		}		#pragma endregion		#pragma region property unsigned short imageflag   {get()}		property unsigned short imageflag {			unsigned short get() {				return e32_imageflags;			}		}		#pragma endregion		#pragma region property unsigned long entryrva     {get()}		property unsigned long entryrva {			unsigned long get() {				return e32_entryrva;			}		}		#pragma endregion		#pragma region property unsigned long vbase        {get()}		property unsigned long vbase {			unsigned long get() {				return e32_vbase;			}		}		#pragma endregion		#pragma region property unsigned short subsysmajor {get()}		property unsigned short subsysmajor {			unsigned short get() {				return e32_subsysmajor;			}		}		#pragma endregion		#pragma region property unsigned short subsysminor {get()}		property unsigned short subsysminor {			unsigned short get() {				return e32_subsysminor;			}		}		#pragma endregion		#pragma region property unsigned long stackmax     {get()}		property unsigned long stackmax {			unsigned long get() {				return e32_stackmax;			}		}		#pragma endregion		#pragma region property unsigned long vsize        {get()}		property unsigned long vsize {			unsigned long get() {				return e32_vsize;			}		}		#pragma endregion		#pragma region property unsigned long sect14rva    {get()}		property unsigned long sect14rva {			unsigned long get() {				return e32_sect14rva;			}		}		#pragma endregion		#pragma region property unsigned long sect14size   {get()}		property unsigned long sect14size {			unsigned long get() {				return e32_sect14size;			}		}		#pragma endregion		#pragma region property array<info>^ unit          {get()}		property array<info>^ unit {			array<info>^ get() {				return e32_unit;			}		}		#pragma endregion		#pragma region property unsigned long subsys       {get()}		property unsigned long subsys {			unsigned long get() {				return e32_subsys;			}		}		#pragma endregion		#pragma region void WriteToText(String^ name, array<o32_rom^>^ o32, BinaryReader^ br)		void WriteToText(String^ name, array<o32_rom^>^ o32, BinaryReader^ br) {			Directory::CreateDirectory (DIR_MODULES+name);			TextWriter^ tw = gcnew StreamWriter (File::Create (DIR_MODULES + name + "\\imageinfo.txt"));			tw->WriteLine(String::Format("  Module name: {0}", name));			tw->WriteLine(String::Format(STR_FROMAT, "e32_objcnt:",      e32_objcnt));			tw->WriteLine(String::Format(STR_FROMAT, "e32_imageflags:",  e32_imageflags));			tw->WriteLine(String::Format(STR_FROMAT, "e32_entryrva:",    e32_entryrva));			if(G::ROMHDR->IsPhys(e32_vbase))				tw->WriteLine(String::Format(STR_FROM_P, "e32_vbase:",  e32_vbase-G::ROMHDR->physfirst));			else				tw->WriteLine(String::Format(STR_F_IS_V, "e32_vbase:",  e32_vbase));			tw->WriteLine(String::Format(STR_FROMAT, "e32_subsysmajor:", e32_subsysmajor));			tw->WriteLine(String::Format(STR_FROMAT, "e32_subsysminor:", e32_subsysminor));			tw->WriteLine(String::Format(STR_FROMAT, "e32_stackmax:",    e32_stackmax));			tw->WriteLine(String::Format(STR_FROMAT, "e32_vsize:",       e32_vsize));			tw->WriteLine(String::Format(STR_FROMAT, "e32_sect14rva:",   e32_sect14rva));			tw->WriteLine(String::Format(STR_FROMAT, "e32_sect14size:",  e32_sect14size));			for(int i = 0; i < ROM_EXTRA; i++)			{				tw->WriteLine(String::Format(STR_FROMAT, String::Format("e32_unit[{0}].rva:", i),  e32_unit[i].rva));				tw->WriteLine(String::Format(STR_FROMAT, String::Format("e32_unit[{0}].size:", i), e32_unit[i].size));			}			tw->WriteLine(String::Format(STR_FROMAT, "e32_subsys:",      e32_subsys));			tw->WriteLine();			Directory::CreateDirectory(DIR_MODULES+name);			for(int i = 0; i < e32_objcnt; i++) {				if (br) {					Stream^ writer = File::Create (DIR_MODULES + name + "\\" + String::Format ("S{0:000}", i));					writer->Write (GetData (br, o32[i]->DataOffset, o32[i]->DataSize), 0, o32[i]->DataSize);					writer->Close();				}				tw->WriteLine(String::Format(STR_FROMAT, String::Format ("o32[{0}].o32_vsize:", i),    o32[i]->vsize));				tw->WriteLine(String::Format(STR_FROMAT, String::Format ("o32[{0}].o32_rva:", i),      o32[i]->rva));				tw->WriteLine(String::Format(STR_FROMAT, String::Format ("o32[{0}].o32_psize:", i),    o32[i]->psize));				if(o32[i]->dataptr)					tw->WriteLine(String::Format(STR_FROM_P, String::Format ("o32[{0}].o32_dataptr:", i),  o32[i]->dataptr-G::ROMHDR->physfirst));				else					tw->WriteLine(String::Format(STR_FROMAT, String::Format ("o32[{0}].o32_dataptr:", i),  o32[i]->dataptr));				if(G::ROMHDR->IsPhys(o32[i]->realaddr))					tw->WriteLine(String::Format(STR_FROM_P, String::Format ("o32[{0}].o32_realaddr:", i), o32[i]->realaddr-G::ROMHDR->physfirst));				else if(G::ROMHDR->IsRAM(o32[i]->realaddr))					tw->WriteLine(String::Format(STR_F_IS_R, String::Format ("o32[{0}].o32_realaddr:", i), o32[i]->realaddr));				else if(G::ROMHDR->IsDll(o32[i]->realaddr))					tw->WriteLine(String::Format(STR_F_IS_D, String::Format ("o32[{0}].o32_realaddr:", i), o32[i]->realaddr));				else if(IsBase(o32[i]->realaddr))					tw->WriteLine(String::Format(STR_FROM_V, String::Format ("o32[{0}].o32_realaddr:", i), o32[i]->realaddr-e32_vbase));				else					tw->WriteLine(String::Format(STR_FROMAT, String::Format ("o32[{0}].o32_realaddr:", i), o32[i]->realaddr));				tw->WriteLine(String::Format(STR_FROMAT, String::Format ("o32[{0}].o32_flags:", i),    o32[i]->flags));				tw->WriteLine();			}			tw->Close();		}		#pragma endregion		#pragma region array<o32_rom^>^ ReadFromText(String^ path, Dictionary<String^, COPYentry^>^ copy)		array<o32_rom^>^ ReadFromText(String^ path, Dictionary<String^, COPYentry^>^ copy) {			TextReader^ tr = gcnew StreamReader(File::OpenRead(DIR_MODULES+path+"\\imageinfo.txt"));			String^ name = tr->ReadLine()->Substring(15);			e32_objcnt      = G::ROMHDR->GetInt16(tr);			e32_imageflags  = G::ROMHDR->GetInt16(tr);			e32_entryrva    = G::ROMHDR->GetInt32(tr);			e32_vbase       = G::ROMHDR->GetInt32(tr);			e32_subsysmajor = G::ROMHDR->GetInt16(tr);			e32_subsysminor = G::ROMHDR->GetInt16(tr);			e32_stackmax    = G::ROMHDR->GetInt32(tr);			e32_vsize       = G::ROMHDR->GetInt32(tr);			e32_sect14rva   = G::ROMHDR->GetInt32(tr);			e32_sect14size  = G::ROMHDR->GetInt32(tr);			e32_unit = gcnew array<info>(ROM_EXTRA);			for(int i = 0; i < ROM_EXTRA; i++) {				e32_unit[i].rva  = G::ROMHDR->GetInt32(tr);				e32_unit[i].size = G::ROMHDR->GetInt32(tr);			}			e32_subsys = G::ROMHDR->GetInt32(tr);			array<o32_rom^>^ o32 = gcnew array<o32_rom^>(e32_objcnt);			for (int i = 0; i < e32_objcnt; i++) {				tr->ReadLine();				o32[i] = gcnew o32_rom;				o32[i]->vsize = G::ROMHDR->GetInt32(tr);				o32[i]->rva = G::ROMHDR->GetInt32(tr);				o32[i]->psize = G::ROMHDR->GetInt32(tr);				o32[i]->dataptr = G::ROMHDR->GetInt32(tr);				o32[i]->realaddr = G::ROMHDR->GetInt32(tr, vbase);				o32[i]->flags = G::ROMHDR->GetInt32(tr);				if (G::ROMHDR->IsRAM(o32[i]->realaddr) && (o32[i]->flags & IMAGE_SCN_CNT_INITIALIZED_DATA)) {					COPYentry^ entry = gcnew COPYentry;					entry->ulSource  = o32[i]->dataptr;					entry->ulCopyLen = o32[i]->psize;					entry->ulDest    = o32[i]->realaddr;					entry->ulDestLen = o32[i]->vsize;					copy->Add(String::Format("region_{0} {1}", i, path), entry);				}			}			tr->Close();			return o32;		}		#pragma endregion		#pragma region bool IsBase(unsigned long ptr)		bool IsBase(unsigned long ptr) {			return e32_vbase < ptr && ptr < e32_vbase+e32_vsize;		}		#pragma endregion		#pragma region virtual String^ ToString(String^ name)		virtual String^ ToString(String^ name) {			return String::Format("e32 struct {0} objs, img={1:x4} entrypt={2:x8} base={3:x8} v{4}.{5} tp{6} {7}", e32_objcnt, e32_imageflags, e32_entryrva, e32_vbase, e32_subsysmajor, e32_subsysminor, e32_subsys, name);		}		#pragma endregion		#pragma region static property unsigned int RomSize {get()}		static property unsigned int RomSize {			unsigned int get() {				return Marshal::SizeOf(e32_rom::typeid)+2;			}		}		#pragma endregion	};	#pragma endregion	#pragma region Module Table of Contents - follows ROMHDR in image	[StructLayout(LayoutKind::Sequential, Pack=1, Size=32)]	ref struct TOCentry : IComparable<TOCentry^> {           // MODULE BIB section structure		Int32 dwFileAttributes;		Int64 ftTime;		Int32 nFileSize;		Int32 lpszFileName;		Int32 ulE32Offset;            // Offset to E32 structure		Int32 ulO32Offset;            // Offset to O32 structure		unsigned int ulLoadOffset;           // MODULE load buffer offset		void WriteToText(String^ name) {			TextWriter^ tw = gcnew StreamWriter(File::Create(DIR_MODULES+name+".txt"));			tw->WriteLine(String::Format("  Module name: {0}", name));			tw->WriteLine(String::Format(STR_FROMAT, "dwFileAttributes:", dwFileAttributes));			tw->WriteLine(String::Format(STR_FROM64, "ftTime:",           ftTime));			tw->WriteLine(String::Format(STR_FROMAT, "nFileSize:",        nFileSize));			tw->WriteLine(String::Format(STR_FROM_P, "lpszFileName:",     NameOffset));			tw->WriteLine(String::Format(STR_FROM_P, "ulE32Offset:",      E32Offset));			tw->WriteLine(String::Format(STR_FROM_P, "ulO32Offset:",      O32Offset[0]));			// ulLoadOffset not writen			tw->Close();		}		String^ ReadFromText(String^ path) {			TextReader^ tr = gcnew StreamReader(File::OpenRead(path+".txt"));			String^ name = tr->ReadLine()->Substring(15);			dwFileAttributes = G::ROMHDR->GetInt32(tr);			ftTime           = G::ROMHDR->GetInt64(tr);			nFileSize        = G::ROMHDR->GetInt32(tr);			lpszFileName     = G::ROMHDR->GetInt32(tr);			ulE32Offset      = G::ROMHDR->GetInt32(tr);			ulO32Offset      = G::ROMHDR->GetInt32(tr);			tr->Close();			return name;		}		property int NameOffset {			int get() {				return lpszFileName - G::ROMHDR->physfirst;			}		}		property int E32Offset {			int get() {				return ulE32Offset - G::ROMHDR->physfirst;			}		}		property int O32Offset[int] {			int get(int index) {				return ulO32Offset - G::ROMHDR->physfirst + index*o32_rom::RomSize;			}		}		virtual String^ ToString(String^ name, int i) {			return String::Format("modent {0,3} {1:x8} {2:x16} {3,8} {4:x8} {5}", i, dwFileAttributes, ftTime, nFileSize, ulLoadOffset, name);		}		virtual int CompareTo( TOCentry^ other ) {			if(ulLoadOffset == other->ulLoadOffset) nFileSize.CompareTo(other->nFileSize);			return ulLoadOffset.CompareTo(other->ulLoadOffset);		}		static property unsigned int RomSize {			unsigned int get() {				return Marshal::SizeOf(TOCentry::typeid);			}		}	};	#pragma endregion	#pragma region Files Section Structure - follows Module Table in image	[StructLayout(LayoutKind::Sequential, Pack=1, Size=28)]	ref struct FILESentry  : IComparable<FILESentry^>{         // FILES BIB section structure		Int32 dwFileAttributes;		Int64 ftTime;		Int32 nRealFileSize;		Int32 nCompFileSize;		Int32 lpszFileName;		Int32 ulLoadOffset;           // FILES load buffer offset		void WriteToText(String^ name, BinaryReader^ br) {			TextWriter^ tw = gcnew StreamWriter(File::Create(DIR_FILES+name+".imageinfo.txt"));			tw->WriteLine(String::Format("  File name: {0}", name));			tw->WriteLine(String::Format(STR_FROMAT, "dwFileAttributes:", dwFileAttributes));			tw->WriteLine(String::Format(STR_FROM64, "ftTime:",           ftTime));			tw->WriteLine(String::Format(STR_FROMAT, "nRealFileSize:",    nRealFileSize));			tw->WriteLine(String::Format(STR_FROMAT, "nCompFileSize:",    nCompFileSize));			tw->WriteLine(String::Format(STR_FROM_P, "lpszFileName:",     NameOffset));			tw->WriteLine(String::Format(STR_FROM_P, "ulLoadOffset:",     LoadOffset));			tw->Close();			if(br) {				Stream^ writer = File::Create(DIR_FILES+name);				writer->Write(GetData(br, LoadOffset, nCompFileSize), 0, nCompFileSize);				writer->Close();			}		}		String^ ReadFromText(String^ path) {			TextReader^ tr = gcnew StreamReader(File::OpenRead(path));			String^ name = tr->ReadLine()->Substring(13);			dwFileAttributes = G::ROMHDR->GetInt32(tr);			ftTime           = G::ROMHDR->GetInt64(tr);			nRealFileSize    = G::ROMHDR->GetInt32(tr);			nCompFileSize    = G::ROMHDR->GetInt32(tr);			lpszFileName     = G::ROMHDR->GetInt32(tr);			ulLoadOffset     = G::ROMHDR->GetInt32(tr);			tr->Close();			return name;		}		property int NameOffset {			int get() {				return lpszFileName - G::ROMHDR->physfirst;			}		}		property int LoadOffset {			int get() {				return ulLoadOffset - G::ROMHDR->physfirst;			}		} 		virtual int CompareTo( FILESentry^ other ) {			if(other->nCompFileSize == nCompFileSize) return ulLoadOffset.CompareTo(other->ulLoadOffset);			return other->nCompFileSize.CompareTo(nCompFileSize);		}		virtual String^ ToString(String^ name, int i) {			return String::Format("filent {0,3} {1:x8} {2:x16} {3,8} {4,8} {5:x8} {6}", i, dwFileAttributes, ftTime, nRealFileSize, nCompFileSize, ulLoadOffset, name);		}		static property unsigned int RomSize {			unsigned int get() {				return Marshal::SizeOf(FILESentry::typeid);			}		}	};	#pragma endregion	#define ROM_SIGNATURE_OFFSET   0x40         // Offset from the image's physfirst address to the ROM signature.	#define ROM_TOC_POINTER_OFFSET 0x44         // Offset from the image's physfirst address to the TOC pointer.	#define ROM_TOC_OFFSET_OFFSET  0x48         // Offset from the image's physfirst address to the TOC offset (from physfirst).	#define ROM_SIGNATURE          0x43454345	#define PARTITION_HEADER_BYTES 0x1000	[StructLayout(LayoutKind::Explicit, Size=PARTITION_HEADER_BYTES)]	ref struct PARTHDR {		[FieldOffset(0x0000)]                 Int32 ulRomUnknown;		[FieldOffset(ROM_SIGNATURE_OFFSET)]   Int32 ulRomSignature;		[FieldOffset(ROM_TOC_POINTER_OFFSET)] Int32 dwRomHdrOffset;		[FieldOffset(ROM_TOC_OFFSET_OFFSET)]  Int32 dwRomHdrAddress;		void WriteToText() {			TextWriter^ tw = gcnew StreamWriter(File::Create(FIL_PRTHDR));			tw->WriteLine(String::Format(STR_FROMAT, "ulRomUnknown:",    ulRomUnknown));			tw->WriteLine(String::Format(STR_FROMAT, "dwRomHdrAddress:", dwRomHdrAddress));			tw->Close();		}		void ReadFromText() {			TextReader^ tr  = gcnew StreamReader(File::OpenRead(FIL_PRTHDR));			ulRomUnknown    = G::ROMHDR->GetInt32(tr);			dwRomHdrAddress = G::ROMHDR->GetInt32(tr);			ulRomSignature  = ROM_SIGNATURE;			dwRomHdrOffset  = dwRomHdrAddress+G::ROMHDR->physfirst;			tr->Close();		}		#pragma region static property unsigned int RomSize {get()}		static property unsigned int RomSize {			unsigned int get() {				return Marshal::SizeOf(PARTHDR::typeid);			}		}		#pragma endregion	};	//	// ROM Header extension: PID	//	#define PID_LENGTH 10	[StructLayout(LayoutKind::Sequential, Pack=1, Size=44)]	ref struct ROMPID {		[MarshalAs(UnmanagedType::ByValArray, SizeConst=PID_LENGTH)]		array<Int32>^ dwPID;        // PID		Int32 pNextExt;                         // pointer to next extension if any	};	generic <class T>	T GetStructure(BinaryReader^ br) {		return (T)Marshal::PtrToStructure(Marshal::UnsafeAddrOfPinnedArrayElement(br->ReadBytes(Marshal::SizeOf(T::typeid)), 0), T::typeid);	}	generic <class T>	T GetStructure(BinaryReader^ br, int offset) {		br->BaseStream->Seek(offset, System::IO::SeekOrigin::Begin);		return GetStructure<T>(br);	}	generic <class T>	T GetStructure(BinaryReader^ br, int offset, bool restore) {		if(!restore) return GetStructure<T>(br, offset);		Int64 position = br->BaseStream->Position;		T t = GetStructure<T>(br, offset);		br->BaseStream->Seek(position, System::IO::SeekOrigin::Begin);		return t;	}	String^ GetString(BinaryReader^ br, int offset) {		Int64 position = br->BaseStream->Position;		br->BaseStream->Seek(offset, SeekOrigin::Begin);		Char b;		String^ string;		while((b = br->ReadByte()) != 0x00) string += b;		br->BaseStream->Seek(position, System::IO::SeekOrigin::Begin);		return string;	}}