Add PE standard dialog parsing and writing

This commit is contained in:
Matt Nadareski
2022-11-11 13:56:23 -08:00
parent 623d1e6a40
commit 475669ac1b
6 changed files with 1259 additions and 9 deletions

View File

@@ -407,7 +407,7 @@ namespace BurnOutSharp.Builder
/// <summary>
/// Read resource data as an accelerator table resource
/// </summary>
/// <param name="data">Resource data entry to parse into an accelerator table resource</param>
/// <param name="entry">Resource data entry to parse into an accelerator table resource</param>
/// <returns>A filled accelerator table resource on success, null on error</returns>
public static Models.PortableExecutable.AcceleratorTableEntry[] AsAcceleratorTableResource(this Models.PortableExecutable.ResourceDataEntry entry)
{
@@ -443,7 +443,7 @@ namespace BurnOutSharp.Builder
/// <summary>
/// Read resource data as a side-by-side assembly manifest
/// </summary>
/// <param name="data">Resource data entry to parse into a side-by-side assembly manifest</param>
/// <param name="entry">Resource data entry to parse into a side-by-side assembly manifest</param>
/// <returns>A filled side-by-side assembly manifest on success, null on error</returns>
public static Models.PortableExecutable.AssemblyManifest AsAssemblyManifest(this Models.PortableExecutable.ResourceDataEntry entry)
{
@@ -462,10 +462,272 @@ namespace BurnOutSharp.Builder
}
}
/// <summary>
/// Read resource data as a dialog box
/// </summary>
/// <param name="entry">Resource data entry to parse into a font group</param>
/// <returns>A filled dialog box on success, null on error</returns>
public static Models.PortableExecutable.DialogBoxResource AsDialogBox(this Models.PortableExecutable.ResourceDataEntry entry)
{
// If we have an invalid entry, just skip
if (entry?.Data == null)
return null;
// Initialize the iterator
int offset = 0;
// Create the output object
var dialogBoxResource = new Models.PortableExecutable.DialogBoxResource();
// Try to read the signature for an extended dialog box template
int signatureOffset = sizeof(ushort);
int possibleSignature = entry.Data.ReadUInt16(ref signatureOffset);
if (possibleSignature == 0xFFFF)
{
Console.WriteLine("Extended dialog box template found, but not implemented");
#region Extended dialog template
// TODO: Implement extended dialog template
#endregion
#region Extended dialog item templates
// TODO: Implement extended dialog item templates
#endregion
}
else
{
#region Dialog template
var dialogTemplate = new Models.PortableExecutable.DialogTemplate();
dialogTemplate.Style = (Models.PortableExecutable.WindowStyles)entry.Data.ReadUInt32(ref offset);
dialogTemplate.ExtendedStyle = (Models.PortableExecutable.ExtendedWindowStyles)entry.Data.ReadUInt32(ref offset);
dialogTemplate.ItemCount = entry.Data.ReadUInt16(ref offset);
dialogTemplate.PositionX = entry.Data.ReadInt16(ref offset);
dialogTemplate.PositionY = entry.Data.ReadInt16(ref offset);
dialogTemplate.WidthX = entry.Data.ReadInt16(ref offset);
dialogTemplate.HeightY = entry.Data.ReadInt16(ref offset);
#region Menu resource
int currentOffset = offset;
ushort menuResourceIdentifier = entry.Data.ReadUInt16(ref offset);
offset = currentOffset;
// 0x0000 means no elements
if (menuResourceIdentifier == 0x0000)
{
// Increment the pointer if it was empty
offset += sizeof(ushort);
}
else
{
// Flag if there's an ordinal at the end
bool menuResourceHasOrdinal = menuResourceIdentifier == 0xFFFF;
if (menuResourceHasOrdinal)
offset += sizeof(ushort);
// Read the menu resource as a string
dialogTemplate.MenuResource = entry.Data.ReadString(ref offset, Encoding.Unicode);
// Align to the WORD boundary
while ((offset % 2) != 0)
_ = entry.Data.ReadByte(ref offset);
// Read the ordinal if we have the flag set
if (menuResourceHasOrdinal)
dialogTemplate.MenuResourceOrdinal = entry.Data.ReadUInt16(ref offset);
}
#endregion
#region Class resource
currentOffset = offset;
ushort classResourceIdentifier = entry.Data.ReadUInt16(ref offset);
offset = currentOffset;
// 0x0000 means no elements
if (classResourceIdentifier == 0x0000)
{
// Increment the pointer if it was empty
offset += sizeof(ushort);
}
else
{
// Flag if there's an ordinal at the end
bool classResourcehasOrdinal = classResourceIdentifier == 0xFFFF;
if (classResourcehasOrdinal)
offset += sizeof(ushort);
// Read the class resource as a string
dialogTemplate.ClassResource = entry.Data.ReadString(ref offset, Encoding.Unicode);
// Align to the WORD boundary
while ((offset % 2) != 0)
_ = entry.Data.ReadByte(ref offset);
// Read the ordinal if we have the flag set
if (classResourcehasOrdinal)
dialogTemplate.ClassResourceOrdinal = entry.Data.ReadUInt16(ref offset);
}
#endregion
#region Title resource
currentOffset = offset;
ushort titleResourceIdentifier = entry.Data.ReadUInt16(ref offset);
offset = currentOffset;
// 0x0000 means no elements
if (titleResourceIdentifier == 0x0000)
{
// Increment the pointer if it was empty
offset += sizeof(ushort);
}
else
{
// Read the title resource as a string
dialogTemplate.TitleResource = entry.Data.ReadString(ref offset, Encoding.Unicode);
// Align to the WORD boundary
while ((offset % 2) != 0)
_ = entry.Data.ReadByte(ref offset);
}
#endregion
#region Point size and typeface
// Only if DS_SETFONT is set are the values here used
if (dialogTemplate.Style.HasFlag(Models.PortableExecutable.WindowStyles.DS_SETFONT))
{
dialogTemplate.PointSizeValue = entry.Data.ReadUInt16(ref offset);
// Read the font name as a string
dialogTemplate.Typeface = entry.Data.ReadString(ref offset, Encoding.Unicode);
}
// Align to the DWORD boundary
while ((offset % 4) != 0)
_ = entry.Data.ReadByte(ref offset);
#endregion
dialogBoxResource.DialogTemplate = dialogTemplate;
#endregion
#region Dialog Item Templates
var dialogItemTemplates = new List<Models.PortableExecutable.DialogItemTemplate>();
for (int i = 0; i < dialogTemplate.ItemCount; i++)
{
var dialogItemTemplate = new Models.PortableExecutable.DialogItemTemplate();
dialogItemTemplate.Style = (Models.PortableExecutable.WindowStyles)entry.Data.ReadUInt32(ref offset);
dialogItemTemplate.ExtendedStyle = (Models.PortableExecutable.ExtendedWindowStyles)entry.Data.ReadUInt32(ref offset);
dialogItemTemplate.PositionX = entry.Data.ReadInt16(ref offset);
dialogItemTemplate.PositionY = entry.Data.ReadInt16(ref offset);
dialogItemTemplate.WidthX = entry.Data.ReadInt16(ref offset);
dialogItemTemplate.HeightY = entry.Data.ReadInt16(ref offset);
dialogItemTemplate.ID = entry.Data.ReadUInt16(ref offset);
#region Class resource
currentOffset = offset;
ushort itemClassResourceIdentifier = entry.Data.ReadUInt16(ref offset);
offset = currentOffset;
// 0xFFFF means ordinal only
if (itemClassResourceIdentifier == 0xFFFF)
{
// Increment the pointer
_ = entry.Data.ReadUInt16(ref offset);
// Read the ordinal
dialogItemTemplate.ClassResourceOrdinal = (Models.PortableExecutable.DialogItemTemplateOrdinal)entry.Data.ReadUInt16(ref offset);
}
else
{
// Flag if there's an ordinal at the end
bool classResourcehasOrdinal = itemClassResourceIdentifier == 0xFFFF;
if (classResourcehasOrdinal)
offset += sizeof(ushort);
// Read the class resource as a string
dialogItemTemplate.ClassResource = entry.Data.ReadString(ref offset, Encoding.Unicode);
// Align to the WORD boundary
while ((offset % 2) != 0)
_ = entry.Data.ReadByte(ref offset);
}
#endregion
#region Title resource
currentOffset = offset;
ushort itemTitleResourceIdentifier = entry.Data.ReadUInt16(ref offset);
offset = currentOffset;
// 0xFFFF means ordinal only
if (itemTitleResourceIdentifier == 0xFFFF)
{
// Increment the pointer
_ = entry.Data.ReadUInt16(ref offset);
// Read the ordinal
dialogItemTemplate.TitleResourceOrdinal = entry.Data.ReadUInt16(ref offset);
}
else
{
// Read the title resource as a string
dialogItemTemplate.TitleResource = entry.Data.ReadString(ref offset, Encoding.Unicode);
// Align to the WORD boundary
while ((offset % 2) != 0)
_ = entry.Data.ReadByte(ref offset);
}
#endregion
#region Creation data
dialogItemTemplate.CreationDataSize = entry.Data.ReadUInt16(ref offset);
if (dialogItemTemplate.CreationDataSize != 0)
dialogItemTemplate.CreationData = entry.Data.ReadBytes(ref offset, dialogItemTemplate.CreationDataSize);
#endregion
// Align to the DWORD boundary if we're not at the end
if (offset != entry.Data.Length)
{
while ((offset % 4) != 0)
_ = entry.Data.ReadByte(ref offset);
}
dialogItemTemplates.Add(dialogItemTemplate);
}
dialogBoxResource.DialogItemTemplates = dialogItemTemplates.ToArray();
#endregion
}
return dialogBoxResource;
}
/// <summary>
/// Read resource data as a font group
/// </summary>
/// <param name="data">Resource data entry to parse into a font group</param>
/// <param name="entry">Resource data entry to parse into a font group</param>
/// <returns>A filled font group on success, null on error</returns>
public static Models.PortableExecutable.FontGroupHeader AsFontGroup(this Models.PortableExecutable.ResourceDataEntry entry)
{
@@ -528,13 +790,13 @@ namespace BurnOutSharp.Builder
}
// TODO: Implement entry parsing
return null;
return fontGroupHeader;
}
/// <summary>
/// Read resource data as a string table resource
/// </summary>
/// <param name="data">Resource data entry to parse into a string table resource</param>
/// <param name="entry">Resource data entry to parse into a string table resource</param>
/// <returns>A filled string table resource on success, null on error</returns>
public static Dictionary<int, string> AsStringTable(this Models.PortableExecutable.ResourceDataEntry entry)
{
@@ -582,7 +844,7 @@ namespace BurnOutSharp.Builder
/// <summary>
/// Read resource data as a version info resource
/// </summary>
/// <param name="data">Resource data entry to parse into a version info resource</param>
/// <param name="entry">Resource data entry to parse into a version info resource</param>
/// <returns>A filled version info resource on success, null on error</returns>
public static Models.PortableExecutable.VersionInfo AsVersionInfo(this Models.PortableExecutable.ResourceDataEntry entry)
{

View File

@@ -0,0 +1,25 @@
namespace BurnOutSharp.Models.PortableExecutable
{
/// <summary>
/// A dialog box is also one resource entry in the resource file. It consists of one
/// DLGTEMPLATE dialog box header structure plus one DLGITEMTEMPLATE structure for each
/// control in the dialog box. The DLGTEMPLATEEX and the DLGITEMTEMPLATEEX structures
/// describe the format of extended dialog box resources.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/menurc/resource-file-formats"/>
public class DialogBoxResource
{
/// <summary>
/// Dialog box header structure
/// </summary>
public DialogTemplate DialogTemplate;
/// <summary>
/// Following the DLGTEMPLATE header in a standard dialog box template are one or more
/// DLGITEMTEMPLATE structures that define the dimensions and style of the controls in the dialog
/// box. The cdit member specifies the number of DLGITEMTEMPLATE structures in the template.
/// These DLGITEMTEMPLATE structures must be aligned on DWORD boundaries.
/// </summary>
public DialogItemTemplate[] DialogItemTemplates;
}
}

View File

@@ -0,0 +1,133 @@
using System.Runtime.InteropServices;
namespace BurnOutSharp.Models.PortableExecutable
{
/// <summary>
/// Defines the dimensions and style of a control in a dialog box. One or more of these
/// structures are combined with a DLGTEMPLATE structure to form a standard template
/// for a dialog box.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-dlgitemtemplate"/>
[StructLayout(LayoutKind.Sequential)]
public class DialogItemTemplate
{
/// <summary>
/// The style of the control. This member can be a combination of window style values
/// (such as WS_BORDER) and one or more of the control style values (such as
/// BS_PUSHBUTTON and ES_LEFT).
/// </summary>
public WindowStyles Style;
/// <summary>
/// The extended styles for a window. This member is not used to create dialog boxes,
/// but applications that use dialog box templates can use it to create other types
/// of windows.
/// </summary>
public ExtendedWindowStyles ExtendedStyle;
/// <summary>
/// The x-coordinate, in dialog box units, of the upper-left corner of the control.
/// This coordinate is always relative to the upper-left corner of the dialog box's
/// client area.
/// </summary>
/// <remarks>
/// The x, y, cx, and cy members specify values in dialog box units. You can convert these values to screen
/// units (pixels) by using the MapDialogRect function.
/// </remarks>
public short PositionX;
/// <summary>
/// The y-coordinate, in dialog box units, of the upper-left corner of the control.
/// This coordinate is always relative to the upper-left corner of the dialog box's
/// client area.
/// </summary>
/// <remarks>
/// The x, y, cx, and cy members specify values in dialog box units. You can convert these values to screen
/// units (pixels) by using the MapDialogRect function.
/// </remarks>
public short PositionY;
/// <summary>
/// The width, in dialog box units, of the control.
/// </summary>
/// <remarks>
/// The x, y, cx, and cy members specify values in dialog box units. You can convert these values to screen
/// units (pixels) by using the MapDialogRect function.
/// </remarks>
public short WidthX;
/// <summary>
/// The height, in dialog box units, of the control.
/// </summary>
/// <remarks>
/// The x, y, cx, and cy members specify values in dialog box units. You can convert these values to screen
/// units (pixels) by using the MapDialogRect function.
/// </remarks>
public short HeightY;
/// <summary>
/// The control identifier.
/// </summary>
public ushort ID;
// In a standard template for a dialog box, the DLGITEMTEMPLATE structure is always immediately
// followed by three variable-length arrays specifying the class, title, and creation data for
// the control. Each array consists of one or more 16-bit elements.
//
// Each DLGITEMTEMPLATE structure in the template must be aligned on a DWORD boundary. The class
// and title arrays must be aligned on WORD boundaries. The creation data array must be aligned
// on a WORD boundary.
/// <summary>
/// Immediately following each DLGITEMTEMPLATE structure is a class array that specifies the window
/// class of the control. If the first element of this array is any value other than 0xFFFF, the
/// system treats the array as a null-terminated Unicode string that specifies the name of a
/// registered window class. If the first element is 0xFFFF, the array has one additional element
/// that specifies the ordinal value of a predefined system class.
/// </summary>
/// <remarks>
/// If you specify character strings in the class and title arrays, you must use Unicode strings. Use the
/// MultiByteToWideChar function to generate Unicode strings from ANSI strings.
/// </remarks>
public string ClassResource;
/// <summary>
/// The ordinal value of a predefined system class.
/// </summary>
public DialogItemTemplateOrdinal ClassResourceOrdinal;
/// <summary>
/// Following the class array is a title array that contains the initial text or resource identifier
/// of the control. If the first element of this array is 0xFFFF, the array has one additional element
/// that specifies an ordinal value of a resource, such as an icon, in an executable file. You can use
/// a resource identifier for controls, such as static icon controls, that load and display an icon
/// or other resource rather than text. If the first element is any value other than 0xFFFF, the system
/// treats the array as a null-terminated Unicode string that specifies the initial text.
/// </summary>
/// <remarks>
/// If you specify character strings in the class and title arrays, you must use Unicode strings. Use the
/// MultiByteToWideChar function to generate Unicode strings from ANSI strings.
/// </remarks>
public string TitleResource;
/// <summary>
/// An ordinal value of a resource, such as an icon, in an executable file
/// </summary>
public ushort TitleResourceOrdinal;
/// <summary>
/// The creation data array begins at the next WORD boundary after the title array. This creation data
/// can be of any size and format. If the first word of the creation data array is nonzero, it indicates
/// the size, in bytes, of the creation data (including the size word).
/// </summary>
public ushort CreationDataSize;
/// <summary>
/// The creation data array begins at the next WORD boundary after the title array. This creation data
/// can be of any size and format. The control's window procedure must be able to interpret the data.
/// When the system creates the control, it passes a pointer to this data in the lParam parameter of the
/// WM_CREATE message that it sends to the control.
/// </summary>
public byte[] CreationData;
}
}

View File

@@ -0,0 +1,163 @@
using System.Runtime.InteropServices;
namespace BurnOutSharp.Models.PortableExecutable
{
/// <summary>
/// Defines the dimensions and style of a dialog box. This structure, always the first
/// in a standard template for a dialog box, also specifies the number of controls in
/// the dialog box and therefore specifies the number of subsequent DLGITEMTEMPLATE
/// structures in the template.
/// </summary>
/// <see href="https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-dlgtemplate"/>
[StructLayout(LayoutKind.Sequential)]
public class DialogTemplate
{
/// <summary>
/// The style of the dialog box. This member can be a combination of window style
/// values (such as WS_CAPTION and WS_SYSMENU) and dialog box style values (such
/// as DS_CENTER).
///
/// If the style member includes the DS_SETFONT style, the header of the dialog box
/// template contains additional data specifying the font to use for text in the
/// client area and controls of the dialog box. The font data begins on the WORD
/// boundary that follows the title array. The font data specifies a 16-bit point
/// size value and a Unicode font name string. If possible, the system creates a
/// font according to the specified values. Then the system sends a WM_SETFONT
/// message to the dialog box and to each control to provide a handle to the font.
/// If DS_SETFONT is not specified, the dialog box template does not include the
/// font data.
///
/// The DS_SHELLFONT style is not supported in the DLGTEMPLATE header.
/// </summary>
public WindowStyles Style;
/// <summary>
/// The extended styles for a window. This member is not used to create dialog boxes,
/// but applications that use dialog box templates can use it to create other types
/// of windows.
/// </summary>
public ExtendedWindowStyles ExtendedStyle;
/// <summary>
/// The number of items in the dialog box.
/// </summary>
public ushort ItemCount;
/// <summary>
/// The x-coordinate, in dialog box units, of the upper-left corner of the dialog box.
/// </summary>
/// <remarks>
/// The x, y, cx, and cy members specify values in dialog box units. You can convert these values
/// to screen units (pixels) by using the MapDialogRect function.
/// </remarks>
public short PositionX;
/// <summary>
/// The y-coordinate, in dialog box units, of the upper-left corner of the dialog box.
/// </summary>
/// <remarks>
/// The x, y, cx, and cy members specify values in dialog box units. You can convert these values
/// to screen units (pixels) by using the MapDialogRect function.
/// </remarks>
public short PositionY;
/// <summary>
/// The width, in dialog box units, of the dialog box.
/// </summary>
/// <remarks>
/// The x, y, cx, and cy members specify values in dialog box units. You can convert these values
/// to screen units (pixels) by using the MapDialogRect function.
/// </remarks>
public short WidthX;
/// <summary>
/// The height, in dialog box units, of the dialog box.
/// </summary>
/// <remarks>
/// The x, y, cx, and cy members specify values in dialog box units. You can convert these values
/// to screen units (pixels) by using the MapDialogRect function.
/// </remarks>
public short HeightY;
// In a standard template for a dialog box, the DLGTEMPLATE structure is always immediately
// followed by three variable-length arrays that specify the menu, class, and title for the
// dialog box. When the DS_SETFONT style is specified, these arrays are also followed by a
// 16-bit value specifying point size and another variable-length array specifying a
// typeface name. Each array consists of one or more 16-bit elements. The menu, class, title,
// and font arrays must be aligned on WORD boundaries.
/// <summary>
/// Immediately following the DLGTEMPLATE structure is a menu array that identifies a menu
/// resource for the dialog box. If the first element of this array is 0x0000, the dialog box
/// has no menu and the array has no other elements. If the first element is 0xFFFF, the array
/// has one additional element that specifies the ordinal value of a menu resource in an
/// executable file. If the first element has any other value, the system treats the array as
/// a null-terminated Unicode string that specifies the name of a menu resource in an executable
/// file.
/// </summary>
/// <remarks>
/// If you specify character strings in the menu, class, title, or typeface arrays, you must use
/// Unicode strings.
/// </remarks>
public string MenuResource;
/// <summary>
/// The ordinal value of a menu resource in an executable file.
/// </summary>
public ushort MenuResourceOrdinal;
/// <summary>
/// Following the menu array is a class array that identifies the window class of the dialog box.
/// If the first element of the array is 0x0000, the system uses the predefined dialog box class
/// for the dialog box and the array has no other elements. If the first element is 0xFFFF,
/// the array has one additional element that specifies the ordinal value of a predefined system
/// window class. If the first element has any other value, the system treats the array as a
/// null-terminated Unicode string that specifies the name of a registered window class.
/// </summary>
/// <remarks>
/// If you specify character strings in the menu, class, title, or typeface arrays, you must use
/// Unicode strings.
/// </remarks>
public string ClassResource;
/// <summary>
/// The ordinal value of a predefined system class.
/// </summary>
public ushort ClassResourceOrdinal;
/// <summary>
/// Following the class array is a title array that specifies a null-terminated Unicode string
/// that contains the title of the dialog box. If the first element of this array is 0x0000,
/// the dialog box has no title and the array has no other elements.
/// </summary>
/// <remarks>
/// If you specify character strings in the menu, class, title, or typeface arrays, you must use
/// Unicode strings.
/// </remarks>
public string TitleResource;
/// <summary>
/// The 16-bit point size value and the typeface array follow the title array, but only if the
/// style member specifies the DS_SETFONT style. The point size value specifies the point size
/// of the font to use for the text in the dialog box and its controls. When these values are
/// specified, the system creates a font having the specified size and typeface (if possible)
/// and sends a WM_SETFONT message to the dialog box procedure and the control window
/// procedures as it creates the dialog box and controls.
/// </summary>
public ushort PointSizeValue;
/// <summary>
/// The 16-bit point size value and the typeface array follow the title array, but only if the
/// style member specifies the DS_SETFONT style. The typeface array is a null-terminated Unicode
/// string specifying the name of the typeface for the font. When these values are specified,
/// the system creates a font having the specified size and typeface (if possible) and sends a
/// WM_SETFONT message to the dialog box procedure and the control window procedures as it
/// creates the dialog box and controls.
/// </summary>
/// <remarks>
/// If you specify character strings in the menu, class, title, or typeface arrays, you must use
/// Unicode strings.
/// </remarks>
public string Typeface;
}
}

View File

@@ -400,6 +400,16 @@ namespace BurnOutSharp.Models.PortableExecutable
IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS = 20,
}
public enum DialogItemTemplateOrdinal : ushort
{
Button = 0x0080,
Edit = 0x0081,
Static = 0x0082,
ListBox = 0x0083,
ScrollBar = 0x0084,
ComboBox = 0x0085,
}
[Flags]
public enum DllCharacteristics : ushort
{
@@ -489,6 +499,209 @@ namespace BurnOutSharp.Models.PortableExecutable
IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT = 0x0001,
}
[Flags]
public enum ExtendedWindowStyles : uint
{
/// <summary>
/// The window has generic left-aligned properties. This is the default.
/// </summary>
WS_EX_LEFT = 0x00000000,
/// <summary>
/// The window text is displayed using left-to-right reading-order properties.
/// This is the default.
/// </summary>
WS_EX_LTRREADING = 0x00000000,
/// <summary>
/// The vertical scroll bar (if present) is to the right of the client area.
/// This is the default.
/// </summary>
WS_EX_RIGHTSCROLLBAR = 0x00000000,
/// <summary>
/// The window has a double border; the window can, optionally, be created with
/// a title bar by specifying the WS_CAPTION style in the dwStyle parameter.
/// </summary>
WS_EX_DLGMODALFRAME = 0x00000001,
/// <summary>
/// The child window created with this style does not send the WM_PARENTNOTIFY
/// message to its parent window when it is created or destroyed.
/// </summary>
WS_EX_NOPARENTNOTIFY = 0x00000004,
/// <summary>
/// The window should be placed above all non-topmost windows and should stay above them,
/// even when the window is deactivated. To add or remove this style, use the
/// SetWindowPos function.
/// </summary>
WS_EX_TOPMOST = 0x00000008,
/// <summary>
/// The window accepts drag-drop files.
/// </summary>
WS_EX_ACCEPTFILES = 0x00000010,
/// <summary>
/// The window should not be painted until siblings beneath the window (that were created
/// by the same thread) have been painted. The window appears transparent because the bits
/// of underlying sibling windows have already been painted.
///
/// To achieve transparency without these restrictions, use the SetWindowRgn function.
/// </summary>
WS_EX_TRANSPARENT = 0x00000020,
/// <summary>
/// The window is a MDI child window.
/// </summary>
WS_EX_MDICHILD = 0x00000040,
/// <summary>
/// The window is intended to be used as a floating toolbar. A tool window has a title
/// bar that is shorter than a normal title bar, and the window title is drawn using a
/// smaller font. A tool window does not appear in the taskbar or in the dialog that
/// appears when the user presses ALT+TAB. If a tool window has a system menu, its icon
/// is not displayed on the title bar. However, you can display the system menu by
/// right-clicking or by typing ALT+SPACE.
/// </summary>
WS_EX_TOOLWINDOW = 0x00000080,
/// <summary>
/// The window has a border with a raised edge.
/// </summary>
WS_EX_WINDOWEDGE = 0x00000100,
/// <summary>
/// The window has a border with a sunken edge.
/// </summary>
WS_EX_CLIENTEDGE = 0x00000200,
/// <summary>
/// The title bar of the window includes a question mark. When the user clicks
/// the question mark, the cursor changes to a question mark with a pointer. If
/// the user then clicks a child window, the child receives a WM_HELP message.
/// The child window should pass the message to the parent window procedure,
/// which should call the WinHelp function using the HELP_WM_HELP command. The
/// Help application displays a pop-up window that typically contains help for
/// the child window.
///
/// WS_EX_CONTEXTHELP cannot be used with the WS_MAXIMIZEBOX or WS_MINIMIZEBOX
/// styles.
/// </summary>
WS_EX_CONTEXTHELP = 0x00000400,
/// <summary>
/// The window has generic "right-aligned" properties. This depends on the window class.
/// This style has an effect only if the shell language is Hebrew, Arabic, or another
/// language that supports reading-order alignment; otherwise, the style is ignored.
///
/// Using the WS_EX_RIGHT style for static or edit controls has the same effect as using
/// the SS_RIGHT or ES_RIGHT style, respectively. Using this style with button controls
/// has the same effect as using BS_RIGHT and BS_RIGHTBUTTON styles.
/// </summary>
WS_EX_RIGHT = 0x00001000,
/// <summary>
/// If the shell language is Hebrew, Arabic, or another language that supports reading-order
/// alignment, the window text is displayed using right-to-left reading-order properties.
/// For other languages, the style is ignored.
/// </summary>
WS_EX_RTLREADING = 0x00002000,
/// <summary>
/// If the shell language is Hebrew, Arabic, or another language that supports
/// reading order alignment, the vertical scroll bar (if present) is to the left
/// of the client area. For other languages, the style is ignored.
/// </summary>
WS_EX_LEFTSCROLLBAR = 0x00004000,
/// <summary>
/// The window itself contains child windows that should take part in dialog box
/// navigation. If this style is specified, the dialog manager recurses into
/// children of this window when performing navigation operations such as handling
/// the TAB key, an arrow key, or a keyboard mnemonic.
/// </summary>
WS_EX_CONTROLPARENT = 0x00010000,
/// <summary>
/// The window has a three-dimensional border style intended to be used for items that do
/// not accept user input.
/// </summary>
WS_EX_STATICEDGE = 0x00020000,
/// <summary>
/// Forces a top-level window onto the taskbar when the window is visible.
/// </summary>
WS_EX_APPWINDOW = 0x00040000,
/// <summary>
/// The window is a layered window. This style cannot be used if the window has a
/// class style of either CS_OWNDC or CS_CLASSDC.
///
/// Windows 8: The WS_EX_LAYERED style is supported for top-level windows and child
/// windows. Previous Windows versions support WS_EX_LAYERED only for top-level windows.
/// </summary>
WS_EX_LAYERED = 0x00080000,
/// <summary>
/// The window does not pass its window layout to its child windows.
/// </summary>
WS_EX_NOINHERITLAYOUT = 0x00100000,
/// <summary>
/// The window does not render to a redirection surface. This is for windows that do not
/// have visible content or that use mechanisms other than surfaces to provide their visual.
/// </summary>
WS_EX_NOREDIRECTIONBITMAP = 0x00200000,
/// <summary>
/// If the shell language is Hebrew, Arabic, or another language that supports reading
/// order alignment, the horizontal origin of the window is on the right edge.
/// Increasing horizontal values advance to the left.
/// </summary>
WS_EX_LAYOUTRTL = 0x00400000,
/// <summary>
/// Paints all descendants of a window in bottom-to-top painting order using
/// double-buffering. Bottom-to-top painting order allows a descendent window
/// to have translucency (alpha) and transparency (color-key) effects, but only
/// if the descendent window also has the WS_EX_TRANSPARENT bit set.
/// Double-buffering allows the window and its descendents to be painted without
/// flicker. This cannot be used if the window has a class style of either
/// CS_OWNDC or CS_CLASSDC.
///
/// Windows 2000: This style is not supported.
/// </summary>
WS_EX_COMPOSITED = 0x02000000,
/// <summary>
/// A top-level window created with this style does not become the foreground window when
/// the user clicks it. The system does not bring this window to the foreground when the
/// user minimizes or closes the foreground window.
///
/// The window should not be activated through programmatic access or via keyboard
/// navigation by accessible technology, such as Narrator.
///
/// To activate the window, use the SetActiveWindow or SetForegroundWindow function.
///
/// The window does not appear on the taskbar by default. To force the window to appear on
/// the taskbar, use the WS_EX_APPWINDOW style.
/// </summary>
WS_EX_NOACTIVATE = 0x08000000,
/// <summary>
/// The window is an overlapped window.
/// </summary>
WS_EX_OVERLAPPEDWINDOW = WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE,
/// <summary>
/// The window is palette window, which is a modeless dialog box that presents an array of
/// commands.
/// </summary>
WS_EX_PALETTEWINDOW = WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST,
}
public enum FixedFileInfoFileSubtype : uint
{
/// <summary>
@@ -2589,6 +2802,398 @@ namespace BurnOutSharp.Models.PortableExecutable
TextData = 1,
}
[Flags]
public enum WindowStyles : uint
{
#region Standard Styles
/// <summary>
/// The window is an overlapped window. An overlapped window has a title
/// bar and a border. Same as the WS_TILED style.
/// </summary>
WS_OVERLAPPED = 0x00000000,
/// <summary>
/// The window is an overlapped window. An overlapped window has a title bar
/// and a border. Same as the WS_OVERLAPPED style.
/// </summary>
WS_TILED = 0x00000000,
/// <summary>
/// The window has a maximize button. Cannot be combined with the
/// WS_EX_CONTEXTHELP style. The WS_SYSMENU style must also be specified.
/// </summary>
WS_MAXIMIZEBOX = 0x00010000,
/// <summary>
/// The window is a control that can receive the keyboard focus when the user
/// presses the TAB key. Pressing the TAB key changes the keyboard focus to
/// the next control with the WS_TABSTOP style.
///
/// You can turn this style on and off to change dialog box navigation. To
/// change this style after a window has been created, use the SetWindowLong
/// function. For user-created windows and modeless dialogs to work with tab
/// stops, alter the message loop to call the IsDialogMessage function.
/// </summary>
WS_TABSTOP = 0x00010000,
/// <summary>
/// The window has a minimize button. Cannot be combined with the
/// WS_EX_CONTEXTHELP style. The WS_SYSMENU style must also be specified.
/// </summary>
WS_MINIMIZEBOX = 0x00020000,
/// <summary>
/// The window is the first control of a group of controls. The group consists
/// of this first control and all controls defined after it, up to the next
/// control with the WS_GROUP style. The first control in each group usually
/// has the WS_TABSTOP style so that the user can move from group to group.
/// The user can subsequently change the keyboard focus from one control in
/// the group to the next control in the group by using the direction keys.
///
/// You can turn this style on and off to change dialog box navigation. To
/// change this style after a window has been created, use the SetWindowLong
/// function.
/// </summary>
WS_GROUP = 0x00020000,
/// <summary>
/// The window has a sizing border. Same as the WS_THICKFRAME style.
/// </summary>
WS_SIZEBOX = 0x00040000,
/// <summary>
/// The window has a sizing border. Same as the WS_SIZEBOX style.
/// </summary>
WS_THICKFRAME = 0x00040000,
/// <summary>
/// The window has a window menu on its title bar. The WS_CAPTION style must
/// also be specified.
/// </summary>
WS_SYSMENU = 0x00080000,
/// <summary>
/// The window has a horizontal scroll bar.
/// </summary>
WS_HSCROLL = 0x00100000,
/// <summary>
/// The window has a vertical scroll bar.
/// </summary>
WS_VSCROLL = 0x00200000,
/// <summary>
/// The window has a border of a style typically used with dialog boxes. A
/// window with this style cannot have a title bar.
/// </summary>
WS_DLGFRAME = 0x00400000,
/// <summary>
/// The window has a thin-line border
/// </summary>
WS_BORDER = 0x00800000,
/// <summary>
/// The window has a title bar
/// </summary>
WS_CAPTION = 0x00C00000,
/// <summary>
/// The window is initially maximized.
/// </summary>
WS_MAXIMIZE = 0x01000000,
/// <summary>
/// Excludes the area occupied by child windows when drawing occurs within the
/// parent window. This style is used when creating the parent window.
/// </summary>
WS_CLIPCHILDREN = 0x02000000,
/// <summary>
/// Clips child windows relative to each other; that is, when a particular child
/// window receives a WM_PAINT message, the WS_CLIPSIBLINGS style clips all other
/// overlapping child windows out of the region of the child window to be updated.
/// If WS_CLIPSIBLINGS is not specified and child windows overlap, it is possible,
/// when drawing within the client area of a child window, to draw within the
/// client area of a neighboring child window.
/// </summary>
WS_CLIPSIBLINGS = 0x04000000,
/// <summary>
/// The window is initially disabled. A disabled window cannot receive input from
/// the user. To change this after a window has been created, use the EnableWindow
/// function.
/// </summary>
WS_DISABLED = 0x08000000,
/// <summary>
/// The window is initially visible.
/// This style can be turned on and off by using the ShowWindow or SetWindowPos
/// function.
/// </summary>
WS_VISIBLE = 0x10000000,
/// <summary>
/// The window is initially minimized. Same as the WS_MINIMIZE style.
/// </summary>
WS_ICONIC = 0x20000000,
/// <summary>
/// The window is initially minimized. Same as the WS_ICONIC style.
/// </summary>
WS_MINIMIZE = 0x20000000,
/// <summary>
/// The window is a child window. A window with this style cannot have a menu
/// bar. This style cannot be used with the WS_POPUP style.
/// </summary>
WS_CHILD = 0x40000000,
/// <summary>
/// Same as the WS_CHILD style.
/// </summary>
WS_CHILDWINDOW = 0x40000000,
/// <summary>
/// The window is a pop-up window. This style cannot be used with the WS_CHILD style.
/// </summary>
WS_POPUP = 0x80000000,
/// <summary>
/// The window is an overlapped window. Same as the WS_TILEDWINDOW style.
/// </summary>
WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
/// <summary>
/// The window is a pop-up window. The WS_CAPTION and WS_POPUPWINDOW styles must be
/// combined to make the window menu visible.
/// </summary>
WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU,
/// <summary>
/// The window is an overlapped window. Same as the WS_OVERLAPPEDWINDOW style.
/// </summary>
WS_TILEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
#endregion
#region Common Control Styles
/// <summary>
/// Causes the control to position itself at the top of the parent window's
/// client area and sets the width to be the same as the parent window's width.
/// Toolbars have this style by default.
/// </summary>
CCS_TOP = 0x00000001,
/// <summary>
/// Causes the control to resize and move itself horizontally, but not vertically,
/// in response to a WM_SIZE message. If CCS_NORESIZE is used, this style does not
/// apply. Header windows have this style by default.
/// </summary>
CCS_NOMOVEY = 0x00000002,
/// <summary>
/// Causes the control to position itself at the bottom of the parent window's
/// client area and sets the width to be the same as the parent window's width.
/// Status windows have this style by default.
/// </summary>
CCS_BOTTOM = 0x00000003,
/// <summary>
/// Prevents the control from using the default width and height when setting its
/// initial size or a new size. Instead, the control uses the width and height
/// specified in the request for creation or sizing.
/// </summary>
CCS_NORESIZE = 0x00000004,
/// <summary>
/// Prevents the control from automatically moving to the top or bottom of the parent
/// window. Instead, the control keeps its position within the parent window despite
/// changes to the size of the parent. If CCS_TOP or CCS_BOTTOM is also used, the
/// height is adjusted to the default, but the position and width remain unchanged.
/// </summary>
CCS_NOPARENTALIGN = 0x00000008,
/// <summary>
/// Enables a toolbar's built-in customization features, which let the user to drag a
/// button to a new position or to remove a button by dragging it off the toolbar.
/// In addition, the user can double-click the toolbar to display the Customize Toolbar
/// dialog box, which enables the user to add, delete, and rearrange toolbar buttons.
/// </summary>
CCS_ADJUSTABLE = 0x00000020,
/// <summary>
/// Prevents a two-pixel highlight from being drawn at the top of the control.
/// </summary>
CCS_NODIVIDER = 0x00000040,
/// <summary>
/// Version 4.70. Causes the control to be displayed vertically.
/// </summary>
CCS_VERT = 0x00000080,
/// <summary>
/// Version 4.70. Causes the control to be displayed vertically on the left side of the
/// parent window.
/// </summary>
CCS_LEFT = CCS_VERT | CCS_TOP,
/// <summary>
/// Version 4.70. Causes the control to be displayed vertically on the right side of the
/// parent window.
/// </summary>
CCS_RIGHT = CCS_VERT | CCS_BOTTOM,
/// <summary>
/// Version 4.70. Causes the control to resize and move itself vertically, but not
/// horizontally, in response to a WM_SIZE message. If CCS_NORESIZE is used, this style
/// does not apply.
/// </summary>
CCS_NOMOVEX = CCS_VERT | CCS_NOMOVEY,
#endregion
#region Dialog Box Styles
/// <summary>
/// Indicates that the coordinates of the dialog box are screen coordinates.
/// If this style is not specified, the coordinates are client coordinates.
/// </summary>
DS_ABSALIGN = 0x00000001,
/// <summary>
/// This style is obsolete and is included for compatibility with 16-bit versions
/// of Windows. If you specify this style, the system creates the dialog box with
/// the WS_EX_TOPMOST style. This style does not prevent the user from accessing
/// other windows on the desktop.
///
/// Do not combine this style with the DS_CONTROL style.
/// </summary>
DS_SYSMODAL = 0x00000002,
/// <summary>
/// Obsolete. The system automatically applies the three-dimensional look to dialog
/// boxes created by applications.
/// </summary>
DS_3DLOOK = 0x00000004,
/// <summary>
/// Causes the dialog box to use the SYSTEM_FIXED_FONT instead of the default
/// SYSTEM_FONT. This is a monospace font compatible with the System font in 16-bit
/// versions of Windows earlier than 3.0.
/// </summary>
DS_FIXEDSYS = 0x00000008,
/// <summary>
/// Creates the dialog box even if errors occur for example, if a child window cannot
/// be created or if the system cannot create a special data segment for an edit control.
/// </summary>
DS_NOFAILCREATE = 0x00000010,
/// <summary>
/// Applies to 16-bit applications only. This style directs edit controls in the
/// dialog box to allocate memory from the application's data segment. Otherwise,
/// edit controls allocate storage from a global memory object.
/// </summary>
DS_LOCALEDIT = 0x00000020,
/// <summary>
/// Indicates that the header of the dialog box template (either standard or extended)
/// contains additional data specifying the font to use for text in the client area
/// and controls of the dialog box. If possible, the system selects a font according
/// to the specified font data. The system passes a handle to the font to the dialog
/// box and to each control by sending them the WM_SETFONT message. For descriptions
/// of the format of this font data, see DLGTEMPLATE and DLGTEMPLATEEX.
///
/// If neither DS_SETFONT nor DS_SHELLFONT is specified, the dialog box template does
/// not include the font data.
/// </summary>
DS_SETFONT = 0x00000040,
/// <summary>
/// Creates a dialog box with a modal dialog-box frame that can be combined with a
/// title bar and window menu by specifying the WS_CAPTION and WS_SYSMENU styles.
/// </summary>
DS_MODALFRAME = 0x00000080,
/// <summary>
/// Suppresses WM_ENTERIDLE messages that the system would otherwise send to the owner
/// of the dialog box while the dialog box is displayed.
/// </summary>
DS_NOIDLEMSG = 0x00000100,
/// <summary>
/// Causes the system to use the SetForegroundWindow function to bring the dialog box
/// to the foreground. This style is useful for modal dialog boxes that require immediate
/// attention from the user regardless of whether the owner window is the foreground
/// window.
///
/// The system restricts which processes can set the foreground window. For more
/// information, see Foreground and Background Windows.
/// </summary>
DS_SETFOREGROUND = 0x00000200,
/// <summary>
/// Creates a dialog box that works well as a child window of another dialog box, much like
/// a page in a property sheet. This style allows the user to tab among the control windows
/// of a child dialog box, use its accelerator keys, and so on.
/// </summary>
DS_CONTROL = 0x00000400,
/// <summary>
/// Centers the dialog box in the working area of the monitor that contains the owner window.
/// If no owner window is specified, the dialog box is centered in the working area of a
/// monitor determined by the system. The working area is the area not obscured by the taskbar
/// or any appbars.
/// </summary>
DS_CENTER = 0x00000800,
/// <summary>
/// Centers the dialog box on the mouse cursor.
/// </summary>
DS_CENTERMOUSE = 0x00001000,
/// <summary>
/// Includes a question mark in the title bar of the dialog box. When the user clicks the
/// question mark, the cursor changes to a question mark with a pointer. If the user then clicks
/// a control in the dialog box, the control receives a WM_HELP message. The control should pass
/// the message to the dialog box procedure, which should call the function using the
/// HELP_WM_HELP command. The help application displays a pop-up window that typically contains
/// help for the control.
///
/// Note that DS_CONTEXTHELP is only a placeholder. When the dialog box is created, the system
/// checks for DS_CONTEXTHELP and, if it is there, adds WS_EX_CONTEXTHELP to the extended style
/// of the dialog box. WS_EX_CONTEXTHELP cannot be used with the WS_MAXIMIZEBOX or WS_MINIMIZEBOX
/// styles.
/// </summary>
DS_CONTEXTHELP = 0x00002000,
/// <remarks>
/// Windows CE Version 5.0 and later
/// </remarks>
DS_USEPIXELS = 0x00008000,
/// <summary>
/// Indicates that the dialog box should use the system font. The typeface member of the extended
/// dialog box template must be set to MS Shell Dlg. Otherwise, this style has no effect. It is
/// also recommended that you use the DIALOGEX Resource, rather than the DIALOG Resource. For
/// more information, see Dialog Box Fonts.
///
/// The system selects a font using the font data specified in the pointsize, weight, and italic
/// members. The system passes a handle to the font to the dialog box and to each control by
/// sending them the WM_SETFONT message. For descriptions of the format of this font data, see
/// DLGTEMPLATEEX.
///
/// If neither DS_SHELLFONT nor DS_SETFONT is specified, the extended dialog box template does
/// not include the font data.
/// </summary>
DS_SHELLFONT = DS_SETFONT | DS_FIXEDSYS,
#endregion
}
public enum WindowsCertificateRevision : ushort
{
/// <summary>

View File

@@ -1,4 +1,5 @@
using System.Text;
using System;
using System.Text;
using System.Xml;
using BurnOutSharp.Builder;
@@ -1178,7 +1179,6 @@ namespace ExecutableTest
{
case BurnOutSharp.Models.PortableExecutable.ResourceType.RT_CURSOR:
Console.WriteLine($"{padding}Hardware-dependent cursor resource found, not parsed yet");
Console.WriteLine($"{padding}Data: {BitConverter.ToString(entry.Data).Replace("-", string.Empty)}");
break;
case BurnOutSharp.Models.PortableExecutable.ResourceType.RT_BITMAP:
Console.WriteLine($"{padding}Bitmap resource found, not parsed yet");
@@ -1190,7 +1190,69 @@ namespace ExecutableTest
Console.WriteLine($"{padding}Menu resource found, not parsed yet");
break;
case BurnOutSharp.Models.PortableExecutable.ResourceType.RT_DIALOG:
Console.WriteLine($"{padding}Dialog box found, not parsed yet");
var dialogBox = entry.AsDialogBox();
if (dialogBox == null)
{
Console.WriteLine($"{padding}Dialog box resource found, but malformed");
}
else
{
if (dialogBox.DialogTemplate != null)
{
Console.WriteLine($"{padding}Style: {dialogBox.DialogTemplate.Style}");
Console.WriteLine($"{padding}Extended style: {dialogBox.DialogTemplate.ExtendedStyle}");
Console.WriteLine($"{padding}Item count: {dialogBox.DialogTemplate.ItemCount}");
Console.WriteLine($"{padding}X-coordinate of upper-left corner: {dialogBox.DialogTemplate.PositionX}");
Console.WriteLine($"{padding}Y-coordinate of upper-left corner: {dialogBox.DialogTemplate.PositionY}");
Console.WriteLine($"{padding}Width of the dialog box: {dialogBox.DialogTemplate.WidthX}");
Console.WriteLine($"{padding}Height of the dialog box: {dialogBox.DialogTemplate.HeightY}");
Console.WriteLine($"{padding}Menu resource: {dialogBox.DialogTemplate.MenuResource ?? "[EMPTY]"}");
Console.WriteLine($"{padding}Menu resource ordinal: {dialogBox.DialogTemplate.MenuResourceOrdinal}");
Console.WriteLine($"{padding}Class resource: {dialogBox.DialogTemplate.ClassResource ?? "[EMPTY]"}");
Console.WriteLine($"{padding}Class resource ordinal: {dialogBox.DialogTemplate.ClassResourceOrdinal}");
Console.WriteLine($"{padding}Title resource: {dialogBox.DialogTemplate.TitleResource ?? "[EMPTY]"}");
Console.WriteLine($"{padding}Point size value: {dialogBox.DialogTemplate.PointSizeValue}");
Console.WriteLine($"{padding}Typeface: {dialogBox.DialogTemplate.Typeface ?? "[EMPTY]"}");
Console.WriteLine();
Console.WriteLine($"{padding}Dialog item templates");
Console.WriteLine($"{padding}-------------------------");
if (dialogBox.DialogTemplate.ItemCount == 0
|| dialogBox.DialogItemTemplates == null
|| dialogBox.DialogItemTemplates.Length == 0)
{
Console.WriteLine($"{padding}No dialog item templates");
}
else
{
for (int i = 0; i < dialogBox.DialogItemTemplates.Length; i++)
{
var dialogItemTemplate = dialogBox.DialogItemTemplates[i];
Console.WriteLine($"{padding}Dialog item template {i}");
Console.WriteLine($"{padding} Style: {dialogItemTemplate.Style}");
Console.WriteLine($"{padding} Extended style: {dialogItemTemplate.ExtendedStyle}");
Console.WriteLine($"{padding} X-coordinate of upper-left corner: {dialogItemTemplate.PositionX}");
Console.WriteLine($"{padding} Y-coordinate of upper-left corner: {dialogItemTemplate.PositionY}");
Console.WriteLine($"{padding} Width of the control: {dialogItemTemplate.WidthX}");
Console.WriteLine($"{padding} Height of the control: {dialogItemTemplate.HeightY}");
Console.WriteLine($"{padding} ID: {dialogItemTemplate.ID}");
Console.WriteLine($"{padding} Class resource: {dialogItemTemplate.ClassResource ?? "[EMPTY]"}");
Console.WriteLine($"{padding} Class resource ordinal: {dialogItemTemplate.ClassResourceOrdinal}");
Console.WriteLine($"{padding} Title resource: {dialogItemTemplate.TitleResource ?? "[EMPTY]"}");
Console.WriteLine($"{padding} Title resource ordinal: {dialogItemTemplate.TitleResourceOrdinal}");
Console.WriteLine($"{padding} Creation data size: {dialogItemTemplate.CreationDataSize}");
if (dialogItemTemplate.CreationData != null && dialogItemTemplate.CreationData.Length != 0)
Console.WriteLine($"{padding} Creation data: {BitConverter.ToString(dialogItemTemplate.CreationData).Replace("-", string.Empty)}");
else
Console.WriteLine($"{padding} Creation data: [EMPTY]");
}
}
}
else
{
Console.WriteLine($"{padding}Dialog box resource found, but malformed");
}
}
break;
case BurnOutSharp.Models.PortableExecutable.ResourceType.RT_STRING:
var stringTable = entry.AsStringTable();