diff --git a/BurnOutSharp.Builder/Extensions.cs b/BurnOutSharp.Builder/Extensions.cs index a87015aa..0dc2dc41 100644 --- a/BurnOutSharp.Builder/Extensions.cs +++ b/BurnOutSharp.Builder/Extensions.cs @@ -407,7 +407,7 @@ namespace BurnOutSharp.Builder /// /// Read resource data as an accelerator table resource /// - /// Resource data entry to parse into an accelerator table resource + /// Resource data entry to parse into an accelerator table resource /// A filled accelerator table resource on success, null on error public static Models.PortableExecutable.AcceleratorTableEntry[] AsAcceleratorTableResource(this Models.PortableExecutable.ResourceDataEntry entry) { @@ -443,7 +443,7 @@ namespace BurnOutSharp.Builder /// /// Read resource data as a side-by-side assembly manifest /// - /// Resource data entry to parse into a side-by-side assembly manifest + /// Resource data entry to parse into a side-by-side assembly manifest /// A filled side-by-side assembly manifest on success, null on error public static Models.PortableExecutable.AssemblyManifest AsAssemblyManifest(this Models.PortableExecutable.ResourceDataEntry entry) { @@ -462,10 +462,272 @@ namespace BurnOutSharp.Builder } } + /// + /// Read resource data as a dialog box + /// + /// Resource data entry to parse into a font group + /// A filled dialog box on success, null on error + 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(); + + 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; + } + /// /// Read resource data as a font group /// - /// Resource data entry to parse into a font group + /// Resource data entry to parse into a font group /// A filled font group on success, null on error 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; } /// /// Read resource data as a string table resource /// - /// Resource data entry to parse into a string table resource + /// Resource data entry to parse into a string table resource /// A filled string table resource on success, null on error public static Dictionary AsStringTable(this Models.PortableExecutable.ResourceDataEntry entry) { @@ -582,7 +844,7 @@ namespace BurnOutSharp.Builder /// /// Read resource data as a version info resource /// - /// Resource data entry to parse into a version info resource + /// Resource data entry to parse into a version info resource /// A filled version info resource on success, null on error public static Models.PortableExecutable.VersionInfo AsVersionInfo(this Models.PortableExecutable.ResourceDataEntry entry) { diff --git a/BurnOutSharp.Models/PortableExecutable/DialogBoxResource.cs b/BurnOutSharp.Models/PortableExecutable/DialogBoxResource.cs new file mode 100644 index 00000000..1bed5211 --- /dev/null +++ b/BurnOutSharp.Models/PortableExecutable/DialogBoxResource.cs @@ -0,0 +1,25 @@ +namespace BurnOutSharp.Models.PortableExecutable +{ + /// + /// 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. + /// + /// + public class DialogBoxResource + { + /// + /// Dialog box header structure + /// + public DialogTemplate DialogTemplate; + + /// + /// 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. + /// + public DialogItemTemplate[] DialogItemTemplates; + } +} diff --git a/BurnOutSharp.Models/PortableExecutable/DialogItemTemplate.cs b/BurnOutSharp.Models/PortableExecutable/DialogItemTemplate.cs new file mode 100644 index 00000000..5d0d0e83 --- /dev/null +++ b/BurnOutSharp.Models/PortableExecutable/DialogItemTemplate.cs @@ -0,0 +1,133 @@ +using System.Runtime.InteropServices; + +namespace BurnOutSharp.Models.PortableExecutable +{ + /// + /// 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. + /// + /// + [StructLayout(LayoutKind.Sequential)] + public class DialogItemTemplate + { + /// + /// 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). + /// + public WindowStyles Style; + + /// + /// 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. + /// + public ExtendedWindowStyles ExtendedStyle; + + /// + /// 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. + /// + /// + /// 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. + /// + public short PositionX; + + /// + /// 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. + /// + /// + /// 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. + /// + public short PositionY; + + /// + /// The width, in dialog box units, of the control. + /// + /// + /// 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. + /// + public short WidthX; + + /// + /// The height, in dialog box units, of the control. + /// + /// + /// 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. + /// + public short HeightY; + + /// + /// The control identifier. + /// + 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. + + /// + /// 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. + /// + /// + /// 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. + /// + public string ClassResource; + + /// + /// The ordinal value of a predefined system class. + /// + public DialogItemTemplateOrdinal ClassResourceOrdinal; + + /// + /// 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. + /// + /// + /// 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. + /// + public string TitleResource; + + /// + /// An ordinal value of a resource, such as an icon, in an executable file + /// + public ushort TitleResourceOrdinal; + + /// + /// 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). + /// + public ushort CreationDataSize; + + /// + /// 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. + /// + public byte[] CreationData; + } +} diff --git a/BurnOutSharp.Models/PortableExecutable/DialogTemplate.cs b/BurnOutSharp.Models/PortableExecutable/DialogTemplate.cs new file mode 100644 index 00000000..fe4a4bc5 --- /dev/null +++ b/BurnOutSharp.Models/PortableExecutable/DialogTemplate.cs @@ -0,0 +1,163 @@ +using System.Runtime.InteropServices; + +namespace BurnOutSharp.Models.PortableExecutable +{ + /// + /// 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. + /// + /// + [StructLayout(LayoutKind.Sequential)] + public class DialogTemplate + { + /// + /// 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. + /// + public WindowStyles Style; + + /// + /// 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. + /// + public ExtendedWindowStyles ExtendedStyle; + + /// + /// The number of items in the dialog box. + /// + public ushort ItemCount; + + /// + /// The x-coordinate, in dialog box units, of the upper-left corner of the dialog box. + /// + /// + /// 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. + /// + public short PositionX; + + /// + /// The y-coordinate, in dialog box units, of the upper-left corner of the dialog box. + /// + /// + /// 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. + /// + public short PositionY; + + /// + /// The width, in dialog box units, of the dialog box. + /// + /// + /// 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. + /// + public short WidthX; + + /// + /// The height, in dialog box units, of the dialog box. + /// + /// + /// 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. + /// + 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. + + /// + /// 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. + /// + /// + /// If you specify character strings in the menu, class, title, or typeface arrays, you must use + /// Unicode strings. + /// + public string MenuResource; + + /// + /// The ordinal value of a menu resource in an executable file. + /// + public ushort MenuResourceOrdinal; + + /// + /// 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. + /// + /// + /// If you specify character strings in the menu, class, title, or typeface arrays, you must use + /// Unicode strings. + /// + public string ClassResource; + + /// + /// The ordinal value of a predefined system class. + /// + public ushort ClassResourceOrdinal; + + /// + /// 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. + /// + /// + /// If you specify character strings in the menu, class, title, or typeface arrays, you must use + /// Unicode strings. + /// + public string TitleResource; + + /// + /// 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. + /// + public ushort PointSizeValue; + + /// + /// 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. + /// + /// + /// If you specify character strings in the menu, class, title, or typeface arrays, you must use + /// Unicode strings. + /// + public string Typeface; + } +} diff --git a/BurnOutSharp.Models/PortableExecutable/Enums.cs b/BurnOutSharp.Models/PortableExecutable/Enums.cs index 8db09aae..6dc191db 100644 --- a/BurnOutSharp.Models/PortableExecutable/Enums.cs +++ b/BurnOutSharp.Models/PortableExecutable/Enums.cs @@ -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 + { + /// + /// The window has generic left-aligned properties. This is the default. + /// + WS_EX_LEFT = 0x00000000, + + /// + /// The window text is displayed using left-to-right reading-order properties. + /// This is the default. + /// + WS_EX_LTRREADING = 0x00000000, + + /// + /// The vertical scroll bar (if present) is to the right of the client area. + /// This is the default. + /// + WS_EX_RIGHTSCROLLBAR = 0x00000000, + + /// + /// 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. + /// + WS_EX_DLGMODALFRAME = 0x00000001, + + /// + /// The child window created with this style does not send the WM_PARENTNOTIFY + /// message to its parent window when it is created or destroyed. + /// + WS_EX_NOPARENTNOTIFY = 0x00000004, + + /// + /// 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. + /// + WS_EX_TOPMOST = 0x00000008, + + /// + /// The window accepts drag-drop files. + /// + WS_EX_ACCEPTFILES = 0x00000010, + + /// + /// 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. + /// + WS_EX_TRANSPARENT = 0x00000020, + + /// + /// The window is a MDI child window. + /// + WS_EX_MDICHILD = 0x00000040, + + /// + /// 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. + /// + WS_EX_TOOLWINDOW = 0x00000080, + + /// + /// The window has a border with a raised edge. + /// + WS_EX_WINDOWEDGE = 0x00000100, + + /// + /// The window has a border with a sunken edge. + /// + WS_EX_CLIENTEDGE = 0x00000200, + + /// + /// 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. + /// + WS_EX_CONTEXTHELP = 0x00000400, + + /// + /// 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. + /// + WS_EX_RIGHT = 0x00001000, + + /// + /// 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. + /// + WS_EX_RTLREADING = 0x00002000, + + /// + /// 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. + /// + WS_EX_LEFTSCROLLBAR = 0x00004000, + + /// + /// 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. + /// + WS_EX_CONTROLPARENT = 0x00010000, + + /// + /// The window has a three-dimensional border style intended to be used for items that do + /// not accept user input. + /// + WS_EX_STATICEDGE = 0x00020000, + + /// + /// Forces a top-level window onto the taskbar when the window is visible. + /// + WS_EX_APPWINDOW = 0x00040000, + + /// + /// 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. + /// + WS_EX_LAYERED = 0x00080000, + + /// + /// The window does not pass its window layout to its child windows. + /// + WS_EX_NOINHERITLAYOUT = 0x00100000, + + /// + /// 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. + /// + WS_EX_NOREDIRECTIONBITMAP = 0x00200000, + + /// + /// 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. + /// + WS_EX_LAYOUTRTL = 0x00400000, + + /// + /// 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. + /// + WS_EX_COMPOSITED = 0x02000000, + + /// + /// 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. + /// + WS_EX_NOACTIVATE = 0x08000000, + + /// + /// The window is an overlapped window. + /// + WS_EX_OVERLAPPEDWINDOW = WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE, + + /// + /// The window is palette window, which is a modeless dialog box that presents an array of + /// commands. + /// + WS_EX_PALETTEWINDOW = WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST, + } + public enum FixedFileInfoFileSubtype : uint { /// @@ -2589,6 +2802,398 @@ namespace BurnOutSharp.Models.PortableExecutable TextData = 1, } + [Flags] + public enum WindowStyles : uint + { + #region Standard Styles + + /// + /// The window is an overlapped window. An overlapped window has a title + /// bar and a border. Same as the WS_TILED style. + /// + WS_OVERLAPPED = 0x00000000, + + /// + /// The window is an overlapped window. An overlapped window has a title bar + /// and a border. Same as the WS_OVERLAPPED style. + /// + WS_TILED = 0x00000000, + + /// + /// The window has a maximize button. Cannot be combined with the + /// WS_EX_CONTEXTHELP style. The WS_SYSMENU style must also be specified. + /// + WS_MAXIMIZEBOX = 0x00010000, + + /// + /// 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. + /// + WS_TABSTOP = 0x00010000, + + /// + /// The window has a minimize button. Cannot be combined with the + /// WS_EX_CONTEXTHELP style. The WS_SYSMENU style must also be specified. + /// + WS_MINIMIZEBOX = 0x00020000, + + /// + /// 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. + /// + WS_GROUP = 0x00020000, + + /// + /// The window has a sizing border. Same as the WS_THICKFRAME style. + /// + WS_SIZEBOX = 0x00040000, + + /// + /// The window has a sizing border. Same as the WS_SIZEBOX style. + /// + WS_THICKFRAME = 0x00040000, + + /// + /// The window has a window menu on its title bar. The WS_CAPTION style must + /// also be specified. + /// + WS_SYSMENU = 0x00080000, + + /// + /// The window has a horizontal scroll bar. + /// + WS_HSCROLL = 0x00100000, + + /// + /// The window has a vertical scroll bar. + /// + WS_VSCROLL = 0x00200000, + + /// + /// The window has a border of a style typically used with dialog boxes. A + /// window with this style cannot have a title bar. + /// + WS_DLGFRAME = 0x00400000, + + /// + /// The window has a thin-line border + /// + WS_BORDER = 0x00800000, + + /// + /// The window has a title bar + /// + WS_CAPTION = 0x00C00000, + + /// + /// The window is initially maximized. + /// + WS_MAXIMIZE = 0x01000000, + + /// + /// Excludes the area occupied by child windows when drawing occurs within the + /// parent window. This style is used when creating the parent window. + /// + WS_CLIPCHILDREN = 0x02000000, + + /// + /// 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. + /// + WS_CLIPSIBLINGS = 0x04000000, + + /// + /// 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. + /// + WS_DISABLED = 0x08000000, + + /// + /// The window is initially visible. + /// This style can be turned on and off by using the ShowWindow or SetWindowPos + /// function. + /// + WS_VISIBLE = 0x10000000, + + /// + /// The window is initially minimized. Same as the WS_MINIMIZE style. + /// + WS_ICONIC = 0x20000000, + + /// + /// The window is initially minimized. Same as the WS_ICONIC style. + /// + WS_MINIMIZE = 0x20000000, + + /// + /// 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. + /// + WS_CHILD = 0x40000000, + + /// + /// Same as the WS_CHILD style. + /// + WS_CHILDWINDOW = 0x40000000, + + /// + /// The window is a pop-up window. This style cannot be used with the WS_CHILD style. + /// + WS_POPUP = 0x80000000, + + /// + /// The window is an overlapped window. Same as the WS_TILEDWINDOW style. + /// + WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, + + /// + /// The window is a pop-up window. The WS_CAPTION and WS_POPUPWINDOW styles must be + /// combined to make the window menu visible. + /// + WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU, + + /// + /// The window is an overlapped window. Same as the WS_OVERLAPPEDWINDOW style. + /// + WS_TILEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, + + #endregion + + #region Common Control Styles + + /// + /// 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. + /// + CCS_TOP = 0x00000001, + + /// + /// 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. + /// + CCS_NOMOVEY = 0x00000002, + + /// + /// 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. + /// + CCS_BOTTOM = 0x00000003, + + /// + /// 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. + /// + CCS_NORESIZE = 0x00000004, + + /// + /// 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. + /// + CCS_NOPARENTALIGN = 0x00000008, + + /// + /// 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. + /// + CCS_ADJUSTABLE = 0x00000020, + + /// + /// Prevents a two-pixel highlight from being drawn at the top of the control. + /// + CCS_NODIVIDER = 0x00000040, + + /// + /// Version 4.70. Causes the control to be displayed vertically. + /// + CCS_VERT = 0x00000080, + + /// + /// Version 4.70. Causes the control to be displayed vertically on the left side of the + /// parent window. + /// + CCS_LEFT = CCS_VERT | CCS_TOP, + + /// + /// Version 4.70. Causes the control to be displayed vertically on the right side of the + /// parent window. + /// + CCS_RIGHT = CCS_VERT | CCS_BOTTOM, + + /// + /// 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. + /// + CCS_NOMOVEX = CCS_VERT | CCS_NOMOVEY, + + #endregion + + #region Dialog Box Styles + + /// + /// Indicates that the coordinates of the dialog box are screen coordinates. + /// If this style is not specified, the coordinates are client coordinates. + /// + DS_ABSALIGN = 0x00000001, + + /// + /// 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. + /// + DS_SYSMODAL = 0x00000002, + + /// + /// Obsolete. The system automatically applies the three-dimensional look to dialog + /// boxes created by applications. + /// + DS_3DLOOK = 0x00000004, + + /// + /// 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. + /// + DS_FIXEDSYS = 0x00000008, + + /// + /// 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. + /// + DS_NOFAILCREATE = 0x00000010, + + /// + /// 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. + /// + DS_LOCALEDIT = 0x00000020, + + /// + /// 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. + /// + DS_SETFONT = 0x00000040, + + /// + /// 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. + /// + DS_MODALFRAME = 0x00000080, + + /// + /// Suppresses WM_ENTERIDLE messages that the system would otherwise send to the owner + /// of the dialog box while the dialog box is displayed. + /// + DS_NOIDLEMSG = 0x00000100, + + /// + /// 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. + /// + DS_SETFOREGROUND = 0x00000200, + + /// + /// 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. + /// + DS_CONTROL = 0x00000400, + + /// + /// 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. + /// + DS_CENTER = 0x00000800, + + /// + /// Centers the dialog box on the mouse cursor. + /// + DS_CENTERMOUSE = 0x00001000, + + /// + /// 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. + /// + DS_CONTEXTHELP = 0x00002000, + + /// + /// Windows CE Version 5.0 and later + /// + DS_USEPIXELS = 0x00008000, + + /// + /// 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. + /// + DS_SHELLFONT = DS_SETFONT | DS_FIXEDSYS, + + #endregion + } + public enum WindowsCertificateRevision : ushort { /// diff --git a/ExecutableTest/Program.cs b/ExecutableTest/Program.cs index 8e58da88..f1aaddff 100644 --- a/ExecutableTest/Program.cs +++ b/ExecutableTest/Program.cs @@ -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();