/// <summary> /// Loads a DOS MZ executable file from disk. /// </summary> /// <param name="fileName">Name of the file to open.</param> public MZFile(string fileName) { if (fileName == null) { throw new ArgumentNullException("fileName"); } using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) using (BinaryReader reader = new BinaryReader(stream)) { // Read file header. header = new MZHeader(); header.Signature = reader.ReadUInt16(); header.LastPageSize = reader.ReadUInt16(); header.PageCount = reader.ReadUInt16(); header.RelocCount = reader.ReadUInt16(); header.HeaderSize = reader.ReadUInt16(); header.MinAlloc = reader.ReadUInt16(); header.MaxAlloc = reader.ReadUInt16(); header.InitialSS = reader.ReadUInt16(); header.InitialSP = reader.ReadUInt16(); header.Checksum = reader.ReadUInt16(); header.InitialIP = reader.ReadUInt16(); header.InitialCS = reader.ReadUInt16(); header.RelocOff = reader.ReadUInt16(); header.Overlay = reader.ReadUInt16(); // Verify signature. Both 'MZ' and 'ZM' are allowed. if (!(header.Signature == 0x5A4D || header.Signature == 0x4D5A)) { throw new InvalidDataException("Signature mismatch."); } // Calculate the stated size of the executable. if (header.PageCount <= 0) { throw new InvalidDataException("The PageCount field must be positive."); } int fileSize = header.PageCount * 512 - (header.LastPageSize > 0 ? 512 - header.LastPageSize : 0); // Make sure the stated file size is within the actual file size. if (fileSize > stream.Length) { throw new InvalidDataException("The stated file size is larger than the actual file size."); } // Validate the header size. int headerSize = header.HeaderSize * 16; if (headerSize < 28 || headerSize > fileSize) { throw new InvalidDataException("The stated header size is invalid."); } // Make sure the relocation table is within the header. if (header.RelocOff < 28 || header.RelocOff + header.RelocCount * 4 > headerSize) { throw new InvalidDataException("The relocation table location is invalid."); } // Load relocation table. relocationTable = new FarPointer[header.RelocCount]; stream.Seek(header.RelocOff, SeekOrigin.Begin); for (int i = 0; i < header.RelocCount; i++) { UInt16 off = reader.ReadUInt16(); UInt16 seg = reader.ReadUInt16(); relocationTable[i] = new FarPointer(seg, off); } // Load the whole image into memory. int imageSize = fileSize - headerSize; stream.Seek(headerSize, SeekOrigin.Begin); image = new byte[imageSize]; stream.Read(image, 0, image.Length); } }
/// <summary> /// Loads a DOS MZ executable file from disk. /// </summary> /// <param name="fileName">Name of the file to open.</param> public MZFile(string fileName) { if (fileName == null) throw new ArgumentNullException("fileName"); using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) using (BinaryReader reader = new BinaryReader(stream)) { // Read file header. header = new MZHeader(); header.Signature = reader.ReadUInt16(); header.LastPageSize = reader.ReadUInt16(); header.PageCount = reader.ReadUInt16(); header.RelocCount = reader.ReadUInt16(); header.HeaderSize = reader.ReadUInt16(); header.MinAlloc = reader.ReadUInt16(); header.MaxAlloc = reader.ReadUInt16(); header.InitialSS = reader.ReadUInt16(); header.InitialSP = reader.ReadUInt16(); header.Checksum = reader.ReadUInt16(); header.InitialIP = reader.ReadUInt16(); header.InitialCS = reader.ReadUInt16(); header.RelocOff = reader.ReadUInt16(); header.Overlay = reader.ReadUInt16(); // Verify signature. Both 'MZ' and 'ZM' are allowed. if (!(header.Signature == 0x5A4D || header.Signature == 0x4D5A)) throw new InvalidDataException("Signature mismatch."); // Calculate the stated size of the executable. if (header.PageCount <= 0) throw new InvalidDataException("The PageCount field must be positive."); int fileSize = header.PageCount * 512 - (header.LastPageSize > 0 ? 512 - header.LastPageSize : 0); // Make sure the stated file size is within the actual file size. if (fileSize > stream.Length) throw new InvalidDataException("The stated file size is larger than the actual file size."); // Validate the header size. int headerSize = header.HeaderSize * 16; if (headerSize < 28 || headerSize > fileSize) throw new InvalidDataException("The stated header size is invalid."); // Make sure the relocation table is within the header. if (header.RelocOff < 28 || header.RelocOff + header.RelocCount * 4 > headerSize) { throw new InvalidDataException("The relocation table location is invalid."); } // Load relocation table. relocationTable = new FarPointer[header.RelocCount]; stream.Seek(header.RelocOff, SeekOrigin.Begin); for (int i = 0; i < header.RelocCount; i++) { UInt16 off = reader.ReadUInt16(); UInt16 seg = reader.ReadUInt16(); relocationTable[i] = new FarPointer(seg, off); } // Load the whole image into memory. int imageSize = fileSize - headerSize; stream.Seek(headerSize, SeekOrigin.Begin); image = new byte[imageSize]; stream.Read(image, 0, image.Length); } }