public static CompilationMode GetCompilationModeTruncatedWithExplanation(this FileInfo info)
        {
            if (!info.Exists)
            {
                throw new ArgumentException($"{info.FullName} does not exist");
            }

            var intPtr = IntPtr.Zero;

            try
            {
                uint unmanagedBufferSize = 4096;
                intPtr = Marshal.AllocHGlobal((int)unmanagedBufferSize);

                using (var stream = new FileReaderStream(info.FullName))
                {
                    stream.Read(intPtr, unmanagedBufferSize);
                }

                //Check DOS header magic number
                if (Marshal.ReadInt16(intPtr) != Constants.PEMagic)
                {
                    return(CompilationMode.Invalid);
                }

                // This will get the address for the WinNT header
                var lfanewAddressOffset   = Marshal.OffsetOf <IMAGE_DOS_HEADER>(nameof(IMAGE_DOS_HEADER.e_lfanew)).ToInt32();
                var ntHeaderAddressOffset = Marshal.ReadInt32(intPtr + lfanewAddressOffset);
                var ntHeaderAddress       = intPtr + ntHeaderAddressOffset;

                // Determine WinNT header signature number address
                var signatureAddressOffset = Marshal.OffsetOf <IMAGE_NT_HEADERS32>(nameof(IMAGE_NT_HEADERS32.Signature)).ToInt32();

                // Check WinNT header signature
                var signature = Marshal.ReadInt32(ntHeaderAddress + signatureAddressOffset);
                if (signature != Constants.NTHeaderSignature)
                {
                    return(CompilationMode.Invalid);
                }

                //Determine file bitness by reading magic from IMAGE_OPTIONAL_HEADER
                var optionalHeaderAddressOffset = Marshal.OffsetOf <IMAGE_NT_HEADERS32>(nameof(IMAGE_NT_HEADERS32.OptionalHeader)).ToInt32();
                var magicValueAddressOffset     = Marshal.OffsetOf <IMAGE_OPTIONAL_HEADER32>(nameof(IMAGE_OPTIONAL_HEADER32.Magic)).ToInt32();
                var magic = (MagicType)Marshal.ReadInt16(ntHeaderAddress + optionalHeaderAddressOffset + magicValueAddressOffset);

                //Check magic value is one of known MagicType values
                if (Enum.GetValues(typeof(MagicType)).OfType <MagicType>().All(v => v != magic))
                {
                    //Invalid magic
                    return(CompilationMode.Invalid);
                }

                var  result        = CompilationMode.Invalid;
                uint clrHeaderSize = 0;
                switch (magic)
                {
                case MagicType.IMAGE_NT_OPTIONAL_HDR32_MAGIC:
                {
                    var optionalHeaderOffset   = Marshal.OffsetOf <IMAGE_NT_HEADERS32>(nameof(IMAGE_NT_HEADERS32.OptionalHeader)).ToInt32();
                    var clrRuntimeHeaderOffset =
                        Marshal.OffsetOf <IMAGE_OPTIONAL_HEADER32>(nameof(IMAGE_OPTIONAL_HEADER32.CLRRuntimeHeader)).ToInt32();
                    var clrRuntimeHeaderImageDataDirectorySizeOffset =
                        Marshal.OffsetOf <IMAGE_DATA_DIRECTORY>(nameof(IMAGE_DATA_DIRECTORY.Size)).ToInt32();
                    clrHeaderSize = (uint)Marshal.ReadInt32(ntHeaderAddress +
                                                            optionalHeaderOffset +
                                                            clrRuntimeHeaderOffset +
                                                            clrRuntimeHeaderImageDataDirectorySizeOffset);
                    result |= CompilationMode.Bit32;
                }
                break;

                case MagicType.IMAGE_NT_OPTIONAL_HDR64_MAGIC:
                {
                    var optionalHeaderOffset   = Marshal.OffsetOf <IMAGE_NT_HEADERS64>(nameof(IMAGE_NT_HEADERS64.OptionalHeader)).ToInt32();
                    var clrRuntimeHeaderOffset =
                        Marshal.OffsetOf <IMAGE_OPTIONAL_HEADER64>(nameof(IMAGE_OPTIONAL_HEADER64.CLRRuntimeHeader)).ToInt32();
                    var clrRuntimeHeaderImageDataDirectorySizeOffset =
                        Marshal.OffsetOf <IMAGE_DATA_DIRECTORY>(nameof(IMAGE_DATA_DIRECTORY.Size)).ToInt32();
                    clrHeaderSize = (uint)Marshal.ReadInt32(ntHeaderAddress +
                                                            optionalHeaderOffset +
                                                            clrRuntimeHeaderOffset +
                                                            clrRuntimeHeaderImageDataDirectorySizeOffset);
                    result |= CompilationMode.Bit64;
                }
                break;
                }
                result |= clrHeaderSize != 0
                    ? CompilationMode.CLR
                    : CompilationMode.Native;
                return(result);
            }
            finally
            {
                if (intPtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(intPtr);
                }
            }
        }
        public static CompilationMode GetCompilationModeTruncated(this FileInfo info)
        {
            if (!info.Exists)
            {
                throw new ArgumentException($"{info.FullName} does not exist");
            }

            var intPtr = IntPtr.Zero;

            try
            {
                uint unmanagedBufferSize = 4096;
                intPtr = Marshal.AllocHGlobal((int)unmanagedBufferSize);

                using (var stream = new FileReaderStream(info.FullName))
                {
                    stream.Read(intPtr, unmanagedBufferSize);
                }

                //Check DOS header magic number
                if (Marshal.ReadInt16(intPtr) != Constants.PEMagic)
                {
                    return(CompilationMode.Invalid);
                }

                // This will get the address for the WinNT header
                var ntHeaderAddressOffset = Marshal.ReadInt32(intPtr + 60);

                // Check WinNT header signature
                var signature = Marshal.ReadInt32(intPtr + ntHeaderAddressOffset);
                if (signature != Constants.NTHeaderSignature)
                {
                    return(CompilationMode.Invalid);
                }

                //Determine file bitness by reading magic from IMAGE_OPTIONAL_HEADER
                var magic = (MagicType)Marshal.ReadInt16(intPtr + ntHeaderAddressOffset + 24);

                //Check magic value is one of known MagicType values
                if (Enum.GetValues(typeof(MagicType)).OfType <MagicType>().All(v => v != magic))
                {
                    return(CompilationMode.Invalid);
                }

                var  result        = CompilationMode.Invalid;
                uint clrHeaderSize = 0;
                switch (magic)
                {
                case MagicType.IMAGE_NT_OPTIONAL_HDR32_MAGIC:
                {
                    clrHeaderSize = (uint)Marshal.ReadInt32(intPtr + ntHeaderAddressOffset + 24 + 208 + 4);
                    result       |= CompilationMode.Bit32;
                }
                break;

                case MagicType.IMAGE_NT_OPTIONAL_HDR64_MAGIC:
                {
                    clrHeaderSize = (uint)Marshal.ReadInt32(intPtr + ntHeaderAddressOffset + 24 + 224 + 4);
                    result       |= CompilationMode.Bit64;
                }
                break;
                }
                result |= clrHeaderSize != 0
                    ? CompilationMode.CLR
                    : CompilationMode.Native;
                return(result);
            }
            finally
            {
                if (intPtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(intPtr);
                }
            }
        }