From 1435421c3c0e63a9c7fa81702373a9bd068237c3 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Wed, 9 Nov 2022 11:26:21 -0800 Subject: [PATCH] Add PE accelerator table resource --- BurnOutSharp.Builder/Extensions.cs | 29 ++++++++++++++ .../AcceleratorTableEntryResource.cs | 34 ++++++++++++++++ .../PortableExecutable/Enums.cs | 40 +++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 BurnOutSharp.Models/PortableExecutable/AcceleratorTableEntryResource.cs diff --git a/BurnOutSharp.Builder/Extensions.cs b/BurnOutSharp.Builder/Extensions.cs index 3c41afbc..00bb2ae0 100644 --- a/BurnOutSharp.Builder/Extensions.cs +++ b/BurnOutSharp.Builder/Extensions.cs @@ -361,6 +361,35 @@ namespace BurnOutSharp.Builder return 0; } + /// + /// Read resource data as an accelerator table resource + /// + /// Data to parse into an accelerator table resource + /// A filled accelerator table resource on success, null on error + public static Models.PortableExecutable.AcceleratorTableEntryResource[] AsAcceleratorTableResource(this byte[] data) + { + // If we have data that's invalid for this resource type, we can't do anything + if (data == null || data.Length % 8 != 0) + return null; + + // Get the number of entries + int count = data.Length / 8; + int offset = 0; + + // Read in the table + var table = new Models.PortableExecutable.AcceleratorTableEntryResource[count]; + for (int i = 0; i < count; i++) + { + var entry = new Models.PortableExecutable.AcceleratorTableEntryResource(); + entry.Flags = (Models.PortableExecutable.AcceleratorTableFlags)data.ReadUInt16(ref offset); + entry.Ansi = data.ReadUInt16(ref offset); + entry.Id = data.ReadUInt16(ref offset); + entry.Padding = data.ReadUInt16(ref offset); + } + + return table; + } + #endregion } } \ No newline at end of file diff --git a/BurnOutSharp.Models/PortableExecutable/AcceleratorTableEntryResource.cs b/BurnOutSharp.Models/PortableExecutable/AcceleratorTableEntryResource.cs new file mode 100644 index 00000000..0ec69ef4 --- /dev/null +++ b/BurnOutSharp.Models/PortableExecutable/AcceleratorTableEntryResource.cs @@ -0,0 +1,34 @@ +using System.Runtime.InteropServices; + +namespace BurnOutSharp.Models.PortableExecutable +{ + /// + /// Describes the data in an individual accelerator table resource. The structure definition + /// provided here is for explanation only; it is not present in any standard header file. + /// + /// + [StructLayout(LayoutKind.Sequential)] + public class AcceleratorTableEntryResource + { + /// + /// Describes keyboard accelerator characteristics. + /// + public AcceleratorTableFlags Flags; + + /// + /// An ANSI character value or a virtual-key code that identifies the accelerator key. + /// + public ushort Ansi; + + /// + /// An identifier for the keyboard accelerator. This is the value passed to the window + /// procedure when the user presses the specified key. + /// + public ushort Id; + + /// + /// The number of bytes inserted to ensure that the structure is aligned on a DWORD boundary. + /// + public ushort Padding; + } +} diff --git a/BurnOutSharp.Models/PortableExecutable/Enums.cs b/BurnOutSharp.Models/PortableExecutable/Enums.cs index 42717c3a..92646a5a 100644 --- a/BurnOutSharp.Models/PortableExecutable/Enums.cs +++ b/BurnOutSharp.Models/PortableExecutable/Enums.cs @@ -2,6 +2,46 @@ namespace BurnOutSharp.Models.PortableExecutable { + [Flags] + public enum AcceleratorTableFlags : ushort + { + /// + /// The accelerator key is a virtual-key code. If this flag is not specified, + /// the accelerator key is assumed to specify an ASCII character code. + /// + FVIRTKEY = 0x01, + + /// + /// A menu item on the menu bar is not highlighted when an accelerator is used. + /// This attribute is obsolete and retained only for backward compatibility with + /// resource files designed for 16-bit Windows. + /// + FNOINVERT = 0x02, + + /// + /// The accelerator is activated only if the user presses the SHIFT key. This flag + /// applies only to virtual keys. + /// + FSHIFT = 0x04, + + /// + /// The accelerator is activated only if the user presses the CTRL key. This flag + /// applies only to virtual keys. + /// + FCONTROL = 0x08, + + /// + /// The accelerator is activated only if the user presses the ALT key. This flag + /// applies only to virtual keys. + /// + FALT = 0x10, + + /// + /// The entry is last in an accelerator table. + /// + LastEntry = 0x80, + } + public enum BaseRelocationTypes : uint { ///