<|start_filename|>src/WinApi.PeCoff/IMAGE_COR20_HEADER.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;

namespace WinApi.PeCoff
{
    public struct IMAGE_COR20_HEADER : IEquatable<IMAGE_COR20_HEADER>
    {
        public uint Cb;
        public IMAGE_DATA_DIRECTORY CodeManagerTable;
        public uint EntryPointToken;
        public IMAGE_DATA_DIRECTORY ExportAddressTableJumps;
        public uint ImageSettings;
        public ushort MajorRuntimeVersion;
        public IMAGE_DATA_DIRECTORY ManagedNativeHeader;
        public IMAGE_DATA_DIRECTORY Metadata;
        public ushort MinorRuntimeVersion;
        public IMAGE_DATA_DIRECTORY Resources;
        public IMAGE_DATA_DIRECTORY StrongNameSignature;
        public IMAGE_DATA_DIRECTORY VTableFixups;

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(obj, null))
            {
                return false;
            }

            var x = obj as IMAGE_COR20_HEADER?;

            if (!x.HasValue)
            {
                return false;
            }

            return Equals(x);
        }

        public bool Equals(IMAGE_COR20_HEADER other)
        {
            if (ReferenceEquals(other, null))
            {
                return false;
            }

            if (Cb != other.Cb)
            {
                return false;
            }

            if (CodeManagerTable != other.CodeManagerTable)
            {
                return false;
            }

            if (EntryPointToken != other.EntryPointToken)
            {
                return false;
            }

            if (ExportAddressTableJumps != other.ExportAddressTableJumps)
            {
                return false;
            }

            if (ImageSettings != other.ImageSettings)
            {
                return false;
            }

            if (MajorRuntimeVersion != other.MajorRuntimeVersion)
            {
                return false;
            }

            if (ManagedNativeHeader != other.ManagedNativeHeader)
            {
                return false;
            }

            if (Metadata != other.Metadata)
            {
                return false;
            }

            if (MinorRuntimeVersion != other.MinorRuntimeVersion)
            {
                return false;
            }

            if (Resources != other.Resources)
            {
                return false;
            }

            if (StrongNameSignature != other.StrongNameSignature)
            {
                return false;
            }

            return VTableFixups == other.VTableFixups;
        }

        public override int GetHashCode()
        {
            // From The Online Encyclopedia of Integer Sequences: https://oeis.org/A000668
            // Mersenne primes (of form 2^p - 1 where p is a prime).
            const int mersenePrime = 131071;
            int hash = 8191;

            unchecked
            {

                hash = (hash * mersenePrime) + this.Cb.GetHashCode();
                hash = (hash * mersenePrime) + this.CodeManagerTable.GetHashCode();
                hash = (hash * mersenePrime) + this.EntryPointToken.GetHashCode();
                hash = (hash * mersenePrime) + this.ExportAddressTableJumps.GetHashCode();
                hash = (hash * mersenePrime) + this.ImageSettings.GetHashCode();
                hash = (hash * mersenePrime) + this.MajorRuntimeVersion.GetHashCode();
                hash = (hash * mersenePrime) + this.ManagedNativeHeader.GetHashCode();
                hash = (hash * mersenePrime) + this.Metadata.GetHashCode();
                hash = (hash * mersenePrime) + this.MinorRuntimeVersion.GetHashCode();
                hash = (hash * mersenePrime) + this.Resources.GetHashCode();
                hash = (hash * mersenePrime) + this.StrongNameSignature.GetHashCode();
                hash = (hash * mersenePrime) + this.VTableFixups.GetHashCode();
            }

            return hash;
        }

        public static bool operator ==(IMAGE_COR20_HEADER x, IMAGE_COR20_HEADER y)
        {
            return x.Equals(y);
        }

        public static bool operator !=(IMAGE_COR20_HEADER x, IMAGE_COR20_HEADER y)
        {
            return !x.Equals(y);
        }
    }
}

<|start_filename|>src/Sandbox/DisplayApi/LOGFONT.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System.Runtime.InteropServices;

namespace Sandbox
{
    // A "logical font" used by old-school windows
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct LOGFONT
    {
        public int lfHeight;
        public int lfWidth;
        public int lfEscapement;
        public int lfOrientation;
        public int lfWeight;
        public byte lfItalic;
        public byte lfUnderline;
        public byte lfStrikeOut;
        public byte lfCharSet;
        public byte lfOutPrecision;
        public byte lfClipPrecision;
        public byte lfQuality;
        public byte lfPitchAndFamily;

        /// <summary>
        /// <see cref="UnmanagedType.ByValTStr"/> means that the string should be marshaled as an
        /// array of TCHAR embedded in the structure. This implies that the font names can be no
        /// larger than <see cref="PInvoke.User32.LF_FACESIZE"/> including the terminating '\0'. That works out to
        /// 31 characters.
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = PInvoke.User32.LF_FACESIZE)]
        public string lfFaceName;

        // to shut it up about the warnings
        public LOGFONT(string lfFaceName)
        {
            this.lfFaceName = lfFaceName;
            lfHeight = lfWidth = lfEscapement = lfOrientation = lfWeight = 0;
            lfItalic = lfUnderline = lfStrikeOut = lfCharSet = lfOutPrecision = lfClipPrecision = lfQuality = lfPitchAndFamily = 0;
        }
    }
}

<|start_filename|>src/Sandbox/DisplayApi/DeviceDescriptionUnion.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System.Runtime.InteropServices;

namespace Sandbox
{
    [StructLayout(LayoutKind.Explicit)]
    public struct DeviceDescriptionUnion
    {
        [FieldOffset(0)]
        public PrintData printData;

        [FieldOffset(0)]
        public DisplayData displayData;
    }
}

<|start_filename|>src/WinApi.Shell/MSGFILTINFO.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

namespace WinApi.Shell
{
    internal enum MSGFLTINFO
    {
        NONE = 0,
        ALREADYALLOWED_FORWND = 1,
        ALREADYDISALLOWED_FORWND = 2,
        ALLOWED_HIGHER = 3,
    }
}


<|start_filename|>src/WinApi.Shell/ITaskbarList.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using System.Runtime.InteropServices;
using PInvoke;

namespace WinApi.Shell
{
    [ComVisible(true)]
    [ComImport]
    [Guid("56FDF342-FD6D-11d0-958A-006097C9A090")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface ITaskbarList
    {
        /// <summary>
        /// Initializes the taskbar list object. This method must be called before any other ITaskbarList methods can be called.
        /// </summary>
        /// <remarks>From ITaskbarList</remarks>
        [PreserveSig]
        HResult HrInit();

        /// <summary>
        /// Adds an item to the taskbar.
        /// </summary>
        /// <param name="hWnd">A handle to the window to be added to the taskbar.</param>
        [PreserveSig]
        HResult AddTab(IntPtr hWnd);

        /// <summary>
        /// Deletes an item from the taskbar.
        /// </summary>
        /// <param name="hWnd">A handle to the window to be deleted from the taskbar.</param>
        [PreserveSig]
        HResult DeleteTab(IntPtr hWnd);

        /// <summary>
        /// Activates an item on the taskbar. The window is not actually activated; the window's item on the taskbar is merely displayed as active.
        /// </summary>
        /// <param name="hWnd">A handle to the window on the taskbar to be displayed as active.</param>
        [PreserveSig]
        HResult ActivateTab(IntPtr hWnd);

        /// <summary>
        /// Marks a taskbar item as active but does not visually activate it.
        /// </summary>
        /// <param name="hWnd">A handle to the window to be marked as active.</param>
        [PreserveSig]
        HResult SetActiveAlt(IntPtr hWnd);
    }
}


<|start_filename|>src/WinApi.User32/WIndowApi.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using System.Runtime.InteropServices;
using PInvoke;
using static PInvoke.User32;

namespace WinApi.User32
{
    public static class WindowApi
    {
        public static bool GetExtendedFrameBounds(IntPtr handle, out RECT rectangle)
        {
            HResult result;
            IntPtr rect = IntPtr.Zero;

            try
            {
                var size = Marshal.SizeOf(typeof(RECT));
                rect = Marshal.AllocHGlobal(size);
                result = DwmApi.DwmGetWindowAttribute(handle, DwmApi.DWMWINDOWATTRIBUTE.DWMWA_EXTENDED_FRAME_BOUNDS, out rect, size);
                rectangle = Marshal.PtrToStructure<RECT>(rect);
            }
            finally
            {
                if (rect == IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(rect);
                }
            }

            return result >= 0;
        }

        public static RECT GetWindowRect(IntPtr handle)
        {
            RECT rect;
            PInvoke.User32.GetWindowRect(handle, out rect);
            return rect;
        }

        //          if (!for_metro)
        //          {
        //              // On restore, resize to the previous saved rect size.
        //              gfx::Rect new_rect(saved_window_info_.window_rect);
        //              SetWindowPos(hwnd_, NULL, new_rect.x(), new_rect.y(),
        //                           new_rect.width(), new_rect.height(),
        //                           SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
        //          }
        //          if (saved_window_info_.maximized)
        //::SendMessage(hwnd_, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
        //      }
        //  }
        public static RECT GetWindowRectangle(IntPtr handle)
        {
            if (Environment.OSVersion.Version.Major < 6)
            {
                return GetWindowRect(handle);
            }

            RECT rectangle;
            return GetExtendedFrameBounds(handle, out rectangle) ? rectangle : GetWindowRect(handle);
        }

        public static string GetWindowTextRaw(IntPtr hwnd)
        {
            // Allocate correct string length first
            var length = SendMessage(hwnd, PInvoke.User32.WindowMessage.WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero).ToInt32();

            return WindowMessage.Send.WM_GETTEXT(hwnd, length);
        }

        // Use this code within a class to show a topmost form without giving focus to it.
        public static void ShowInactiveTopmost(IntPtr hwnd)
        {
            var rect = GetWindowRectangle(hwnd);
            ShowWindow(hwnd, WindowShowStyle.SW_SHOWNOACTIVATE);
            SetWindowPos(
                hwnd,
                new IntPtr((int)SpecialWindowHandles.HWND_TOPMOST),
                rect.left,
                rect.top,
                rect.bottom - rect.top,
                rect.right - rect.left,
                SetWindowPosFlags.SWP_NOACTIVATE);
        }

        public static IntPtr WindowFromPhysicalPoint(int physicalX, int physicalY)
        {
            var ps = new POINT
            {
                x = physicalX,
                y = physicalY
            };

            if (Environment.OSVersion.Version.Major >= 6)
            {
                return PInvoke.User32.WindowFromPhysicalPoint(ps);
            }

            return WindowFromPoint(ps);
        }
    }
}

<|start_filename|>src/WinApi.PeCoff/IMAGE_FILE_HEADER.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;

namespace WinApi.PeCoff
{
    public struct IMAGE_FILE_HEADER : IEquatable<IMAGE_FILE_HEADER>
    {
        public static readonly IMAGE_FILE_HEADER Empty = Create();

        public Characteristics Characteristics;
        public uint[] DataDictionaryRVA;
        public uint[] DataDictionarySize;
        public MachineType Machine;
        public ushort NumberOfSections;
        public uint NumberOfSymbols;
        public PEType PEFormat;
        public uint PointerToSymbolTable;
        public ushort SizeOfOptionalHeader;
        public DateTime TimeDateStamp;

        public static IMAGE_FILE_HEADER Create()
        {
            var result = default(IMAGE_FILE_HEADER);
            result.DataDictionaryRVA = new uint[16];
            result.DataDictionarySize = new uint[16];
            return result;
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(obj, null))
            {
                return false;
            }

            var x = obj as IMAGE_FILE_HEADER?;

            if (!x.HasValue)
            {
                return false;
            }

            return Equals(x);
        }

        public bool Equals(IMAGE_FILE_HEADER other)
        {
            if (ReferenceEquals(other, null))
            {
                return false;
            }

            if (Characteristics != other.Characteristics)
            {
                return false;
            }

            if (DataDictionaryRVA != other.DataDictionaryRVA)
            {
                return false;
            }

            if (DataDictionarySize != other.DataDictionarySize)
            {
                return false;
            }

            if (Machine != other.Machine)
            {
                return false;
            }

            if (NumberOfSections != other.NumberOfSections)
            {
                return false;
            }

            if (NumberOfSymbols != other.NumberOfSymbols)
            {
                return false;
            }

            if (PEFormat != other.PEFormat)
            {
                return false;
            }

            if (PointerToSymbolTable != other.PointerToSymbolTable)
            {
                return false;
            }

            if (SizeOfOptionalHeader != other.SizeOfOptionalHeader)
            {
                return false;
            }
          
            return TimeDateStamp == other.TimeDateStamp;
        }

        public override int GetHashCode()
        {
            // From The Online Encyclopedia of Integer Sequences: https://oeis.org/A000668
            // Mersenne primes (of form 2^p - 1 where p is a prime).
            const int mersenePrime = 131071;
            int hash = 8191;

            unchecked
            {

                hash = (hash * mersenePrime) + this.Characteristics.GetHashCode();
                hash = (hash * mersenePrime) + this.DataDictionaryRVA.GetHashCode();
                hash = (hash * mersenePrime) + this.DataDictionarySize.GetHashCode();
                hash = (hash * mersenePrime) + this.Machine.GetHashCode();
                hash = (hash * mersenePrime) + this.NumberOfSections.GetHashCode();
                hash = (hash * mersenePrime) + this.NumberOfSymbols.GetHashCode();
                hash = (hash * mersenePrime) + this.PEFormat.GetHashCode();
                hash = (hash * mersenePrime) + this.PointerToSymbolTable.GetHashCode();
                hash = (hash * mersenePrime) + this.SizeOfOptionalHeader.GetHashCode();
                hash = (hash * mersenePrime) + this.TimeDateStamp.GetHashCode();
            }

            return hash;
        }

        public static bool operator ==(IMAGE_FILE_HEADER x, IMAGE_FILE_HEADER y)
        {
            return x.Equals(y);
        }

        public static bool operator !=(IMAGE_FILE_HEADER x, IMAGE_FILE_HEADER y)
        {
            return !x.Equals(y);
        }
    }
}

<|start_filename|>src/WinApi.HighDpi/InternalHelpers.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using Microsoft.Win32;

namespace WinApi.HighDpi
{
    internal static class InternalHelpers
    {
        public static T GetValue<T>(this RegistryKey registryKey, string key, string valueName)
        {
            if (registryKey == null)
                throw new ArgumentNullException(nameof(registryKey));

            if (string.IsNullOrWhiteSpace(key))
                throw new ArgumentNullException(nameof(key));

            if (valueName == null)
                throw new ArgumentNullException(nameof(valueName));

            using (var subKey = registryKey.OpenSubKey(key))
            {
                if (subKey == null)
                {
                    return default(T);
                }

                return (T)registryKey.GetValue(valueName, default(T));
            }
        }

        public static T GetValue<T>(this RegistryKey registryKey, string key)
        {
            if (registryKey == null)
                throw new ArgumentNullException(nameof(registryKey));

            if (string.IsNullOrWhiteSpace(key))
                throw new ArgumentNullException(nameof(key));

            var keys = key.Split('\\');
            var subKeys = string.Join("\\", keys, 0, keys.Length - 1);

            return GetValue<T>(registryKey, subKeys, keys[keys.Length - 1]);
        }

        public static bool SetValue<T>(this RegistryKey registryKey, string key, string valueName, T value)
        {
            if (registryKey == null)
                throw new ArgumentNullException(nameof(registryKey));

            if (string.IsNullOrWhiteSpace(key))
                throw new ArgumentNullException(nameof(key));

            if (valueName == null)
                throw new ArgumentNullException(nameof(valueName));

            using (var subKey = registryKey.OpenSubKey(key))
            {
                if (subKey == null)
                {
                    return false;
                }

                registryKey.SetValue(valueName, value);
                registryKey.Flush();
                return true;
            }
        }

        public static bool SetValue<T>(this RegistryKey registryKey, string key, T value)
        {
            if (registryKey == null)
                throw new ArgumentNullException(nameof(registryKey));

            if (string.IsNullOrWhiteSpace(key))
                throw new ArgumentNullException(nameof(key));

            var keys = key.Split('\\');
            var subKeys = string.Join("\\", keys, 0, keys.Length - 1);

            return SetValue(registryKey, subKeys, keys[keys.Length - 1], value);
        }
    }
}

<|start_filename|>src/WinApi.Shell/ThumbnailButton.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using System.Collections.Generic;
using System.Drawing;
using PInvoke;

namespace WinApi.Shell
{
    public class ThumbnailButton : IDisposable
    {
        private bool isInitialized;
        private static readonly IList<uint> idList = new List<uint>();
        private THUMBBUTTONMASK type;
        private THUMBBUTTONFLAGS state;
        private Icon icon;
        private Taskbar taskbar;

        public uint ID { get; set; }
        public string ToolTip { get; set; }
        public IntPtr Parent { get; private set; }

        public event EventHandler Click;
        public event EventHandler Updated;

        public bool IsEnabled
        {
            get
            {
                return (state & THUMBBUTTONFLAGS.THBF_ENABLED) != 0;
            }

            set
            {
                if (value == IsEnabled)
                {
                    return;
                }

                if (value)
                {
                    state = state | THUMBBUTTONFLAGS.THBF_ENABLED;
                    state = state ^ THUMBBUTTONFLAGS.THBF_DISABLED;
                }
                else
                {
                    state = state ^ THUMBBUTTONFLAGS.THBF_ENABLED;
                    state = state | THUMBBUTTONFLAGS.THBF_DISABLED;
                }

                OnUpdate();
            }
        }

        public bool HasBackground
        {
            get
            {
                return (state & THUMBBUTTONFLAGS.THBF_NOBACKGROUND) == 0;
            }

            set
            {
                if (value == HasBackground)
                {
                    return;
                }

                state = value ? state ^ THUMBBUTTONFLAGS.THBF_NOBACKGROUND : state | THUMBBUTTONFLAGS.THBF_NOBACKGROUND;
                OnUpdate();
            }
        }

        public bool IsVisible
        {
            get
            {
                return (state & THUMBBUTTONFLAGS.THBF_HIDDEN) == 0;
            }

            set
            {
                if (value == IsVisible)
                {
                    return;
                }

                state = value ? state ^ THUMBBUTTONFLAGS.THBF_HIDDEN : state | THUMBBUTTONFLAGS.THBF_HIDDEN;
                OnUpdate();
            }
        }

        public bool IsDismissOnClick
        {
            get
            {
                return (state & THUMBBUTTONFLAGS.THBF_DISMISSONCLICK) != 0;
            }

            set
            {
                if (value == IsDismissOnClick)
                {
                    return;
                }

                state = value ? state | THUMBBUTTONFLAGS.THBF_DISMISSONCLICK : state ^ THUMBBUTTONFLAGS.THBF_DISMISSONCLICK;
                OnUpdate();
            }
        }

        public Icon Icon
        {
            get
            {
                return icon;
            }

            set
            {
                icon = value;
                OnUpdate();
            }
        }

        public ThumbnailButton(IntPtr parent, string tooltip, Icon icon)
        {
            this.ID = CreateID();
            this.ToolTip = tooltip;
            this.state = THUMBBUTTONFLAGS.THBF_ENABLED;

            this.icon = icon;
            this.type = THUMBBUTTONMASK.THB_ICON | THUMBBUTTONMASK.THB_TOOLTIP | THUMBBUTTONMASK.THB_FLAGS;

            this.Parent = parent;
        }

        public void Initialize(Taskbar taskbar)
        {
            this.taskbar = taskbar;

            taskbar.AddThumbnailButtons(this.Parent, this);
            taskbar.UpdateThumbnailButtons(this.Parent, this);
            this.isInitialized = true;
        }

        internal THUMBBUTTON ToTHUMBBUTTON()
        {
            var btn = new THUMBBUTTON
            {
                dwFlags = state,
                dwMask = type,
                hIcon = icon.Handle,
                iBitmap = 0,
                iId = ID,
                szTip = ToolTip
            };

            return btn;
        }

        public void WndProcCall(ref User32.MSG msg)
        {
            switch (msg.message)
            {
                case User32.WindowMessage.WM_COMMAND:
                    if ((uint)(msg.wParam.ToInt32() & 0xFFFF) == this.ID)
                    {
                        Click?.Invoke(this, new EventArgs());
                    }
                    break;
            }
        }

        protected virtual void OnUpdate()
        {
            if (!isInitialized)
            {
                return;
            }

            Updated?.Invoke(this, new EventArgs());

            taskbar.UpdateThumbnailButtons(this.Parent, this);
        }

        public void Dispose()
        {
            taskbar = null;

            if (isInitialized)
            {
                taskbar.UpdateThumbnailButtons(this.Parent);
            }

            DeleteID(ID);
        }

        private static uint CreateID()
        {
            var rand = new Random();
            var id = (uint)rand.Next();

            while (idList.Contains(id))
            {
                id = (uint)rand.Next();
            }

            return id;
        }

        private static void DeleteID(uint id)
        {
            idList.Remove(id);
        }
    }
}


<|start_filename|>src/Sandbox/DisplayApi/DisplayData.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System.Runtime.InteropServices;

namespace Sandbox
{
    [StructLayout(LayoutKind.Sequential)]
    public struct DisplayData
    {
        // DWORD->unsigned int
        public uint dmDisplayFixedOutput;

        // DWORD->unsigned int
        public uint dmDisplayOrientation;

        // POINTL->_POINTL
        public PInvoke.POINT dmPosition;
    }
}

<|start_filename|>src/WinApi.PeCoff/PEType.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

namespace WinApi.PeCoff
{
    public enum PEType : ushort
    {
        None = 0,

        /// <summary>
        /// ROM Image
        /// </summary>
        ROMImage = 0x107,

        /// <summary>
        /// Normal executable
        /// </summary>
        PE32 = 0x10B,

        /// <summary>
        /// PE32+ executable
        /// </summary>
        PE32Plus = 0x20B
    }
}

<|start_filename|>src/WinApi.DisplayApi.Tests/DisplayApiFacts.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using Xunit;

namespace WinApi.PeCoff
{
    public class DisplayApiFacts
    {
        [Fact(Skip = "No tests yet")]
        public void NoTests()
        {
        }
    }
}

<|start_filename|>src/WinApi.Shell/CHANGEFILTERSTRUCT.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System.Runtime.InteropServices;

namespace WinApi.Shell
{
    [StructLayout(LayoutKind.Sequential)]
    internal struct CHANGEFILTERSTRUCT
    {
        public uint cbSize;
        public MSGFLTINFO ExtStatus;

        public static CHANGEFILTERSTRUCT Create() => new CHANGEFILTERSTRUCT
        {
            cbSize = (uint)Marshal.SizeOf(typeof(CHANGEFILTERSTRUCT)),
            ExtStatus = MSGFLTINFO.NONE
        };
    }
}



<|start_filename|>src/WinApi.DisplayApi/DisplayInfo.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using PInvoke;

namespace WinApi
{
    /// <summary>
    /// The struct that contains the display information
    /// </summary>
    public class DisplayInfo
    {
        public string Availability { get; set; }

        public RECT MonitorArea { get; set; }

        public string ScreenHeight { get; set; }

        public string ScreenWidth { get; set; }

        public RECT WorkArea { get; set; }
    }
}

<|start_filename|>src/Sandbox/DisplayApi/NONCLIENTMETRICS.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System.Runtime.InteropServices;

namespace Sandbox
{
    //NONCLIENTMETRICS ncm;
    //memset(&ncm, 0, sizeof(NONCLIENTMETRICS));
    //ncm.cbSize = sizeof(NONCLIENTMETRICS);
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct NONCLIENTMETRICS
    {
        public int cbSize;
        public int iBorderWidth;
        public int iCaptionHeight;
        public int iCaptionWidth;
        public int iMenuHeight;
        public int iMenuWidth;
        public int iScrollHeight;
        public int iScrollWidth;
        public int iSMCaptionHeight;

        public int iSMCaptionWidth;

        /// <summary>
        /// Since <see cref="LOGFONT"/> is a struct instead of a class, we don't have to do any
        /// special marshaling here. Much simpler this way.
        /// </summary>
        public LOGFONT lfCaptionFont;

        public LOGFONT lfMenuFont;
        public LOGFONT lfMessageFont;
        public LOGFONT lfSMCaptionFont;
        public LOGFONT lfStatusFont;
    }
}

<|start_filename|>src/Sandbox/DisplayApi/SizeMessages.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

namespace Sandbox
{
    public enum SizeMessages
    {
        SIZE_RESTORED = 0,
        SIZE_MINIMIZED = 1,
        SIZE_MAXIMIZED = 2,
        SIZE_MAXSHOW = 3,
        SIZE_MAXHIDE = 4
    }
}

<|start_filename|>src/WinApi.Console/EnhancedConsole.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Win32;
using PInvoke;

using ThreadState = System.Threading.ThreadState;

namespace WinApi.Console
{
    public sealed class EnhancedConsole : IDisposable
    {
        private const string WAIT_PROMPT = "\n\nPress any key to quit ...";
        private static readonly char[] spinner = { '-', '\\', '|', '/' };

        private Kernel32.HandlerRoutine consoleCtrlHandler;
        private volatile bool hasFaulted ;
        private volatile bool hasHandledOnExit;
        private bool isCapturingFirstChanceException;
        private bool disposedValue;
        
        private volatile bool marqueeRunning;

        private Thread marqueeThread;

        private volatile bool marqueeWithProgress = true;

        private volatile float pctComplete;

        private bool shouldContinueOnBreak;

        private bool shouldPrompt = true;

        private bool consoleAlloced = false;

        private int spinnerPos;

        public EnhancedConsole()
        {
            if (System.Console.LargestWindowHeight == 0 && System.Console.LargestWindowWidth == 0)
            {
                consoleAlloced = AttachOrAllocConsole();
            }

            AppDomain.CurrentDomain.UnhandledException += AppDomain_UnhandledException;
            AppDomain.CurrentDomain.ProcessExit += AppDomain_ProcessExit;

            var currentProcess = Process.GetCurrentProcess();
            currentProcess.Exited += Process_Exited;
            currentProcess.Disposed += Process_Disposed;

            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;

            System.Console.CancelKeyPress += Console_CancelKeyPress;

            consoleCtrlHandler = new Kernel32.HandlerRoutine(Console_CtrlEvent);
            Kernel32.SetConsoleCtrlHandler(consoleCtrlHandler, true);

            SystemEvents.EventsThreadShutdown += SystemEvents_EventsThreadShutdown;
            SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
            SystemEvents.SessionEnded += SystemEvents_SessionEnded;
            SystemEvents.SessionEnding += SystemEvents_SessionEnding;
            SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
        }

        ~EnhancedConsole()
        {
            Dispose(false);
        }

        public event EventHandler<ConsoleCancelEventArgs> OnCancelKeyPressExit;

        public event EventHandler<EventArgs> OnProcessExit;

        public event EventHandler<UnhandledExceptionEventArgs> OnUnhandledException;

        public bool CaptureFirstChanceException
        {
            get
            {
                return isCapturingFirstChanceException;
            }

            set
            {
                if (!value && isCapturingFirstChanceException)
                {
                    AppDomain.CurrentDomain.FirstChanceException -= AppDomain_FirstChanceException;
                }

                isCapturingFirstChanceException = value;

                if (isCapturingFirstChanceException)
                {
                    AppDomain.CurrentDomain.FirstChanceException += AppDomain_FirstChanceException;
                }
            }
        }

        public float Progress
        {
            get
            {
                return pctComplete;
            }

            set
            {
                if (value >= 100f)
                {
                    pctComplete = 100;

                    if (marqueeRunning)
                    {
                        StopMarquee();
                    }
                }
                else if (value <= 0)
                {
                    pctComplete = 0;
                }

                UpdateProgress(pctComplete);
            }
        }

        public bool ShouldExitOnErrors
        {
            get
            {
                return !shouldContinueOnBreak;
            }

            set
            {
                shouldContinueOnBreak = !value;
            }
        }

        public bool ShowProgress
        {
            get
            {
                return marqueeWithProgress;
            }
            set
            {
                marqueeWithProgress = value;
            }
        }

        public bool Unattended
        {
            get
            {
                return !shouldPrompt;
            }

            set
            {
                shouldPrompt = !value;
            }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        public void SetTitle()
        {
            var assembly = Assembly.GetCallingAssembly();
            var company = assembly.GetAttribute<AssemblyCompanyAttribute>();
            var name = assembly.GetAttribute<AssemblyTitleAttribute>();

            System.Console.Title = $"{company?.Company ?? "Console"} | {name?.Title ?? "Application"}";
        }

        public void StartMarquee(bool showProgress = true)
        {          
            StopMarquee();

            marqueeWithProgress = showProgress;
            marqueeRunning = true;
            marqueeThread = new Thread(MarqueeThread);
            marqueeThread.Start();
        }

        public void StopMarquee()
        {
            marqueeRunning = false;
            var threadState = marqueeThread?.ThreadState ?? ThreadState.Unstarted;

            if (threadState != ThreadState.Aborted && threadState != ThreadState.Unstarted && threadState != ThreadState.Stopped)
            {
                if (!marqueeThread?.Join(750) ?? false)
                {
                    try
                    {
                        marqueeThread.Abort();
                    }
                    catch (ThreadAbortException)
                    {
                    }
                }
            }

            marqueeThread = null;
        }

        private bool AttachConsole()
        {
            const int ParentProcess = unchecked((int)0xFFFFFFFF);
            if (!Kernel32.AttachConsole(ParentProcess))
            {
                return false;
            }

            System.Console.Clear();
            return true;
        }

        private bool AttachOrAllocConsole()
        {
            if (!AttachConsole())
            {
                return Kernel32.AllocConsole();
            }

            return false;
        }

        private bool FreeConsole()
        {
            return Kernel32.FreeConsole();
        }

        [HandleProcessCorruptedStateExceptions]
        [SecurityCritical]
        private void AppDomain_FirstChanceException(object sender, FirstChanceExceptionEventArgs e)
        {
            hasFaulted = true;

            var message = "\nFirst Chance Exception";

            try
            {
                var stacktrace = new StackTrace(e.Exception, true);
                var thisStacktrace = new StackTrace(1 + stacktrace.FrameCount, true);

                StopMarquee();

                var assemblyName = Assembly.GetExecutingAssembly().GetName();
                message = $"\nFirst Chance Exception ({e.Exception.GetType().FullName}) in {assemblyName.Name} v{assemblyName.Version}: {e.Exception.Flatten()}{thisStacktrace.ToString()}";
            }
            catch (Exception ex)
            {
                System.Console.Error.WriteLine($"\nError in First Chance Exception handler: {ex.Flatten()}");
            }
            finally
            {
                System.Console.Error.WriteLine(message);

                if (shouldPrompt)
                {
                    ConsoleExtensions.WaitIfDebugging(WAIT_PROMPT);
                }

                var args = new UnhandledExceptionEventArgs(e);
                OnUnhandledException?.Invoke(sender, args);

                if (e.Exception is SEHException ||
                    e.Exception is AccessViolationException ||
                    e.Exception is StackOverflowException)
                {
                    Dispose();
                    Environment.Exit(args.ExitCode);
                }
            }
        }

        private void AppDomain_ProcessExit(object sender, EventArgs e)
        {
            if (!hasHandledOnExit)
            {
                hasHandledOnExit = true;

                var message = "\nProcess Exit";

                try
                {
                    StopMarquee();

                    var assemblyName = Assembly.GetExecutingAssembly().GetName();
                    message = $"\nProcess ({Process.GetCurrentProcess()?.Id.ToString() ?? "unknown"}) Exit in {assemblyName.Name} v{assemblyName.Version}";
                }
                catch (Exception ex)
                {
                    System.Console.Error.WriteLine($"\nError in Process Exit handler: {ex.Flatten()}");
                }
                finally
                {
                    if (hasFaulted)
                    {
                        System.Console.Error.WriteLine(message);

                        if (shouldPrompt)
                        {
                            ConsoleExtensions.WaitIfDebugging(WAIT_PROMPT);
                        }
                    }

                    OnProcessExit?.Invoke(sender, e);

                    Dispose();
                }
            }
        }

        [HandleProcessCorruptedStateExceptions]
        [SecurityCritical]
        private void AppDomain_UnhandledException(object sender, System.UnhandledExceptionEventArgs e)
        {
            hasFaulted = true;

            var message = "\nUnhandled Exception";

            try
            {
                var exception = (e.ExceptionObject as Exception);
                if (exception != null)
                {
                    var stacktrace = new StackTrace(exception, true);
                    var thisStacktrace = new StackTrace(1 + stacktrace.FrameCount, true);

                    StopMarquee();

                    var assemblyName = Assembly.GetExecutingAssembly().GetName();
                    message = $"\nUnhandled Exception ({e.ExceptionObject.GetType().FullName}) in {assemblyName.Name} v{assemblyName.Version}: {exception.Flatten()}{thisStacktrace.ToString()}";
                }
                else
                {
                    throw new ArgumentException($"parameter is not of the Exception type ({e.ExceptionObject.GetType().FullName})", nameof(e.ExceptionObject));
                }
            }
            catch (Exception ex)
            {
                System.Console.Error.WriteLine($"\nError in Unhandled Exception handler: {ex.Flatten()}");
            }
            finally
            {
                System.Console.Error.WriteLine(message);

                if (shouldPrompt)
                {
                    ConsoleExtensions.WaitIfDebugging(WAIT_PROMPT);
                }

                var args = new UnhandledExceptionEventArgs(e);
                OnUnhandledException?.Invoke(sender, args);

                Dispose();
                Environment.Exit(args.ExitCode);
            }
        }

        private void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
        {
            hasFaulted = true;

            var message = "\nCancel Key Press";

            try
            {
                StopMarquee();

                var assemblyName = Assembly.GetExecutingAssembly().GetName();
                message = $"\nCatched Cancel Key Press ({e.SpecialKey.ToString("G")}) in {assemblyName.Name} v{assemblyName.Version}";
            }
            catch (Exception ex)
            {
                System.Console.Error.WriteLine($"\nError in Cancel Key Press handler: {ex.Flatten()}");
            }
            finally
            {
                System.Console.Error.WriteLine(message);

                e.Cancel = shouldContinueOnBreak;

                if (!shouldContinueOnBreak)
                {
                    OnCancelKeyPressExit?.Invoke(sender, e);
                }

                Dispose();
            }
        }

        private bool Console_CtrlEvent(Kernel32.ControlType sig)
        {
            hasFaulted = true;

            var message = "\nExiting system due to external CTRL-C, process kill or shutdown";

            try
            {
                StopMarquee();

                var assemblyName = Assembly.GetExecutingAssembly().GetName();
                message = $"\nCatched Console Ctrl Event ({sig.ToString("G")}) in {assemblyName.Name} v{assemblyName.Version}";
            }
            catch (Exception ex)
            {
                System.Console.Error.WriteLine($"\nError in Console Ctrl Event handler: {ex.Flatten()}");
            }
            finally
            {
                System.Console.Error.WriteLine(message);

                if (!shouldContinueOnBreak)
                {
                    OnCancelKeyPressExit?.Invoke(Process.GetCurrentProcess(), null);

                    Dispose();
                    Environment.Exit(int.MinValue);
                }
            }

            return true;
        }

        private void MarqueeThread()
        {
            while (marqueeRunning && pctComplete <= 100)
            {
                UpdateProgress(pctComplete);

                Thread.Sleep(250);
            }

            System.Console.Out.WriteLine(Environment.NewLine);
        }

        private void Process_Disposed(object sender, EventArgs e)
        {
            if (!hasHandledOnExit)
            {
                hasHandledOnExit = true;

                var message = "\nProcess Disposed";

                try
                {
                    StopMarquee();

                    var assemblyName = Assembly.GetExecutingAssembly().GetName();
                    message = $"\nProcess ({Process.GetCurrentProcess()?.Id.ToString() ?? "unknown"}) Disposed in {assemblyName.Name} v{assemblyName.Version}";
                }
                catch (Exception ex)
                {
                    System.Console.Error.WriteLine($"\nError in Process Disposed handler: {ex.Flatten()}");
                }
                finally
                {
                    System.Console.Error.WriteLine(message);

                    if (shouldPrompt)
                    {
                        ConsoleExtensions.WaitIfDebugging(WAIT_PROMPT);
                    }

                    OnProcessExit?.Invoke(sender, e);

                    Dispose();
                }
            }
        }

        private void Process_Exited(object sender, EventArgs e)
        {
            if (!hasHandledOnExit)
            {
                hasHandledOnExit = true;

                var message = "\nProcess Exited";

                try
                {
                    StopMarquee();

                    var assemblyName = Assembly.GetExecutingAssembly().GetName();
                    message = $"\nProcess ({Process.GetCurrentProcess()?.Id.ToString() ?? "unknown"}) Exited in {assemblyName.Name} v{assemblyName.Version}";
                }
                catch (Exception ex)
                {
                    System.Console.Error.WriteLine($"\nError in Process Exited handler: {ex.Flatten()}");
                }
                finally
                {
                    System.Console.Error.WriteLine(message);

                    if (shouldPrompt)
                    {
                        ConsoleExtensions.WaitIfDebugging(WAIT_PROMPT);
                    }

                    OnProcessExit?.Invoke(sender, e);

                    Dispose();
                }
            }
        }

        private void SystemEvents_EventsThreadShutdown(object sender, EventArgs e)
        {
            Dispose();
        }

        private void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
        {
        }

        private void SystemEvents_SessionEnded(object sender, SessionEndedEventArgs e)
        {
            Dispose();
        }

        private void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
        {
            Dispose();
            e.Cancel = false;
        }

        private void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e)
        {
            Dispose();
        }

        [HandleProcessCorruptedStateExceptions]
        [SecurityCritical]
        private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
        {
            hasFaulted = true;

            var message = "\nUnobserved Task Exception";

            try
            {
                StopMarquee();

                var assemblyName = Assembly.GetExecutingAssembly().GetName();
                message = $"\nUnobserved Task Exception ({e.Exception.GetType().FullName}) in {assemblyName.Name} v{assemblyName.Version}: {e.Exception.ToFlattenedString()}";
            }
            catch (Exception ex)
            {
                System.Console.Error.WriteLine($"\nError in Unobserved Task Exception handler: {ex.Flatten()}");
            }
            finally
            {
                System.Console.Error.WriteLine(message);

                if (shouldPrompt)
                {
                    ConsoleExtensions.WaitIfDebugging(WAIT_PROMPT);
                }

                var args = new UnhandledExceptionEventArgs(e);
                OnUnhandledException?.Invoke(sender, args);
            }
        }

        private void UpdateProgress(float completion)
        {
            if (completion >= 100f)
            {
                System.Console.Out.WriteLine("\rProcess Complete!".PadRight(System.Console.BufferWidth));
            }
            else
            {
                string marquee;

                if (marqueeWithProgress)
                {
                    marquee = $"\rWorking... {spinner[spinnerPos]} - {completion:0.0}%";
                }
                else
                {
                    marquee = $"\rWorking... {spinner[spinnerPos]}";
                }

                System.Console.Out.Write(marquee.PadRight(System.Console.BufferWidth));
                spinnerPos = (spinnerPos >= 3) ? 0 : spinnerPos + 1;
            }
        }

        private void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    StopMarquee();

                    CaptureFirstChanceException = false;

                    SystemEvents.SessionSwitch -= SystemEvents_SessionSwitch;
                    SystemEvents.SessionEnding -= SystemEvents_SessionEnding;
                    SystemEvents.SessionEnded -= SystemEvents_SessionEnded;
                    SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
                    SystemEvents.EventsThreadShutdown -= SystemEvents_EventsThreadShutdown;
                    System.Console.CancelKeyPress -= Console_CancelKeyPress;

                    var currentProcess = Process.GetCurrentProcess();
                    currentProcess.Disposed -= Process_Disposed;
                    currentProcess.Exited -= Process_Exited;

                    TaskScheduler.UnobservedTaskException -= TaskScheduler_UnobservedTaskException;
                }

                Kernel32.SetConsoleCtrlHandler(consoleCtrlHandler, false);
                consoleCtrlHandler = null;

                if (consoleAlloced)
                {
                    FreeConsole();
                }

                AppDomain.CurrentDomain.ProcessExit -= AppDomain_ProcessExit;
                AppDomain.CurrentDomain.UnhandledException -= AppDomain_UnhandledException;

                disposedValue = true;
            }
        }
    }
}

<|start_filename|>src/Sandbox/DisplayApi/SystemIcons.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

namespace Sandbox
{
    public enum SystemIcons
    {
        IDI_APPLICATION = 32512,
        IDI_HAND = 32513,
        IDI_QUESTION = 32514,
        IDI_EXCLAMATION = 32515,
        IDI_ASTERISK = 32516,
        IDI_WINLOGO = 32517,
        IDI_WARNING = IDI_EXCLAMATION,
        IDI_ERROR = IDI_HAND,
        IDI_INFORMATION = IDI_ASTERISK,
    }
}

<|start_filename|>src/WinApi.PeCoff/IMAGE_RESOURCE_DIRECTORY.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;

namespace WinApi.PeCoff
{
    public struct IMAGE_RESOURCE_DIRECTORY : IEquatable<IMAGE_RESOURCE_DIRECTORY>
    {
        public uint Characteristics;
        public ushort MajorVersion;
        public ushort MinorVersion;
        public ushort NumberOfIdEntries;
        public ushort NumberOfNamedEntries;
        public uint TimeDateStamp;

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(obj, null))
            {
                return false;
            }

            var x = obj as IMAGE_RESOURCE_DIRECTORY?;

            if (!x.HasValue)
            {
                return false;
            }

            return Equals(x);
        }

        public bool Equals(IMAGE_RESOURCE_DIRECTORY other)
        {
            if (ReferenceEquals(other, null))
            {
                return false;
            }

            if (Characteristics != other.Characteristics)
            {
                return false;
            }

            if (MajorVersion != other.MajorVersion)
            {
                return false;
            }

            if (MinorVersion != other.MinorVersion)
            {
                return false;
            }

            if (NumberOfIdEntries != other.NumberOfIdEntries)
            {
                return false;
            }

            if (NumberOfNamedEntries != other.NumberOfNamedEntries)
            {
                return false;
            }

            return TimeDateStamp == other.TimeDateStamp;
        }

        public override int GetHashCode()
        {
            // From The Online Encyclopedia of Integer Sequences: https://oeis.org/A000668
            // Mersenne primes (of form 2^p - 1 where p is a prime).
            const int mersenePrime = 131071;
            int hash = 8191;

            unchecked
            {
                hash = (hash * mersenePrime) + this.Characteristics.GetHashCode();
                hash = (hash * mersenePrime) + this.MajorVersion.GetHashCode();
                hash = (hash * mersenePrime) + this.MinorVersion.GetHashCode();
                hash = (hash * mersenePrime) + this.NumberOfIdEntries.GetHashCode();
                hash = (hash * mersenePrime) + this.NumberOfNamedEntries.GetHashCode();
                hash = (hash * mersenePrime) + this.TimeDateStamp.GetHashCode();
            }

            return hash;
        }

        public static bool operator ==(IMAGE_RESOURCE_DIRECTORY x, IMAGE_RESOURCE_DIRECTORY y)
        {
            return x.Equals(y);
        }

        public static bool operator !=(IMAGE_RESOURCE_DIRECTORY x, IMAGE_RESOURCE_DIRECTORY y)
        {
            return !x.Equals(y);
        }
    }
}


<|start_filename|>src/WinApi.Shell/ITaskbarList3+THUMBBUTTONFLAGS.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;

namespace WinApi.Shell
{
    [Flags]
    internal enum THUMBBUTTONFLAGS
    {
        THBF_ENABLED = 0x00,
        THBF_DISABLED = 0x01,
        THBF_DISMISSONCLICK = 0x02,
        THBF_NOBACKGROUND = 0x04,
        THBF_HIDDEN = 0x08,
        THBF_NONINTERACTIVE = 0x10
    }
}


<|start_filename|>src/Sandbox/DisplayApi/IDC_STANDARD_CURSORS.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

namespace Sandbox
{
    public enum IDC_STANDARD_CURSORS
    {
        IDC_ARROW = 32512,
        IDC_IBEAM = 32513,
        IDC_WAIT = 32514,
        IDC_CROSS = 32515,
        IDC_UPARROW = 32516,
        IDC_SIZE = 32640,
        IDC_ICON = 32641,
        IDC_SIZENWSE = 32642,
        IDC_SIZENESW = 32643,
        IDC_SIZEWE = 32644,
        IDC_SIZENS = 32645,
        IDC_SIZEALL = 32646,
        IDC_NO = 32648,
        IDC_HAND = 32649,
        IDC_APPSTARTING = 32650,
        IDC_HELP = 32651
    }
}

<|start_filename|>src/WinApi.User32/KeyboardInputApi.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using System.Runtime.InteropServices;

using static PInvoke.User32;

namespace WinApi.User32
{
    public static class KeyboardInputApi
    {
        public static void SendKeyDownInput(VirtualKey vkKey)
        {
            INPUT[] input = { new INPUT() };

            input[0].type = InputType.INPUT_KEYBOARD;
            var ki = new KEYBDINPUT();
            ki.wVk = vkKey;
            ki.wScan = ScanCode.NONAME;
            ki.dwFlags = /* User32.KEYEVENTF.KEYEVENTF_KEY_DOWN */ 0;
            ki.time = 0;
            ki.dwExtraInfo_IntPtr = IntPtr.Zero;
            input[0].ki = ki;
            var result = SendInput(input.Length, input, Marshal.SizeOf(input[0].GetType()));
        }

        public static void SendKeyDownInput(ScanCode scanCode)
        {
            INPUT[] input = { new INPUT() };

            input[0].type = InputType.INPUT_KEYBOARD;
            var ki = new KEYBDINPUT();
            ki.wVk = VirtualKey.VK_NO_KEY;
            ki.wScan = scanCode;
            ki.dwFlags = /*User32.KEYEVENTF.KEYEVENTF_KEY_DOWN |*/ KEYEVENTF.KEYEVENTF_SCANCODE;
            ki.time = 0;
            ki.dwExtraInfo_IntPtr = IntPtr.Zero;
            input[0].ki = ki;
            var result = SendInput(input.Length, input, Marshal.SizeOf(input[0].GetType()));
        }

        public static void SendKeyUpInput(VirtualKey vkKey)
        {
            INPUT[] input = { new INPUT() };

            input[0].type = InputType.INPUT_KEYBOARD;
            var ki = new KEYBDINPUT();
            ki.wVk = vkKey;
            ki.wScan = ScanCode.NONAME;
            ki.dwFlags = KEYEVENTF.KEYEVENTF_KEYUP;
            ki.time = 0;
            ki.dwExtraInfo_IntPtr = IntPtr.Zero;
            input[0].ki = ki;
            var result = SendInput(input.Length, input, Marshal.SizeOf(input[0].GetType()));
        }

        public static void SendKeyUpInput(ScanCode scanCode)
        {
            INPUT[] input = { new INPUT() };

            input[0].type = InputType.INPUT_KEYBOARD;
            var ki = new KEYBDINPUT();
            ki.wVk = VirtualKey.VK_NO_KEY;
            ki.wScan = scanCode;
            ki.dwFlags = KEYEVENTF.KEYEVENTF_KEYUP | KEYEVENTF.KEYEVENTF_SCANCODE;
            ki.time = 0;
            ki.dwExtraInfo_IntPtr = IntPtr.Zero;
            input[0].ki = ki;
            var result = SendInput(input.Length, input, Marshal.SizeOf(input[0].GetType()));
        }
    }
}

<|start_filename|>src/WinApi.Console/UnhandledExceptionEventArgs.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System.Runtime.ExceptionServices;
using System.Threading.Tasks;

namespace WinApi.Console
{
    public class UnhandledExceptionEventArgs : System.UnhandledExceptionEventArgs
    {
        public UnhandledExceptionEventArgs(object exception, bool isTerminating) : base(exception, isTerminating)
        {
        }

        public UnhandledExceptionEventArgs(System.UnhandledExceptionEventArgs e) : base(e?.ExceptionObject, e?.IsTerminating ?? false)
        {
        }

        public UnhandledExceptionEventArgs(UnobservedTaskExceptionEventArgs e) : base(e?.Exception.Flatten(), !e?.Observed ?? false)
        {
        }

        public UnhandledExceptionEventArgs(FirstChanceExceptionEventArgs e) : base(e?.Exception, false)
        {
        }

        public int ExitCode { get; set; } = int.MinValue;
    }
}

<|start_filename|>src/WinApi.Console/ConsoleEventHooker.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using PInvoke;

namespace WinApi.Console
{
    public sealed class ConsoleEventHooker : IDisposable
    {
        private static Kernel32.HandlerRoutine callback;
        private static ConsoleEventHooker instance;

        public EventHandler Closed;

        public EventHandler Shutdown;

        public ConsoleEventHooker()
        {
            if (instance != null)
            {
                throw new InvalidOperationException("ConsoleEventHooker already setup for this AppDomain");
            }

            instance = this;
            callback = ConsoleEventCallback;
            Kernel32.SetConsoleCtrlHandler(callback, true);
        }

        private bool ConsoleEventCallback(Kernel32.ControlType dwCtrlType)
        {
            if (dwCtrlType == Kernel32.ControlType.CTRL_CLOSE_EVENT)
            {
                Closed?.Invoke(null, new EventArgs());
            }

            if (dwCtrlType == Kernel32.ControlType.CTRL_SHUTDOWN_EVENT)
            {
                Shutdown?.Invoke(null, new EventArgs());
            }

            return false;
        }

        public void Dispose()
        {
            if (ReferenceEquals(instance, this))
            {
                Kernel32.SetConsoleCtrlHandler(callback, false);
                instance = null;
            }
        }
    }
}

<|start_filename|>src/WinApi.Shell/ITaskbarList4+STPFLAG.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;

namespace WinApi.Shell
{
    [Flags]
    internal enum STPFLAG
    {
        STPF_NONE = 0x0,
        STPF_USEAPPTHUMBNAILALWAYS = 0x1,
        STPF_USEAPPTHUMBNAILWHENACTIVE = 0x2,
        STPF_USEAPPPEEKALWAYS = 0x4,
        STPF_USEAPPPEEKWHENACTIVE = 0x8,
    }
}


<|start_filename|>src/WinApi.Shell/TaskbarIconOverlay.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using System.Drawing;
using System.Drawing.Imaging;

namespace WinApi.Shell
{
    public class TaskbarIconOverlay : IDisposable
    {
        private bool isInitialized;
        private THUMBBUTTONFLAGS state;
        private Icon icon;
        private Taskbar taskbar;

        public string Description { get; set; }
        public IntPtr Parent { get; private set; }

        public event EventHandler Updated;

        public bool IsEnabled
        {
            get
            {
                return (state & THUMBBUTTONFLAGS.THBF_ENABLED) != 0;
            }

            set
            {
                if (value == IsEnabled)
                {
                    return;
                }

                if (value)
                {
                    state = state | THUMBBUTTONFLAGS.THBF_ENABLED;
                    state = state ^ THUMBBUTTONFLAGS.THBF_DISABLED;
                }
                else
                {
                    state = state ^ THUMBBUTTONFLAGS.THBF_ENABLED;
                    state = state | THUMBBUTTONFLAGS.THBF_DISABLED;
                }

                OnUpdate();
            }
        }

        public bool HasBackground
        {
            get
            {
                return (state & THUMBBUTTONFLAGS.THBF_NOBACKGROUND) == 0;
            }

            set
            {
                if (value == HasBackground)
                {
                    return;
                }

                state = value ? state ^ THUMBBUTTONFLAGS.THBF_NOBACKGROUND : state | THUMBBUTTONFLAGS.THBF_NOBACKGROUND;
                OnUpdate();
            }
        }

        public bool IsVisible
        {
            get
            {
                return (state & THUMBBUTTONFLAGS.THBF_HIDDEN) == 0;
            }

            set
            {
                if (value == IsVisible)
                {
                    return;
                }

                state = value ? state ^ THUMBBUTTONFLAGS.THBF_HIDDEN : state | THUMBBUTTONFLAGS.THBF_HIDDEN;
                OnUpdate();
            }
        }

        public Icon Icon
        {
            get
            {
                return icon;
            }

            set
            {
                icon = value;
                OnUpdate();
            }
        }

        public TaskbarIconOverlay(IntPtr parent, Icon icon, string description)
        {
            this.Description = description;
            this.state = THUMBBUTTONFLAGS.THBF_ENABLED;
            this.icon = icon;
            this.Parent = parent;
        }

        public TaskbarIconOverlay(IntPtr parent, Bitmap bitmap, string description)
        {
            this.Description = description;
            this.state = THUMBBUTTONFLAGS.THBF_ENABLED;
            this.icon = Icon.FromHandle(bitmap.GetHicon());
            this.Parent = parent;
        }

        public TaskbarIconOverlay(IntPtr parent, string message)
        {
            this.Description = message;
            this.state = THUMBBUTTONFLAGS.THBF_ENABLED;
            this.icon = BuildIcon(message);
            this.Parent = parent;
        }

        private static Icon BuildIcon(string text)
        {
            Bitmap image = null;
            IntPtr icon = IntPtr.Zero;

            try
            {
                // The source Bitmap must use PixelFormat.Format24BppRgb or PixelFormat.Format32bppArgb 
                // The source Bitmap must use at most 256 colors when using Format24BppRgb
                // The source Bitmap must be 16x16 pixels
                // The target Icon must be 16x16 pixels
                // The pixel in the lower left corner (0, 15) is used to determine the transparency color
                image = new Bitmap(16, 16, PixelFormat.Format24bppRgb);

                using (var graphics = Graphics.FromImage(image))
                {
                    graphics.DrawString(text, new Font("Arial", 54), Brushes.White, 10, 25);
                }

                icon = image.GetHicon();
            }
            finally
            {
                image?.Dispose();
            }

            if (icon == IntPtr.Zero)
            {
                return null;
            }

            return Icon.FromHandle(icon);
        }

        public void Initialize(Taskbar taskbar)
        {
            this.taskbar = taskbar;

            taskbar.SetOverlayIcon(this.Parent, icon, Description);
            this.isInitialized = true;
        }

        protected virtual void OnUpdate()
        {
            if (!isInitialized)
            {
                return;
            }

            Updated?.Invoke(this, new EventArgs());

            if (IsEnabled && IsVisible)
            {
                taskbar.SetOverlayIcon(this.Parent, icon, Description);
            }
            else
            {
                taskbar.SetOverlayIcon(this.Parent, (Icon)null, null);
            }
        }

        public void Dispose()
        {
            taskbar = null;

            if (isInitialized)
            {
                taskbar.SetOverlayIcon(this.Parent, (Icon)null, null);
            }
        }
    }
}


<|start_filename|>src/WinApi.Shell/ITaskbarList3+THUMBBUTTON.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using System.Runtime.InteropServices;

namespace WinApi.Shell
{
    [StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Unicode)]
    internal struct THUMBBUTTON
    {
        /// <summary>
        /// WPARAM value for a THUMBBUTTON being clicked.
        /// </summary>
        public const int THBN_CLICKED = 0x1800;

        public THUMBBUTTONMASK dwMask;
        public uint iId;
        public uint iBitmap;
        public IntPtr hIcon;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string szTip;
        public THUMBBUTTONFLAGS dwFlags;
    }
}


<|start_filename|>src/Sandbox/HelloWin.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using PInvoke;
using static PInvoke.User32;

namespace Sandbox
{
    //This is a sample HelloWin ported from Petzolds book (chapter 3) to illustrate the IntPtr issue for classname on CreateWindow
    public class Program
    {
        private const string APP_NAME = "HelloWin";

        private static unsafe IntPtr WndProc(IntPtr hWnd, WindowMessage msg, void* wParam, void* lParam)
        {
            PAINTSTRUCT ps;
            RECT rect;

            switch (msg)
            {
                case WindowMessage.WM_PAINT:
                    using (var hdc = BeginPaint(hWnd, out ps))
                    {
                        GetClientRect(hWnd, out rect);

                        DrawText(hdc, "Hello, Windows 98!".ToCharArray(), -1, ref rect, TextFormats.DT_SINGLELINE | TextFormats.DT_CENTER | TextFormats.DT_VCENTER);

                        EndPaint(hWnd, ps);
                    }
                    return IntPtr.Zero;

                case WindowMessage.WM_DESTROY:
                    PostQuitMessage(0);
                    return IntPtr.Zero;
            }

            return DefWindowProc(hWnd, msg, (IntPtr)wParam, (IntPtr)lParam);
        }

#pragma warning disable RECS0154 // Parameter is never used
        private static unsafe void Main(string[] args)
#pragma warning restore RECS0154 // Parameter is never used
        {
            var hInstance = Process.GetCurrentProcess().Handle;

            ushort regResult;
            fixed (char* className = APP_NAME)
            {
                WNDCLASS wndclass;
                wndclass.style = ClassStyles.CS_HREDRAW | ClassStyles.CS_VREDRAW;
                wndclass.lpfnWndProc = WndProc;
                wndclass.cbClsExtra = 0;
                wndclass.cbWndExtra = 0;
                wndclass.hInstance = hInstance;
                wndclass.hIcon = LoadIcon(IntPtr.Zero, new IntPtr((int)SystemIcons.IDI_APPLICATION));
                wndclass.hCursor = LoadCursor(IntPtr.Zero, new IntPtr((int)IDC_STANDARD_CURSORS.IDC_ARROW));
                wndclass.hbrBackground = Gdi32.GetStockObject(Gdi32.StockObject.WHITE_BRUSH);
                wndclass.lpszMenuName = null;
                wndclass.lpszClassName = className;

                regResult = RegisterClass(ref wndclass);
            }

            if (regResult == 0)
            {
                MessageBox(IntPtr.Zero, "This program requires Windows NT!", APP_NAME, MessageBoxOptions.MB_ICONERROR);
                return;
            }

            var hwnd = CreateWindowEx(
                WindowStylesEx.WS_EX_OVERLAPPEDWINDOW,
                APP_NAME, // window class name
                "The Hello Program", // window caption
                WindowStyles.WS_OVERLAPPEDWINDOW, // window style
                CW_USEDEFAULT, // initial x position
                CW_USEDEFAULT, // initial y position
                CW_USEDEFAULT, // initial x size
                CW_USEDEFAULT, // initial y size
                IntPtr.Zero, // parent window handle
                IntPtr.Zero, // window menu handle
                hInstance, // program instance handle
                IntPtr.Zero); // creation parameters

            if (hwnd == IntPtr.Zero)
            {
                var lastError = Kernel32.GetLastError();
                var errorMessage = lastError.GetMessage();
            }

            ShowWindow(hwnd, WindowShowStyle.SW_SHOWNORMAL);
            UpdateWindow(hwnd);

            
            IntPtr message = IntPtr.Zero;
            try
            {
                var size = Marshal.SizeOf(typeof(RECT));
                message = Marshal.AllocHGlobal(size);

                while (GetMessage(message, IntPtr.Zero, 0, 0) != 0)
                {
                    TranslateMessage(message);
                    DispatchMessage(message);
                }
            }
            finally
            {
                if (message == IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(message);
                }
            }

            return;
        }
    }
}

<|start_filename|>src/Sandbox/DisplayApi/DEVMOD.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System.Runtime.InteropServices;

namespace Sandbox
{
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct DEVMODE
    {
        public DeviceDescriptionUnion description;

        // DWORD->unsigned int
        public uint dmBitsPerPel;

        // short
        public short dmCollate;

        // short
        public short dmColor;

        // WCHAR[32]
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
        public string dmDeviceName;

        // DWORD->unsigned int
        public uint dmDisplayFrequency;

        // DWORD->unsigned int
        public uint dmDitherType;

        // WORD->unsigned short
        public ushort dmDriverExtra;

        // WORD->unsigned short
        public ushort dmDriverVersion;

        // short
        public short dmDuplex;

        // DWORD->unsigned int
        public uint dmFields;

        // WCHAR[32]
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
        public string dmFormName;

        // DWORD->unsigned int
        public uint dmICMIntent;

        // DWORD->unsigned int
        public uint dmICMMethod;

        // WORD->unsigned short
        public ushort dmLogPixels;

        // DWORD->unsigned int
        public uint dmMediaType;

        // DWORD->unsigned int
        public uint dmPanningHeight;

        // DWORD->unsigned int
        public uint dmPanningWidth;

        // DWORD->unsigned int
        public uint dmPelsHeight;

        // DWORD->unsigned int
        public uint dmPelsWidth;

        // DWORD->unsigned int
        public uint dmReserved1;

        // DWORD->unsigned int
        public uint dmReserved2;

        // WORD->unsigned short
        public ushort dmSize;

        // WORD->unsigned short
        public ushort dmSpecVersion;

        // short
        public short dmTTOption;

        // short
        public short dmYResolution;

        public DeviceFlagsUnion flags;
    }
}

<|start_filename|>src/WinApi.PeCoff/PeCoffFiles.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;

namespace WinApi.PeCoff
{
    public static class PeCoffFiles
    {
        public static IMAGE_FILE_HEADER GetDllMachineType(string dllPath)
        {
            // See http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx Offset to PE
            // header is always at 0x3C. The PE header starts with "PE\0\0" = 0x50 0x45 0x00 0x00,
            // followed by a 2-byte machine type field (see the document above for the enum).
            var result = IMAGE_FILE_HEADER.Empty;

            FileStream stream = null;
            try
            {
                stream = new FileStream(dllPath, FileMode.Open, FileAccess.Read);
                stream.Seek(0, SeekOrigin.Begin);
                using (var reader = new BinaryReader(stream))
                {
                    stream = null;

                    // PE Header starts @ 0x3C (60). Its a 4 byte header.
                    reader.BaseStream.Seek(0x3c, SeekOrigin.Begin);
                    var peHeaderOffset = reader.ReadInt32();
                    if (peHeaderOffset == 0)
                    {
                        peHeaderOffset = 0x80;
                    }

                    // Ensure there is at least enough room for the following structures: 24 byte PE
                    // Signature & Header 28 byte Standard Fields (24 bytes for PE32+) 68 byte NT Fields
                    // (88 bytes for PE32+) >= 128 byte Data Dictionary Table
                    if (peHeaderOffset > reader.BaseStream.Length - 256)
                    {
                        throw new BadImageFormatException("File either is not a PE/COFF file or is corrupted.", dllPath);
                    }

                    // Moving to PE Header start location...
                    reader.BaseStream.Seek(peHeaderOffset, SeekOrigin.Begin);
                    var peHeaderSignature = reader.ReadUInt32();

                    // Check the PE signature. Should equal 'PE\0\0'.
                    if (peHeaderSignature != 0x00004550)
                    {
                        throw new BadImageFormatException("Can't find PE header", dllPath);
                    }

                    result.Machine = (MachineType)reader.ReadUInt16();
                    result.NumberOfSections = reader.ReadUInt16();
                    var seconds = reader.ReadUInt32();
                    result.TimeDateStamp = new DateTime(1970, 1, 1, 0, 0, 0).AddSeconds(seconds);
                    result.PointerToSymbolTable = reader.ReadUInt32();
                    result.NumberOfSymbols = reader.ReadUInt32();
                    result.SizeOfOptionalHeader = reader.ReadUInt16();
                    result.Characteristics = (Characteristics)reader.ReadUInt16();

                    // Now we are at the end of the PE Header and from here, the PE Optional Headers
                    // starts... Read PE magic number from Standard Fields to determine format.
                    result.PEFormat = (PEType)reader.ReadUInt16();
                    if (result.PEFormat != PEType.PE32 && result.PEFormat != PEType.PE32Plus)
                    {
                        throw new BadImageFormatException("Found neither PE nor PE+ magic numbers", dllPath);
                    }

                    // we'll increase the stream's current position to with 96 for PE headers and 112 for
                    // PE+ headers we want to skip these structures: 28 byte Standard Fields (24 bytes
                    // for PE32+) 68 byte NT Fields (88 bytes for PE32+)
                    var dataDictionaryStart = peHeaderOffset + (result.PEFormat == PEType.PE32 ? 96 : 112);

                    // To go directly to the datadictionary
                    reader.BaseStream.Position += dataDictionaryStart;

                    // DataDictionay has 16 directories in total, doing simple maths 128/16 = 8. So each
                    // directory is of 8 bytes. In this 8 bytes, 4 bytes is of RVA and 4 bytes of Size.
                    for (int i = 0; i < 15; i++)
                    {
                        result.DataDictionaryRVA[i] = reader.ReadUInt32();
                        result.DataDictionarySize[i] = reader.ReadUInt32();
                    }
                }
            }
            catch
            {
            }
            finally
            {
                stream?.Dispose();
            }

            return result;
        }

        // Returns true if the dll is Managed, false if it is native, and null if unknown
        public static bool? Is32BitManagedDll(string dllPath)
        {
            try
            {
                var pe = GetDllMachineType(dllPath);

                // The 15th directory consist of CLR header! if its 0, its not a CLR file :)
                if (pe.DataDictionaryRVA[14] == 0)
                {
                    return false;
                }

                return pe.PEFormat == PEType.PE32 && !pe.Characteristics.HasFlag(Characteristics.IMAGE_FILE_32BIT_MACHINE);
            }
            catch
            {
            }

            return null;
        }

        // Returns true if the dll is Managed, false if it is native, and null if unknown
        public static bool? Is64BitManagedDll(string dllPath)
        {
            try
            {
                var pe = GetDllMachineType(dllPath);

                // The 15th directory consist of CLR header! if its 0, its not a CLR file :)
                if (pe.DataDictionaryRVA[14] == 0)
                {
                    return false;
                }
                return pe.PEFormat == PEType.PE32Plus && !pe.Characteristics.HasFlag(Characteristics.IMAGE_FILE_32BIT_MACHINE);
            }
            catch
            {
            }

            return null;
        }

        // Returns true if the dll is Managed, false if it is native, and null if unknown
        public static bool? IsAnyCPUManagedDll(string dllPath)
        {
            try
            {
                var pe = GetDllMachineType(dllPath);

                // The 15th directory consist of CLR header! if its 0, its not a CLR file :)
                if (pe.DataDictionaryRVA[14] == 0)
                {
                    return false;
                }
                return pe.PEFormat == PEType.PE32 && !pe.Characteristics.HasFlag(Characteristics.IMAGE_FILE_32BIT_MACHINE);
            }
            catch
            {
            }

            return null;
        }

        // Returns true if the dll is Managed, false if it is native, and null if unknown
        public static bool? IsManagedDll(string dllPath)
        {
            try
            {
                var pe = GetDllMachineType(dllPath);

                // The 15th directory consist of CLR header! if its 0, its not a CLR file :)
                return pe.DataDictionaryRVA[14] != 0;
            }
            catch
            {
            }

            return null;
        }

        // Returns true if the dll is 64-bit, false if 32-bit, and null if unknown
        public static bool? IsUnmanagedDll64Bit(string dllPath)
        {
            try
            {
                var pe = GetDllMachineType(dllPath);
                switch (pe.Machine)
                {
                    case MachineType.IMAGE_FILE_MACHINE_AMD64:
                    case MachineType.IMAGE_FILE_MACHINE_IA64:
                        return true;

                    case MachineType.IMAGE_FILE_MACHINE_I386:
                        return false;

                    default:
                        return null;
                }
            }
            catch
            {
            }

            return null;
        }

        public static bool? IsDebugDLL(string dllPath, out bool pdbOnly)
        {
            pdbOnly = false;

            if (IsManagedDll(dllPath) ?? false)
            {
                try
                {
                    var result = false;
                    var assembly = Assembly.ReflectionOnlyLoadFrom(dllPath);
                    var attribs = assembly.GetCustomAttributes(typeof(DebuggableAttribute), false);
                    bool IsJITOptimized = true;

                    // If the 'DebuggableAttribute' is not found then it is definitely an OPTIMIZED build
                    if (attribs.Length > 0)
                    {
                        // Just because the 'DebuggableAttribute' is found doesn't necessarily mean
                        // it's a DEBUG build; we have to check the JIT Optimization flag
                        // i.e. it could have the "generate PDB" checked but have JIT Optimization enabled
                        var debuggableAttribute = attribs[0] as DebuggableAttribute;
                        if (debuggableAttribute != null)
                        {
                            result = true;
                            IsJITOptimized = !debuggableAttribute.IsJITOptimizerDisabled;
                            result &= debuggableAttribute.IsJITOptimizerDisabled;

                            // check for Debug Output "full" or "pdb-only"
                            pdbOnly = !debuggableAttribute.DebuggingFlags.HasFlag(DebuggableAttribute.DebuggingModes.Default);
                        }
                    }
                }
                catch
                {
                }
            }

            return null;
        }
    }
}

<|start_filename|>src/WinApi.PeCoff/CharacteristicsFlags.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;

namespace WinApi.PeCoff
{
    [Flags]
    public enum Characteristics : ushort
    {
        /// <summary>
        /// Image only, Windows CE, and Microsoft Windows NT and later. This indicates that the
        /// file does not contain base relocations and must therefore be loaded at its preferred
        /// base address. If the base address is not available, the loader reports an error.
        /// </summary>
        /// <remarks>
        /// The default behavior of the linker is to strip base relocations from executable (EXE) files.
        /// </remarks>
        IMAGE_FILE_RELOCS_STRIPPED = 0x0001,

        /// <summary>
        /// Image only. This indicates that the image file is valid and can be run.
        /// </summary>
        /// <remarks>If this flag is not set, it indicates a linker error.</remarks>
        IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002,

        /// <summary>
        /// COFF line numbers have been removed.
        /// </summary>
        /// <remarks>This flag is deprecated and should be zero.</remarks>
        [Obsolete("This flag is deprecated and should be zero.")]
        IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004,

        /// <summary>
        /// COFF symbol table entries for local symbols have been removed.
        /// </summary>
        /// <remarks>This flag is deprecated and should be zero.</remarks>
        [Obsolete("This flag is deprecated and should be zero.")]
        IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008,

        /// <summary>
        /// Aggressively trim working set.
        /// </summary>
        /// <remarks>This flag is deprecated for Windows 2000 and later and must be zero.</remarks>
        [Obsolete("This flag is deprecated for Windows 2000 and later and must be zero.")]
        IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x0010,

        /// <summary>
        /// Application can handle &gt; 2 GB addresses
        /// </summary>
        IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020,

        /// <summary>
        /// This flag is reserved for future use.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1700:DoNotNameEnumValuesReserved")]
        Reserved = 0x0040,

        /// <summary>
        /// Little endian: the least significant bit (LSB) precedes the most significant bit
        /// (MSB) in memory.
        /// </summary>
        /// <remarks>This flag is deprecated and should be zero.</remarks>
        [Obsolete("This flag is deprecated and should be zero.")]
        IMAGE_FILE_BYTES_REVERSED_LO = 0x0080,

        /// <summary>
        /// Machine is based on a 32-bit-word architecture.
        /// </summary>
        IMAGE_FILE_32BIT_MACHINE = 0x0100,

        /// <summary>
        /// Debugging information is removed from the image file.
        /// </summary>
        IMAGE_FILE_DEBUG_STRIPPED = 0x0200,

        /// <summary>
        /// If the image is on removable media, fully load it and copy it to the swap file.
        /// </summary>
        IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400,

        /// <summary>
        /// If the image is on network media, fully load it and copy it to the swap file.
        /// </summary>
        IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800,

        /// <summary>
        /// The image file is a system file, not a user program.
        /// </summary>
        IMAGE_FILE_SYSTEM = 0x1000,

        /// <summary>
        /// The image file is a dynamic-link library (DLL). Such files are considered executable
        /// files for almost all purposes, although they cannot be directly run.
        /// </summary>
        IMAGE_FILE_DLL = 0x2000,

        /// <summary>
        /// The file should be run only on a uniprocessor machine.
        /// </summary>
        IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000,

        /// <summary>
        /// Big endian: the MSB precedes the LSB in memory.
        /// </summary>
        /// <remarks>This flag is deprecated and should be zero.</remarks>
        [Obsolete("This flag is deprecated and should be zero.")]
        IMAGE_FILE_BYTES_REVERSED_HI = 0x8000
    }
}

<|start_filename|>src/WinApi.Kernel32/Clipboard.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using System.Runtime.InteropServices;
using System.Text;

namespace WinApi.Kernel32
{
    public static class Clipboard
    {
        public static bool SetText(string text)
        {
            IntPtr ptr = IntPtr.Zero;
            bool result = false;

            result = PInvoke.User32.OpenClipboard(IntPtr.Zero);
            if (!result)
            {
                return result;
            }

            try
            {
                result &= PInvoke.User32.EmptyClipboard();

                if (result)
                {
                    // IMPORTANT: SetClipboardData requires memory that was acquired with GlobalAlloc
                    //            using GMEM_MOVABLE.
                    ptr = CopyToMoveableMemory(text);
                    result &= ptr == IntPtr.Zero;

                    result &= PInvoke.User32.SetClipboardData(13, ptr).ToInt64() == 0;
                }
            }
            finally
            {
                result &= PInvoke.User32.CloseClipboard();

                if (ptr != IntPtr.Zero)
                {
                    PInvoke.Kernel32.GlobalFree(ptr);
                }
            }

            return result;
        }

        /// <summary>
        /// Creates a memory block with GlobalAlloc(GMEM_MOVEABLE), copies the data into it, and
        /// returns the handle to the memory.
        /// </summary>
        /// <param name="data">The data. Must not be null or zero-length — see the exception notes.</param>
        /// <returns>The *handle* to the allocated GMEM_MOVEABLE block.</returns>
        /// <exception cref="T:System.ArgumentException">
        /// The data was null or zero length. This is disallowed since a zero length allocation can't
        /// be made
        /// </exception>
        /// <exception cref="T:System.ComponentModel.Win32Exception">
        /// The allocation, or locking (handle-&gt;pointer) failed. Either out of memory or the
        /// handle table is full (256 max currently). Note Win32Exception is a subclass of
        /// ExternalException so this is OK in the documented Clipboard interface.
        /// </exception>
        internal static unsafe IntPtr CopyToMoveableMemory(byte[] data)
        {
            // detect this before GlobalAlloc does.
            if (data == null || data.Length == 0)
            {
                throw new ArgumentException("Can't create a zero length memory block.");
            }

            var hmem = PInvoke.Kernel32.GlobalAlloc(
                PInvoke.Kernel32.GlobalAllocFlags.GMEM_MOVEABLE | PInvoke.Kernel32.GlobalAllocFlags.GMEM_DDESHARE, new IntPtr(data.Length));

            if (hmem == null)
            {
                throw new PInvoke.Win32Exception();
            }

            var hmem_ptr = PInvoke.Kernel32.GlobalLock(hmem);

            // If the allocation was valid this shouldn't occur.
            if (hmem_ptr == null)
            {
                throw new PInvoke.Win32Exception();
            }

            Marshal.Copy(data, 0, new IntPtr(hmem_ptr), data.Length);
            PInvoke.Kernel32.GlobalUnlock(hmem);

            return new IntPtr(hmem);
        }

        internal static IntPtr CopyToMoveableMemory(string data)
        {
            return CopyToMoveableMemory(Encoding.UTF8.GetBytes(data));
        }
    }
}

<|start_filename|>src/WinApi.Core/CoreExtensions.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;

namespace WinApi.Core
{
    public static class CoreExtensions
    {
        public static ushort GetHiWord(IntPtr dwValue)
        {
            return unchecked((ushort)((((long)dwValue) >> 0x10) & 0xffff));
        }

        public static ushort GetHiWord(uint dwValue)
        {
            return unchecked((ushort)(dwValue >> 0x10));
        }

        public static ushort GetLoWord(IntPtr dwValue)
        {
            return unchecked((ushort)(((long)dwValue) & 0xffff));
        }

        public static ushort GetLoWord(uint dwValue)
        {
            return unchecked((ushort)(dwValue & 0xffff));
        }

        public static IntPtr MakeLParam(int loWord, int hiWord)
        {
            return new IntPtr(unchecked((loWord & 0xffff) | ((hiWord & 0xffff) << 0x10)));
        }

        public static IntPtr MakeWParam(int loWord, int hiWord)
        {
            return new IntPtr(unchecked((loWord & 0xffff) | ((hiWord & 0xffff) << 0x10)));
        }
    }
}

<|start_filename|>src/WinApi.Shell/ITaskbarList3.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using System.Runtime.InteropServices;
using PInvoke;

namespace WinApi.Shell
{
    [ComVisible(true)]
    [ComImport]
    [Guid("C43DC798-95D1-4BEA-9030-BB99E2983A1A")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface ITaskbarList3 : ITaskbarList2, ITaskbarList
    {
        /// <summary>
        /// Initializes the taskbar list object. This method must be called before any other ITaskbarList methods can be called.
        /// </summary>
        /// <remarks>From ITaskbarList</remarks>
        [PreserveSig]
        new HResult HrInit();

        /// <summary>
        /// Adds an item to the taskbar.
        /// </summary>
        /// <param name="hWnd">A handle to the window to be added to the taskbar.</param>
        /// <remarks>From ITaskbarList</remarks>
        [PreserveSig]
        new HResult AddTab(IntPtr hWnd);

        /// <summary>
        /// Deletes an item from the taskbar.
        /// </summary>
        /// <param name="hWnd">A handle to the window to be deleted from the taskbar.</param>
        /// <remarks>From ITaskbarList</remarks>
        [PreserveSig]
        new HResult DeleteTab(IntPtr hWnd);

        /// <summary>
        /// Activates an item on the taskbar. The window is not actually activated; the window's item on the taskbar is merely displayed as active.
        /// </summary>
        /// <param name="hWnd">A handle to the window on the taskbar to be displayed as active.</param>
        /// <remarks>From ITaskbarList</remarks>
        [PreserveSig]
        new HResult ActivateTab(IntPtr hWnd);

        /// <summary>
        /// Marks a taskbar item as active but does not visually activate it.
        /// </summary>
        /// <param name="hWnd">A handle to the window to be marked as active.</param>
        /// <remarks>From ITaskbarList</remarks>
        [PreserveSig]
        new HResult SetActiveAlt(IntPtr hWnd);

        /// <summary>
        /// Marks a window as full-screen
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="fFullscreen"></param>
        /// <remarks>From ITaskbarList2</remarks>
        [PreserveSig]
        new HResult MarkFullscreenWindow(
            IntPtr hWnd,
            [MarshalAs(UnmanagedType.Bool)] bool fFullscreen);

        /// <summary>
        /// Displays or updates a progress bar hosted in a taskbar button to show the specific percentage
        /// completed of the full operation.
        /// </summary>
        /// <param name="hWnd">The handle of the window whose associated taskbar button is being used as
        /// a progress indicator.</param>
        /// <param name="ullCompleted">An application-defined value that indicates the proportion of the
        /// operation that has been completed at the time the method is called.</param>
        /// <param name="ullTotal">An application-defined value that specifies the value ullCompleted will
        /// have when the operation is complete.</param>
        [PreserveSig]
        HResult SetProgressValue(IntPtr hWnd, ulong ullCompleted, ulong ullTotal);

        /// <summary>
        /// Sets the type and state of the progress indicator displayed on a taskbar button.
        /// </summary>
        /// <param name="hWnd">The handle of the window in which the progress of an operation is being
        /// shown. This window's associated taskbar button will display the progress bar.</param>
        /// <param name="tbpFlags">Flags that control the current state of the progress button. Specify
        /// only one of the following flags; all states are mutually exclusive of all others.</param>
        [PreserveSig]
        HResult SetProgressState(IntPtr hWnd, TBPFLAG tbpFlags);

        /// <summary>
        /// Informs the taskbar that a new tab or document thumbnail has been provided for display in an
        /// application's taskbar group flyout.
        /// </summary>
        /// <param name="hWndTab">Handle of the tab or document window. This value is required and cannot
        /// be NULL.</param>
        /// <param name="hWndMDI">Handle of the application's main window. This value tells the taskbar
        /// which application's preview group to attach the new thumbnail to. This value is required and
        /// cannot be NULL.</param>
        [PreserveSig]
        HResult RegisterTab(IntPtr hWndTab, IntPtr hWndMDI);

        /// <summary>
        /// Removes a thumbnail from an application's preview group when that tab or document is closed in the application.
        /// </summary>
        /// <param name="hWndTab">The handle of the tab window whose thumbnail is being removed. This is the same
        /// value with which the thumbnail was registered as part the group through ITaskbarList3::RegisterTab.
        /// This value is required and cannot be NULL.</param>
        [PreserveSig]
        HResult UnregisterTab(IntPtr hWndTab);

        /// <summary>
        /// Inserts a new thumbnail into a tabbed-document interface (TDI) or multiple-document interface
        /// (MDI) application's group flyout or moves an existing thumbnail to a new position in the
        /// application's group.
        /// </summary>
        /// <param name="hWndTab">The handle of the tab window whose thumbnail is being placed. This value
        /// is required, must already be registered through ITaskbarList3::RegisterTab, and cannot be NULL.</param>
        /// <param name="hWndInsertBefore">[Optional] The handle of the tab window whose thumbnail that hwndTab is
        /// inserted to the left of. This handle must already be registered through ITaskbarList3::RegisterTab.
        /// If this value is NULL, the new thumbnail is added to the end of the list.</param>
        [PreserveSig]
        HResult SetTabOrder(IntPtr hWndTab, IntPtr hWndInsertBefore);

        /// <summary>
        /// Informs the taskbar that a tab or document window has been made the active window.
        /// </summary>
        /// <param name="hWndTab">Handle of the active tab window. This handle must already be registered
        /// through ITaskbarList3::RegisterTab. This value can be NULL if no tab is active.</param>
        /// <param name="hWndMDI">Handle of the application's main window. This value tells the taskbar
        /// which group the thumbnail is a member of. This value is required and cannot be NULL.</param>
        /// <param name="tbatFlags">None, one, or both of the following values that specify a thumbnail
        /// and peek view to use in place of a representation of the specific tab or document.</param>
        [PreserveSig]
        HResult SetTabActive(IntPtr hWndTab, IntPtr hWndMDI, uint tbatFlags);

        /// <summary>
        /// Adds a thumbnail toolbar with a specified set of buttons to the thumbnail image of a window in a
        /// taskbar button flyout.
        /// </summary>
        /// <param name="hWnd">The handle of the window whose thumbnail representation will receive the toolbar.
        /// This handle must belong to the calling process.</param>
        /// <param name="cButtons">The number of buttons defined in the array pointed to by pButton. The maximum
        /// number of buttons allowed is 7.</param>
        /// <param name="pButton">A pointer to an array of THUMBBUTTON structures. Each THUMBBUTTON defines an
        /// individual button to be added to the toolbar. Buttons cannot be added or deleted later, so this must
        /// be the full defined set. Buttons also cannot be reordered, so their order in the array, which is the
        /// order in which they are displayed left to right, will be their permanent order.</param>
        [PreserveSig]
        HResult ThumbBarAddButtons(
            IntPtr hWnd,
            uint cButtons,
            [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] THUMBBUTTON[] pButton);

        /// <summary>
        /// Updates a thumbnail toolbar with a specified set of buttons to the thumbnail image of a window in a
        /// taskbar button flyout.
        /// </summary>
        /// <param name="hWnd">The handle of the window whose thumbnail representation will receive the toolbar.
        /// This handle must belong to the calling process.</param>
        /// <param name="cButtons">The number of buttons defined in the array pointed to by pButton. The maximum
        /// number of buttons allowed is 7.</param>
        /// <param name="pButton">A pointer to an array of THUMBBUTTON structures. Each THUMBBUTTON defines an
        /// individual button to be added to the toolbar. Buttons cannot be added or deleted later, so this must
        /// be the full defined set. Buttons also cannot be reordered, so their order in the array, which is the
        /// order in which they are displayed left to right, will be their permanent order.</param>
        [PreserveSig]
        HResult ThumbBarUpdateButtons(
            IntPtr hWnd,
            uint cButtons,
            [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] THUMBBUTTON[] pButton);

        /// <summary>
        /// Specifies an image list that contains button images for a toolbar embedded in a thumbnail image of a
        /// window in a taskbar button flyout.
        /// </summary>
        /// <param name="hWnd">The handle of the window whose thumbnail representation contains the toolbar to be
        /// updated. This handle must belong to the calling process.</param>
        /// <param name="himl">The handle of the image list that contains all button images to be used in the toolbar.</param>
        [PreserveSig]
        HResult ThumbBarSetImageList(
            IntPtr hWnd,
            [MarshalAs(UnmanagedType.IUnknown)] object himl);

        /// <summary>
        /// Applies an overlay to a taskbar button to indicate application status or a notification to the user.
        /// </summary>
        /// <param name="hWnd">The handle of the window whose associated taskbar button receives the overlay.
        /// This handle must belong to a calling process associated with the button's application and must be
        /// a valid HWND or the call is ignored.</param>
        /// <param name="hIcon">The handle of an icon to use as the overlay. This should be a small icon,
        /// measuring 16x16 pixels at 96 dots per inch (dpi). If an overlay icon is already applied to the
        /// taskbar button, that existing overlay is replaced.</param>
        /// <param name="pszDescription">A pointer to a string that provides an alt text version of the
        /// information conveyed by the overlay, for accessibility purposes.</param>
        [PreserveSig]
        HResult SetOverlayIcon(
            IntPtr hWnd, 
            IntPtr hIcon, 
            [MarshalAs(UnmanagedType.LPWStr)] string pszDescription);

        /// <summary>
        /// Specifies or updates the text of the tooltip that is displayed when the mouse pointer rests on an
        /// individual preview thumbnail in a taskbar button flyout.
        /// </summary>
        /// <param name="hWnd">The handle to the window whose thumbnail displays the tooltip. This handle must
        /// belong to the calling process.</param>
        /// <param name="pszTip">The pointer to the text to be displayed in the tooltip. This value can be NULL,
        /// in which case the title of the window specified by hwnd is used as the tooltip.</param>
        [PreserveSig]
        HResult SetThumbnailTooltip(
            IntPtr hWnd,
            [MarshalAs(UnmanagedType.LPWStr)] string pszTip);

        /// <summary>
        /// Selects a portion of a window's client area to display as that window's thumbnail in the taskbar.
        /// </summary>
        /// <param name="hWnd">The handle to a window represented in the taskbar.</param>
        /// <param name="prcClip">[In, RECT*] A pointer to a RECT structure that specifies a selection within the window's
        /// client area, relative to the upper-left corner of that client area. To clear a clip that is already
        /// in place and return to the default display of the thumbnail, set this parameter to NULL.</param>
        [PreserveSig]
        HResult SetThumbnailClip(IntPtr hWnd, ref RECT prcClip);
    }
}


<|start_filename|>src/WinApi.Console/InternalHelpers.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;

namespace WinApi.Console
{
    internal static class InternalHelpers
    {
        public const string EXCEPTION_SEPARATOR = "----------------------------------------";

        public static string Flatten(this Exception exception)
        {
            var stringBuilder = new StringBuilder();

            while (exception != null)
            {
                stringBuilder.AppendLine(exception.Message);
                stringBuilder.AppendLine(exception.StackTrace);
                stringBuilder.AppendLine(EXCEPTION_SEPARATOR);

                exception = exception.InnerException;
            }

            return stringBuilder.ToString();
        }

        public static T GetAttribute<T>(this Assembly assembly)
                            where T : Attribute
        {
            return GetAttributes<T>(assembly).FirstOrDefault();
        }

        public static IEnumerable<T> GetAttributes<T>(this Assembly assembly)
            where T : Attribute
        {
            if (assembly == null)
            {
                throw new ArgumentNullException(nameof(assembly));
            }

            var attributes = assembly.GetCustomAttributes<T>();

            return attributes;
        }

        public static Process Parent(this Process process)
        {
            return FindPidFromIndexedProcessName(FindIndexedProcessName(process.Id));
        }

        public static string ToFlattenedString(this AggregateException exception)
        {
            var stringBuilder = new StringBuilder();
            var flattenedException = exception?.Flatten();

            stringBuilder.AppendLine(flattenedException.Message);
            stringBuilder.AppendLine(flattenedException.StackTrace);
            stringBuilder.AppendLine(EXCEPTION_SEPARATOR);

            stringBuilder.AppendLine("BASE EXCEPTION");
            stringBuilder.AppendLine(flattenedException.GetBaseException().Flatten());

            stringBuilder.AppendLine("INNER EXCEPTION");
            stringBuilder.AppendLine(flattenedException.InnerException.Flatten());

            stringBuilder.AppendLine("AGGREGATED INNER EXCEPTIONS");
            stringBuilder.AppendLine(EXCEPTION_SEPARATOR);

            foreach (var ex in flattenedException.InnerExceptions)
            {
                stringBuilder.AppendLine(ex.Flatten());
            }

            return stringBuilder.ToString();
        }

        private static string FindIndexedProcessName(int pid)
        {
            var processName = Process.GetProcessById(pid).ProcessName;
            var processesByName = Process.GetProcessesByName(processName);
            string processIndexdName = null;

            for (var index = 0; index < processesByName.Length; index++)
            {
                processIndexdName = index == 0 ? processName : processName + "#" + index;
                using (var processId = new PerformanceCounter("Process", "ID Process", processIndexdName))
                {
                    if ((int)processId.NextValue() == pid)
                    {
                        return processIndexdName;
                    }
                }
            }

            return processIndexdName;
        }

        private static Process FindPidFromIndexedProcessName(string indexedProcessName)
        {
            int processId;
            using (var parentId = new PerformanceCounter("Process", "Creating Process ID", indexedProcessName))
            {
                processId = (int)parentId.NextValue();
            }

            return processId == 0 ? null : Process.GetProcessById(processId);
        }
    }
}

<|start_filename|>src/WinApi.Core/SystemDrawingExtensions.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System.Drawing;
using PInvoke;

namespace WinApi.Core
{
    public static class SystemDrawingExtensions
    {
        public static Point ToPoint(this POINT point)
        {
            return new Point(point.x, point.y);
        }

        public static POINT ToPOINT(this Point point)
        {
            return new POINT
            {
                x = point.X,
                y = point.Y
            };
        }

        public static RECT ToRECT(this Rectangle rect)
        {
            return new RECT
            {
                top = rect.Top,
                bottom = rect.Bottom,
                left = rect.Left,
                right = rect.Right
            };
        }

        public static Rectangle ToRectangle(this RECT rect)
        {
            return new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
        }
    }
}

<|start_filename|>src/WinApi.Shell/ITaskbarList3+TBPFLAG.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

namespace WinApi.Shell
{
    internal enum TBPFLAG
    {
        TBPF_NOPROGRESS = 0,
        TBPF_INDETERMINATE = 0x1,
        TBPF_NORMAL = 0x2,
        TBPF_ERROR = 0x4,
        TBPF_PAUSED = 0x8
    }
}


<|start_filename|>src/Sandbox/DisplayApi/MinimizedMetrics.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System.Runtime.InteropServices;

namespace Sandbox
{
    [StructLayout(LayoutKind.Sequential)]
    public struct MinimizedMetrics
    {
        private uint cbSize;
        private MinimizedMetricsArrangement iArrange;
        private int iHorzGap;
        private int iVertGap;
        private int iWidth;
    }
}

<|start_filename|>src/WinApi.Kernel32/Platform.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using System.Diagnostics;

using static PInvoke.Kernel32;

namespace WinApi.Kernel32
{
    public static class Platform
    {
        public static bool IsOS64Bit
        {
            get
            {
                return Is64Bit();
            }
        }

        public static bool IsRunningAs64Bit
        {
            get
            {
                if (IntPtr.Size == 8)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "This method should not throw exceptions")]
        public static bool Is64Bit(SafeObjectHandle hProcess = null)
        {
            bool isWow64 = false;

            try
            {
                if ((Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1) ||
                      Environment.OSVersion.Version.Major > 5)
                {
                    using (var moduleHandle = GetModuleHandle("Kernel32.dll"))
                    {
                        if (!moduleHandle.IsInvalid)
                        {
                            var proc = GetProcAddress(moduleHandle, "IsWow64Process");

                            if (proc != IntPtr.Zero)
                            {
                                if (hProcess == null || hProcess.IsInvalid || hProcess.IsClosed || hProcess == SafeObjectHandle.Null)
                                {
                                    var process = Process.GetCurrentProcess().Handle;

                                    using (var processHandle = new SafeObjectHandle(process, true))
                                    {
                                        isWow64 = IsWow64Process(processHandle);
                                    }
                                }
                                else
                                {
                                    isWow64 = IsWow64Process(hProcess);
                                }
                            }
                        }
                    }
                }
            }
#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
            catch
#pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body
            {
            }

            if (IntPtr.Size == 8 || (IntPtr.Size == 4 && isWow64))
            {
                return true;
            }

            return false;
        }
    }
}

<|start_filename|>src/WinApi.HighDpi/Dpi.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

namespace WinApi.HighDpi
{
    public struct Dpi
    {
        public static readonly Dpi Default = new Dpi(96, 96);

        public Dpi(int x, int y)
            : this()
        {
            this.X = x;
            this.Y = y;
        }

        public int X { get; set; }

        public int Y { get; set; }

        public static bool operator !=(Dpi dpi1, Dpi dpi2)
        {
            return !(dpi1 == dpi2);
        }

        public static bool operator ==(Dpi dpi1, Dpi dpi2)
        {
            return dpi1.X == dpi2.X && dpi1.Y == dpi2.Y;
        }

        public bool Equals(Dpi other)
        {
            return this.X == other.X && this.Y == other.Y;
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(this, obj))
            {
                return false;
            }

            if (ReferenceEquals(obj, null))
            {
                return false;
            }

            return obj is Dpi && this.Equals((Dpi)obj);
        }

        public override int GetHashCode()
        {
            unchecked
            {
                return this.X * 397 ^ this.Y;
            }
        }

        public override string ToString()
        {
            return string.Format("[X={0},Y={1}]", this.X, this.Y);
        }
    }
}

<|start_filename|>src/Sandbox/DisplayApi/ANIMATIONINFO.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System.Runtime.InteropServices;

namespace Sandbox
{
    /// <summary>
    /// ANIMATIONINFO specifies animation effects associated with user actions. Used with
    /// SystemParametersInfo when SPI_GETANIMATION or SPI_SETANIMATION action is specified.
    /// </summary>
    /// <remark>
    /// The uiParam value must be set to (System.UInt32)Marshal.SizeOf(typeof(ANIMATIONINFO)) when
    /// using this structure.
    /// </remark>
    [StructLayout(LayoutKind.Sequential)]
    public struct ANIMATIONINFO
    {
        /// <summary>
        /// Always must be set to (System.UInt32)Marshal.SizeOf(typeof(ANIMATIONINFO)).
        /// </summary>
        public uint cbSize;

        /// <summary>
        /// If non-zero, minimize/restore animation is enabled, otherwise disabled.
        /// </summary>
        public int iMinAnimate;

        /// <summary>
        /// Creates an AMINMATIONINFO structure.
        /// </summary>
        /// <param name="iMinAnimate">
        /// If non-zero and SPI_SETANIMATION is specified, enables minimize/restore animation.
        /// </param>
        public ANIMATIONINFO(int iMinAnimate)
        {
            this.cbSize = (uint)Marshal.SizeOf(typeof(ANIMATIONINFO));
            this.iMinAnimate = iMinAnimate;
        }
    }
}

<|start_filename|>src/WinApi.Shell/MSGFLT.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

namespace WinApi.Shell
{
    internal enum MSGFLT
    {
        // Win7 versions of this enum:
        RESET = 0,
        ALLOW = 1,
        DISALLOW = 2,

        // Vista versions of this enum:
        ADD = 1,
        REMOVE = 2
    }
}


<|start_filename|>src/Sandbox/OleApi.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using System.Runtime.InteropServices;
using System.Security;
using System.Threading;
using System.Windows.Threading;

namespace Sandbox
{
    public static class OleApi
    {
        private const string OLE_INITIALIZARION_FAILURE = "OLE initialization failed.";
        private const string THREAD_MUST_BE_STA = "Current thread must be set to single thread apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked on it. This exception is only raised if a debugger is attached to the process.";

        ///<SecurityNote>
        ///  Critical as this code performs an elevation.
        ///</SecurityNote>
        [SecurityCritical]
        [SuppressUnmanagedCodeSecurity]
        [DllImport("ole32", ExactSpelling = true, SetLastError = true)]
        public static extern int OleInitialize(IntPtr val);

        // Wrapper for UnsafeNativeMethods.OleInitialize, useful for debugging.
        /// <SecurityNote>
        /// Critical - calls critical method (OleInitialize) TreatAsSafe - safe to call anytime (ref
        /// counting issues aside)
        /// </SecurityNote>
        [SecurityCritical]
        public static int OleInitialize()
        {
            return OleInitialize(IntPtr.Zero);
        }

        /// <SecurityNote>
        /// Critical: This code calls into unmanaged code which elevates TreatAsSafe - safe to call OLeUninitialize
        /// </SecurityNote>
        /// ///
        [SecurityCritical]
        [SuppressUnmanagedCodeSecurity]
        [DllImport("ole32", ExactSpelling = true, CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int OleUninitialize();

        /// <summary>
        /// This is a callback when Dispatcher is shut down.
        /// </summary>
        /// <remarks>
        /// This method must be called before shutting down the application on the dispatcher thread.
        /// It must be called by the same thread running the dispatcher and the thread must have its
        /// ApartmentState property set to ApartmentState.STA.
        /// </remarks>
        public static void OnDispatcherShutdown(object sender, EventArgs args)
        {
            if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)
            {
                throw new ThreadStateException(THREAD_MUST_BE_STA);
            }

            // Uninitialize Ole services. Balanced with OleInitialize call in SetDispatcherThread.
            OleUninitialize();
        }

        /// <summary>
        /// SetDispatcherThread - Initialize OleServicesContext that will call Ole initialize for ole
        /// services(DragDrop and Clipboard) and add the disposed event handler of Dispatcher to
        /// clean up resources and uninitalize Ole.
        /// </summary>
        public static void SetDispatcherThread()
        {
            int hr;

            if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)
            {
                throw new ThreadStateException(THREAD_MUST_BE_STA);
            }

            // Initialize Ole services. Balanced with OleUninitialize call in OnDispatcherShutdown.
            hr = OleInitialize();

            if (!Succeeded(hr))
            {
                throw new SystemException(OLE_INITIALIZARION_FAILURE);
            }

            // Add Dispatcher.Shutdown event handler. We will call ole Uninitialize and clean up the
            // resource when UIContext is terminated.
            Dispatcher.CurrentDispatcher.ShutdownFinished += OnDispatcherShutdown;
        }

        public static bool Succeeded(int hr)
        {
            return hr >= 0;
        }
    }
}

<|start_filename|>src/WinApi.PeCoff/IMAGE_RESOURCE_DIRECTORY_ENTRY.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;

namespace WinApi.PeCoff
{
    public struct IMAGE_RESOURCE_DIRECTORY_ENTRY : IEquatable<IMAGE_RESOURCE_DIRECTORY_ENTRY>
    {
        public uint Name;
        public uint OffsetToData;

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(obj, null))
            {
                return false;
            }

            var x = obj as IMAGE_RESOURCE_DIRECTORY_ENTRY?;

            if (!x.HasValue)
            {
                return false;
            }

            return Equals(x);
        }

        public bool Equals(IMAGE_RESOURCE_DIRECTORY_ENTRY other)
        {
            if (ReferenceEquals(other, null))
            {
                return false;
            }

            if (Name != other.Name)
            {
                return false;
            }

            return OffsetToData == other.OffsetToData;
        }

        public override int GetHashCode()
        {
            // From The Online Encyclopedia of Integer Sequences: https://oeis.org/A000668
            // Mersenne primes (of form 2^p - 1 where p is a prime).
            const int mersenePrime = 131071;
            int hash = 8191;

            unchecked
            {
                hash = (hash * mersenePrime) + this.Name.GetHashCode();
                hash = (hash * mersenePrime) + this.OffsetToData.GetHashCode();
            }

            return hash;
        }

        public static bool operator ==(IMAGE_RESOURCE_DIRECTORY_ENTRY x, IMAGE_RESOURCE_DIRECTORY_ENTRY y)
        {
            return x.Equals(y);
        }

        public static bool operator !=(IMAGE_RESOURCE_DIRECTORY_ENTRY x, IMAGE_RESOURCE_DIRECTORY_ENTRY y)
        {
            return !x.Equals(y);
        }
    }
}


<|start_filename|>src/Sandbox/User32.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

namespace Sandbox
{
    public class User32
    {
        // http://www.codeproject.com/Articles/8460/Advanced-MessageBoxing-with-the-C-MessageBoxIndire
    }
}

<|start_filename|>src/WinApi.User32/MouseInputApi.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using System.Runtime.InteropServices;
using WinApi.Core;
using static PInvoke.User32;

namespace WinApi.User32
{
    public static class MouseInputApi
    {
        public static int GetWheelDeltaWParam(IntPtr wParam)
        {
            return unchecked((short)CoreExtensions.GetHiWord(wParam));
        }

        public static int GetWheelDeltaWParam(uint wParam)
        {
            return unchecked((short)CoreExtensions.GetHiWord(wParam));
        }

        public static void SendMouseInput(MOUSEEVENTF mouseEvent, int data, int dx = 0, int dy = 0)
        {
            INPUT[] input = { new INPUT() };

            input[0].type = InputType.INPUT_MOUSE;
            var mi = new MOUSEINPUT();
            mi.dx = dx;
            mi.dy = dy;
            mi.dwFlags = mouseEvent;
            mi.time = 0;
            mi.dwExtraInfo_IntPtr = IntPtr.Zero;
            mi.mouseData = unchecked((uint)data);
            input[0].mi = mi;
            var result = SendInput(input.Length, input, Marshal.SizeOf(input[0].GetType()));
        }
    }
}

<|start_filename|>src/WinApi.PeCoff/IMAGE_SECTION_HEADER.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;

namespace WinApi.PeCoff
{
    public struct IMAGE_SECTION_HEADER : IEquatable<IMAGE_SECTION_HEADER>
    {
        public uint Characteristics;
        public byte[] Name;
        public ushort NumberOfLinenumbers;
        public ushort NumberOfRelocations;
        public uint PointerToLinenumbers;
        public uint PointerToRawData;
        public uint PointerToRelocations;
        public uint SizeOfRawData;
        public uint VirtualAddress;
        public uint VirtualSize;

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(obj, null))
            {
                return false;
            }

            var x = obj as IMAGE_SECTION_HEADER?;

            if (!x.HasValue)
            {
                return false;
            }
            
            return Equals(x);
        }

        public bool Equals(IMAGE_SECTION_HEADER other)
        {
            if (ReferenceEquals(other, null))
            {
                return false;
            }

            if (Characteristics != other.Characteristics)
            {
                return false;
            }

            if (Name != other.Name)
            {
                return false;
            }

            if (NumberOfLinenumbers != other.NumberOfLinenumbers)
            {
                return false;
            }

            if (NumberOfRelocations != other.NumberOfRelocations)
            {
                return false;
            }

            if (PointerToLinenumbers != other.PointerToLinenumbers)
            {
                return false;
            }
            if (PointerToRawData != other.PointerToRawData)
            {
                return false;
            }
            if (PointerToRelocations != other.PointerToRelocations)
            {
                return false;
            }
            if (SizeOfRawData != other.SizeOfRawData)
            {
                return false;
            }
            if (VirtualAddress != other.VirtualAddress)
            {
                return false;
            }

            return VirtualSize == other.VirtualSize;
        }

        public override int GetHashCode()
        {
            // From The Online Encyclopedia of Integer Sequences: https://oeis.org/A000668
            // Mersenne primes (of form 2^p - 1 where p is a prime).
            const int mersenePrime = 131071;
            int hash = 8191;

            unchecked
            {
                hash = (hash * mersenePrime) + this.Characteristics.GetHashCode();
                hash = (hash * mersenePrime) + this.Name.GetHashCode();
                hash = (hash * mersenePrime) + this.NumberOfLinenumbers.GetHashCode();
                hash = (hash * mersenePrime) + this.NumberOfRelocations.GetHashCode();
                hash = (hash * mersenePrime) + this.PointerToLinenumbers.GetHashCode();
                hash = (hash * mersenePrime) + this.PointerToRawData.GetHashCode();
                hash = (hash * mersenePrime) + this.PointerToRelocations.GetHashCode();
                hash = (hash * mersenePrime) + this.SizeOfRawData.GetHashCode();
                hash = (hash * mersenePrime) + this.VirtualAddress.GetHashCode();
            }

            return hash;
        }

        public static bool operator ==(IMAGE_SECTION_HEADER x, IMAGE_SECTION_HEADER y)
        {
            return x.Equals(y);
        }

        public static bool operator !=(IMAGE_SECTION_HEADER x, IMAGE_SECTION_HEADER y)
        {
            return !x.Equals(y);
        }
    }
}


<|start_filename|>src/WinApi.Console.Tests/ConsoleTests.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

#define NO_UNHANDLED_EXCEPTION
#define NO_CORRUPTED_STATE_EXCEPTION
#define NO_UNOBSERVED_TASK_EXCEPTION
#define NO_CATCH_EXCEPTION
#define NO_CATCH_TASK_EXCEPTION

using System;
using System.Collections;
using System.Diagnostics;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Threading.Tasks;

namespace WinApi.Console
{
    public static class ConsoleTests
    {
        [DebuggerStepThrough]
        [Conditional("UNOBSERVED_TASK_EXCEPTION")]
        [Conditional("CORRUPTED_STATE_EXCEPTION")]
        [Conditional("UNHANDLED_EXCEPTION")]
        [Conditional("DEBUG")]
        public static void RunTests()
        {
            bool useTasks = false;
            ShouldUseTasks(ref useTasks);

            if (useTasks)
            {
                TestUnsobservedTaskException();
            }
            else
            {
                TestCorruptedStateExceptions();
                TestUncatchedException();
            }
        }

        [DebuggerStepThrough]
        [Conditional("CATCH_EXCEPTION")]
        private static void ShouldCatchException(ref bool catchException)
        {
            catchException = true;
        }

        [DebuggerStepThrough]
        [Conditional("CATCH_TASK_EXCEPTION")]
        private static void ShouldCatchTaskException(ref bool catchTaskException)
        {
            catchTaskException = true;
        }

        [DebuggerStepThrough]
        [Conditional("UNOBSERVED_TASK_EXCEPTION")]
        private static void ShouldUseTasks(ref bool useTasks)
        {
            useTasks = true;
        }

        /// <summary>
        /// Here is the list of native Win32 exceptions that are considered CSEs on Structured
        /// Exception Handling (SEH) Exceptions:
        /// <list>
        /// <item>EXCEPTION_ACCESS_VIOLATION</item>
        /// <item>EXCEPTION_STACK_OVERFLOW</item>
        /// <item>EXCEPTION_ILLEGAL_INSTRUCTION</item>
        /// <item>EXCEPTION_IN_PAGE_ERROR</item>
        /// <item>EXCEPTION_INVALID_DISPOSITION</item>
        /// <item>EXCEPTION_NONCONTINUABLE_EXCEPTION</item>
        /// <item>EXCEPTION_PRIV_INSTRUCTION</item>
        /// <item>STATUS_UNWIND_CONSOLIDATE</item>
        /// </list>
        /// </summary>
        /// <remarks>
        /// The CLR converts most of these to a
        /// <see cref="SEHException"/> object. Except for
        /// EXCEPTION_ACCESS_VIOLATION, which is converted to a
        /// <see cref="AccessViolationException"/> object, and EXCEPTION_STACK_OVERFLOW, which
        /// is converted to a <see cref="StackOverflowException"/> object.
        /// </remarks>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "This method should not throw exceptions")]
        [HandleProcessCorruptedStateExceptions]
        [SecurityCritical]
        [DebuggerStepThrough]
        [Conditional("CORRUPTED_STATE_EXCEPTION")]
        private static void TestCorruptedStateExceptions()
        {
            bool catchException = false;
            ShouldCatchException(ref catchException);

            if (catchException)
            {
                try
                {
                    IntPtr ptr = new IntPtr(123);
                    Marshal.StructureToPtr(123, ptr, true);
                }
                catch (SEHException e)
                {
                    System.Console.Error.WriteLine($"\nSEHException: {e.ToString()}");
                }
                catch (AccessViolationException e)
                {
                    System.Console.Error.WriteLine($"\nAccessViolationException: {e.ToString()}");
                }
                catch (StackOverflowException e)
                {
                    System.Console.Error.WriteLine($"\nStackOverflowException: {e.ToString()}");
                }
                catch (Exception e)
                {
                    System.Console.Error.WriteLine($"\nProcessCorruptedStateException: {e.ToString()}");
                }
            }
            else
            {
                IntPtr ptr = new IntPtr(123);
                Marshal.StructureToPtr(123, ptr, true);
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "This method should not throw exceptions")]
        [HandleProcessCorruptedStateExceptions]
        [SecurityCritical]
        [DebuggerStepThrough]
        [Conditional("UNOBSERVED_TASK_EXCEPTION")]
        private static void TestTask(bool catchTaskException)
        {
            if (catchTaskException)
            {
                try
                {
                    TestCorruptedStateExceptions();
                    TestUncatchedException();
                }
                catch (Exception e)
                {
                    System.Console.Error.WriteLine($"\nInner ObservedTaskException: {e.ToString()}");
                }
            }
            else
            {
                TestCorruptedStateExceptions();
                TestUncatchedException();
            }
        }

        [DebuggerStepThrough]
        [Conditional("UNHANDLED_EXCEPTION")]
        private static void TestUncatchedException()
        {
            ArrayList nullTest = null;
            nullTest.Contains("null");
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "This method should not throw exceptions")]
        [HandleProcessCorruptedStateExceptions]
        [SecurityCritical]
        [DebuggerStepThrough]
        [Conditional("UNOBSERVED_TASK_EXCEPTION")]
        private static void TestUnsobservedTaskException()
        {
            bool catchException = false;
            ShouldCatchException(ref catchException);

            bool catchTaskException = false;
            ShouldCatchTaskException(ref catchTaskException);

            if (catchException || (catchException && catchTaskException))
            {
                try
                {
                    var t = Task.Run(() => TestTask(catchTaskException));
                }
                catch (Exception e)
                {
                    System.Console.Error.WriteLine($"\nObservedTaskException: {e.ToString()}");
                }
            }
            else
            {
                var t = Task.Run(() => TestTask(catchTaskException));
            }
        }
    }
}

<|start_filename|>src/WinApi.Shell/ITaskbarList3+THUMBBUTTONMASK.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;

namespace WinApi.Shell
{
    [Flags]
    internal enum THUMBBUTTONMASK
    {
        THB_BITMAP = 0x1,
        THB_ICON = 0x2,
        THB_TOOLTIP = 0x4,
        THB_FLAGS = 0x8
    }
}


<|start_filename|>src/WinApi.DisplayApi/DisplayApi.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using PInvoke;
using WinApi.Core;
using WinApi.User32;

using static PInvoke.User32;

namespace WinApi
{
    public class DisplayApi
    {
        // http://src.chromium.org/viewvc/chrome/trunk/src/ui/views/win/fullscreen_handler.cc?revision=HEAD&view=markup
        // void FullscreenHandler::SetFullscreenImpl(bool fullscreen, bool for_metro) {
        //   ScopedFullscreenVisibility visibility(hwnd_);
        // 
        //   // Save current window state if not already fullscreen.
        //   if (!fullscreen_) {
        //     // Save current window information.  We force the window into restored mode
        //     // before going fullscreen because Windows doesn't seem to hide the
        //     // taskbar if the window is in the maximized state.
        //     saved_window_info_.maximized = !!::IsZoomed(hwnd_);
        //     if (saved_window_info_.maximized)
        //       ::SendMessage(hwnd_, WM_SYSCOMMAND, SC_RESTORE, 0);
        //     saved_window_info_.style = GetWindowLong(hwnd_, GWL_STYLE);
        //     saved_window_info_.ex_style = GetWindowLong(hwnd_, GWL_EXSTYLE);
        //     GetWindowRect(hwnd_, &saved_window_info_.window_rect);
        //   }
        // 
        //   fullscreen_ = fullscreen;
        // 
        //   if (fullscreen_) {
        //     // Set new window style and size.
        //     SetWindowLong(hwnd_, GWL_STYLE,
        //                   saved_window_info_.style & ~(WS_CAPTION | WS_THICKFRAME));
        //     SetWindowLong(hwnd_, GWL_EXSTYLE,
        //                   saved_window_info_.ex_style & ~(WS_EX_DLGMODALFRAME |
        //                   WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));
        // 
        //     // On expand, if we're given a window_rect, grow to it, otherwise do
        //     // not resize.
        //     if (!for_metro) {
        //       MONITORINFO monitor_info;
        //       monitor_info.cbSize = sizeof(monitor_info);
        //       GetMonitorInfo(MonitorFromWindow(hwnd_, MONITOR_DEFAULTTONEAREST),
        //                      &monitor_info);
        //       gfx::Rect window_rect(monitor_info.rcMonitor);
        //       SetWindowPos(hwnd_, NULL, window_rect.x(), window_rect.y(),
        //                    window_rect.width(), window_rect.height(),
        //                    SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
        //     }
        //   } else {
        //     // Reset original window style and size.  The multiple window size/moves
        //     // here are ugly, but if SetWindowPos() doesn't redraw, the taskbar won't be
        //     // repainted.  Better-looking methods welcome.
        //     SetWindowLong(hwnd_, GWL_STYLE, saved_window_info_.style);
        //     SetWindowLong(hwnd_, GWL_EXSTYLE, saved_window_info_.ex_style);
        // 
        //     if (!for_metro) {
        //       // On restore, resize to the previous saved rect size.
        //       gfx::Rect new_rect(saved_window_info_.window_rect);
        //       SetWindowPos(hwnd_, NULL, new_rect.x(), new_rect.y(),
        //                    new_rect.width(), new_rect.height(),
        //                    SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
        //     }
        //     if (saved_window_info_.maximized)
        //       ::SendMessage(hwnd_, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
        //   }
        // }

        public static IntPtr CreateFullscreenWindow(string className, string windowName)
        {
            return CreateFullscreenWindow(IntPtr.Zero, className, windowName, IntPtr.Zero);
        }

        public static IntPtr CreateFullscreenWindow(IntPtr hwndParent, string className, string windowName)
        {
            return CreateFullscreenWindow(hwndParent, className, windowName, IntPtr.Zero);
        }

        public static unsafe IntPtr CreateFullscreenWindow(IntPtr hwndParent, string className, string windowName, IntPtr hInstance)
        {
            if (hInstance == IntPtr.Zero)
            {
                hInstance = Process.GetCurrentProcess().Handle;
            }

            if (hwndParent == IntPtr.Zero)
            {
                hwndParent = Process.GetCurrentProcess().MainWindowHandle;
            }

            var hmon = MonitorFromWindow(hwndParent, MonitorOptions.MONITOR_DEFAULTTONEAREST);
            var mi = new MONITORINFO();

            if (!GetMonitorInfo(hmon, new IntPtr(&mi)))
            {
                return IntPtr.Zero;
            }

            return CreateWindow(
                className,
                windowName,
                WindowStyles.WS_POPUP | WindowStyles.WS_VISIBLE,
                mi.rcMonitor.left,
                mi.rcMonitor.top,
                mi.rcMonitor.right - mi.rcMonitor.left,
                mi.rcMonitor.bottom - mi.rcMonitor.top,
                hwndParent,
                IntPtr.Zero,
                hInstance,
                IntPtr.Zero);
        }

        public static bool IsForegroundWindowFullScreen()
        {
            IntPtr hWnd;

            hWnd = GetForegroundWindow();

            return IsFullScreenWindow(hWnd);
        }

        public static bool IsFullScreenWindow(IntPtr hWnd)
        {
            var desktopHandle = GetDesktopWindow();
            var shellHandle = GetShellWindow();

            bool runningFullScreen = false;

            if (!hWnd.Equals(IntPtr.Zero))
            {
                if (!(hWnd.Equals(desktopHandle) || hWnd.Equals(shellHandle)))
                {
                    var appBounds = WindowApi.GetWindowRectangle(hWnd);

                    var screenBounds = Screen.FromHandle(hWnd).Bounds;

                    if (appBounds.ToRectangle() == screenBounds)
                    {
                        runningFullScreen = true;
                    }
                }
            }

            return runningFullScreen;
        }

        // you use Windows Presentation Foundation you'll need WindowInteropHelper to get Window
        // handle. Make sure you referenced PresentationFramework assembly. Insert this into Using
        // block using System.Windows.Interop; Create instance of WindowInteropHelper
        // WindowInteropHelper winHelp = new WindowInteropHelper(target); Then use winHelp.Handle
        // insted of GetActiveWindowHandle(). To bad that this cannot be resized out of the fixed
        // screen resolution size.
        public static void MoveWindowToMonitor(int monitor, IntPtr hwnd)
        {
            var windowRec = WindowApi.GetWindowRect(hwnd);

            // When I move a window to a different monitor it subtracts 16 from the Width and 38 from
            // the Height, Not sure if this is on my system or others.
            SetWindowPos(
                hwnd,
                SpecialWindowHandles.HWND_TOP,
                Screen.AllScreens[monitor].WorkingArea.Left,
                Screen.AllScreens[monitor].WorkingArea.Top,
                (windowRec.right - windowRec.left) + 16,
                (windowRec.bottom - windowRec.top) + 38,
                SetWindowPosFlags.SWP_SHOWWINDOW);
        }

        public Screen DetectScreen(IntPtr windowHandle)
        {
            // Figure out which screen the window is located on (in a multi screen setup)
            var appWindowBounds = WindowApi.GetWindowRectangle(windowHandle).ToRectangle();
            foreach (var screen in Screen.AllScreens)
            {
                // If the app is not fullscreen then the screen.bounds will contain the window if the
                // app is fullscreen then IT will actually contain the screen bounds
                if (screen.Bounds.Contains(appWindowBounds) ||
                    appWindowBounds.Contains(screen.Bounds))
                {
                    return screen;
                }
            }

            // By default use the primary screen
            return Screen.PrimaryScreen;
        }

        /// <summary>
        /// Returns the number of Displays using the Win32 functions
        /// </summary>
        /// <returns>collection of Display Info</returns>
        public unsafe List<DisplayInfo> GetDisplays()
        {
            var col = new List<DisplayInfo>();

            EnumDisplayMonitors(
                IntPtr.Zero,
                null,
                (IntPtr hMonitor, IntPtr hdcMonitor, RECT* lprcMonitor, void* dwData) =>
                {
                    var mi = new MONITORINFO();
                    mi.cbSize = Marshal.SizeOf(mi);
                    var success = GetMonitorInfo(hMonitor, new IntPtr(&mi));

                    if (success)
                    {
                        var di = new DisplayInfo();
                        di.ScreenWidth = (mi.rcMonitor.right - mi.rcMonitor.left).ToString();
                        di.ScreenHeight = (mi.rcMonitor.bottom - mi.rcMonitor.top).ToString();
                        di.MonitorArea = mi.rcMonitor;
                        di.WorkArea = mi.rcWork;
                        di.Availability = mi.dwFlags.ToString();
                        col.Add(di);
                    }

                    return true;
                },
                null);
            return col;
        }
    }
}

<|start_filename|>src/WinApi.User32/WindowMessage+Send.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using static PInvoke.User32;

namespace WinApi.User32
{
    public static partial class WindowMessage
    {
        public static class Send
        {
            /// <summary>
            /// Copies the text that corresponds to a window into a buffer provided by the caller.
            /// </summary>
            /// <param name="hwnd">The window or control handle</param>
            /// <param name="length">
            /// The maximum number of characters to be copied, including the terminating null character.
            /// ANSI applications may have the string in the buffer reduced in size (to a minimum of half that of the wParam value) due to conversion from ANSI to Unicode.
            /// </param>
            /// <returns>The string of the requested window or control</returns>
            /// <remarks>
            /// <para>
            /// The DefWindowProc function copies the text associated with the window into the specified buffer and returns the number of characters copied.
            /// Note, for non-text static controls this gives you the text with which the control was originally created, that is, the ID number.
            /// However, it gives you the ID of the non-text static control as originally created.
            /// That is, if you subsequently used a STM_SETIMAGE to change it the original ID would still be returned.
            /// </para>
            /// <para>
            /// For an edit control, the text to be copied is the content of the edit control.
            /// For a combo box, the text is the content of the edit control (or static-text) portion of the combo box.
            /// For a button, the text is the button name.
            /// For other windows, the text is the window title.
            /// To copy the text of an item in a list box, an application can use the LB_GETTEXT message.
            /// </para>
            /// <para>
            /// When the WM_GETTEXT message is sent to a static control with the SS_ICON style, a handle to the icon will be returned in the first four bytes of the buffer pointed to by lParam.
            /// This is true only if the WM_SETTEXT message has been used to set the icon.
            /// Rich Edit: If the text to be copied exceeds 64K, use either the EM_STREAMOUT or EM_GETSELTEXT message.
            /// </para>
            /// <para>
            /// Sending a WM_GETTEXT message to a non-text static control, such as a static bitmap or static icon control, does not return a string value.
            /// nstead, it returns zero.
            /// In addition, in early versions of Windows, applications could send a WM_GETTEXT message to a non-text static control to retrieve the control's ID.
            /// To retrieve a control's ID, applications can use GetWindowLong passing GWL_ID as the index value or GetWindowLongPtr using GWLP_ID.
            /// </para>
            /// </remarks>
            public static unsafe string WM_GETTEXT(IntPtr hwnd, int length = 256) // Any good enought value
            {
                if (length == 0)
                {
                    return string.Empty;
                }

                char* windowText = stackalloc char[length + 1];
                int capacity = length + 1;

                var result = SendMessage(hwnd, PInvoke.User32.WindowMessage.WM_GETTEXT, &capacity, windowText);

                if (result == IntPtr.Zero)
                {
                    return string.Empty;
                }

                return new string(windowText, 0, result.ToInt32());
            }

            /// <summary>
            /// Determines the length, in characters, of the text associated with a window.
            /// </summary>
            /// <param name="hwnd">The window or control handle</param>
            /// <returns>The return value is the length of the text in characters, not including the terminating null character.</returns>
            /// <remarks>
            /// <para>
            /// For an edit control, the text to be copied is the content of the edit control. For a combo box, the text is the content of the edit control (or static-text) portion of the combo box.
            /// For a button, the text is the button name. For other windows, the text is the window title. To determine the length of an item in a list box, an application can use the LB_GETTEXTLEN message.
            /// </para>
            /// <para>
            /// When the WM_GETTEXTLENGTH message is sent, the DefWindowProc function returns the length, in characters, of the text.
            /// Under certain conditions, the DefWindowProc function returns a value that is larger than the actual length of the text. This occurs with certain mixtures of ANSI and Unicode,
            /// and is due to the system allowing for the possible existence of double-byte character set (DBCS) characters within the text. The return value, however,
            /// will always be at least as large as the actual length of the text; you can thus always use it to guide buffer allocation.
            /// This behavior can occur when an application uses both ANSI functions and common dialogs, which use Unicode.
            /// </para>
            /// <para>
            /// To obtain the exact length of the text, use the <see cref="WM_GETTEXT"/>, LB_GETTEXT, or CB_GETLBTEXT messages, or the GetWindowText function.
            /// </para>
            /// <para>
            /// Sending a WM_GETTEXTLENGTH message to a non-text static control, such as a static bitmap or static icon controlc, does not return a string value. Instead, it returns zero.
            /// </para>
            /// </remarks>
            public static int WM_GETTEXTLENGTH(IntPtr hwnd)
            {
                return SendMessage(hwnd, PInvoke.User32.WindowMessage.WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero).ToInt32();
            }
        }
    }
}

<|start_filename|>src/Sandbox/DisplayApi/QueryDisplayConfig.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System.Runtime.InteropServices;

namespace Sandbox
{
    public enum D3DKMDT_VIDEO_SIGNAL_STANDARD
    {
        // D3DKMDT_VSS_UNINITIALIZED -> 0
        D3DKMDT_VSS_UNINITIALIZED = 0,

        // D3DKMDT_VSS_VESA_DMT -> 1
        D3DKMDT_VSS_VESA_DMT = 1,

        // D3DKMDT_VSS_VESA_GTF -> 2
        D3DKMDT_VSS_VESA_GTF = 2,

        // D3DKMDT_VSS_VESA_CVT -> 3
        D3DKMDT_VSS_VESA_CVT = 3,

        // D3DKMDT_VSS_IBM -> 4
        D3DKMDT_VSS_IBM = 4,

        // D3DKMDT_VSS_APPLE -> 5
        D3DKMDT_VSS_APPLE = 5,

        // D3DKMDT_VSS_NTSC_M -> 6
        D3DKMDT_VSS_NTSC_M = 6,

        // D3DKMDT_VSS_NTSC_J -> 7
        D3DKMDT_VSS_NTSC_J = 7,

        // D3DKMDT_VSS_NTSC_443 -> 8
        D3DKMDT_VSS_NTSC_443 = 8,

        // D3DKMDT_VSS_PAL_B -> 9
        D3DKMDT_VSS_PAL_B = 9,

        // D3DKMDT_VSS_PAL_B1 -> 10
        D3DKMDT_VSS_PAL_B1 = 10,

        // D3DKMDT_VSS_PAL_G -> 11
        D3DKMDT_VSS_PAL_G = 11,

        // D3DKMDT_VSS_PAL_H -> 12
        D3DKMDT_VSS_PAL_H = 12,

        // D3DKMDT_VSS_PAL_I -> 13
        D3DKMDT_VSS_PAL_I = 13,

        // D3DKMDT_VSS_PAL_D -> 14
        D3DKMDT_VSS_PAL_D = 14,

        // D3DKMDT_VSS_PAL_N -> 15
        D3DKMDT_VSS_PAL_N = 15,

        // D3DKMDT_VSS_PAL_NC -> 16
        D3DKMDT_VSS_PAL_NC = 16,

        // D3DKMDT_VSS_SECAM_B -> 17
        D3DKMDT_VSS_SECAM_B = 17,

        // D3DKMDT_VSS_SECAM_D -> 18
        D3DKMDT_VSS_SECAM_D = 18,

        // D3DKMDT_VSS_SECAM_G -> 19
        D3DKMDT_VSS_SECAM_G = 19,

        // D3DKMDT_VSS_SECAM_H -> 20
        D3DKMDT_VSS_SECAM_H = 20,

        // D3DKMDT_VSS_SECAM_K -> 21
        D3DKMDT_VSS_SECAM_K = 21,

        // D3DKMDT_VSS_SECAM_K1 -> 22
        D3DKMDT_VSS_SECAM_K1 = 22,

        // D3DKMDT_VSS_SECAM_L -> 23
        D3DKMDT_VSS_SECAM_L = 23,

        // D3DKMDT_VSS_SECAM_L1 -> 24
        D3DKMDT_VSS_SECAM_L1 = 24,

        // D3DKMDT_VSS_EIA_861 -> 25
        D3DKMDT_VSS_EIA_861 = 25,

        // D3DKMDT_VSS_EIA_861A -> 26
        D3DKMDT_VSS_EIA_861A = 26,

        // D3DKMDT_VSS_EIA_861B -> 27
        D3DKMDT_VSS_EIA_861B = 27,

        // D3DKMDT_VSS_PAL_K -> 28
        D3DKMDT_VSS_PAL_K = 28,

        // D3DKMDT_VSS_PAL_K1 -> 29
        D3DKMDT_VSS_PAL_K1 = 29,

        // D3DKMDT_VSS_PAL_L -> 30
        D3DKMDT_VSS_PAL_L = 30,

        // D3DKMDT_VSS_PAL_M -> 31
        D3DKMDT_VSS_PAL_M = 31,

        // D3DKMDT_VSS_OTHER -> 255
        D3DKMDT_VSS_OTHER = 255,
    }   
       
}

<|start_filename|>src/WinApi.Console/ConsoleExtensions.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System.Diagnostics;

namespace WinApi.Console
{
    public static class ConsoleExtensions
    {
        public static void WaitIfDebugging(string message)
        {
            var parentProcess = Process.GetCurrentProcess().Parent();

            if ((parentProcess != null && parentProcess.ProcessName != "cmd") ||
                Debugger.IsAttached)
            {
                System.Console.Out.WriteLine(message);
                System.Console.ReadKey();
            }
        }

        public static void WaitIfNotDebugging(string message)
        {
            var parentProcess = Process.GetCurrentProcess().Parent();

            if ((parentProcess != null && parentProcess.ProcessName == "cmd") &&
                !Debugger.IsAttached)
            {
                System.Console.Out.WriteLine(message);
                System.Console.ReadKey();
            }
        }
    }
}


<|start_filename|>src/WinApi.Console/NativeAPI.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System.Runtime.InteropServices;

namespace WinApi.Console
{
    internal static class NativeAPI
    {
        /// _CALL_REPORTFAULT -> 0x2
        public const int _CALL_REPORTFAULT = 2;

        /// _ONEXIT_T_DEFINED ->
        /// Error generating expression: Der Wert darf nicht NULL sein.
        ///Parametername: node
        public const string _ONEXIT_T_DEFINED = "";

        /// _WRITE_ABORT_MSG -> 0x1
        public const int _WRITE_ABORT_MSG = 1;

        /// CREATE_NEW_CONSOLE -> 0x00000010
        public const int CREATE_NEW_CONSOLE = 16;

        /// EVENT_CONSOLE_CARET -> 0x4001
        public const int EVENT_CONSOLE_CARET = 16385;

        /// EVENT_CONSOLE_LAYOUT -> 0x4005
        public const int EVENT_CONSOLE_LAYOUT = 16389;

        /// EVENT_CONSOLE_START_APPLICATION -> 0x4006
        public const int EVENT_CONSOLE_START_APPLICATION = 16390;

        /// EVENT_CONSOLE_UPDATE_REGION -> 0x4002
        public const int EVENT_CONSOLE_UPDATE_REGION = 16386;

        /// EVENT_CONSOLE_UPDATE_SCROLL -> 0x4004
        public const int EVENT_CONSOLE_UPDATE_SCROLL = 16388;

        /// EVENT_CONSOLE_UPDATE_SIMPLE -> 0x4003
        public const int EVENT_CONSOLE_UPDATE_SIMPLE = 16387;

        /// SEE_MASK_NO_CONSOLE -> 0x00008000
        public const int SEE_MASK_NO_CONSOLE = 32768;

        /// Return Type: int
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate int _onexit_t();

        /// Return Type: void
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate void atexit_function();

        /// Return Type: int
        ///param0: Anonymous_a3debd67_ecba_49a0_9c67_1b83f463a375
        [DllImport("msvcr80.dll", EntryPoint = "atexit", CallingConvention = CallingConvention.Cdecl)]
        public static extern int atexit(atexit_function param0);

        /// Return Type: terminate_function
        [DllImport("msvcr80.dll", EntryPoint = "_get_terminate")]
        public static extern terminate_function _get_terminate();

        /// Return Type: unexpected_function
        [DllImport("msvcr80.dll", EntryPoint = "_get_unexpected")]
        public static extern unexpected_function _get_unexpected();

        /// Return Type: _onexit_t
        ///_Func: _onexit_t
        [DllImport("msvcr80.dll", EntryPoint = "_onexit", CallingConvention = CallingConvention.Cdecl)]
        public static extern _onexit_t _onexit(_onexit_t _Func);

        /// Return Type: unsigned int
        ///_Flags: unsigned int
        ///_Mask: unsigned int
        [DllImport("msvcr80.dll", EntryPoint = "_set_abort_behavior", CallingConvention = CallingConvention.Cdecl)]
        public static extern uint _set_abort_behavior(uint _Flags, uint _Mask);

        /// Return Type: void
        ///param0: terminate_function
        [DllImport("msvcr80.dll", EntryPoint = "set_terminate", CallingConvention = CallingConvention.Cdecl)]
        public static extern void set_terminate(terminate_function param0);

        /// Return Type: void
        ///param0: int
        [DllImport("msvcr80.dll", EntryPoint = "set_unexpected", CallingConvention = CallingConvention.Cdecl)]
        public static extern void set_unexpected(int param0);

        /// Return Type: int
        ///sig: int
        ///param1: signal_function
        [DllImport("msvcr80.dll", EntryPoint = "signal", CallingConvention = CallingConvention.Cdecl)]
        private static extern int signal(int sig, signal_function param1);

        /// Return Type: void
        ///param0: int[]
        public delegate void signal_function(int[] param0);

        /// Return Type: void
        public delegate void terminate_function();

        /// Return Type: void
        public delegate void unexpected_function();
    }
}


<|start_filename|>src/WinApi.Shell/Taskbar.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.InteropServices;
using PInvoke;

namespace WinApi.Shell
{
    /// <summary>
    /// Implements ITaskbarList1, ITaskbarList2, ITaskbarList3, ITaskbarList4  by exposing methods that support the 
    /// unified launching and switching taskbar button functionality added in Windows 7. 
    /// This functionality includes thumbnail representations and switch targets based on individual tabs in a tabbed application,
    /// thumbnail toolbars, notification and status overlays, and progress indicators.
    /// </summary>
    public class Taskbar : IDisposable
    {
        private const string WM_TASKBARBUTTONCREATED = "TaskbarButtonCreated";
        private ITaskbarList4 taskbarInstance;
        private static bool isCapturingMessages;
        private static int taskbarButtonCreated = -1;

        private static readonly bool taskbarSupported;

        public static int TaskbarButtonCreatedMessage => taskbarButtonCreated;

        public static bool TaskbarSupported => taskbarSupported;

        static Taskbar()
        {
            taskbarSupported = Environment.OSVersion.Version >= new Version(6, 1);

            if (taskbarSupported)
            {
                try
                {
                    taskbarButtonCreated = User32.RegisterWindowMessage(WM_TASKBARBUTTONCREATED);
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Trace.TraceError(ex.Message);
                }
            }
        }

        public Taskbar(IntPtr hwnd)
        {
            if (taskbarSupported && !isCapturingMessages)
            {
                try
                {
                    var filter = CHANGEFILTERSTRUCT.Create();

                    if (!NativeMethods.ChangeWindowMessageFilterEx(hwnd, (User32.WindowMessage)taskbarButtonCreated, MSGFLT.ALLOW, ref filter))
                    {
                        Kernel32.GetLastError().ThrowOnError();
                    }

                    isCapturingMessages = true;
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Trace.TraceError(ex.Message);
                }
            }
        }

        /// <summary>
        /// Increments the RCW reference count
        /// </summary>
        /// <typeparam name="T">The RCW type</typeparam>
        /// <param name="t">The RCW to be released</param>
        /// <returns>An instance of the RCW object, from the proper IUnknown interface</returns>
        private static T AddRcwRef<T>(T t)
        {
            IntPtr ptr = IntPtr.Zero;
            try
            {
                ptr = Marshal.GetIUnknownForObject(t);
                return (T)Marshal.GetObjectForIUnknown(ptr);
            }
            finally
            {
                if (ptr != IntPtr.Zero)
                {
                    Marshal.Release(ptr);
                }
            }
        }


        /// <summary>
        /// Releases the RCW decrementing the reference count, this method lets the finalizer do the work
        /// </summary>
        /// <typeparam name="T">The RCW type</typeparam>
        /// <param name="t">The RCW to be released</param>
        /// <remarks>If the object in question is an argument to a function the call stack will have a reference and this won’t work</remarks>
        private static void ReleaseRcw<T>(ref T t)
        {
            t = default(T);
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }

        public void Initialize()
        {
            if (taskbarSupported && taskbarInstance == null)
            {
                try
                {
                    taskbarInstance = (ITaskbarList4)new TaskbarInstance();
                    taskbarInstance.HrInit().ThrowOnFailure();
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Trace.TraceError(ex.Message);

                    taskbarInstance = null;
                }
            }
        }

        public void WndProcCall(ref User32.MSG msg)
        {
            if (msg.message == (User32.WindowMessage)taskbarButtonCreated)
            {
                Initialize();
            }
        }

        public void SetState(IntPtr windowHandle, TaskbarState taskbarState)
        {
            if (taskbarSupported)
            {
                taskbarInstance?.SetProgressState(windowHandle, (TBPFLAG)taskbarState);
            }
        }

        public void SetValue(IntPtr windowHandle, ulong progressValue, ulong progressMax)
        {
            if (taskbarSupported)
            {
                taskbarInstance?.SetProgressValue(windowHandle, progressValue, progressMax);
            }
        }

        public void SetOverlayIcon(IntPtr hwnd, Icon icon, string description)
        {
            if (taskbarSupported)
            {
                taskbarInstance?.SetOverlayIcon(hwnd, icon.Handle, description);
            }
        }

        public void SetOverlayIcon(IntPtr hwnd, Bitmap icon, string description)
        {
            if (taskbarSupported)
            {
                taskbarInstance?.SetOverlayIcon(hwnd, icon.GetHicon(), description);
            }
        }

        public void SetThumbnailClip(IntPtr hwnd, int x, int y, int width, int height)
        {
            if (taskbarSupported)
            {
                var rect = new RECT { left = x, top = y, right = x + width, bottom = y + height };
                taskbarInstance?.SetThumbnailClip(hwnd, ref rect);
            }
        }

        public void SetThumbnailToolTip(IntPtr hwnd, string tip)
        {
            if (taskbarSupported)
            {
                taskbarInstance?.SetThumbnailTooltip(hwnd, tip);
            }
        }

        public void UpdateThumbnailButtons(IntPtr hwnd, params ThumbnailButton[] buttons)
        {
            if (taskbarSupported)
            {
                var comButtons = new List<THUMBBUTTON>();
                foreach (ThumbnailButton button in buttons)
                {
                    comButtons.Add(button.ToTHUMBBUTTON());
                }

                var result = taskbarInstance?.ThumbBarUpdateButtons(hwnd, (uint)buttons.Length, comButtons.ToArray()) ?? HResult.Code.E_FAIL;

                if (result.Failed)
                {
                    throw new COMException("Cannot update thumb button: " + result.ToString());
                }
            }
        }

        public void AddThumbnailButtons(IntPtr hwnd, params ThumbnailButton[] buttons)
        {
            if (taskbarSupported)
            {
                var comButtons = new List<THUMBBUTTON>();
                foreach (ThumbnailButton button in buttons)
                {
                    comButtons.Add(button.ToTHUMBBUTTON());
                }

                var result = taskbarInstance?.ThumbBarAddButtons(hwnd, (uint)buttons.Length, comButtons.ToArray()) ?? HResult.Code.E_FAIL;

                if (result.Failed)
                {
                    throw new COMException("Cannot add thumb button: " + result.ToString());
                }
            }
        }

        public void Dispose()
        {
            if (taskbarInstance != null)
            {
                Marshal.ReleaseComObject(taskbarInstance);
                taskbarInstance = null;
            }
        }

        [ComImport]
        [Guid("56FDF344-FD6D-11D0-958A-006097C9A090")]
        [ClassInterface(ClassInterfaceType.None)]
        private class TaskbarInstance
        {
        }
    }
}

<|start_filename|>src/Sandbox/DisplayApi/MinimizedMetricsArrangement.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;

namespace Sandbox
{
    [Flags]
    public enum MinimizedMetricsArrangement
    {
        BottomLeft = 0,
        BottomRight = 1,
        TopLeft = 2,
        TopRight = 3,
        Left = 0,
        Right = 0,
        Up = 4,
        Down = 4,
        Hide = 8
    }
}

<|start_filename|>src/WinApi.Console/ConsoleLogger.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using System.IO;

namespace WinApi.Console
{
    public sealed class ConsoleLogger : IDisposable
    {
        /// <summary>
        /// Implements IDisposable so we implement IDisposable, too!
        /// </summary>
        private readonly StreamWriter writer;

        /// <summary>
        /// Creates a new instance of Logger.
        /// </summary>
        /// <param name="fileName">File to log to.</param>
        public ConsoleLogger(string fileName)
        {
            writer = new StreamWriter(fileName);
        }

        /// <summary>
        /// Dispose / close this instance.
        /// </summary>
        public void Close()
        {
            Dispose();
        }

        /// <summary>
        /// Dispose / close this instance.
        /// </summary>
        public void Dispose()
        {
            writer.Close();
        }
    }
}

<|start_filename|>src/WinApi.Shell/TaskbarStates.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

namespace WinApi.Shell
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1027:MarkEnumsWithFlags", Justification = "These are not flags")]
    public enum TaskbarState
    {
        NoProgress = 0,
        Indeterminate = 0x1,
        Normal = 0x2,
        Error = 0x4,
        Paused = 0x8
    }
}


<|start_filename|>src/WinApi.PeCoff/IMAGE_OPTIONAL_HEADER.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

namespace WinApi.PeCoff
{
    public struct IMAGE_OPTIONAL_HEADER32
    {
        public uint AddressOfEntryPoint;
        public uint BaseOfCode;
        public uint BaseOfData;
        public uint Checksum;
        public ushort DllCharacteristics;
        public uint FileAlignment;
        public uint ImageBase;
        public uint LoaderConfig;
        public ushort Magic;
        public ushort MajorImageVersion;
        public byte MajorLinkerVersion;
        public ushort MajorOperatingSystemVersion;
        public ushort MajorSubsystemVersion;
        public ushort MinorImageVersion;
        public byte MinorLinkerVersion;
        public ushort MinorOperatingSystemVersion;
        public ushort MinorSubsystemVersion;
        public uint NumberOfRvaAndSizes;
        public uint SectionAlignment;
        public uint SizeOfCode;
        public uint SizeOfHeaders;
        public uint SizeOfHeapCommit;
        public uint SizeOfHeapReserve;
        public uint SizeOfImage;
        public uint SizeOfInitializedData;
        public uint SizeOfStackCommit;
        public uint SizeOfStackReserve;
        public uint SizeOfUninitializedData;
        public ushort Subsystem;
        public uint Win32VersionValue;
    }

}


<|start_filename|>src/WinApi.Shell/NativeMethods.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using System.Runtime.InteropServices;
using PInvoke;

namespace WinApi.Shell
{
    internal static class NativeMethods
    {
        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool ChangeWindowMessageFilterEx(
            IntPtr hwnd,
            User32.WindowMessage message,
            MSGFLT action,
            /*[In, Out, Optional]*/ ref CHANGEFILTERSTRUCT pChangeFilterStruct);
    }
}


<|start_filename|>src/Sandbox/DisplayApi/PrintData.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System.Runtime.InteropServices;

namespace Sandbox
{
    [StructLayout(LayoutKind.Sequential)]
    public struct PrintData
    {
        // short
        public short dmOrientation;

        // short
        public short dmPaperSize;

        // short
        public short dmPaperLength;

        // short
        public short dmPaperWidth;

        // short
        public short dmScale;

        // short
        public short dmCopies;

        // short
        public short dmDefaultSource;

        // short
        public short dmPrintQuality;
    }
}

<|start_filename|>src/WinApi.WindowStationApi/DesktopExtensions.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using System.Runtime.InteropServices;
using PInvoke;

namespace WinApi.WindowStationApi
{
    public static class DesktopExtensions
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "The user should dispose the handle when appropriate")]
        public static unsafe User32.SafeDesktopHandle CreateDesktop(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentException("Invalid desktop station name", nameof(name));
            }

            var access = (uint)Kernel32.ACCESS_MASK.DesktopSpecificRight.DESKTOP_ALL_ACCESS;
            var handle = User32.CreateDesktop(name, null, IntPtr.Zero, User32.DesktopCreationFlags.None, access, (Kernel32.SECURITY_ATTRIBUTES*)null);
            var error = Marshal.GetLastWin32Error();

            if (handle.IsInvalid)
            {
                throw new Win32Exception(error);
            }

            return handle;
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "The user should dispose the handle when appropriate")]
        public static unsafe User32.SafeWindowStationHandle CreateWindowStation(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentException("Invalid window station name", nameof(name));
            }

            var access = (uint)Kernel32.ACCESS_MASK.WindowStationSpecificRight.WINSTA_ALL_ACCESS;
            var handle = User32.CreateWindowStation(name, User32.WindowStationCreationFlags.None, access, (Kernel32.SECURITY_ATTRIBUTES*)null);
            var error = Marshal.GetLastWin32Error();

            if (handle.IsInvalid)
            {
                throw new Win32Exception(error);
            }

            return handle;
        }

        public static unsafe int GetDesktopHeapSize(User32.SafeDesktopHandle desktop)
        {
            if (desktop == null)
            {
                throw new ArgumentNullException(nameof(desktop));
            }

            if (desktop.IsInvalid)
            {
                throw new ArgumentException("Handle should not be invalid", nameof(desktop));
            }

            ulong heapSize = 0;
            uint capacity = sizeof(ulong);

            bool success = false;
            bool result = false;

            try
            {
                desktop.DangerousAddRef(ref success);

                result = User32.GetUserObjectInformation(desktop.DangerousGetHandle(), User32.ObjectInformationType.UOI_HEAPSIZE, &heapSize, capacity, &capacity);
            }
            finally
            {
                if (success)
                {
                    desktop.DangerousRelease();
                }
            }

            if (result)
            {
                return unchecked((int)heapSize);
            }

            return -1;
        }

        public static unsafe string GetUserObjectName(User32.SafeDesktopHandle desktop)
        {
            if (desktop == null)
            {
                throw new ArgumentNullException(nameof(desktop));
            }

            if (desktop.IsInvalid)
            {
                throw new ArgumentException("Handle should not be invalid", nameof(desktop));
            }

            if (desktop.IsClosed)
            {
                throw new ArgumentException("Handle should not be closed", nameof(desktop));
            }

            bool success = false;
            string result = null;

            try
            {
                desktop.DangerousAddRef(ref success);

                result = GetUserObjectName(desktop.DangerousGetHandle());
            }
            finally
            {
                if (success)
                {
                    desktop.DangerousRelease();
                }
            }

            return result;
        }

        public static unsafe string GetUserObjectName(User32.SafeWindowStationHandle winsta)
        {
            if (winsta == null)
            {
                throw new ArgumentNullException(nameof(winsta));
            }

            if (winsta.IsInvalid)
            {
                throw new ArgumentException("Handle should not be invalid", nameof(winsta));
            }

            if (winsta.IsClosed)
            {
                throw new ArgumentException("Handle should not be closed", nameof(winsta));
            }

            bool success = false;
            string result = null;

            try
            {
                winsta.DangerousAddRef(ref success);

                result = GetUserObjectName(winsta.DangerousGetHandle());
            }
            finally
            {
                if (success)
                {
                    winsta.DangerousRelease();
                }
            }

            return result;
        }

        public static unsafe string GetUserObjectName(IntPtr handle)
        {
            char* text = stackalloc char[1025];
            uint capacity = 1025;

            if (User32.GetUserObjectInformation(handle, User32.ObjectInformationType.UOI_NAME, text, capacity, &capacity))
            {
                return new string(text, 0, unchecked((int)capacity)).Replace("\0", "");
            }

            return string.Empty;
        }

        public static unsafe string GetUserObjectType(User32.SafeDesktopHandle desktop)
        {
            if (desktop == null)
            {
                throw new ArgumentNullException(nameof(desktop));
            }

            if (desktop.IsInvalid)
            {
                throw new ArgumentException("Handle should not be invalid", nameof(desktop));
            }

            if (desktop.IsClosed)
            {
                throw new ArgumentException("Handle should not be closed", nameof(desktop));
            }

            bool success = false;
            string result = null;

            try
            {
                desktop.DangerousAddRef(ref success);

                result = GetUserObjectType(desktop.DangerousGetHandle());
            }
            finally
            {
                if (success)
                {
                    desktop.DangerousRelease();
                }
            }

            return result;
        }

        public static unsafe string GetUserObjectType(User32.SafeWindowStationHandle winsta)
        {
            if (winsta == null)
            {
                throw new ArgumentNullException(nameof(winsta));
            }

            if (winsta.IsInvalid)
            {
                throw new ArgumentException("Handle should not be invalid", nameof(winsta));
            }

            if (winsta.IsClosed)
            {
                throw new ArgumentException("Handle should not be closed", nameof(winsta));
            }

            bool success = false;
            string result = null;

            try
            {
                winsta.DangerousAddRef(ref success);

                result = GetUserObjectType(winsta.DangerousGetHandle());
            }
            finally
            {
                if (success)
                {
                    winsta.DangerousRelease();
                }
            }

            return result;
        }

        public static unsafe string GetUserObjectType(IntPtr handle)
        {
            char* text = stackalloc char[1025];
            uint capacity = 1025;

            if (User32.GetUserObjectInformation(handle, User32.ObjectInformationType.UOI_TYPE, text, capacity, &capacity))
            {
                return new string(text, 0, unchecked((int)capacity)).Replace("\0", "");
            }

            return string.Empty;
        }

        public static unsafe bool HasDesktopInput(User32.SafeDesktopHandle desktop)
        {
            if (desktop == null)
            {
                throw new ArgumentNullException(nameof(desktop));
            }

            if (desktop.IsInvalid)
            {
                throw new ArgumentException("Handle should not be invalid", nameof(desktop));
            }

            if (desktop.IsClosed)
            {
                throw new ArgumentException("Handle should not be closed", nameof(desktop));
            }

            bool hasInput = false;
            uint capacity = sizeof(bool);
            bool success = false;

            try
            {
                desktop.DangerousAddRef(ref success);

                hasInput = User32.GetUserObjectInformation(desktop.DangerousGetHandle(), User32.ObjectInformationType.UOI_IO, &hasInput, unchecked(capacity), &capacity);
            }
            finally
            {
                if (success)
                {
                    desktop.DangerousRelease();
                }
            }

            return false;
        }
    }
}

<|start_filename|>src/WinApi.HighDpi/DpiAwareApi.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;
using System.Linq;
using Microsoft.Win32;
using PInvoke;

namespace WinApi.HighDpi
{
    public static class DpiAwareApi
    {
        private const string HKCU_CONTROL_PANEL_DESKTOP_DESKTOP_DPI_OVERRIDE = @"Control Panel\Desktop\DesktopDPIOverride";
        private const string HKCU_CONTROL_PANEL_DESKTOP_LOGPIXELS = @"Control Panel\Desktop\LogPixels";
        private const string HKCU_CONTROL_PANEL_DESKTOP_WIN8_DPI_SCALING = @"Control Panel\Desktop\Win8DpiScaling";

        /// <summary>
        /// <para>
        /// Checks if the Control Panel\Appearance and Personalization\Display user interface (UI) includes a checkbox: "Let me choose one scaling level for all my displays" is disabled,
        /// and gets the scaling factor the user provided to override the current scale factors, from Smaller, to Medium, to Larger.
        /// </para>
        /// <para>
        /// Possible values are:
        /// <list>
        /// <item>Key value &lt; 0, Meaning: Reduce each display scale factor from the default by this value (for example, if the default was 150% scaling, -1 corresponds to 125%, -2 to 100%).</item>
        /// <item>Key value = 0, Meaning: Use the default value for each display.</item>
        /// <item>Key value &gt; 0, Meaning: Increase each display factor by this value (using the previous example, +1 corresponds to 200% scaling).</item>
        /// </list>
        /// </para>
        /// </summary>
        /// <remarks>
        /// All display scale factors in this mode are constrained to be one of these four values: 100%, 125%, 150%, 200%. In addition, after scaling is applied,
        /// applications expect to have at least 720 effective lines of resolution (that is, the physical vertical resolution of the display divided by the scale factor);
        /// this can further limit the range of allowed display scale factors.
        /// </remarks>
        public static int DesktopDPIOverride
        {
            get
            {
                if (Win8DpiScaling)
                {
                    return 0;
                }

                // Key value &lt; 0, Meaning: Reduce each display scale factor from the default by this value (for example, if the default was 150% scaling, -1 corresponds to 125%, -2 to 100%).
                // Key value = 0, Meaning: Use the default value for each display.
                // Key value &gt; 0, Meaning: Increase each display factor by this value (using the previous example, +1 corresponds to 200% scaling).
                return Registry.CurrentUser.GetValue<int>(HKCU_CONTROL_PANEL_DESKTOP_DESKTOP_DPI_OVERRIDE);
            }
        }

        /// <summary>
        /// <para>
        /// Checks if the Control Panel\Appearance and Personalization\Display user interface (UI) includes a checkbox: "Let me choose one scaling level for all my displays" is disabled,
        /// and gets the scaling factor the user provided to override the current scale factors, from Smaller, to Medium, to Larger.
        /// </para>
        /// </summary>
        /// <remarks>
        /// All display scale factors in this mode are constrained to be one of these four values: 100%, 125%, 150%, 200%. In addition, after scaling is applied,
        /// applications expect to have at least 720 effective lines of resolution (that is, the physical vertical resolution of the display divided by the scale factor);
        /// this can further limit the range of allowed display scale factors.
        /// </remarks>
        public static ScaleFactor DesktopDPIOverrideScaleFactor
        {
            get
            {
                var possibleValues = Enum.GetValues(typeof(ScaleFactor)).Cast<ScaleFactor>().ToArray();
                var defaultValue = 0;

                return possibleValues[defaultValue + DesktopDPIOverride];
            }
        }

        /// <summary>
        /// Checks if the Windows version is Vista (Windows Server 2008) or higher.
        /// </summary>
        public static bool HasDpiSupport
        {
            get
            {
                var version = Environment.OSVersion.Version;
                return ((version.Major * 1000) + version.Minor) >= 6000; // Windows Vista or Windows Server 2008: 6.0
            }
        }

        /// <summary>
        /// Checks if the Windows version is 8.1 (Windows Server 2012 R2) or higher.
        /// </summary>
        public static bool HasPerMonitorDpiSupport
        {
            get
            {
                var version = Environment.OSVersion.Version;
                var result = ((version.Major * 1000) + version.Minor) >= 6003; // Windows 8.1 or Windows Server 2012 R2: 6.3

                return result;
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Properties should not throw exceptions")]
        public static Dpi SystemDPI
        {
            get
            {
                var dpi = Dpi.Default;
                var desktopDC = User32.SafeDCHandle.Null;

                try
                {
                    desktopDC = User32.GetDC(IntPtr.Zero);

                    if (!desktopDC.IsInvalid)
                    {
                        dpi.X = Gdi32.GetDeviceCaps(desktopDC, Gdi32.DeviceCap.LOGPIXELSX);
                        dpi.Y = Gdi32.GetDeviceCaps(desktopDC, Gdi32.DeviceCap.LOGPIXELSY);
                    }
                }
#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
                catch
#pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body
                {
                }
                finally
                {
                    if (!desktopDC.IsInvalid)
                    {
                        desktopDC.Dispose();
                    }
                }

                return dpi;
            }
        }

        /// <summary>
        /// When the Let me choose one scaling level for all my displays checkbox is checked, the user can specify a scale factor that applies to all displays,
        /// regardless of each display’s pixel density. By using the custom setting, the user can select values other than 100%, 125%, 150%, 200%,
        /// although they are limited to the range (100%-500%).
        /// It will return zero (0) if the setting is not there.
        /// </summary>
        public static int SystemWideScaleFactor
        {
            get
            {
                if (Win8DpiScaling)
                {
                    var scaleFactor = Registry.CurrentUser.GetValue<int>(HKCU_CONTROL_PANEL_DESKTOP_LOGPIXELS);
                    return scaleFactor / 96;
                }

                return 0;
            }
        }

        /// <summary>
        /// Checks if the Control Panel\Appearance and Personalization\Display user interface (UI) includes a checkbox: "Let me choose one scaling level for all my displays" is enabled.
        /// </summary>
        /// <remarks>
        /// It controls whether the system applies a single scale factor to all displays (as in Windows® 8 and earlier versions of Windows),
        /// or different scale factors that take into account the pixel density of each display (the Windows 8.1 default).
        /// </remarks>
        public static bool Win8DpiScaling
        {
            get
            {
                // Key value = 0, Meaning: Different scale factors for each display: Windows 8.1 default.Content that is moved from one display to another will be the right size, but can be bitmap - scaled.
                // Key value = 1, Meaning: Same scale factor is applied to all displays: Windows 8 and earlier Windows versions behavior.Content that is moved from one display to another might be the wrong size
                return Registry.CurrentUser.GetValue<int>(HKCU_CONTROL_PANEL_DESKTOP_WIN8_DPI_SCALING) == 1;
            }
        }

        public static Dpi GetDpiForMonitor(IntPtr hwndMonitor, MONITOR_DPI_TYPE dpiType = MONITOR_DPI_TYPE.MDT_DEFAULT)
        {
            if (!HasPerMonitorDpiSupport || hwndMonitor == IntPtr.Zero)
            {
                if (HasDpiSupport)
                {
                    return SystemDPI;
                }
                else
                {
                    return Dpi.Default;
                }
            }

            int dpiX = 96;
            int dpiY = 96;
            if (SHCore.GetDpiForMonitor(hwndMonitor, dpiType, out dpiX, out dpiY).Failed)
            {
                return Dpi.Default;
            }

            return new Dpi(dpiX, dpiY);
        }

        public static Dpi GetDpiForWindow(IntPtr hwnd, MONITOR_DPI_TYPE dpiType = MONITOR_DPI_TYPE.MDT_DEFAULT)
        {
            if (!HasPerMonitorDpiSupport || hwnd == IntPtr.Zero)
            {
                if (HasDpiSupport)
                {
                    return SystemDPI;
                }
                else
                {
                    return Dpi.Default;
                }
            }

            var monitor = User32.MonitorFromWindow(hwnd, User32.MonitorOptions.MONITOR_DEFAULTTONEAREST);

            return GetDpiForMonitor(monitor, dpiType);
        }

        /// <summary>
        /// Retrieves the dots per inch (dpi) awareness of the specified process.
        /// Compatible with all Windows versions.
        /// </summary>
        /// <param name="hprocess">Handle of the process that is being queried. If this parameter is NULL (<see cref="IntPtr.Zero"/>, the current process is queried</param>
        /// <returns>The DPI awareness of the specified process from the <see cref="PROCESS_DPI_AWARENESS"/> enumeration.</returns>
        /// <remarks>
        /// Windows versions prior to Windows Vista do not support High DPI.
        /// This method will return <see cref="PROCESS_DPI_AWARENESS.PROCESS_DPI_UNAWARE"/> on these cases.
        /// </remarks>
        public static PROCESS_DPI_AWARENESS GetProcessDpiAwareness(IntPtr hprocess)
        {
            var awareness = PROCESS_DPI_AWARENESS.PROCESS_DPI_UNAWARE;

            try
            {
                var result = SHCore.GetProcessDpiAwareness(hprocess, out awareness);

                if (result.Failed)
                {
                    result.ThrowOnFailure();
                }
            }
            catch (DllNotFoundException)
            {
                try
                {
                    // We're running on either Vista, Windows 7 or Windows 8.
                    // Return the correct ProcessDpiAwareness value.
                    awareness = User32.IsProcessDPIAware() ? PROCESS_DPI_AWARENESS.PROCESS_SYSTEM_DPI_AWARE : PROCESS_DPI_AWARENESS.PROCESS_DPI_UNAWARE;
                }
                catch (EntryPointNotFoundException)
                {
                }
            }
            catch (EntryPointNotFoundException)
            {
                try
                {
                    // We're running on either Vista, Windows 7 or Windows 8.
                    // Return the correct ProcessDpiAwareness value.
                    awareness = User32.IsProcessDPIAware() ? PROCESS_DPI_AWARENESS.PROCESS_SYSTEM_DPI_AWARE : PROCESS_DPI_AWARENESS.PROCESS_DPI_UNAWARE;
                }
                catch (EntryPointNotFoundException)
                {
                }
            }

            // Return the value in awareness.
            return awareness;
        }

        /// <summary>
        /// Retrieves the dots per inch (dpi) awareness of the current process.
        /// Compatible with all Windows versions.
        /// </summary>
        /// <returns>The DPI awareness of the specified process from the <see cref="PROCESS_DPI_AWARENESS"/> enumeration.</returns>
        /// <remarks>
        /// Windows versions prior to Windows Vista do not support High DPI.
        /// This method will return <see cref="PROCESS_DPI_AWARENESS.PROCESS_DPI_UNAWARE"/> on these cases.
        /// </remarks>
        public static PROCESS_DPI_AWARENESS GetProcessDpiAwareness()
        {
            // hprocess NULL (IntPtr.Zero) means query the current process
            return GetProcessDpiAwareness(IntPtr.Zero);
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Try* methods should not throw exceptions")]
        public static unsafe int TryLogicalMonitorScaleFactor(IntPtr hwndMonitor)
        {
            try
            {
                return LogicalMonitorScaleFactor(hwndMonitor);
            }
#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
            catch
#pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body
            {
            }

            return 0;
        }

        public static unsafe int LogicalMonitorScaleFactor(IntPtr hwndMonitor)
        {
                var monitorInfo = User32.MONITORINFOEX.Create();
                if (User32.GetMonitorInfo(hwndMonitor, new IntPtr(&monitorInfo)))
                {
                    var logicalDesktopWidth = User32.GetSystemMetrics(User32.SystemMetric.SM_CXVIRTUALSCREEN);
                    int logicalMonitorWidth = monitorInfo.Monitor.right - monitorInfo.Monitor.left;

                return (logicalMonitorWidth / logicalDesktopWidth);
                }

            return 0;
        }

        /// <summary>
        /// Overrides the scaling factor for all monitors on Windows 8.1 or higher versions
        /// </summary>
        /// <param name="scalingFactor">The desired scaling factor to override current configuration</param>
        /// <returns>Returns true if the system is overriding the scaling factor, false otherwise</returns>
        /// <remarks>Requires logoff/logon to enable the new settings</remarks>
        public static bool OverrideScalingFactor(ScaleFactor scalingFactor)
        {
            if (HasPerMonitorDpiSupport)
            {
                // If(verticalResolution < 1080) and (DPI == 125 %)
                var result = true;

                if (scalingFactor == HighDpi.ScaleFactor.NotAvailable)
                {
                    return false;
                }

                var value = ((int)scalingFactor / 100) * 96;

                result &= Registry.CurrentUser.SetValue<int>(HKCU_CONTROL_PANEL_DESKTOP_WIN8_DPI_SCALING, 1);
                result &= Registry.CurrentUser.SetValue<int>(HKCU_CONTROL_PANEL_DESKTOP_LOGPIXELS, value);

                return result;
            }

            return false;
        }

        public static bool RegisterAsDpiAware(bool perMonitorAwareness = true, bool fallbackToSystemAwareness = true)
        {
            if (HasPerMonitorDpiSupport)
            {
                var result = SHCore.SetProcessDpiAwareness(perMonitorAwareness ? PROCESS_DPI_AWARENESS.PROCESS_PER_MONITOR_DPI_AWARE : PROCESS_DPI_AWARENESS.PROCESS_SYSTEM_DPI_AWARE);

                if (result.Succeeded)
                {
                    return true;
                }

                if (fallbackToSystemAwareness)
                {
                    return User32.SetProcessDPIAware();
                }
            }
            else if (fallbackToSystemAwareness)
            {
                return User32.SetProcessDPIAware();
            }

            return false;
        }

        public static int ScaleFactor(this Dpi dpi)
        {
            // |--------------------|-----------------------|-----------------------|-----------------------|---------------|-------------------|
            // |    Display size    |   Display resolution  |   Horizontal (pixels) |    Vertical (pixels)  |    Panel DPI  |    Scaling level  |
            // |--------------------|-----------------------|-----------------------|-----------------------|---------------|-------------------|
            // |    10.6"           |    FHD                |            1920       |            1080       |        208    |        150%       |
            // |    10.6"           |    HD                 |            1366       |            768        |        148    |        100%       |
            // |    11.6"           |    WUXGA              |            1920       |            1200       |        195    |        150%       |
            // |    11.6"           |    HD                 |            1366       |            768        |        135    |        100%       |
            // |    13.3"           |    WUXGA              |            1920       |            1200       |        170    |        150%       |
            // |    13.3"           |    QHD                |            2560       |            1440       |        221    |        200%       |
            // |    13.3"           |    HD                 |            1366       |            768        |        118    |        100%       |
            // |    15.4"           |    FHD                |            1920       |            1080       |        143    |        125%       |
            // |    15.6"           |    QHD+               |            3200       |            1800       |        235    |        200%       |
            // |    17"             |    FHD                |            1920       |            1080       |        130    |        125%       |
            // |    23”             |    QFHD (4K)          |            3840       |            2160       |        192    |        200%       |
            // |    24"             |    QHD                |            2560       |            1440       |        122    |        125%       |
            // |--------------------|-----------------------|-----------------------|-----------------------|---------------|-------------------|
            return dpi.X * 100 / 96;
        }

        /// <summary>
        /// Sets the current process to a specified dots per inch (dpi) awareness level. The DPI awareness levels are from the <see cref="PROCESS_DPI_AWARENESS"/> enumeration.
        /// Compatible with all Windows versions.
        /// </summary>
        /// <param name="value">The DPI awareness value to set. Possible values are from the <see cref="PROCESS_DPI_AWARENESS"/> enumeration</param>
        /// <returns>true if the function succeeded on setting the DPI awareness, and false otherwise.</returns>
        /// <remarks>
        /// Windows versions prior to Windows Vista do not support High DPI, trying to set any value on these versions will result in returning false.
        /// Windows versions prior to Windows 8.1 do not support per-monitor DPI awareness. If you try to set it on these versions, the method will
        /// fall back to <see cref="PROCESS_DPI_AWARENESS.PROCESS_SYSTEM_DPI_AWARE"/> and try to set it and return true if it succeeds.
        /// </remarks>
        public static bool SetProcessDpiAwareness(PROCESS_DPI_AWARENESS value)
        {
            try
            {
                var result = SHCore.SetProcessDpiAwareness(value);

                return result.Succeeded;
            }
            catch (DllNotFoundException)
            {
                try
                {
                    // We're running on either Vista, Windows 7 or Windows 8.
                    // Trying to set it as ShellScalingApi.PROCESS_DPI_AWARENESS.PROCESS_SYSTEM_DPI_AWARE.
                    return value == PROCESS_DPI_AWARENESS.PROCESS_SYSTEM_DPI_AWARE && User32.SetProcessDPIAware();
                }
                catch (EntryPointNotFoundException)
                {
                }
            }
            catch (EntryPointNotFoundException)
            {
                try
                {
                    // We're running on either Vista, Windows 7 or Windows 8.
                    // Trying to set it as ShellScalingApi.PROCESS_DPI_AWARENESS.PROCESS_SYSTEM_DPI_AWARE.
                    return value == PROCESS_DPI_AWARENESS.PROCESS_SYSTEM_DPI_AWARE && User32.SetProcessDPIAware();
                }
                catch (EntryPointNotFoundException)
                {
                }
            }

            return false;
        }
    }
}

<|start_filename|>src/WinApi.HighDpi/ScaleFactors.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

namespace WinApi.HighDpi
{
    public enum ScaleFactor
    {
        /// <summary>
        /// Scaling is not available or supported
        /// </summary>
        NotAvailable = 0,

        /// <summary>
        /// If the display have less then 900 vertical lines this the only supported option
        /// </summary>
        NoScaling = 100,

        /// <summary>
        /// This is supported on displays with 900 lines or more and less than 1080 lines
        /// </summary>
        Quarter = 125,

        /// <summary>
        /// This is supported on displays with 1080 lines or more and less than 1440 lines
        /// </summary>
        Half = 150,

        /// <summary>
        /// This is supported on displays with 1440 lines
        /// </summary>
        Twice = 200,

        /// <summary>
        /// Not supported yet, but valid value
        /// </summary>
        TwoAndAHalf = 250,

        /// <summary>
        /// Not supported yet, but valid value
        /// </summary>
        Thrice = 300,

        /// <summary>
        /// Not supported yet, but valid value
        /// </summary>
        FourTimes = 400,

        /// <summary>
        /// Not supported yet, but valid value (this is the highest possible value)
        /// </summary>
        FiveTimes = 500
    }
}

<|start_filename|>src/Sandbox/DisplayApi/DeviceFlagsUnion.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System.Runtime.InteropServices;

namespace Sandbox
{
    [StructLayout(LayoutKind.Explicit)]
    public struct DeviceFlagsUnion
    {
        #region Public Fields

        // DWORD->unsigned int
        [FieldOffset(0)]
        public uint dmDisplayFlags;

        // DWORD->unsigned int
        [FieldOffset(0)]
        public uint dmNup;

        #endregion Public Fields
    }
}

<|start_filename|>src/WinApi.PeCoff/IMAGE_DOS_HEADER.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;

namespace WinApi.PeCoff
{
    public struct IMAGE_DOS_HEADER : IEquatable<IMAGE_DOS_HEADER>
    {
        public ushort e_cblp;
        public ushort e_cp;
        public ushort e_cparhdr;
        public ushort e_crlc;
        public ushort e_cs;
        public ushort e_csum;
        public ushort e_ip;
        public uint e_lfanew;
        public ushort e_lfarlc;
        public ushort e_magic;
        public ushort e_maxalloc;
        public ushort e_minalloc;
        public ushort e_oemid;
        public ushort e_oeminfo;
        public ushort e_ovno;
        public ushort[] e_res;
        public ushort[] e_res2;
        public ushort e_sp;
        public ushort e_ss;

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(obj, null))
            {
                return false;
            }

            var x = obj as IMAGE_DOS_HEADER?;

            if (!x.HasValue)
            {
                return false;
            }

            return Equals(x);
        }

        public bool Equals(IMAGE_DOS_HEADER other)
        {
            if (ReferenceEquals(other, null))
            {
                return false;
            }

            if (e_cblp != other.e_cblp)
            {
                return false;
            }

            if (e_cp != other.e_cp)
            {
                return false;
            }

            if (e_cparhdr != other.e_cparhdr)
            {
                return false;
            }

            if (e_crlc != other.e_crlc)
            {
                return false;
            }

            if (e_cs != other.e_cs)
            {
                return false;
            }

            if (e_csum != other.e_csum)
            {
                return false;
            }

            if (e_ip != other.e_ip)
            {
                return false;
            }

            if (e_lfanew != other.e_lfanew)
            {
                return false;
            }

            if (e_lfarlc != other.e_lfarlc)
            {
                return false;
            }

            if (e_magic != other.e_magic)
            {
                return false;
            }

            if (e_maxalloc != other.e_maxalloc)
            {
                return false;
            }

            if (e_minalloc != other.e_minalloc)
            {
                return false;
            }

            if (e_oemid != other.e_oemid)
            {
                return false;
            }

            if (e_oeminfo != other.e_oeminfo)
            {
                return false;
            }

            if (e_ovno != other.e_ovno)
            {
                return false;
            }

            if (e_res != other.e_res)
            {
                return false;
            }

            if (e_res2 != other.e_res2)
            {
                return false;
            }

            if (e_sp != other.e_sp)
            {
                return false;
            }

            return e_ss == other.e_ss;
        }

        public override int GetHashCode()
        {
            // From The Online Encyclopedia of Integer Sequences: https://oeis.org/A000668
            // Mersenne primes (of form 2^p - 1 where p is a prime).
            const int mersenePrime = 131071;
            int hash = 8191;

            unchecked
            {

                hash = (hash * mersenePrime) + this.e_cblp.GetHashCode();
                hash = (hash * mersenePrime) + this.e_cp.GetHashCode();
                hash = (hash * mersenePrime) + this.e_cparhdr.GetHashCode();
                hash = (hash * mersenePrime) + this.e_crlc.GetHashCode();
                hash = (hash * mersenePrime) + this.e_cs.GetHashCode();
                hash = (hash * mersenePrime) + this.e_csum.GetHashCode();
                hash = (hash * mersenePrime) + this.e_ip.GetHashCode();
                hash = (hash * mersenePrime) + this.e_lfanew.GetHashCode();
                hash = (hash * mersenePrime) + this.e_lfarlc.GetHashCode();
                hash = (hash * mersenePrime) + this.e_magic.GetHashCode();
                hash = (hash * mersenePrime) + this.e_maxalloc.GetHashCode();
                hash = (hash * mersenePrime) + this.e_minalloc.GetHashCode();
                hash = (hash * mersenePrime) + this.e_oemid.GetHashCode();
                hash = (hash * mersenePrime) + this.e_oeminfo.GetHashCode();
                hash = (hash * mersenePrime) + this.e_ovno.GetHashCode();
                hash = (hash * mersenePrime) + this.e_res.GetHashCode();
                hash = (hash * mersenePrime) + this.e_res2.GetHashCode();
                hash = (hash * mersenePrime) + this.e_sp.GetHashCode();
                hash = (hash * mersenePrime) + this.e_ss.GetHashCode();
            }

            return hash;
        }

        public static bool operator ==(IMAGE_DOS_HEADER x, IMAGE_DOS_HEADER y)
        {
            return x.Equals(y);
        }

        public static bool operator !=(IMAGE_DOS_HEADER x, IMAGE_DOS_HEADER y)
        {
            return !x.Equals(y);
        }
    }
}


<|start_filename|>src/WinApi.HighDpi/Properties/AssemblyInfo.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System.Reflection;
using System.Resources;
using System.Runtime.InteropServices;

[assembly: AssemblyTitle("WinApi.HighDpi")]
[assembly: AssemblyProduct("WinApi.HighDpi")]
[assembly: AssemblyCopyright("Copyright © 2016 <NAME>")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("<NAME> e Marcondes")]
[assembly: AssemblyTrademark("<NAME> e Marcondes")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]
[assembly: ComVisible(false)]


<|start_filename|>src/WinApi.PeCoff/IMAGE_OPTIONAL_HEADER64.cs<|end_filename|>
﻿// Copyright (c) to owners found in https://github.com/arlm/WinApi/blob/master/COPYRIGHT.md. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.

using System;

namespace WinApi.PeCoff
{
    public struct IMAGE_OPTIONAL_HEADER64 : IEquatable<IMAGE_OPTIONAL_HEADER64>
    {
        public override bool Equals(object obj)
        {
            if (ReferenceEquals(obj, null))
            {
                return false;
            }

            var x = obj as IMAGE_OPTIONAL_HEADER64?;

            if (!x.HasValue)
            {
                return false;
            }

            return Equals(x);
        }

        public bool Equals(IMAGE_OPTIONAL_HEADER64 other)
        {
            if (ReferenceEquals(other, this))
            {
                return false;
            }

            return true;
        }

        public override int GetHashCode()
        {
            // From The Online Encyclopedia of Integer Sequences: https://oeis.org/A000668
            // Mersenne primes (of form 2^p - 1 where p is a prime).
            const int mersenePrime = 131071;
            int hash = 8191;

            unchecked
            {

                hash = (hash * mersenePrime);
            }

            return hash;
        }

        public static bool operator ==(IMAGE_OPTIONAL_HEADER64 x, IMAGE_OPTIONAL_HEADER64 y)
        {
            return x.Equals(y);
        }

        public static bool operator !=(IMAGE_OPTIONAL_HEADER64 x, IMAGE_OPTIONAL_HEADER64 y)
        {
            return !x.Equals(y);
        }
    }
}
