mirror of
https://github.com/claunia/libexeinfo.git
synced 2025-12-16 19:14:24 +00:00
Added MagiC resource format.
This commit is contained in:
@@ -201,7 +201,7 @@ namespace exeinfo
|
||||
if(!recognized) Console.WriteLine("Executable format not recognized");
|
||||
}
|
||||
|
||||
static void PrintGemResources(GEM.GemResourceHeader resourceHeader, IReadOnlyList<GEM.TreeObjectNode> roots,
|
||||
static void PrintGemResources(GEM.MagiCResourceHeader resourceHeader, IReadOnlyList<GEM.TreeObjectNode> roots,
|
||||
GEM.GemResourceExtension resourceExtension,
|
||||
GEM.ColorIcon[] colorIcons)
|
||||
{
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace libexeinfo
|
||||
{
|
||||
public GEM.ColorIcon[] GemColorIcons;
|
||||
public GEM.GemResourceExtension ResourceExtension;
|
||||
public GEM.GemResourceHeader ResourceHeader;
|
||||
public GEM.MagiCResourceHeader ResourceHeader;
|
||||
public GEM.TreeObjectNode[] ResourceObjectRoots;
|
||||
public Stream ResourceStream;
|
||||
|
||||
@@ -133,10 +133,20 @@ namespace libexeinfo
|
||||
buffer = new byte[Marshal.SizeOf(typeof(GEM.GemResourceHeader))];
|
||||
ResourceStream.Position = 0;
|
||||
ResourceStream.Read(buffer, 0, buffer.Length);
|
||||
ResourceHeader = BigEndianMarshal.ByteArrayToStructureBigEndian<GEM.GemResourceHeader>(buffer);
|
||||
GEM.GemResourceHeader gemResourceHeader =
|
||||
BigEndianMarshal.ByteArrayToStructureBigEndian<GEM.GemResourceHeader>(buffer);
|
||||
|
||||
if(ResourceHeader.rsh_vrsn != 0 && ResourceHeader.rsh_vrsn != 1 && ResourceHeader.rsh_vrsn != 4 &&
|
||||
ResourceHeader.rsh_vrsn != 5) return;
|
||||
if(gemResourceHeader.rsh_vrsn != 0 && gemResourceHeader.rsh_vrsn != 1 && gemResourceHeader.rsh_vrsn != 3 &&
|
||||
gemResourceHeader.rsh_vrsn != 4 && gemResourceHeader.rsh_vrsn != 5) return;
|
||||
|
||||
if(gemResourceHeader.rsh_vrsn == 3)
|
||||
{
|
||||
buffer = new byte[Marshal.SizeOf(typeof(GEM.MagiCResourceHeader))];
|
||||
ResourceStream.Position = 0;
|
||||
ResourceStream.Read(buffer, 0, buffer.Length);
|
||||
ResourceHeader = BigEndianMarshal.ByteArrayToStructureBigEndian<GEM.MagiCResourceHeader>(buffer);
|
||||
}
|
||||
else ResourceHeader = GEM.GemToMagiC(gemResourceHeader);
|
||||
|
||||
if((ResourceHeader.rsh_vrsn & 4) == 4)
|
||||
{
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace libexeinfo
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum ObjectFlags : short
|
||||
public enum ObjectFlags : ushort
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that the user can select the object
|
||||
@@ -123,7 +123,53 @@ namespace libexeinfo
|
||||
/// <summary>
|
||||
/// Indicates that the value in <see cref="ObjectNode.ob_spec" /> is a pointer to the actual value.
|
||||
/// </summary>
|
||||
Indirect = 0x0100
|
||||
Indirect = 0x0100,
|
||||
/// <summary>
|
||||
/// Under MultiTOS this object creates a three-dimensional object.
|
||||
/// </summary>
|
||||
Fl3Dind = 0x0200,
|
||||
/// <summary>
|
||||
/// Pressing the [Esc] key corresponds to the selection of the object with this flag.
|
||||
/// </summary>
|
||||
EscCancel = 0x0200,
|
||||
/// <summary>
|
||||
/// In 3D operation this object will be treated as an AES background object.
|
||||
/// </summary>
|
||||
Fl3DBak = 0x0400,
|
||||
/// <summary>
|
||||
/// A button with this flag uses a bitmap instead of text.
|
||||
/// </summary>
|
||||
BitButton = 0x0400,
|
||||
/// <summary>
|
||||
/// In 3D operation this object will be treated as an activator.
|
||||
/// </summary>
|
||||
Fl3DAct = 0x0600,
|
||||
/// <summary>
|
||||
/// In MultiTOS and from MagiC 5.10 this flag indicates submenus.
|
||||
/// </summary>
|
||||
SubMenu = 0x0800,
|
||||
/// <summary>
|
||||
/// Pressing the [PAGEUP] key corresponds to the selection of the first object with this flag in the dialog. Pressing
|
||||
/// the [PAGEDOWN] key corresponds to the selection of the last object with this flag.
|
||||
/// </summary>
|
||||
Scroller = 0x0800,
|
||||
/// <summary>
|
||||
/// An object with this flag will be drawn with a 3D border.
|
||||
/// </summary>
|
||||
Flag3D = 0x1000,
|
||||
/// <summary>
|
||||
/// The color of the object is not a color index of the VDI, but an entry in a table with colors for designated
|
||||
/// categories.
|
||||
/// </summary>
|
||||
UseColorCat = 0x2000,
|
||||
/// <summary>
|
||||
/// Sunken 3D background
|
||||
/// </summary>
|
||||
Fl3DBak2 = 0x4000,
|
||||
/// <summary>
|
||||
/// Not implemented
|
||||
/// </summary>
|
||||
SubMenu2 = 0x8000
|
||||
}
|
||||
|
||||
public enum ObjectFont : short
|
||||
@@ -140,7 +186,7 @@ namespace libexeinfo
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum ObjectStates : short
|
||||
public enum ObjectStates : ushort
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that the object is highlighted by being drawn with reversed colors
|
||||
@@ -165,7 +211,25 @@ namespace libexeinfo
|
||||
/// <summary>
|
||||
/// Indicates that the object (usually a box) is drawn with a drop shadow
|
||||
/// </summary>
|
||||
Shadowed = 0x0020
|
||||
Shadowed = 0x0020,
|
||||
/// <summary>
|
||||
/// In PC-GEM ignores icon background. As of MagiC 3 controls the underscoring of character strings.
|
||||
/// </summary>
|
||||
Whitebak = 0x0040,
|
||||
/// <summary>
|
||||
/// Indicates that the object is to be drawn with a 3D effect.
|
||||
/// </summary>
|
||||
Draw3D = 0x0080,
|
||||
/// <summary>
|
||||
/// An object with this status will be surrounded by a dashed line.
|
||||
/// </summary>
|
||||
Highlighted = 0x0100,
|
||||
/// <summary>
|
||||
/// Setting this state undoes the line by <see cref="Highlighted" />
|
||||
/// </summary>
|
||||
Unhighlighted = 0x0200,
|
||||
Underline = 0x0F00,
|
||||
Xstate = 0xF000
|
||||
}
|
||||
|
||||
public enum ObjectTypes : short
|
||||
@@ -190,7 +254,8 @@ namespace libexeinfo
|
||||
/// </summary>
|
||||
G_IMAGE = 23,
|
||||
/// <summary>
|
||||
/// A programmed defined object. Its <see cref="ObjectNode.ob_spec" /> is a pointer to a <see cref="ApplicationBlock" />
|
||||
/// A programmed defined object. Its <see cref="ObjectNode.ob_spec" /> is a pointer to a
|
||||
/// <see cref="ApplicationBlock" />
|
||||
/// structure.
|
||||
/// </summary>
|
||||
G_USERDEF = 24,
|
||||
@@ -238,10 +303,36 @@ namespace libexeinfo
|
||||
G_TITLE = 32,
|
||||
/// <summary>
|
||||
/// An object that describes a color icon. Its <see cref="ObjectNode.ob_spec" /> is a pointer to an
|
||||
/// <see cref="ColorIconBlock" />
|
||||
/// structure.
|
||||
/// <see cref="ColorIconBlock" /> structure.
|
||||
/// </summary>
|
||||
G_CICON = 33
|
||||
G_CICON = 33,
|
||||
/// <summary>
|
||||
/// An object that describes a cycle button (a button which alters its text cyclically when clicked on).
|
||||
/// Its <see cref="ObjectNode.ob_spec" /> is a pointer to a <see cref="SwInfoBlock" /> structure.
|
||||
/// </summary>
|
||||
G_SWBUTTON = 34,
|
||||
/// <summary>
|
||||
/// An object that describes a popup menu. Its <see cref="ObjectNode.ob_spec" /> is a pointer to a
|
||||
/// <see cref="PopInfoBlock" /> structure.
|
||||
/// </summary>
|
||||
G_POPUP = 35,
|
||||
/// <summary>
|
||||
/// This object is user internally by MagiC to depict window titles.
|
||||
/// </summary>
|
||||
G_WINTITLE = 36,
|
||||
/// <summary>
|
||||
/// As of MagiC 5.20 an editable object implemented in a shared library. Its <see cref="ObjectNode.ob_spec" /> is a
|
||||
/// pointer to the object.
|
||||
/// </summary>
|
||||
G_EDIT = 37,
|
||||
/// <summary>
|
||||
/// Similar to <see cref="G_STRING" />, but any keyboard shortcut present is split off and output ranged right.
|
||||
/// </summary>
|
||||
G_SHORTCUT = 38,
|
||||
/// <summary>
|
||||
/// Scrolling list
|
||||
/// </summary>
|
||||
G_SLIST = 39
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -157,8 +157,10 @@ namespace libexeinfo
|
||||
buffer = new byte[Marshal.SizeOf(typeof(ApplicationBlock))];
|
||||
resourceStream.Read(buffer, 0, buffer.Length);
|
||||
node.ApplicationBlock = bigEndian
|
||||
? BigEndianMarshal.ByteArrayToStructureBigEndian<ApplicationBlock>(buffer)
|
||||
: BigEndianMarshal.ByteArrayToStructureLittleEndian<ApplicationBlock>(buffer);
|
||||
? BigEndianMarshal
|
||||
.ByteArrayToStructureBigEndian<ApplicationBlock>(buffer)
|
||||
: BigEndianMarshal
|
||||
.ByteArrayToStructureLittleEndian<ApplicationBlock>(buffer);
|
||||
break;
|
||||
case ObjectTypes.G_ICON:
|
||||
if(node.data <= 0 || node.data >= resourceStream.Length) break;
|
||||
@@ -178,6 +180,7 @@ namespace libexeinfo
|
||||
case ObjectTypes.G_BUTTON:
|
||||
case ObjectTypes.G_STRING:
|
||||
case ObjectTypes.G_TITLE:
|
||||
case ObjectTypes.G_SHORTCUT:
|
||||
if(node.data <= 0 || node.data >= resourceStream.Length) break;
|
||||
|
||||
resourceStream.Position = node.data;
|
||||
@@ -492,5 +495,30 @@ namespace libexeinfo
|
||||
|
||||
return colorIcons;
|
||||
}
|
||||
|
||||
public static MagiCResourceHeader GemToMagiC(GemResourceHeader header)
|
||||
{
|
||||
return new MagiCResourceHeader
|
||||
{
|
||||
rsh_vrsn = header.rsh_vrsn,
|
||||
rsh_object = header.rsh_object,
|
||||
rsh_tedinfo = header.rsh_tedinfo,
|
||||
rsh_iconblk = header.rsh_iconblk,
|
||||
rsh_bitblk = header.rsh_bitblk,
|
||||
rsh_frstr = header.rsh_frstr,
|
||||
rsh_string = header.rsh_string,
|
||||
rsh_imdata = header.rsh_imdata,
|
||||
rsh_frimg = header.rsh_frimg,
|
||||
rsh_trindex = header.rsh_trindex,
|
||||
rsh_nobs = header.rsh_nobs,
|
||||
rsh_ntree = header.rsh_ntree,
|
||||
rsh_nted = header.rsh_nted,
|
||||
rsh_nib = header.rsh_nib,
|
||||
rsh_nbb = header.rsh_nbb,
|
||||
rsh_nstring = header.rsh_nstring,
|
||||
rsh_nimages = header.rsh_nimages,
|
||||
rsh_rssize = header.rsh_rssize
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,6 +110,88 @@ namespace libexeinfo
|
||||
public short rsh_rssize;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct MagiCResourceHeader
|
||||
{
|
||||
/// <summary>
|
||||
/// Must be version 3
|
||||
/// </summary>
|
||||
public short rsh_vrsn;
|
||||
/// <summary>
|
||||
/// Not used
|
||||
/// </summary>
|
||||
public short rsh_extvrsn;
|
||||
/// <summary>
|
||||
/// Contains an offset from the beginning of the file to the OBJECT structures.
|
||||
/// </summary>
|
||||
public int rsh_object;
|
||||
/// <summary>
|
||||
/// Contains an offset from the beginning of the file to the TEDINFO structures.
|
||||
/// </summary>
|
||||
public int rsh_tedinfo;
|
||||
/// <summary>
|
||||
/// Contains an offset from the beginning of the file to the ICONBLK structures.
|
||||
/// </summary>
|
||||
public int rsh_iconblk;
|
||||
/// <summary>
|
||||
/// Contains an offset from the beginning of the file to the BITBLK structures.
|
||||
/// </summary>
|
||||
public int rsh_bitblk;
|
||||
/// <summary>
|
||||
/// Contains an offset from the beginning of the file to the string pointer table.
|
||||
/// </summary>
|
||||
public int rsh_frstr;
|
||||
/// <summary>
|
||||
/// Contains an offset from the beginning of the file to the string data.
|
||||
/// </summary>
|
||||
public int rsh_string;
|
||||
/// <summary>
|
||||
/// Contains an offset from the beginning of the file to the image data.
|
||||
/// </summary>
|
||||
public int rsh_imdata;
|
||||
/// <summary>
|
||||
/// Contains an offset from the beginning of the file to the image pointer table.
|
||||
/// </summary>
|
||||
public int rsh_frimg;
|
||||
/// <summary>
|
||||
/// Contains an offset from the beginning of the file to the tree pointer table.
|
||||
/// </summary>
|
||||
public int rsh_trindex;
|
||||
/// <summary>
|
||||
/// Number of OBJECTs in the file.
|
||||
/// </summary>
|
||||
public int rsh_nobs;
|
||||
/// <summary>
|
||||
/// Number of object trees in the file.
|
||||
/// </summary>
|
||||
public int rsh_ntree;
|
||||
/// <summary>
|
||||
/// Number of TEDINFOs in the file.
|
||||
/// </summary>
|
||||
public int rsh_nted;
|
||||
/// <summary>
|
||||
/// Number of ICONBLKs in the file.
|
||||
/// </summary>
|
||||
public int rsh_nib;
|
||||
/// <summary>
|
||||
/// Number of BITBLKs in the file.
|
||||
/// </summary>
|
||||
public int rsh_nbb;
|
||||
/// <summary>
|
||||
/// Number of free strings in the file.
|
||||
/// </summary>
|
||||
public int rsh_nstring;
|
||||
/// <summary>
|
||||
/// Number of free images in the file.
|
||||
/// </summary>
|
||||
public int rsh_nimages;
|
||||
/// <summary>
|
||||
/// Size of the resource file (in bytes). Note that this is the size of the old format resource file. If the newer
|
||||
/// format file is being used then this value can be used as an offset to the extension array.
|
||||
/// </summary>
|
||||
public int rsh_rssize;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct GemResourceExtension
|
||||
{
|
||||
@@ -191,20 +273,20 @@ namespace libexeinfo
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public class TreeObjectNode
|
||||
{
|
||||
public BitmapBlock BitBlock;
|
||||
public TreeObjectNode child;
|
||||
public ColorIcon ColorIcon;
|
||||
public int data;
|
||||
public ObjectFlags flags;
|
||||
public short height;
|
||||
public Icon IconBlock;
|
||||
public TreeObjectNode sibling;
|
||||
public ObjectStates state;
|
||||
public string String;
|
||||
public ApplicationBlock ApplicationBlock;
|
||||
public BitmapBlock BitBlock;
|
||||
public TreeObjectNode child;
|
||||
public ColorIcon ColorIcon;
|
||||
public int data;
|
||||
public ObjectFlags flags;
|
||||
public short height;
|
||||
public Icon IconBlock;
|
||||
public TreeObjectNode sibling;
|
||||
public ObjectStates state;
|
||||
public string String;
|
||||
|
||||
public TextBlock TedInfo;
|
||||
public ObjectTypes type;
|
||||
public ApplicationBlock ApplicationBlock;
|
||||
public short width;
|
||||
public short x;
|
||||
public short y;
|
||||
@@ -432,7 +514,8 @@ namespace libexeinfo
|
||||
|
||||
/// <summary>
|
||||
/// The APPLBLK structure is used to locate and call an application-defined routine that will draw and/or change an
|
||||
/// object. The object type G_USERDEF points with its <see cref="ObjectNode.ob_spec" /> pointer to an USERBLK structure.
|
||||
/// object. The object type G_USERDEF points with its <see cref="ObjectNode.ob_spec" /> pointer to an USERBLK
|
||||
/// structure.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct ApplicationBlock
|
||||
@@ -442,7 +525,7 @@ namespace libexeinfo
|
||||
/// </summary>
|
||||
public int ab_code;
|
||||
/// <summary>
|
||||
/// A pointer to a <see cref="ParameterBlock"/>
|
||||
/// A pointer to a <see cref="ParameterBlock" />
|
||||
/// </summary>
|
||||
public int ab_parm;
|
||||
}
|
||||
@@ -502,12 +585,14 @@ namespace libexeinfo
|
||||
/// </summary>
|
||||
public short pb_hc;
|
||||
/// <summary>
|
||||
/// A long value, identical to <see cref="ApplicationBlock.ab_parm" />, that is passed to the application when it is time for
|
||||
/// A long value, identical to <see cref="ApplicationBlock.ab_parm" />, that is passed to the application when it is
|
||||
/// time for
|
||||
/// the application to draw or change the object. Low word.
|
||||
/// </summary>
|
||||
public short pb_parm_low;
|
||||
/// <summary>
|
||||
/// A long value, identical to <see cref="ApplicationBlock.ab_parm" />, that is passed to the application when it is time for
|
||||
/// A long value, identical to <see cref="ApplicationBlock.ab_parm" />, that is passed to the application when it is
|
||||
/// time for
|
||||
/// the application to draw or change the object. High word.
|
||||
/// </summary>
|
||||
public short pb_parm_high;
|
||||
@@ -545,5 +630,35 @@ namespace libexeinfo
|
||||
/// </summary>
|
||||
public int next_res;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct PopInfoBlock
|
||||
{
|
||||
/// <summary>
|
||||
/// Points to the start of an object tree that corresponds to the popup menu
|
||||
/// </summary>
|
||||
public int tree;
|
||||
/// <summary>
|
||||
/// Current object of
|
||||
/// </summary>
|
||||
public short obnum;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct SwInfoBlock
|
||||
{
|
||||
/// <summary>
|
||||
/// Points to the string
|
||||
/// </summary>
|
||||
public int str;
|
||||
/// <summary>
|
||||
/// Index of the current character string
|
||||
/// </summary>
|
||||
public short num;
|
||||
/// <summary>
|
||||
/// Maximum permitted number
|
||||
/// </summary>
|
||||
public short maxnum;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ namespace libexeinfo
|
||||
/// </summary>
|
||||
internal MZHeader Header;
|
||||
public GEM.GemResourceExtension ResourceExtension;
|
||||
public GEM.GemResourceHeader ResourceHeader;
|
||||
public GEM.MagiCResourceHeader ResourceHeader;
|
||||
public GEM.TreeObjectNode[] ResourceObjectRoots;
|
||||
public Stream ResourceStream;
|
||||
|
||||
@@ -149,10 +149,20 @@ namespace libexeinfo
|
||||
buffer = new byte[Marshal.SizeOf(typeof(GEM.GemResourceHeader))];
|
||||
ResourceStream.Position = 0;
|
||||
ResourceStream.Read(buffer, 0, buffer.Length);
|
||||
ResourceHeader = BigEndianMarshal.ByteArrayToStructureLittleEndian<GEM.GemResourceHeader>(buffer);
|
||||
GEM.GemResourceHeader gemResourceHeader =
|
||||
BigEndianMarshal.ByteArrayToStructureLittleEndian<GEM.GemResourceHeader>(buffer);
|
||||
|
||||
if(ResourceHeader.rsh_vrsn != 0 && ResourceHeader.rsh_vrsn != 1 && ResourceHeader.rsh_vrsn != 4 &&
|
||||
ResourceHeader.rsh_vrsn != 5) return;
|
||||
if(gemResourceHeader.rsh_vrsn != 0 && gemResourceHeader.rsh_vrsn != 1 && gemResourceHeader.rsh_vrsn != 3 &&
|
||||
gemResourceHeader.rsh_vrsn != 4 && gemResourceHeader.rsh_vrsn != 5) return;
|
||||
|
||||
if(gemResourceHeader.rsh_vrsn == 3)
|
||||
{
|
||||
buffer = new byte[Marshal.SizeOf(typeof(GEM.MagiCResourceHeader))];
|
||||
ResourceStream.Position = 0;
|
||||
ResourceStream.Read(buffer, 0, buffer.Length);
|
||||
ResourceHeader = BigEndianMarshal.ByteArrayToStructureLittleEndian<GEM.MagiCResourceHeader>(buffer);
|
||||
}
|
||||
else ResourceHeader = GEM.GemToMagiC(gemResourceHeader);
|
||||
|
||||
if((ResourceHeader.rsh_vrsn & 4) == 4)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user