Add PE menu resource reading and writing

This commit is contained in:
Matt Nadareski
2022-11-11 15:31:00 -08:00
parent 5b974260cc
commit f9e1518da6
8 changed files with 472 additions and 18 deletions

View File

@@ -1036,22 +1036,6 @@ namespace BurnOutSharp.Models.PortableExecutable
IMPORT_NAME_UNDECORATE = 3,
}
[Flags]
public enum MemoryFlags : ushort
{
// TODO: Validate the ~ statements
MOVEABLE = 0x0010,
FIXED = 0xFFEF, // ~MOVEABLE
PURE = 0x0020,
IMPURE = 0xFFDF, // ~PURE
PRELOAD = 0x0040,
LOADONCALL = 0xFFBF, // ~PRELOAD
DISCARDABLE = 0x1000,
}
public enum MachineType : ushort
{
/// <summary>
@@ -1190,6 +1174,83 @@ namespace BurnOutSharp.Models.PortableExecutable
IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x0169,
}
[Flags]
public enum MemoryFlags : ushort
{
// TODO: Validate the ~ statements
MOVEABLE = 0x0010,
FIXED = 0xFFEF, // ~MOVEABLE
PURE = 0x0020,
IMPURE = 0xFFDF, // ~PURE
PRELOAD = 0x0040,
LOADONCALL = 0xFFBF, // ~PRELOAD
DISCARDABLE = 0x1000,
}
[Flags]
public enum MenuFlags : uint
{
MF_INSERT = 0x00000000,
MF_CHANGE = 0x00000080,
MF_APPEND = 0x00000100,
MF_DELETE = 0x00000200,
MF_REMOVE = 0x00001000,
MF_BYCOMMAND = 0x00000000,
MF_BYPOSITION = 0x00000400,
MF_SEPARATOR = 0x00000800,
MF_ENABLED = 0x00000000,
MF_GRAYED = 0x00000001,
MF_DISABLED = 0x00000002,
MF_UNCHECKED = 0x00000000,
MF_CHECKED = 0x00000008,
MF_USECHECKBITMAPS = 0x00000200,
MF_STRING = 0x00000000,
MF_BITMAP = 0x00000004,
MF_OWNERDRAW = 0x00000100,
MF_POPUP = 0x00000010,
MF_MENUBARBREAK = 0x00000020,
MF_MENUBREAK = 0x00000040,
MF_UNHILITE = 0x00000000,
MF_HILITE = 0x00000080,
MF_DEFAULT = 0x00001000,
MF_SYSMENU = 0x00002000,
MF_HELP = 0x00004000,
MF_RIGHTJUSTIFY = 0x00004000,
MF_MOUSESELECT = 0x00008000,
MF_END = 0x00000080,
MFT_STRING = MF_STRING,
MFT_BITMAP = MF_BITMAP,
MFT_MENUBARBREAK = MF_MENUBARBREAK,
MFT_MENUBREAK = MF_MENUBREAK,
MFT_OWNERDRAW = MF_OWNERDRAW,
MFT_RADIOCHECK = 0x00000200,
MFT_SEPARATOR = MF_SEPARATOR,
MFT_RIGHTORDER = 0x00002000,
MFT_RIGHTJUSTIFY = MF_RIGHTJUSTIFY,
MFS_GRAYED = 0x00000003,
MFS_DISABLED = MFS_GRAYED,
MFS_CHECKED = MF_CHECKED,
MFS_HILITE = MF_HILITE,
MFS_ENABLED = MF_ENABLED,
MFS_UNCHECKED = MF_UNCHECKED,
MFS_UNHILITE = MF_UNHILITE,
MFS_DEFAULT = MF_DEFAULT,
}
public enum OptionalHeaderMagicNumber : ushort
{
ROMImage = 0x0107,

View File

@@ -0,0 +1,25 @@
using System.Runtime.InteropServices;
namespace BurnOutSharp.Models.PortableExecutable
{
/// <summary>
/// Contains version information for the menu resource. The structure definition provided
/// here is for explanation only; it is not present in any standard header file.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/menurc/menuheader"/>
[StructLayout(LayoutKind.Sequential)]
public class MenuHeader
{
/// <summary>
/// The version number of the menu template. This member must be equal to zero to indicate
/// that this is an RT_MENU created with a standard menu template.
/// </summary>
public ushort Version;
/// <summary>
/// The size of the menu template header. This value is zero for menus you create with a
/// standard menu template.
/// </summary>
public ushort HeaderSize;
}
}

View File

@@ -0,0 +1,30 @@
using System.Runtime.InteropServices;
namespace BurnOutSharp.Models.PortableExecutable
{
/// <summary>
/// Defines the header for an extended menu template. This structure definition is for
/// explanation only; it is not present in any standard header file.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/menurc/menuex-template-header"/>
[StructLayout(LayoutKind.Sequential)]
public class MenuHeaderExtended
{
/// <summary>
/// The template version number. This member must be 1 for extended menu templates.
/// </summary>
public ushort Version;
/// <summary>
/// The offset to the first MENUEX_TEMPLATE_ITEM structure, relative to the end of
/// this structure member. If the first item definition immediately follows the
/// dwHelpId member, this member should be 4.
/// </summary>
public ushort Offset;
/// <summary>
/// The help identifier of menu bar.
/// </summary>
public uint HelpID;
}
}

View File

@@ -0,0 +1,62 @@
namespace BurnOutSharp.Models.PortableExecutable
{
/// <summary>
/// Contains information about each item in a menu resource that does not open a menu
/// or a submenu. The structure definition provided here is for explanation only; it
/// is not present in any standard header file.
///
/// Contains information about the menu items in a menu resource that open a menu
/// or a submenu. The structure definition provided here is for explanation only;
/// it is not present in any standard header file.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/menurc/normalmenuitem"/>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/menurc/popupmenuitem"/>
public class MenuItem
{
#region NORMALMENUITEM
/// <summary>
/// The type of menu item.
/// </summary>
public MenuFlags NormalResInfo;
/// <summary>
/// A null-terminated Unicode string that contains the text for this menu item.
/// There is no fixed limit on the size of this string.
/// </summary>
public string NormalMenuText;
#endregion
#region POPUPMENUITEM
/// <summary>
/// Describes the menu item.
/// </summary>
public MenuFlags PopupItemType;
/// <summary>
/// Describes the menu item.
/// </summary>
public MenuFlags PopupState;
/// <summary>
/// A numeric expression that identifies the menu item that is passed in the
/// WM_COMMAND message.
/// </summary>
public uint PopupID;
/// <summary>
/// A set of bit flags that specify the type of menu item.
/// </summary>
public MenuFlags PopupResInfo;
/// <summary>
/// A null-terminated Unicode string that contains the text for this menu item.
/// There is no fixed limit on the size of this string.
/// </summary>
public string PopupMenuText;
#endregion
}
}

View File

@@ -0,0 +1,37 @@
namespace BurnOutSharp.Models.PortableExecutable
{
/// <summary>
/// Defines a menu item in an extended menu template. This structure definition is for
/// explanation only; it is not present in any standard header file.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/menurc/menuex-template-item"/>
public class MenuItemExtended
{
/// <summary>
/// Describes the menu item.
/// </summary>
public MenuFlags ItemType;
/// <summary>
/// Describes the menu item.
/// </summary>
public MenuFlags State;
/// <summary>
/// A numeric expression that identifies the menu item that is passed in the
/// WM_COMMAND message.
/// </summary>
public uint ID;
/// <summary>
/// A set of bit flags that specify the type of menu item.
/// </summary>
public MenuFlags Flags;
/// <summary>
/// A null-terminated Unicode string that contains the text for this menu item.
/// There is no fixed limit on the size of this string.
/// </summary>
public string MenuText;
}
}

View File

@@ -0,0 +1,40 @@
namespace BurnOutSharp.Models.PortableExecutable
{
/// <summary>
/// A menu resource consists of a MENUHEADER structure followed by one or more
/// NORMALMENUITEM or POPUPMENUITEM structures, one for each menu item in the menu
/// template. The MENUEX_TEMPLATE_HEADER and the MENUEX_TEMPLATE_ITEM structures
/// describe the format of extended menu resources.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/menurc/resource-file-formats"/>
public class MenuResource
{
#region Menu header
/// <summary>
/// Menu header structure
/// </summary>
public MenuHeader MenuHeader;
/// <summary>
/// Menu extended header structure
/// </summary>
public MenuHeaderExtended ExtendedMenuHeader;
#endregion
#region Menu items
/// <summary>
/// Menu items
/// </summary>
public MenuItem[] MenuItems;
/// <summary>
/// Extended menu items
/// </summary>
public MenuItemExtended[] ExtendedMenuItems;
#endregion
}
}