// dnlib: See LICENSE.txt for more info using dnlib.IO; using dnlib.PE; using dnlib.Protection; using dnlib.Utils; namespace dnlib.DotNet.Writer { /// /// Base class of most heaps /// public abstract class HeapBase : IHeap { internal const uint ALIGNMENT = 4; FileOffset offset; RVA rva; /// /// true if has been called /// protected bool isReadOnly; /// public FileOffset FileOffset => offset; /// public RVA RVA => rva; /// public abstract string Name { get; } /// public bool IsEmpty => GetRawLength() <= 1; /// /// true if offsets require 4 bytes instead of 2 bytes. /// public bool IsBig => GetFileLength() > 0xFFFF; /// public void SetReadOnly() => isReadOnly = true; /// public virtual void SetOffset(FileOffset offset, RVA rva) { this.offset = offset; this.rva = rva; // NOTE: This method can be called twice by NativeModuleWriter, see Metadata.SetOffset() for more info } /// public uint GetFileLength() => Utils.AlignUp(GetRawLength(), ALIGNMENT); /// public uint GetVirtualSize() => GetFileLength(); /// public uint CalculateAlignment() => 0; /// /// Gets the raw length of the heap /// /// Raw length of the heap public abstract uint GetRawLength(); private void WriteTo0(DataWriter writer) { WriteToImpl(writer); writer.WriteZeroes((int)(Utils.AlignUp(GetRawLength(), ALIGNMENT) - GetRawLength())); } protected abstract EncryptionMethod GetEncryptionMethod(IEncryption e); /// public void WriteTo(DataWriter writer) { EncryptionUtil.WriteWithEncIfNeed(writer, WriteTo0, this.GetEncryptionMethod, EncryptionContext.BigSegmentSize); } /// /// Writes all data to at its current location. /// /// Destination protected abstract void WriteToImpl(DataWriter writer); /// public override string ToString() => Name; } }