Compare commits

126 Commits
v0.2 ... master

Author SHA1 Message Date
f3d9f2dee7 Add more test executables. 2018-03-15 13:27:00 +00:00
049a9135c0 Neither Haiku nor BeOS >=R4 store resources in an ELF section but in an extended attribute. 2018-03-15 13:25:43 +00:00
bdecb2d0d8 Add another way of detecting Haiku executables. 2018-03-15 13:23:51 +00:00
c4b2ef6945 Add more test executables. 2018-03-15 11:38:15 +00:00
6305cfdf66 Add headers. 2018-03-15 11:35:02 +00:00
22e6cab198 Add ELF detection if Dell System V, UnixWare, PowerPC OS/2, NonStop Kernel for MIPS, Solaris/ppc and Amiga UNIX. 2018-03-15 11:31:53 +00:00
a6d5abe8f1 Handle OpenVMS ELF notes, as the only ones found using 64-bit fields. 2018-03-15 10:59:41 +00:00
7c9d288fcb Handle ELF notes with arrays. 2018-03-15 10:30:13 +00:00
8644a36e40 Handle ELF files with incorrect section header pointer. 2018-03-15 10:14:25 +00:00
93ce2ab0ab Decode ELF OS tag from notes that are in program headers on files without section headers. 2018-03-15 09:56:39 +00:00
7f78c4f151 Decode ELF architecture. 2018-03-15 00:49:28 +00:00
51f2591a82 Support ELF files without sections but with program headers. 2018-03-14 23:13:24 +00:00
60601230e3 Add detection of BeOS, Haiku, Solaris, LynxOS, SkyOS, Android, BSD/OS, QNX, DG/UX, AmigaOS, AROS and MorphOS on ELF executables. 2018-03-14 16:00:26 +00:00
ac6cf3d1c2 Decode ELF version tags from FreeBSD, MINIX, OpenBSD and NetBSD. 2018-03-13 20:00:53 +00:00
bb6b17800f Decode ELF GNU ABI tag and build ID. 2018-03-13 18:33:05 +00:00
3945a53fce Decode ELF notes. 2018-03-13 18:10:09 +00:00
d4ae6253f0 Decode ELF information. 2018-03-13 17:27:13 +00:00
803973496b Add ELF structures and detection. 2018-03-13 03:20:12 +00:00
dbb936c760 Fill BeOS version strings to PE as UTF-8 strings. 2018-03-10 19:12:58 +00:00
5f82a969d8 Add decoding of Haiku PNG icons. 2018-03-10 19:12:45 +00:00
6486b78716 Add decoding for BeOS version resource. 2018-03-10 18:53:16 +00:00
cc6ddf378e Add GUI to decode BeOS icons. 2018-03-10 18:08:40 +00:00
315454ce02 Add more BeOS resource types. 2018-03-10 18:08:24 +00:00
1e26c119a8 Add GUI for BeOS resources. 2018-03-10 16:54:07 +00:00
22d1b6e1f8 Correct handling of BeOS resource index. 2018-03-10 16:52:38 +00:00
0b669a62bf Add decoding of BeOS resources section. (It's the same on ELF and PEFF).
Thanks to @waddlesplash for pointing me to the structures.
2018-03-10 16:14:52 +00:00
61521fe4d3 Make hex dump panel faster. 2018-03-09 17:46:08 +00:00
c24f44cfb7 Add GUI viewers for PE resources. 2018-03-09 17:45:58 +00:00
5d6a0c1766 Decode RT_STRING from PE resources. 2018-03-09 16:58:28 +00:00
a2ed853dc1 Move common RT_VERSION structures to both PE and NE to Windows class. 2018-03-09 16:36:39 +00:00
658a82ac10 Decode RT_VERSION resource from PE executables. 2018-03-09 16:21:19 +00:00
e18d4c26c3 Decode Windows resources from PE. 2018-03-09 15:29:57 +00:00
b11468bfdc Split resource types and id-to-name converters from NE to Windows/OS2 classes as they are used also by LX and PE formats. 2018-03-09 14:56:56 +00:00
5fdb9a2452 Add more test executables. 2018-03-09 12:43:48 +00:00
f91efd1568 Add decoding of section list, .edata, .idata and .debug from PE. Also recognize BeOS and Singularity executables. 2018-03-09 12:42:56 +00:00
3d2b2adb71 Add panel to view LX resources. 2018-03-08 17:19:32 +00:00
a22c0fea3b Add more test executables. 2018-03-08 16:51:22 +00:00
26007b6b8b Add full decoding of LE and LX objects, tables, and resource tables, plus viewer for LE VxD version resource. 2018-03-08 16:50:25 +00:00
4e130af164 Update copyright year. 2018-03-07 20:15:17 +00:00
8a67fffbd2 Use GEOS character set. 2018-03-07 20:12:19 +00:00
7f5c4f87c5 Added several GEOS test executables. 2018-03-07 18:16:45 +00:00
079d677f76 Change how GEOS application version is shown to how GEOS shows it. 2018-03-07 18:16:31 +00:00
150a6ad828 Add more test executables. 2018-03-07 15:55:37 +00:00
abd532981a Add support for GEOS v1 and v2 executables (resource format is unknown). 2018-03-07 15:55:18 +00:00
7106e39901 Corrected test executable format. 2018-03-06 18:01:23 +00:00
249161a3a3 Separated common operating system structures from executable format to their own namespace. 2018-03-06 17:55:47 +00:00
1f31619ad5 Added other known OS/2 structures. 2018-03-06 17:40:12 +00:00
b8e89849fe Some OS/2 executables contain Windows "RT_ICON" resources, in OS/2 NE format, so show them as such in the GUI. 2018-03-06 17:39:48 +00:00
095221a349 Add decoding of Windows icons, panel for RT_ICON resources in NE, and detect Windows icon inside OS/2 RT_POINTER resources in NE. 2018-03-06 15:48:43 +00:00
54cc979d0e Add test executables for EFI PE. 2018-03-06 07:16:56 +00:00
6b988e16fb Add panel to view OS/2 icons, bitmaps and pointers in NE executables. 2018-03-05 15:01:57 +00:00
2c89daf694 Correct when OS/2 bitmap size is image size and not header size. 2018-03-05 15:01:33 +00:00
432f11ea57 Add pointer and bitmap extensions to icon viewer. 2018-03-05 14:17:15 +00:00
2085f0c6fc Add list of icons to icon viewer. 2018-03-05 14:02:36 +00:00
081292f2d0 Correct calculation of data length when icon size is not word or byte aligned. 2018-03-05 13:49:10 +00:00
e28cf7624e Add decoding of OS/2 color icons, pointers, and bitmaps. 2018-03-05 13:37:04 +00:00
ec57e0fd03 Add code to decode OS/2 monochrome icons and pointers, and a separate Icon Viewer for debugging. 2018-03-05 12:50:28 +00:00
378cbd5d33 Correct GUI visualization of NE accelerators when they refer to a character instead of a virtual key. 2018-03-04 07:00:22 +00:00
c88683a380 Add missing resource flags for NE. 2018-03-04 07:00:02 +00:00
4be0e9884c Correct decoding of OS/2 accelerators in NE. 2018-03-04 06:59:38 +00:00
f82b64c02e Correct decoding of NE alignment shift. 2018-03-04 06:58:47 +00:00
2b4c73a78c Add gui panel to hex dump unknown ne resources by default. 2018-03-03 19:12:36 +00:00
b78157bf4d Add decoding RT_ACCELERATOR (Windows) and RT_ACCELTABLE (OS/2) resources from NE, and appropriate GUI. 2018-03-03 18:58:47 +00:00
18464bacff Add decoding RT_STRING resources from NE (Windows and OS/2), and appropriate GUI. 2018-03-03 06:01:35 +00:00
691f9e3a8a Get strings from currently decoded NE fields. 2018-03-03 05:05:51 +00:00
03b452118e Added GUI panel for Windows NE resources and RT_VERSION. 2018-03-03 04:57:40 +00:00
7b360ad466 Correct Win16 version resource order of fields. 2018-03-03 04:15:02 +00:00
4120619128 Add segments to gui. 2018-03-03 02:48:47 +00:00
a5f2e805f2 Add segments to interface. 2018-03-03 01:31:45 +00:00
27a7bbf5d1 Add support for NE OS/2 resource table format and resource types. 2018-03-02 22:49:19 +00:00
6ac77ac1fa Correct typo in NE resource type. 2018-03-02 20:47:12 +00:00
5532d4d9e0 NE resource format is completely different between Windows and OS/2, only Windows format is known. 2018-03-02 20:26:26 +00:00
a57b4e2be7 Add NE resource table printing. 2018-03-02 20:25:16 +00:00
75a347fd2a Add new NE resource flags. 2018-03-02 20:21:52 +00:00
a8b4e2b9da Get NE import table. 2018-03-02 20:00:33 +00:00
6ff9daf956 Get NE module name and description. 2018-03-02 19:18:09 +00:00
ef509be234 Add NE segments. 2018-03-02 18:26:53 +00:00
3798a7d488 Add MagiC test files. 2018-03-02 13:34:21 +00:00
179a4e80a8 Change signedness of some GEM resource fields, corrects working with >=32KiB resources. 2018-03-02 13:34:04 +00:00
66e4b9101d Add more test executables. 2018-03-02 12:31:13 +00:00
54edd46223 Add MagiC operating system detection. 2018-03-02 12:27:53 +00:00
90f178d5dd Add Atari ST symbol entries and executable flags. 2018-03-02 12:25:48 +00:00
f6fc1491ec Added decoder for Atari Falcon 16-bit pixel format. 2018-03-02 12:25:20 +00:00
c1e7636a7e If a GEM resource is found it is to expect the MZ executable requires PC-GEM to run. 2018-03-02 12:24:58 +00:00
3874bd6421 Added SpeedGDOS values to GEM TedInfo block. 2018-03-02 12:24:30 +00:00
d52ca1c883 Use PC GEM encoding for GEM resources on MZ. 2018-03-01 18:34:38 +00:00
0f0f09ba27 Added MagiC resource format. 2018-03-01 17:51:37 +00:00
e37b116029 Corrected USERBLK. 2018-03-01 16:58:22 +00:00
7c2f798dd1 Update headers. 2018-03-01 16:49:54 +00:00
d7b2df59b1 Add full support for Gem color icons. 2018-03-01 16:33:04 +00:00
e4a20f73af Correct typo. 2018-03-01 10:56:52 +00:00
d4fe2c8485 Added GUI pages for GEM resources. 2018-02-28 20:06:05 +00:00
b1ef08f06a GEM null strings are now correctly handled, and images are now correctly swapped when little-endian. 2018-02-28 20:05:39 +00:00
b95c3c0fce Added string handlers. 2018-02-28 20:05:13 +00:00
83495c22ce Use codepage 850 when decoding PC GEM resources. 2018-02-28 20:04:58 +00:00
ece71a9953 Added GEM gray colors and RGB values for default palette. 2018-02-28 20:03:59 +00:00
2790e41dad Added GUI page for strings. 2018-02-27 21:33:43 +00:00
8c322d9928 GEM for PC and Atari ST's GEM used same resource format, just changing endianness. 2018-02-27 20:53:03 +00:00
6419fcf8ed Add marshaler for little endian structures. 2018-02-27 20:22:56 +00:00
396f982600 Add resource decoders for all GEM resources but the color icon. 2018-02-27 20:21:27 +00:00
6cec04d72f Add Claunia.Encoding package. 2018-02-27 04:53:33 +00:00
be2fbf3918 Move Atari ST resource processing code to a separate file. 2018-02-27 04:48:47 +00:00
e77f8827a2 Add list of strings to interface. 2018-02-27 04:47:13 +00:00
0737cc8645 Add Atari ST resource object tree walking. 2018-02-27 04:41:20 +00:00
9938058e96 Correct Atari ST field signed-ness. 2018-02-27 03:45:58 +00:00
3dc43b8bc4 Add Atari ST resource file format. 2018-02-26 23:24:56 +00:00
7e3a0d65bb Added MiNT executable detection. 2018-02-26 19:14:02 +00:00
3ecb5a4c8f Added NE resident and non-resident names. 2018-02-26 08:06:46 +00:00
654b07fe05 Correct NE when resource entries are set to 0 but there are resources. 2018-02-26 04:48:48 +00:00
c889345182 Moved some test executables. 2018-02-26 04:17:22 +00:00
94c3e8bf83 Added BeOS R3.1 binary (Portable Executable). 2018-02-26 04:16:20 +00:00
d97c0957b3 Added required operating system name and version to executable interface. 2018-02-26 04:14:40 +00:00
6e5f90eec3 Changed how executables are detected and shown in cli and gui. 2018-02-26 02:33:09 +00:00
bafda9c22f Added architecture to executable interface. 2018-02-26 02:23:30 +00:00
c3cd0b5831 Refactor. 2018-02-25 22:44:26 +00:00
7bfb6744f2 Convert classes to interface. 2018-02-25 18:42:56 +00:00
a58d4a636b Add tests executables. 2018-02-25 06:34:57 +00:00
1c7f2f15cb Add tests executables. 2018-02-25 04:13:09 +00:00
708b66a2e0 Close file. 2018-02-25 04:12:51 +00:00
cf1f1c0289 Refactor 2018-02-25 03:08:28 +00:00
9dd6c1efa0 Add GUI. 2018-02-25 02:53:18 +00:00
952b61d1f8 Added support for PE and COFF. 2017-10-17 17:33:46 +01:00
e305f78f5f Added support for LE/LX executables. 2017-10-16 21:06:41 +01:00
91cc5f8998 Added support for Atari ST executable. 2017-10-16 18:01:15 +01:00
bfaa7fb37a Better handle OS/2 1.x, Windows 1.x and Windows 2.x target os fields. 2017-10-16 17:43:12 +01:00
2241458e7e Do not fill NE resources if there are no entries in resource table. 2017-10-16 17:25:08 +01:00
466 changed files with 20465 additions and 1106 deletions

View File

@@ -1,12 +1,17 @@
libexeinfo v0.2
===============
Copyright © 2017 Natalia Portillo <claunia@claunia.com>
Copyright © 2017-2018 Natalia Portillo <claunia@claunia.com>
libexeinfo is a library to identify and decode information from executable files.
It is also accompanied by a command line application as an example of usage.
Supported executable formats
============================
* Atari ST executable
* Common Object File Format (COFF)
* LE (Microsoft Linear Executable)
* LX (IBM Linear eXecutable)
* MZ (aka DOS relocatable executable)
* NE (Microsoft New Executable)
* NE (Microsoft New Executable)
* PE (Microsoft Portable Executable)

View File

@@ -4,7 +4,7 @@
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017 Copyright © Claunia.com
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -25,90 +25,455 @@
// THE SOFTWARE.
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using libexeinfo;
using libexeinfo.Windows;
using Version = libexeinfo.Windows.Version;
namespace exeinfo
{
class MainClass
static class MainClass
{
public static void Main(string[] args)
{
if (args.Length != 1)
if(args.Length != 1)
{
Console.WriteLine("exeinfo version 0.1 © 2017 Natalia Portillo");
Console.WriteLine("exeinfo version 0.1 © 2017-2018 Natalia Portillo");
Console.WriteLine("Usage: exeinfo file.exe");
return;
}
FileStream exeFs = File.Open(args[0], FileMode.Open, FileAccess.Read);
bool recognized = false;
MZ mzExe = new MZ(exeFs);
NE neExe = new NE(exeFs);
IExecutable mzExe = new MZ(args[0]);
IExecutable neExe = new NE(args[0]);
IExecutable stExe = new AtariST(args[0]);
IExecutable lxExe = new LX(args[0]);
IExecutable coffExe = new COFF(args[0]);
IExecutable peExe = new PE(args[0]);
IExecutable geosExe = new Geos(args[0]);
IExecutable elfExe = new ELF(args[0]);
if (mzExe.IsMZ)
if(neExe.Recognized)
{
recognized = true;
Console.Write(mzExe.GetInfo());
}
Console.Write(neExe.Information);
if(((NE)neExe).Versions != null)
foreach(NE.Version vers in ((NE)neExe).Versions)
{
Console.WriteLine("\tVersion resource {0}:", vers.Name);
Console.WriteLine("\t\tFile version: {0}", vers.FileVersion);
Console.WriteLine("\t\tProduct version: {0}", vers.ProductVersion);
Console.WriteLine("\t\tFile type: {0}", Version.TypeToString(vers.FileType));
if(vers.FileType == VersionFileType.VFT_DRV)
Console.WriteLine("\t\tFile subtype: {0} driver", Version.DriverToString(vers.FileSubtype));
else if(vers.FileType == VersionFileType.VFT_DRV)
Console.WriteLine("\t\tFile subtype: {0} font", Version.FontToString(vers.FileSubtype));
else if(vers.FileSubtype > 0)
Console.WriteLine("\t\tFile subtype: {0}", (uint)vers.FileSubtype);
Console.WriteLine("\t\tFile flags: {0}", vers.FileFlags);
Console.WriteLine("\t\tFile OS: {0}", Version.OsToString(vers.FileOs));
if (neExe.IsNE)
{
recognized = true;
Console.Write(neExe.GetInfo());
foreach (NE.Version vers in neExe.Versions)
foreach(KeyValuePair<string, Dictionary<string, string>> strByLang in vers.StringsByLanguage)
{
string cultureName;
string encodingName;
try
{
cultureName = new CultureInfo(Convert.ToInt32(strByLang.Key.Substring(0, 4), 16))
.DisplayName;
}
catch
{
cultureName =
$"unsupported culture 0x{Convert.ToInt32(strByLang.Key.Substring(0, 4), 16):X4}";
}
try
{
encodingName = Encoding
.GetEncoding(Convert.ToInt32(strByLang.Key.Substring(4), 16))
.EncodingName;
}
catch
{
encodingName =
$"unsupported encoding 0x{Convert.ToInt32(strByLang.Key.Substring(4), 16):X4}";
}
Console.WriteLine("\t\tStrings for {0} in codepage {1}:", cultureName, encodingName);
foreach(KeyValuePair<string, string> strings in strByLang.Value)
Console.WriteLine("\t\t\t{0}: {1}", strings.Key, strings.Value);
}
}
if(neExe.Strings != null && neExe.Strings.Any())
{
Console.WriteLine("\tVersion resource {0}:", vers.Name);
Console.WriteLine("\t\tFile version: {0}", vers.FileVersion);
Console.WriteLine("\t\tProduct version: {0}", vers.ProductVersion);
Console.WriteLine("\t\tFile type: {0}", NE.Version.TypeToString(vers.FileType));
if (vers.FileType == NE.VersionFileType.VFT_DRV)
Console.WriteLine("\t\tFile subtype: {0} driver", NE.Version.DriverToString(vers.FileSubtype));
else if (vers.FileType == NE.VersionFileType.VFT_DRV)
Console.WriteLine("\t\tFile subtype: {0} font", NE.Version.FontToString(vers.FileSubtype));
else if (vers.FileSubtype > 0)
Console.WriteLine("\t\tFile subtype: {0}", (uint)vers.FileSubtype);
Console.WriteLine("\t\tFile flags: {0}", vers.FileFlags);
Console.WriteLine("\t\tFile OS: {0}", NE.Version.OsToString(vers.FileOS));
Console.WriteLine("\tStrings:");
foreach(string str in neExe.Strings) Console.WriteLine("\t\t{0}", str);
}
}
else if(lxExe.Recognized)
{
recognized = true;
Console.Write(lxExe.Information);
foreach (KeyValuePair<string, Dictionary<string, string>> strByLang in vers.StringsByLanguage)
if(((LX)lxExe).WinVersion != null)
{
NE.Version vers = ((LX)lxExe).WinVersion;
Console.WriteLine("\tVxD version resource {0}:", vers.Name);
Console.WriteLine("\t\tFile version: {0}", vers.FileVersion);
Console.WriteLine("\t\tProduct version: {0}", vers.ProductVersion);
Console.WriteLine("\t\tFile type: {0}", Version.TypeToString(vers.FileType));
if(vers.FileType == VersionFileType.VFT_DRV)
Console.WriteLine("\t\tFile subtype: {0} driver", Version.DriverToString(vers.FileSubtype));
else if(vers.FileType == VersionFileType.VFT_DRV)
Console.WriteLine("\t\tFile subtype: {0} font",
Version.FontToString(vers.FileSubtype));
else if(vers.FileSubtype > 0) Console.WriteLine("\t\tFile subtype: {0}", (uint)vers.FileSubtype);
Console.WriteLine("\t\tFile flags: {0}", vers.FileFlags);
Console.WriteLine("\t\tFile OS: {0}", Version.OsToString(vers.FileOs));
foreach(KeyValuePair<string, Dictionary<string, string>> strByLang in vers.StringsByLanguage)
{
string cultureName;
string encodingName;
try
{
cultureName = new CultureInfo(Convert.ToInt32(strByLang.Key.Substring(0, 4), 16)).DisplayName;
cultureName = new CultureInfo(Convert.ToInt32(strByLang.Key.Substring(0, 4), 16))
.DisplayName;
}
catch
{
cultureName = string.Format("unsupported culture 0x{0:X4}", Convert.ToInt32(strByLang.Key.Substring(0, 4), 16));
cultureName =
$"unsupported culture 0x{Convert.ToInt32(strByLang.Key.Substring(0, 4), 16):X4}";
}
try
{
encodingName = Encoding.GetEncoding(Convert.ToInt32(strByLang.Key.Substring(4), 16)).EncodingName;
encodingName = Encoding.GetEncoding(Convert.ToInt32(strByLang.Key.Substring(4), 16))
.EncodingName;
}
catch
{
encodingName = string.Format("unsupported encoding 0x{0:X4}", Convert.ToInt32(strByLang.Key.Substring(4), 16));
encodingName =
$"unsupported encoding 0x{Convert.ToInt32(strByLang.Key.Substring(4), 16):X4}";
}
Console.WriteLine("\t\tStrings for {0} in codepage {1}:", cultureName, encodingName);
foreach (KeyValuePair<string, string> strings in strByLang.Value)
foreach(KeyValuePair<string, string> strings in strByLang.Value)
Console.WriteLine("\t\t\t{0}: {1}", strings.Key, strings.Value);
}
}
if(lxExe.Strings != null && lxExe.Strings.Any())
{
Console.WriteLine("\tStrings:");
foreach(string str in lxExe.Strings) Console.WriteLine("\t\t{0}", str);
}
}
else if(peExe.Recognized)
{
recognized = true;
Console.Write(peExe.Information);
if(((PE)peExe).Versions != null)
foreach(PE.Version vers in ((PE)peExe).Versions)
{
Console.WriteLine("\tVersion resource {0}:", vers.Name);
Console.WriteLine("\t\tFile version: {0}", vers.FileVersion);
Console.WriteLine("\t\tProduct version: {0}", vers.ProductVersion);
Console.WriteLine("\t\tFile type: {0}", Version.TypeToString(vers.FileType));
if(vers.FileType == VersionFileType.VFT_DRV)
Console.WriteLine("\t\tFile subtype: {0} driver", Version.DriverToString(vers.FileSubtype));
else if(vers.FileType == VersionFileType.VFT_DRV)
Console.WriteLine("\t\tFile subtype: {0} font", Version.FontToString(vers.FileSubtype));
else if(vers.FileSubtype > 0)
Console.WriteLine("\t\tFile subtype: {0}", (uint)vers.FileSubtype);
Console.WriteLine("\t\tFile flags: {0}", vers.FileFlags);
Console.WriteLine("\t\tFile OS: {0}", Version.OsToString(vers.FileOs));
foreach(KeyValuePair<string, Dictionary<string, string>> strByLang in vers.StringsByLanguage)
{
string cultureName;
string encodingName;
try
{
cultureName = new CultureInfo(Convert.ToInt32(strByLang.Key.Substring(0, 4), 16))
.DisplayName;
}
catch
{
cultureName =
$"unsupported culture 0x{Convert.ToInt32(strByLang.Key.Substring(0, 4), 16):X4}";
}
try
{
encodingName = Encoding
.GetEncoding(Convert.ToInt32(strByLang.Key.Substring(4), 16))
.EncodingName;
}
catch
{
encodingName =
$"unsupported encoding 0x{Convert.ToInt32(strByLang.Key.Substring(4), 16):X4}";
}
Console.WriteLine("\t\tStrings for {0} in codepage {1}:", cultureName, encodingName);
foreach(KeyValuePair<string, string> strings in strByLang.Value)
Console.WriteLine("\t\t\t{0}: {1}", strings.Key, strings.Value);
}
}
if(peExe.Strings != null && peExe.Strings.Any())
{
Console.WriteLine("\tStrings:");
foreach(string str in peExe.Strings) Console.WriteLine("\t\t{0}", str);
}
}
else if(mzExe.Recognized)
{
recognized = true;
Console.Write(mzExe.Information);
if(((MZ)mzExe).ResourceStream != null || ((MZ)mzExe).ResourceHeader.rsh_vrsn != 0 &&
((MZ)mzExe).ResourceHeader.rsh_vrsn != 1 &&
((MZ)mzExe).ResourceHeader.rsh_vrsn != 4 &&
((MZ)mzExe).ResourceHeader.rsh_vrsn != 5)
PrintGemResources(((MZ)mzExe).ResourceHeader, ((MZ)mzExe).ResourceObjectRoots,
((MZ)mzExe).ResourceExtension, ((MZ)mzExe).GemColorIcons);
if(mzExe.Strings != null && mzExe.Strings.Any())
{
Console.WriteLine("\tStrings:");
foreach(string str in mzExe.Strings) Console.WriteLine("\t\t{0}", str);
}
}
if (!recognized)
Console.WriteLine("Executable format not recognized");
if(stExe.Recognized)
{
recognized = true;
Console.Write(stExe.Information);
if(((AtariST)stExe).ResourceStream != null || ((AtariST)stExe).ResourceHeader.rsh_vrsn != 0 &&
((AtariST)stExe).ResourceHeader.rsh_vrsn != 1 &&
((AtariST)stExe).ResourceHeader.rsh_vrsn != 4 &&
((AtariST)stExe).ResourceHeader.rsh_vrsn != 5)
PrintGemResources(((AtariST)stExe).ResourceHeader, ((AtariST)stExe).ResourceObjectRoots,
((AtariST)stExe).ResourceExtension, ((AtariST)stExe).GemColorIcons);
if(stExe.Strings != null && stExe.Strings.Any())
{
Console.WriteLine("\tStrings:");
foreach(string str in stExe.Strings) Console.WriteLine("\t\t{0}", str);
}
}
if(coffExe.Recognized)
{
recognized = true;
Console.Write(coffExe.Information);
if(coffExe.Strings != null && coffExe.Strings.Any())
{
Console.WriteLine("\tStrings:");
foreach(string str in coffExe.Strings) Console.WriteLine("\t\t{0}", str);
}
}
else if(elfExe.Recognized)
{
recognized = true;
Console.Write(elfExe.Information);
if(elfExe.Strings != null && elfExe.Strings.Any())
{
Console.WriteLine("\tStrings:");
foreach(string str in elfExe.Strings) Console.WriteLine("\t\t{0}", str);
}
}
if(geosExe.Recognized)
{
recognized = true;
Console.Write(geosExe.Information);
if(geosExe.Strings != null && geosExe.Strings.Any())
{
Console.WriteLine("\tStrings:");
foreach(string str in geosExe.Strings) Console.WriteLine("\t\t{0}", str);
}
}
if(!recognized) Console.WriteLine("Executable format not recognized");
}
static void PrintGemResources(GEM.MagiCResourceHeader resourceHeader,
IReadOnlyList<GEM.TreeObjectNode> roots,
GEM.GemResourceExtension resourceExtension,
GEM.ColorIcon[] colorIcons)
{
Console.WriteLine("\t\tGEM Resources:");
Console.WriteLine("\t\t\t{0} OBJECTs start at {1}", resourceHeader.rsh_nobs, resourceHeader.rsh_object);
Console.WriteLine("\t\t\t{0} TEDINFOs start at {1}", resourceHeader.rsh_nted, resourceHeader.rsh_tedinfo);
Console.WriteLine("\t\t\t{0} ICONBLKs start at {1}", resourceHeader.rsh_nib, resourceHeader.rsh_iconblk);
Console.WriteLine("\t\t\t{0} BITBLKs start at {1}", resourceHeader.rsh_nbb, resourceHeader.rsh_bitblk);
Console.WriteLine("\t\t\t{0} object trees start at {1}", resourceHeader.rsh_ntree,
resourceHeader.rsh_trindex);
Console.WriteLine("\t\t\t{0} free strings start at {1}", resourceHeader.rsh_nstring,
resourceHeader.rsh_frstr);
Console.WriteLine("\t\t\t{0} free images start at {1}", resourceHeader.rsh_nimages,
resourceHeader.rsh_frimg);
Console.WriteLine("\t\t\tString data starts at {0}", resourceHeader.rsh_string);
Console.WriteLine("\t\t\tImage data starts at {0}", resourceHeader.rsh_imdata);
Console.WriteLine("\t\t\tStandard resource data is {0} bytes", resourceHeader.rsh_rssize);
if(resourceHeader.rsh_vrsn >= 4)
{
Console.WriteLine("\t\t\tColor icon table starts at {0}", resourceExtension.color_ic);
Console.WriteLine("\t\t\tThere are {0}more extensions",
resourceExtension.end_extensions == 0 ? "no " : "");
Console.WriteLine("\t\t\tExtended resource data is {0} bytes", resourceExtension.filesize);
}
if(roots == null || roots.Count <= 0) return;
for(int i = 0; i < roots.Count; i++)
{
Console.WriteLine("\t\t\tObject tree {0}:", i);
PrintGemResourceTree(roots[i], 4, colorIcons);
}
}
static void PrintGemResourceTree(GEM.TreeObjectNode node, int level, GEM.ColorIcon[] colorIcons)
{
for(int i = 0; i < level; i++) Console.Write("\t");
string thickStr;
switch(node.type)
{
case GEM.ObjectTypes.G_BOX:
case GEM.ObjectTypes.G_IBOX:
Console.WriteLine("{0} ({1} {2}) {3} border, {4} text, {5} interior, {6} fill, {7} mode," + " coordinates ({8},{9}) size {10}x{11}",
node.type, node.flags, node.state,
(GEM.ObjectColors)((node.data & 0xFFFF & GEM.BorderColorMask) >> 12),
(GEM.ObjectColors)((node.data & 0xFFFF & GEM.TextColorMask) >> 8),
(GEM.ObjectColors)((node.data & 0xFFFF & GEM.InsideColorMask) >> 8),
(GEM.ObjectFillPattern)((node.data & 0xFFFF & GEM.FillPatternMask) >> 4),
(node.data & 0xFFFF & GEM.TransparentColor) != 0 ? "transparent" : "replace",
node.x, node.y, node.width, node.height);
break;
case GEM.ObjectTypes.G_BOXCHAR:
sbyte thickness = (sbyte)((node.data & 0xFF0000) >> 16);
if(thickness < 0) thickStr = $"{thickness * -1} pixels outward thickness";
else if(thickness > 0) thickStr = $"{thickness} pixels inward thickness";
else thickStr = "no thickness";
char character =
Claunia.Encoding.Encoding.AtariSTEncoding.GetString(new[]
{
(byte)((node.data & 0xFF000000) >> 24)
})[0];
Console.WriteLine(
"{0} ({1} {2}) {3} border, {4} text, {5} interior, {6} fill, {7} mode, {8}," +
" '{9}' character, coordinates ({10},{11}) size {12}x{13}", node.type, node.flags,
node.state, (GEM.ObjectColors)((node.data & 0xFFFF & GEM.BorderColorMask) >> 12),
(GEM.ObjectColors)((node.data & 0xFFFF & GEM.TextColorMask) >> 8),
(GEM.ObjectColors)((node.data & 0xFFFF & GEM.InsideColorMask) >> 8),
(GEM.ObjectFillPattern)((node.data & 0xFFFF & GEM.FillPatternMask) >> 4),
(node.data & 0xFFFF & GEM.TransparentColor) != 0 ? "transparent" : "replace",
thickStr, character, node.x, node.y, node.width, node.height);
break;
case GEM.ObjectTypes.G_BUTTON:
case GEM.ObjectTypes.G_STRING:
case GEM.ObjectTypes.G_TITLE:
Console.WriteLine("{0} ({1} {2}), coordinates ({3},{4}) size {5}x{6}: {7}", node.type, node.flags,
node.state, node.x, node.y, node.width, node.height, node.String);
break;
case GEM.ObjectTypes.G_TEXT:
case GEM.ObjectTypes.G_BOXTEXT:
case GEM.ObjectTypes.G_FTEXT:
case GEM.ObjectTypes.G_FBOXTEXT:
if(node.TedInfo == null) goto default;
if(node.TedInfo.Thickness < 0)
thickStr = $"{node.TedInfo.Thickness * -1} pixels outward thickness";
else if(node.TedInfo.Thickness > 0) thickStr = $"{node.TedInfo.Thickness} pixels inward thickness";
else thickStr = "no thickness";
Console.WriteLine("{0} ({1} {2}), coordinates ({3},{4}) size {5}x{6}, font {7}, {8}-justified," + " {9}, {10} border, {11} text, {12} interior, {13} fill, {14} mode," + " text: \"{15}\", validation: \"{16}\", template: \"{17}\"",
node.type, node.flags, node.state, node.x, node.y, node.width, node.height,
node.TedInfo.Font, node.TedInfo.Justification, thickStr, node.TedInfo.BorderColor,
node.TedInfo.TextColor, node.TedInfo.InsideColor, node.TedInfo.Fill,
node.TedInfo.Transparency ? "transparent" : "replace", node.TedInfo.Text,
node.TedInfo.Validation, node.TedInfo.Template);
break;
case GEM.ObjectTypes.G_IMAGE:
if(node.BitBlock == null) goto default;
Console.WriteLine("{0} ({1} {2}), coordinates ({3},{4}) size {5}x{6}, colored {7}, {8} bytes",
node.type, node.flags, node.state, node.BitBlock.X, node.BitBlock.Y,
node.BitBlock.Width, node.BitBlock.Height, node.BitBlock.Color,
node.BitBlock.Data?.Length);
break;
/*
case GEM.ObjectTypes.G_USERDEF: break;*/
case GEM.ObjectTypes.G_ICON:
if(node.IconBlock == null) goto default;
Console.WriteLine(
"{0} ({1} {2}), coordinates ({3},{4}) size {5}x{6}, {7} foreground," +
" {8} background, char '{9}' at ({10},{11}), {12} bytes data, text \"{13}\" at" +
" ({14},{15}) within a box {16}x{17} pixels", node.type, node.flags, node.state,
node.IconBlock.X, node.IconBlock.Y, node.IconBlock.Width, node.IconBlock.Height,
node.IconBlock.ForegroundColor, node.IconBlock.BackgroundColor,
node.IconBlock.Character, node.IconBlock.CharX, node.IconBlock.CharY,
node.IconBlock.Data?.Length, node.IconBlock.Text, node.IconBlock.TextX,
node.IconBlock.TextY, node.IconBlock.TextWidth, node.IconBlock.TextHeight);
break;
case GEM.ObjectTypes.G_CICON:
if(colorIcons == null || colorIcons.Length < node.data ||
colorIcons[node.data] == null ||
colorIcons[node.data].Monochrome == null)
{
Console.WriteLine("{0} ({1} {2}) with index {3} NOT FOUND", node.type, node.flags, node.state,
node.data);
break;
}
Console.WriteLine(
"{0} ({1} {2}), coordinates ({3},{4}) size {5}x{6}, {7} foreground," +
" {8} background, char '{9}' at ({10},{11}), {12} bytes data, text \"{13}\" at" +
" ({14},{15}) within a box {16}x{17} pixels, with {18} different planes",
node.type, node.flags, node.state, colorIcons[node.data].Monochrome.X,
colorIcons[node.data].Monochrome.Y, colorIcons[node.data].Monochrome.Width,
colorIcons[node.data].Monochrome.Height,
colorIcons[node.data].Monochrome.ForegroundColor,
colorIcons[node.data].Monochrome.BackgroundColor,
colorIcons[node.data].Monochrome.Character,
colorIcons[node.data].Monochrome.CharX, colorIcons[node.data].Monochrome.CharY,
colorIcons[node.data].Monochrome.Data?.Length,
colorIcons[node.data].Monochrome.Text, colorIcons[node.data].Monochrome.TextX,
colorIcons[node.data].Monochrome.TextY,
colorIcons[node.data].Monochrome.TextWidth,
colorIcons[node.data].Monochrome.TextHeight, colorIcons[node.data].Color.Length);
break;
default:
Console.WriteLine("{0} ({1} {2}) data = {3}, coordinates ({4},{5}) size {6}x{7}", node.type,
node.flags, node.state, node.data, node.x, node.y, node.width, node.height);
break;
}
if(node.child != null) PrintGemResourceTree(node.child, level + 1, colorIcons);
if(node.sibling != null) PrintGemResourceTree(node.sibling, level, colorIcons);
}
}
}
}

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -30,6 +30,9 @@
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="Claunia.Encoding, Version=1.6.1.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\packages\Claunia.Encoding.1.6.1\lib\portable40-net40+sl5+win8+wp8\Claunia.Encoding.dll</HintPath>
</Reference>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
@@ -49,6 +52,7 @@
<None Include="..\README.md">
<Link>README.md</Link>
</None>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

4
exeinfo/packages.config Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Claunia.Encoding" version="1.6.1" targetFramework="net461" />
</packages>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>exeinfogui</string>
<key>CFBundleIdentifier</key>
<string>com.example.exeinfogui</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>LSMinimumSystemVersion</key>
<string>10.7</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>NSHumanReadableCopyright</key>
<string></string>
<key>CFBundleIconFile</key>
<string>MacIcon.icns</string>
</dict>
</plist>

Binary file not shown.

View File

@@ -0,0 +1,41 @@
//
// Program.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using Eto;
using Eto.Forms;
namespace exeinfogui.Desktop
{
static class Program
{
[STAThread]
static void Main(string[] args)
{
new Application(Platform.Detect).Run(new MainForm());
}
}
}

View File

@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net461</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Eto.Platform.Wpf" Version="2.4.1" />
<PackageReference Include="Eto.Platform.Gtk" Version="2.4.1" />
<PackageReference Include="Eto.Platform.Mac64" Version="2.4.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\exeinfogui\exeinfogui.csproj" />
</ItemGroup>
</Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 711 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@@ -0,0 +1,68 @@
{
"images": [
{
"filename": "AppIcon-16.png",
"size": "16x16",
"scale": "1x",
"idiom": "mac"
},
{
"filename": "AppIcon-16@2x.png",
"size": "16x16",
"scale": "2x",
"idiom": "mac"
},
{
"filename": "AppIcon-32.png",
"size": "32x32",
"scale": "1x",
"idiom": "mac"
},
{
"filename": "AppIcon-32@2x.png",
"size": "32x32",
"scale": "2x",
"idiom": "mac"
},
{
"filename": "AppIcon-128.png",
"size": "128x128",
"scale": "1x",
"idiom": "mac"
},
{
"filename": "AppIcon-128@2x.png",
"size": "128x128",
"scale": "2x",
"idiom": "mac"
},
{
"filename": "AppIcon-256.png",
"size": "256x256",
"scale": "1x",
"idiom": "mac"
},
{
"filename": "AppIcon-256@2x.png",
"size": "256x256",
"scale": "2x",
"idiom": "mac"
},
{
"filename": "AppIcon-512.png",
"size": "512x512",
"scale": "1x",
"idiom": "mac"
},
{
"filename": "AppIcon-512@2x.png",
"size": "512x512",
"scale": "2x",
"idiom": "mac"
}
],
"info": {
"version": 1,
"author": "xcode"
}
}

View File

@@ -0,0 +1,6 @@
{
"info": {
"version": 1,
"author": "xcode"
}
}

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>EtoApp</string>
<key>CFBundleIdentifier</key>
<string>com.example.EtoApp</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>10.7</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>NSHumanReadableCopyright</key>
<string></string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>XSAppIconAssets</key>
<string>Assets.xcassets/AppIcon.appiconset</string>
</dict>
</plist>

View File

@@ -0,0 +1,39 @@
//
// Program.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using AppKit;
using Eto.Forms;
namespace exeinfogui.XamMac
{
static class MainClass
{
static void Main(string[] args)
{
new Application(Eto.Platforms.XamMac2).Run(new MainForm());
}
}
}

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{E2DC1857-A942-419B-849E-58AC8BBB94CD}</ProjectGuid>
<ProjectTypeGuids>{A3F8F2AB-B479-4A4A-A458-A89E7DC349F1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Exe</OutputType>
<RootNamespace>exeinfogui.XamMac</RootNamespace>
<AssemblyName>exeinfogui.XamMac</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<TargetFrameworkIdentifier>Xamarin.Mac</TargetFrameworkIdentifier>
<MonoMacResourcePrefix>Resources</MonoMacResourcePrefix>
<ReleaseVersion>0.2</ReleaseVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<UseSGen>false</UseSGen>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<UseSGen>false</UseSGen>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="Xamarin.Mac" />
</ItemGroup>
<ItemGroup>
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Contents.json" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\AppIcon-128.png" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\AppIcon-128%402x.png" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\AppIcon-16.png" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\AppIcon-16%402x.png" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\AppIcon-256.png" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\AppIcon-256%402x.png" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\AppIcon-32.png" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\AppIcon-32%402x.png" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\AppIcon-512.png" />
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\AppIcon-512%402x.png" />
<ImageAsset Include="Assets.xcassets\Contents.json" />
</ItemGroup>
<ItemGroup>
<None Include="Info.plist" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Eto.Platform.XamMac2">
<Version>2.4.1</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\exeinfogui\exeinfogui.csproj">
<Project>{223AE794-0CBD-42D3-8C98-D79090006DE5}</Project>
<Name>exeinfogui</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Mac\Xamarin.Mac.CSharp.targets" />
</Project>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<Panel xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackLayout Orientation="Vertical">
<StackLayout Orientation="Horizontal">
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<Label ID="lblSize">Size</Label>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<TextBox ID="txtSize" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<ImageView ID="imgIcon"/>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<Panel ID="pnlPanel"/>
</StackLayoutItem>
</StackLayout>
</Panel>

View File

@@ -0,0 +1,73 @@
using System.Collections.Generic;
using System.Linq;
using Eto.Drawing;
using Eto.Forms;
using Eto.Serialization.Xaml;
using libexeinfo.BeOS;
namespace exeinfogui.BeOS
{
public class PanelBeIcon : Panel
{
ImageView imgIcon;
Label lblSize;
PanelHexDump panelHexDump;
Panel pnlPanel;
TextBox txtSize;
public PanelBeIcon()
{
XamlReader.Load(this);
panelHexDump = new PanelHexDump();
pnlPanel.Content = panelHexDump;
}
public void Update(byte[] data, string type)
{
bool recognized = type == Consts.B_LARGE_ICON_TYPE || type == Consts.B_MINI_ICON_TYPE ||
type == Consts.B_PNG_FORMAT;
if(type == Consts.B_PNG_FORMAT)
{
Bitmap png = new Bitmap(data);
if(png.Width == 0 || png.Height == 0)
{
txtSize.Text = $"{png.Width}x{png.Height} pixels";
imgIcon.Image = png;
lblSize.Text = "Size";
lblSize.Visible = true;
txtSize.Visible = true;
pnlPanel.Visible = false;
return;
}
recognized = false;
}
if(data == null || !recognized)
{
imgIcon.Image = null;
lblSize.Text = "No data";
lblSize.Visible = false;
txtSize.Visible = false;
pnlPanel.Visible = false;
panelHexDump.Update(data);
return;
}
int width = type == Consts.B_LARGE_ICON_TYPE ? 32 : 16;
int height = width;
List<int> pixels = data.Select(p => (int)Consts.ArgbSystemPalette[p]).ToList();
txtSize.Text = $"{width}x{height} pixels";
imgIcon.Image = new Bitmap(width, height, PixelFormat.Format32bppRgba, pixels);
lblSize.Text = "Size";
lblSize.Visible = true;
txtSize.Visible = true;
pnlPanel.Visible = false;
}
}
}

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<Panel xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackLayout Orientation="Vertical" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Top">
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblMajorVersion">Major version</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtMajorVersion" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblMiddleVersion">Middle version</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtMiddleVersion" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblMinorVersion">Minor version</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtMinorVersion" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblVariety">Variety</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtVariety" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblInternal">Internal</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtInternal" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblShortInfo">Short information</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtShortInfo" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblLongInfo">Long information</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextArea ID="txtLongInfo" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
</StackLayout>
</Panel>

View File

@@ -0,0 +1,39 @@
using System.Text;
using Eto.Forms;
using Eto.Serialization.Xaml;
using libexeinfo;
using libexeinfo.BeOS;
namespace exeinfogui.BeOS
{
public class PanelBeVersion : Panel
{
TextBox txtInternal;
TextArea txtLongInfo;
TextBox txtMajorVersion;
TextBox txtMiddleVersion;
TextBox txtMinorVersion;
TextBox txtShortInfo;
TextBox txtVariety;
public PanelBeVersion()
{
XamlReader.Load(this);
}
public void Update(byte[] data, bool bigEndian)
{
VersionInfo versionInfo = bigEndian
? BigEndianMarshal.ByteArrayToStructureBigEndian<VersionInfo>(data)
: BigEndianMarshal.ByteArrayToStructureLittleEndian<VersionInfo>(data);
txtMajorVersion.Text = $"{versionInfo.major}";
txtMiddleVersion.Text = $"{versionInfo.middle}";
txtMinorVersion.Text = $"{versionInfo.minor}";
txtVariety.Text = $"{versionInfo.variety}";
txtInternal.Text = $"{versionInfo.interna1}";
txtShortInfo.Text = StringHandlers.CToString(versionInfo.short_info, Encoding.UTF8);
txtLongInfo.Text = StringHandlers.CToString(versionInfo.long_info, Encoding.UTF8);
}
}
}

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<TabPage Text="BeOS Resources" xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<StackLayout Orientation="Horizontal">
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<TreeGridView ID="treeResources"/>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<Panel ID="pnlResource"/>
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
</StackLayout>
</TabPage>

View File

@@ -0,0 +1,127 @@
//
// TabBeResources.xeto.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Eto.Forms;
using Eto.Serialization.Xaml;
using libexeinfo.BeOS;
namespace exeinfogui.BeOS
{
public class TabBeResources : TabPage
{
bool bigEndian;
PanelBeIcon panelBeIcon;
PanelBeVersion panelBeVersion;
PanelHexDump panelHexDump;
PanelText panelText;
Panel pnlResource;
TreeGridView treeResources;
public TabBeResources()
{
XamlReader.Load(this);
treeResources.Columns.Add(new GridColumn {HeaderText = "Name", DataCell = new TextBoxCell(0)});
treeResources.Columns.Add(new GridColumn {HeaderText = "ID", DataCell = new TextBoxCell(1)});
treeResources.Columns.Add(new GridColumn {HeaderText = "Size", DataCell = new TextBoxCell(2)});
treeResources.AllowMultipleSelection = false;
treeResources.SelectionChanged += TreeResourcesOnSelectionChanged;
panelHexDump = new PanelHexDump();
panelText = new PanelText();
panelBeIcon = new PanelBeIcon();
panelBeVersion = new PanelBeVersion();
}
public void Update(IEnumerable<ResourceTypeBlock> resources, bool bigEndian)
{
TreeGridItemCollection treeData = new TreeGridItemCollection();
foreach(ResourceTypeBlock type in resources.OrderBy(r => r.type))
{
TreeGridItem root = new TreeGridItem {Values = new object[] {$"{type.type}", null, null, null, null}};
foreach(Resource resource in type.resources.OrderBy(r => r.name).ThenBy(r => r.id).ThenBy(r => r.index))
{
TreeGridItem child = new TreeGridItem
{
Values = new object[]
{
$"{resource.name}", $"{resource.id}",
resource.data == null ? null : $"{resource.data.Length}", $"{type.type}", resource.data
}
};
root.Children.Add(child);
}
treeData.Add(root);
}
treeResources.DataStore = treeData;
this.bigEndian = bigEndian;
}
void TreeResourcesOnSelectionChanged(object sender, EventArgs eventArgs)
{
if(((TreeGridItem)treeResources.SelectedItem)?.Values[4] == null)
{
pnlResource.Content = null;
return;
}
byte[] data = ((TreeGridItem)treeResources.SelectedItem)?.Values[4] as byte[];
string type = ((TreeGridItem)treeResources.SelectedItem)?.Values[3] as string;
switch(type)
{
case Consts.B_MIME_STRING_TYPE:
pnlResource.Content = panelText;
panelText.Update(data, Encoding.ASCII);
break;
case Consts.B_LARGE_ICON_TYPE:
case Consts.B_MINI_ICON_TYPE:
case Consts.B_PNG_FORMAT:
pnlResource.Content = panelBeIcon;
panelBeIcon.Update(data, type);
break;
case Consts.B_VERSION_INFO_TYPE:
pnlResource.Content = panelBeVersion;
panelBeVersion.Update(data, bigEndian);
break;
default:
pnlResource.Content = panelHexDump;
panelHexDump.Update(data);
break;
}
}
}
}

View File

@@ -0,0 +1,58 @@
//
// GemColor.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using Eto.Drawing;
namespace exeinfogui.GEM
{
public static class GemColor
{
internal static Color GemToEtoColor(libexeinfo.GEM.ObjectColors color)
{
switch(color)
{
case libexeinfo.GEM.ObjectColors.White: return Color.FromRgb((int)libexeinfo.GEM.ObjectColorsRgb.White);
case libexeinfo.GEM.ObjectColors.Black: return Color.FromRgb((int)libexeinfo.GEM.ObjectColorsRgb.Black);
case libexeinfo.GEM.ObjectColors.Red: return Color.FromRgb((int)libexeinfo.GEM.ObjectColorsRgb.Red);
case libexeinfo.GEM.ObjectColors.Green: return Color.FromRgb((int)libexeinfo.GEM.ObjectColorsRgb.Green);
case libexeinfo.GEM.ObjectColors.Blue: return Color.FromRgb((int)libexeinfo.GEM.ObjectColorsRgb.Blue);
case libexeinfo.GEM.ObjectColors.Cyan: return Color.FromRgb((int)libexeinfo.GEM.ObjectColorsRgb.Cyan);
case libexeinfo.GEM.ObjectColors.Yellow: return Color.FromRgb((int)libexeinfo.GEM.ObjectColorsRgb.Yellow);
case libexeinfo.GEM.ObjectColors.Magenta: return Color.FromRgb((int)libexeinfo.GEM.ObjectColorsRgb.Magenta);
case libexeinfo.GEM.ObjectColors.LightGray: return Color.FromRgb((int)libexeinfo.GEM.ObjectColorsRgb.LightGray);
case libexeinfo.GEM.ObjectColors.Gray: return Color.FromRgb((int)libexeinfo.GEM.ObjectColorsRgb.Gray);
case libexeinfo.GEM.ObjectColors.LightRed: return Color.FromRgb((int)libexeinfo.GEM.ObjectColorsRgb.LightRed);
case libexeinfo.GEM.ObjectColors.LightGreen: return Color.FromRgb((int)libexeinfo.GEM.ObjectColorsRgb.LightGreen);
case libexeinfo.GEM.ObjectColors.LightBlue: return Color.FromRgb((int)libexeinfo.GEM.ObjectColorsRgb.LightBlue);
case libexeinfo.GEM.ObjectColors.LightCyan: return Color.FromRgb((int)libexeinfo.GEM.ObjectColorsRgb.LightCyan);
case libexeinfo.GEM.ObjectColors.LightYellow: return Color.FromRgb((int)libexeinfo.GEM.ObjectColorsRgb.LightYellow);
case libexeinfo.GEM.ObjectColors.LightMagenta: return Color.FromRgb((int)libexeinfo.GEM.ObjectColorsRgb.LightMagenta);
}
return Color.FromRgb(0);
}
}
}

View File

@@ -0,0 +1,45 @@
//
// GemColorIcon.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using Eto.Drawing;
namespace exeinfogui.GEM
{
public static class GemColorIcon
{
public static Bitmap GemColorIconToEto(libexeinfo.GEM.ColorIconPlane icon, int width, int height, bool selected)
{
if(selected && icon.SelectedData == null) return null;
byte[] data = selected ? icon.SelectedData : icon.Data;
byte[] mask = selected ? icon.SelectedMask : icon.Mask;
int[] pixels = libexeinfo.GEM.PlaneToRaster(data, mask, width, height, icon.Planes);
return new Bitmap(width, height, PixelFormat.Format32bppRgba, pixels);
}
}
}

54
exeinfogui/GEM/GemIcon.cs Normal file
View File

@@ -0,0 +1,54 @@
//
// GemIcon.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System.Collections.Generic;
using Eto.Drawing;
namespace exeinfogui.GEM
{
public static class GemIcon
{
public static Bitmap GemIconToEto(libexeinfo.GEM.Icon icon)
{
const uint COLOR = 0x00000000;
const uint BACKGROUND = 0x00FFFFFF;
const uint ALPHAMASK = 0xFF000000;
List<int> pixels = new List<int>();
byte[] data = libexeinfo.GEM.FlipPlane(icon.Data, (int)icon.Width);
byte[] mask = libexeinfo.GEM.FlipPlane(icon.Mask, (int)icon.Width);
for(int pos = 0; pos < data.Length; pos++)
{
for(int i = 0; i < 8; i++)
pixels.Add((int)(((data[pos] & (1 << i)) != 0 ? COLOR : BACKGROUND) +
((mask[pos] & (1 << i)) != 0 ? ALPHAMASK : 0)));
}
return new Bitmap((int)icon.Width, (int)icon.Height, PixelFormat.Format32bppRgba, pixels);
}
}
}

View File

@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<Panel xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackLayout Orientation="Vertical" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Top">
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblFlags">Flags</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtFlags" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblState">State</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtState" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblCoordinates">Coordinates</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtCoordinates" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblSize">Size</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtSize" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblThickness">Border thickness</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtThickness" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblTransparency">Transparency</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtTransparency" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblFill">Fill</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtFill" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblBorderColor">Border color</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtBorderColor" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblInsideColor">Inside color</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtInsideColor" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblTextColor">Text color</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtTextColor" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblCharacter">Character</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtCharacter" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
</StackLayout>
</Panel>

View File

@@ -0,0 +1,99 @@
//
// PanelGemBox.xeto.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using Claunia.Encoding;
using Eto.Forms;
using Eto.Serialization.Xaml;
namespace exeinfogui.GEM
{
public class PanelGemBox : Panel
{
Label lblCharacter;
Label lblThickness;
TextBox txtBorderColor;
TextBox txtCharacter;
TextBox txtCoordinates;
TextBox txtFill;
TextBox txtFlags;
TextBox txtInsideColor;
TextBox txtSize;
TextBox txtState;
TextBox txtTextColor;
TextBox txtThickness;
TextBox txtTransparency;
public PanelGemBox()
{
XamlReader.Load(this);
}
public void Update(libexeinfo.GEM.TreeObjectNode node)
{
sbyte thickness = (sbyte)((node.data & 0xFF0000) >> 16);
char character = Encoding.AtariSTEncoding.GetString(new[] {(byte)((node.data & 0xFF000000) >> 24)})[0];
txtFlags.Text = node.flags == 0 ? "None" : node.flags.ToString();
txtState.Text = node.state == 0 ? "Normal" : node.state.ToString();
txtCoordinates.Text = $"{node.x},{node.y}";
txtSize.Text = $"{node.width}x{node.height} pixels";
txtBorderColor.Text =
((libexeinfo.GEM.ObjectColors)((node.data & 0xFFFF & libexeinfo.GEM.BorderColorMask) >> 12)).ToString();
txtFill.Text =
((libexeinfo.GEM.ObjectFillPattern)((node.data & 0xFFFF & libexeinfo.GEM.FillPatternMask) >> 4))
.ToString();
txtInsideColor.Text =
((libexeinfo.GEM.ObjectColors)((node.data & 0xFFFF & libexeinfo.GEM.InsideColorMask) >> 8)).ToString();
txtTextColor.Text =
((libexeinfo.GEM.ObjectColors)((node.data & 0xFFFF & libexeinfo.GEM.TextColorMask) >> 8)).ToString();
txtTransparency.Text = (node.data & 0xFFFF & libexeinfo.GEM.TransparentColor) != 0
? "Transparent mode"
: "Replace mode";
if(thickness < 0) txtThickness.Text = $"{thickness * -1} pixels outward";
else if(thickness < 0)
txtThickness.Text = $"{thickness} pixels inward";
else
txtThickness.Text = "None";
txtCharacter.Text = new string(new []{character});
if(node.type == libexeinfo.GEM.ObjectTypes.G_BOXCHAR)
{
txtCharacter.Visible = true;
txtThickness.Visible = true;
lblCharacter.Visible = true;
lblThickness.Visible = true;
}
else
{
txtCharacter.Visible = false;
txtThickness.Visible = false;
lblCharacter.Visible = false;
lblThickness.Visible = false;
}
}
}
}

View File

@@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8"?>
<Panel xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="500" Height="500">
<StackLayout Orientation="Vertical" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Top">
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblFlags">Flags</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtFlags" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblState">State</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtState" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblCoordinates">Coordinates</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtCoordinates" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblSize">Size</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtSize" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblCharacter">Character</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtCharater" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblCharCoordinates">Character coordinates</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtCharCoordinates" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblFgColor">Character foreground color</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtFgColor" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblBgColor">Character background color</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtBgColor" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblTextCoordinates">Text coordinates</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtTextCoordinates" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblTextBoxSize">Text box size</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtTextBoxSize" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblText">Text</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtText" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayoutItem HorizontalAlignment="Center">
<Label ID="lblMonochrome">Monochrome icon</Label>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Center">
<ImageView ID="imgIcon"/>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Center">
<Label ID="lblColor">Color icons</Label>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<StackLayout Orientation="Horizontal">
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<GridView ID="treePlanes"/>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Center" VerticalAlignment="Top" Expand="True">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Center">
<Label ID="lblColorIcon">Normal</Label>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Center">
<ImageView ID="imgColorIcon"/>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Center">
<Label ID="lblSelectedIcon">Selected</Label>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Center">
<ImageView ID="imgSelectedIcon"/>
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
</StackLayout>
</Panel>

View File

@@ -0,0 +1,114 @@
//
// PanelGemColorIcon.xeto.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using Eto.Forms;
using Eto.Serialization.Xaml;
namespace exeinfogui.GEM
{
public class PanelGemColorIcon : Panel
{
int iconHeight;
int iconWidth;
ImageView imgColorIcon;
ImageView imgIcon;
ImageView imgSelectedIcon;
GridView treePlanes;
TextBox txtBgColor;
TextBox txtCharater;
TextBox txtCharCoordinates;
TextBox txtCoordinates;
TextBox txtFgColor;
TextBox txtFlags;
TextBox txtSize;
TextBox txtState;
TextBox txtText;
TextBox txtTextBoxSize;
TextBox txtTextCoordinates;
public PanelGemColorIcon()
{
XamlReader.Load(this);
treePlanes.Columns.Add(new GridColumn
{
DataCell = new TextBoxCell
{
Binding = Binding.Property<libexeinfo.GEM.ColorIconPlane, string>(i => $"{i.Planes}")
},
HeaderText = "Planes"
});
treePlanes.AllowMultipleSelection = false;
treePlanes.SelectedItemsChanged += TreePlanesOnSelectedItemsChanged;
}
void TreePlanesOnSelectedItemsChanged(object sender, EventArgs eventArgs)
{
if(!(treePlanes.SelectedItem is libexeinfo.GEM.ColorIconPlane cicon))
{
imgColorIcon.Image = null;
imgSelectedIcon.Image = null;
return;
}
imgColorIcon.Image = GemColorIcon.GemColorIconToEto(cicon, iconWidth, iconHeight, false);
imgSelectedIcon.Image = GemColorIcon.GemColorIconToEto(cicon, iconWidth, iconHeight, true);
}
public void Update(libexeinfo.GEM.TreeObjectNode node, libexeinfo.GEM.ColorIcon colorIcon)
{
txtFlags.Text = node.flags == 0 ? "None" : node.flags.ToString();
txtState.Text = node.state == 0 ? "Normal" : node.state.ToString();
txtCoordinates.Text = $"{colorIcon.Monochrome.X},{colorIcon.Monochrome.Y}";
txtSize.Text = $"{colorIcon.Monochrome.Width}x{colorIcon.Monochrome.Height} pixels";
txtCharater.Text = $"{colorIcon.Monochrome.Character}";
txtCharCoordinates.Text = $"{colorIcon.Monochrome.CharX},{colorIcon.Monochrome.CharY}";
txtFgColor.Text = $"{colorIcon.Monochrome.ForegroundColor}";
txtBgColor.Text = $"{colorIcon.Monochrome.BackgroundColor}";
txtTextCoordinates.Text = $"{colorIcon.Monochrome.TextX},{colorIcon.Monochrome.TextY}";
txtTextBoxSize.Text = $"{colorIcon.Monochrome.TextWidth}x{colorIcon.Monochrome.TextHeight} pixels";
txtText.Text = colorIcon.Monochrome.Text;
imgIcon.Image = GemIcon.GemIconToEto(colorIcon.Monochrome);
treePlanes.DataStore = colorIcon.Color;
iconWidth = (int)colorIcon.Monochrome.Width;
iconHeight = (int)colorIcon.Monochrome.Height;
treePlanes.SelectRow(0);
if(colorIcon.Color != null && colorIcon.Color.Length >= 1 && colorIcon.Color[0] != null)
{
imgColorIcon.Image =
GemColorIcon.GemColorIconToEto(colorIcon.Color[0], iconWidth, iconHeight, false);
imgSelectedIcon.Image = GemColorIcon.GemColorIconToEto(colorIcon.Color[0], iconWidth, iconHeight, true);
}
else
{
imgColorIcon.Image = null;
imgSelectedIcon.Image = null;
}
}
}
}

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<Panel xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="500" Height="300">
<StackLayout Orientation="Vertical" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Top">
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblFlags">Flags</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtFlags" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblState">State</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtState" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblCoordinates">Coordinates</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtCoordinates" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblSize">Size</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtSize" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblData">Data pointer</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtData" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
</StackLayout>
</Panel>

View File

@@ -0,0 +1,54 @@
//
// PanelGemGeneric.xeto.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using Eto.Forms;
using Eto.Serialization.Xaml;
namespace exeinfogui.GEM
{
public class PanelGemGeneric : Panel
{
TextBox txtCoordinates;
TextBox txtData;
TextBox txtFlags;
TextBox txtSize;
TextBox txtState;
public PanelGemGeneric()
{
XamlReader.Load(this);
}
public void Update(libexeinfo.GEM.TreeObjectNode node)
{
txtFlags.Text = node.flags == 0 ? "None" : node.flags.ToString();
txtState.Text = node.state == 0 ? "Normal" : node.state.ToString();
txtCoordinates.Text = $"{node.x},{node.y}";
txtSize.Text = $"{node.width}x{node.height} pixels";
txtData.Text = $"{node.data}";
}
}
}

View File

@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<Panel xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="500" Height="300">
<StackLayout Orientation="Vertical" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Top">
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblFlags">Flags</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtFlags" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblState">State</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtState" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblCoordinates">Coordinates</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtCoordinates" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblSize">Size</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtSize" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblCharacter">Character</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtCharater" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblCharCoordinates">Character coordinates</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtCharCoordinates" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblFgColor">Character foreground color</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtFgColor" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblBgColor">Character background color</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtBgColor" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblTextCoordinates">Text coordinates</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtTextCoordinates" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblTextBoxSize">Text box size</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtTextBoxSize" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblText">Text</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtText" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayoutItem Expand="True" HorizontalAlignment="Center">
<ImageView ID="imgIcon"/>
</StackLayoutItem>
</StackLayout>
</Panel>

View File

@@ -0,0 +1,68 @@
//
// PanelGemIcon.xeto.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using Eto.Forms;
using Eto.Serialization.Xaml;
namespace exeinfogui.GEM
{
public class PanelGemIcon : Panel
{
ImageView imgIcon;
TextBox txtBgColor;
TextBox txtCharater;
TextBox txtCharCoordinates;
TextBox txtCoordinates;
TextBox txtFgColor;
TextBox txtFlags;
TextBox txtSize;
TextBox txtState;
TextBox txtText;
TextBox txtTextBoxSize;
TextBox txtTextCoordinates;
public PanelGemIcon()
{
XamlReader.Load(this);
}
public void Update(libexeinfo.GEM.TreeObjectNode node)
{
txtFlags.Text = node.flags == 0 ? "None" : node.flags.ToString();
txtState.Text = node.state == 0 ? "Normal" : node.state.ToString();
txtCoordinates.Text = $"{node.IconBlock.X},{node.IconBlock.Y}";
txtSize.Text = $"{node.IconBlock.Width}x{node.IconBlock.Height} pixels";
txtCharater.Text = $"{node.IconBlock.Character}";
txtCharCoordinates.Text = $"{node.IconBlock.CharX},{node.IconBlock.CharY}";
txtFgColor.Text = $"{node.IconBlock.ForegroundColor}";
txtBgColor.Text = $"{node.IconBlock.BackgroundColor}";
txtTextCoordinates.Text = $"{node.IconBlock.TextX},{node.IconBlock.TextY}";
txtTextBoxSize.Text = $"{node.IconBlock.TextWidth}x{node.IconBlock.TextHeight} pixels";
txtText.Text = node.IconBlock.Text;
imgIcon.Image = GemIcon.GemIconToEto(node.IconBlock);
}
}
}

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<Panel xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="500" Height="300">
<StackLayout Orientation="Vertical" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Top">
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblFlags">Flags</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtFlags" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblState">State</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtState" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblCoordinates">Coordinates</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtCoordinates" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblSize">Size</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtSize" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblColor">Color</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtColor" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayoutItem Expand="True" HorizontalAlignment="Center">
<ImageView ID="imgImage"/>
</StackLayoutItem>
</StackLayout>
</Panel>

View File

@@ -0,0 +1,97 @@
//
// PanelGemImage.xeto.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System.Collections.Generic;
using Eto.Drawing;
using Eto.Forms;
using Eto.Serialization.Xaml;
namespace exeinfogui.GEM
{
public class PanelGemImage : Panel
{
ImageView imgImage;
TextBox txtColor;
TextBox txtCoordinates;
TextBox txtFlags;
TextBox txtSize;
TextBox txtState;
public PanelGemImage()
{
XamlReader.Load(this);
}
public void Update(libexeinfo.GEM.TreeObjectNode node)
{
txtFlags.Text = node.flags == 0 ? "None" : node.flags.ToString();
txtState.Text = node.state == 0 ? "Normal" : node.state.ToString();
txtCoordinates.Text = $"{node.BitBlock.X},{node.BitBlock.Y}";
txtSize.Text = $"{node.BitBlock.Width}x{node.BitBlock.Height} pixels";
txtColor.Text = $"{node.BitBlock.Color}";
imgImage.Image = GemImageToEto(node);
}
static Bitmap GemImageToEto(libexeinfo.GEM.TreeObjectNode node)
{
Color color = GemColor.GemToEtoColor(node.BitBlock.Color);
Color background;
background = GemColor.GemToEtoColor(node.BitBlock.Color == libexeinfo.GEM.ObjectColors.White
? libexeinfo.GEM.ObjectColors.Black
: libexeinfo.GEM.ObjectColors.White);
List<Color> pixels = new List<Color>();
byte[] data = new byte[node.BitBlock.Data.Length];
int pos = 0;
int w = (int)(node.BitBlock.Width / 8);
// This flips the image.
while(pos < data.Length)
{
for(int i = 0; i < w; i++)
{
byte b = node.BitBlock.Data[pos + i];
data[pos + i] = (byte)(b >> 7);
data[pos + i] += (byte)((b >> 5) & 0x02);
data[pos + i] += (byte)((b >> 3) & 0x04);
data[pos + i] += (byte)((b >> 1) & 0x08);
data[pos + i] += (byte)((b << 1) & 0x10);
data[pos + i] += (byte)((b << 3) & 0x20);
data[pos + i] += (byte)((b << 5) & 0x40);
data[pos + i] += (byte)(b << 7);
}
pos += w;
}
foreach(byte b in data)
for(int i = 0; i < 8; i++)
pixels.Add((b & (1 << i)) != 0 ? color : background);
return new Bitmap((int)node.BitBlock.Width, (int)node.BitBlock.Height, PixelFormat.Format32bppRgb, pixels);
}
}
}

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<Panel xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackLayout Orientation="Vertical">
<StackLayout Orientation="Horizontal">
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Right" Expand="True">
<Label ID="lblFlags">Flags</Label>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Right" Expand="True">
<Label ID="lblState">State</Label>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Right" Expand="True">
<Label ID="lblCoordinates">Coordinates</Label>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Right" Expand="True">
<Label ID="lblSize">Size</Label>
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<TextBox ID="txtFlags" ReadOnly="True"/>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<TextBox ID="txtState" ReadOnly="True"/>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<TextBox ID="txtCoordinates" ReadOnly="True"/>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<TextBox ID="txtSize" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
</StackLayout>
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<StackLayout Orientation="Vertical" ID="stkString">
<StackLayoutItem HorizontalAlignment="Center">
<Label ID="lblString">String</Label>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<TextArea ID="txtString" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
</StackLayout>
</Panel>

View File

@@ -0,0 +1,54 @@
//
// PanelGemString.xeto.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using Eto.Forms;
using Eto.Serialization.Xaml;
namespace exeinfogui.GEM
{
public class PanelGemString : Panel
{
TextBox txtCoordinates;
TextBox txtFlags;
TextBox txtSize;
TextBox txtState;
TextArea txtString;
public PanelGemString()
{
XamlReader.Load(this);
}
public void Update(libexeinfo.GEM.TreeObjectNode node)
{
txtFlags.Text = node.flags == 0 ? "None" : node.flags.ToString();
txtState.Text = node.state == 0 ? "Normal" : node.state.ToString();
txtCoordinates.Text = $"{node.x},{node.y}";
txtSize.Text = $"{node.width}x{node.height} pixels";
txtString.Text = node.String;
}
}
}

View File

@@ -0,0 +1,133 @@
<?xml version="1.0" encoding="UTF-8"?>
<Panel xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackLayout Orientation="Vertical" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Top">
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblFlags">Flags</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtFlags" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblState">State</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtState" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblCoordinates">Coordinates</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtCoordinates" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblSize">Size</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtSize" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblFont">Font</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtFont" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblJustification">Justification</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtJustification" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblThickness">Border thickness</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtThickness" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblTransparency">Transparency</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtTransparency" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblFill">Fill</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtFill" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblBorderColor">Border color</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtBorderColor" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblInsideColor">Inside color</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtInsideColor" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblTextColor">Text color</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtTextColor" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblTemplate">Template</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtTemplate" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblText">Text</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtText" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblValidation">Validation</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtValidation" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblPreview">Preview</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtPreview" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
</StackLayout>
</Panel>

View File

@@ -0,0 +1,146 @@
//
// PanelGemText.xeto.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using Eto.Forms;
using Eto.Serialization.Xaml;
namespace exeinfogui.GEM
{
public class PanelGemText : Panel
{
Label lblTemplate;
Label lblText;
Label lblValidation;
TextBox txtBorderColor;
TextBox txtCoordinates;
TextBox txtFill;
TextBox txtFlags;
TextBox txtFont;
TextBox txtInsideColor;
TextBox txtJustification;
TextBox txtPreview;
TextBox txtSize;
TextBox txtState;
TextBox txtTemplate;
TextBox txtText;
TextBox txtTextColor;
TextBox txtThickness;
TextBox txtTransparency;
TextBox txtValidation;
public PanelGemText()
{
XamlReader.Load(this);
}
public void Update(libexeinfo.GEM.TreeObjectNode node)
{
txtFlags.Text = node.flags == 0 ? "None" : node.flags.ToString();
txtState.Text = node.state == 0 ? "Normal" : node.state.ToString();
txtCoordinates.Text = $"{node.x},{node.y}";
txtSize.Text = $"{node.width}x{node.height} pixels";
txtBorderColor.Text = $"{node.TedInfo.BorderColor}";
txtFill.Text = $"{node.TedInfo.Fill}";
txtFont.Text = $"{node.TedInfo.Font}";
txtInsideColor.Text = $"{node.TedInfo.InsideColor}";
txtJustification.Text = $"{node.TedInfo.Justification}";
txtTemplate.Text = node.TedInfo.Template;
txtText.Text = node.TedInfo.Text;
txtTextColor.Text = $"{node.TedInfo.TextColor}";
txtTransparency.Text =
node.TedInfo.Transparency ? "Transparent mode" : "Replace mode";
txtValidation.Text = node.TedInfo.Validation;
if(node.TedInfo.Thickness < 0) txtThickness.Text = $"{node.TedInfo.Thickness * -1} pixels outward";
else if(node.TedInfo.Thickness < 0)
txtThickness.Text = $"{node.TedInfo.Thickness} pixels inward";
else
txtThickness.Text = "None";
if(string.IsNullOrWhiteSpace(node.TedInfo.Template))
{
txtTemplate.Visible = false;
lblTemplate.Visible = false;
}
else
{
txtTemplate.Visible = true;
lblTemplate.Visible = true;
}
if(string.IsNullOrWhiteSpace(node.TedInfo.Text))
{
txtText.Visible = false;
lblText.Visible = false;
}
else
{
txtText.Visible = true;
lblText.Visible = true;
}
if(string.IsNullOrWhiteSpace(node.TedInfo.Validation))
{
txtValidation.Visible = false;
lblValidation.Visible = false;
}
else
{
txtValidation.Visible = true;
lblValidation.Visible = true;
}
if(!string.IsNullOrEmpty(node.TedInfo.Template))
if(string.IsNullOrEmpty(node.TedInfo.Text))
txtPreview.Text = node.TedInfo.Template;
else
{
char[] preview = node.TedInfo.Template.ToCharArray();
char[] template = node.TedInfo.Text.ToCharArray();
if(template[0] == '@')
for(int i = 0; i < template.Length; i++)
template[i] = ' ';
int templatePos = 0;
for(int i = 0; i < preview.Length; i++)
{
if(preview[i] != '_') continue;
if(templatePos >= template.Length) continue;
preview[i] = template[templatePos];
templatePos++;
}
txtPreview.Text = new string(preview);
}
else txtPreview.Text = txtText.Text;
txtPreview.BackgroundColor = GemColor.GemToEtoColor(node.TedInfo.InsideColor);
txtPreview.TextColor = GemColor.GemToEtoColor(node.TedInfo.TextColor);
}
}
}

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<TabPage Text="GEM Resources" xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<StackLayout Orientation="Horizontal">
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<TreeGridView ID="treeResources" ShowHeader="False"/>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<Panel ID="pnlResource"/>
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
</StackLayout>
</TabPage>

View File

@@ -0,0 +1,154 @@
//
// TabGemResources.xeto.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using Eto.Forms;
using Eto.Serialization.Xaml;
namespace exeinfogui.GEM
{
public class TabGemResources : TabPage
{
libexeinfo.GEM.ColorIcon[] colorIcons;
PanelGemBox panelBox;
PanelGemColorIcon panelColorIcon;
PanelGemGeneric panelGeneric;
PanelGemIcon panelIcon;
PanelGemImage panelImage;
PanelGemString panelString;
PanelGemText panelText;
Panel pnlResource;
TreeGridItemCollection treeData;
TreeGridView treeResources;
public TabGemResources()
{
XamlReader.Load(this);
treeResources.Columns.Add(new GridColumn {HeaderText = "Type", DataCell = new TextBoxCell(0)});
treeResources.AllowMultipleSelection = false;
treeResources.SelectionChanged += TreeResourcesOnSelectionChanged;
panelGeneric = new PanelGemGeneric();
panelString = new PanelGemString();
panelText = new PanelGemText();
panelBox = new PanelGemBox();
panelImage = new PanelGemImage();
panelIcon = new PanelGemIcon();
panelColorIcon = new PanelGemColorIcon();
}
public void Update(libexeinfo.GEM.TreeObjectNode[] roots, libexeinfo.GEM.ColorIcon[] cicons)
{
treeData = new TreeGridItemCollection();
for(int i = 0; i < roots.Length; i++)
{
TreeGridItem root = new TreeGridItem {Values = new object[] {$"Root {i}", null}};
AddObjectToTree(root, roots[i]);
treeData.Add(root);
}
treeResources.DataStore = treeData;
colorIcons = cicons;
}
void TreeResourcesOnSelectionChanged(object sender, EventArgs eventArgs)
{
if(!(((TreeGridItem)treeResources.SelectedItem)?.Values[1] is libexeinfo.GEM.TreeObjectNode node))
{
pnlResource.Content = null;
return;
}
switch(node.type)
{
case libexeinfo.GEM.ObjectTypes.G_BUTTON:
case libexeinfo.GEM.ObjectTypes.G_STRING:
case libexeinfo.GEM.ObjectTypes.G_TITLE:
panelString.Update(node);
pnlResource.Content = panelString;
break;
case libexeinfo.GEM.ObjectTypes.G_TEXT:
case libexeinfo.GEM.ObjectTypes.G_BOXTEXT:
case libexeinfo.GEM.ObjectTypes.G_FTEXT:
case libexeinfo.GEM.ObjectTypes.G_FBOXTEXT:
panelText.Update(node);
pnlResource.Content = panelText;
break;
case libexeinfo.GEM.ObjectTypes.G_BOX:
case libexeinfo.GEM.ObjectTypes.G_IBOX:
case libexeinfo.GEM.ObjectTypes.G_BOXCHAR:
panelBox.Update(node);
pnlResource.Content = panelBox;
break;
case libexeinfo.GEM.ObjectTypes.G_IMAGE:
panelImage.Update(node);
pnlResource.Content = panelImage;
break;
case libexeinfo.GEM.ObjectTypes.G_ICON:
panelIcon.Update(node);
pnlResource.Content = panelIcon;
break;
/* case libexeinfo.GEM.ObjectTypes.G_USERDEF: break;*/
case libexeinfo.GEM.ObjectTypes.G_CICON:
if(colorIcons == null || node.data >= colorIcons.Length || colorIcons[node.data] == null)
goto default;
panelColorIcon.Update(node, colorIcons[node.data]);
pnlResource.Content = panelColorIcon;
break;
default:
panelGeneric.Update(node);
pnlResource.Content = panelGeneric;
break;
}
}
static void AddObjectToTree(TreeGridItem parent, libexeinfo.GEM.TreeObjectNode node)
{
while(true)
{
TreeGridItem item = new TreeGridItem {Values = new object[] {$"{node.type}", node}};
if(node.child != null) AddObjectToTree(item, node.child);
parent.Children.Add(item);
if(node.sibling != null)
{
node = node.sibling;
continue;
}
break;
}
}
}
}

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<TabPage Text="VxD Version" xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<Panel ID="pnlVersion"/>
</StackLayoutItem>
</StackLayout>
</TabPage>

View File

@@ -0,0 +1,51 @@
//
// TabLeVxdVersion.xeto.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using exeinfogui.Win16;
using Eto.Forms;
using Eto.Serialization.Xaml;
namespace exeinfogui.LE
{
public class TabLeVxdVersion : TabPage
{
PanelWin16Version panelWin16Version;
Panel pnlVersion;
public TabLeVxdVersion()
{
XamlReader.Load(this);
panelWin16Version = new PanelWin16Version();
pnlVersion.Content = panelWin16Version;
}
public void Update(libexeinfo.NE.Version version)
{
panelWin16Version.Update(version);
}
}
}

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<TabPage Text="LX Resources" xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<StackLayout Orientation="Horizontal">
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<TreeGridView ID="treeResources"/>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<Panel ID="pnlResource"/>
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
</StackLayout>
</TabPage>

View File

@@ -0,0 +1,141 @@
//
// TabLxResources.xeto.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using exeinfogui.NE;
using exeinfogui.Os2;
using exeinfogui.Win16;
using exeinfogui.Windows;
using Eto.Forms;
using Eto.Serialization.Xaml;
namespace exeinfogui.LX
{
public class TabLxResources : TabPage
{
PanelHexDump panelHexDump;
PanelNeAccelerators panelNeAccelerators;
PanelNeStrings panelNeStrings;
PanelOs2Bitmap panelOs2Bitmap;
Panel pnlResource;
TreeGridItemCollection treeData;
TreeGridView treeResources;
PanelWindowsIcon panelWindowsIcon;
public TabLxResources()
{
XamlReader.Load(this);
treeResources.Columns.Add(new GridColumn {HeaderText = "Type", DataCell = new TextBoxCell(0)});
treeResources.Columns.Add(new GridColumn {HeaderText = "Size", DataCell = new TextBoxCell(1)});
treeResources.AllowMultipleSelection = false;
treeResources.SelectionChanged += TreeResourcesOnSelectionChanged;
panelNeStrings = new PanelNeStrings();
panelNeAccelerators = new PanelNeAccelerators();
panelHexDump = new PanelHexDump();
panelOs2Bitmap = new PanelOs2Bitmap();
panelWindowsIcon = new PanelWindowsIcon();
}
public void Update(IEnumerable<libexeinfo.NE.ResourceType> resourceTypes)
{
treeData = new TreeGridItemCollection();
foreach(libexeinfo.NE.ResourceType resourceType in resourceTypes.OrderBy(r => r.name))
{
TreeGridItem root = new TreeGridItem
{
Values = new object[] {$"{resourceType.name}", null, null, null}
};
foreach(libexeinfo.NE.Resource resource in resourceType.resources.OrderBy(r => r.name))
root.Children.Add(new TreeGridItem
{
Values = new object[]
{
$"{resource.name}", $"{resource.data.Length}", $"{resourceType.name}", resource
}
});
treeData.Add(root);
}
treeResources.DataStore = treeData;
}
void TreeResourcesOnSelectionChanged(object sender, EventArgs eventArgs)
{
if(!(((TreeGridItem)treeResources.SelectedItem)?.Values[3] is libexeinfo.NE.Resource resource))
{
pnlResource.Content = null;
return;
}
byte[] data = ((libexeinfo.NE.Resource)((TreeGridItem)treeResources.SelectedItem).Values[3]).data;
switch(((TreeGridItem)treeResources.SelectedItem).Values[2])
{
case "RT_STRING":
pnlResource.Content = panelNeStrings;
panelNeStrings.Update(data, libexeinfo.NE.TargetOS.OS2);
break;
case "RT_ACCELTABLE":
pnlResource.Content = panelNeAccelerators;
panelNeAccelerators.Update(data, libexeinfo.NE.TargetOS.OS2);
break;
case "RT_BITMAP":
case "RT_POINTER":
// TODO: Some do not contain valid OS/2 bitmaps
try
{
pnlResource.Content = panelOs2Bitmap;
panelOs2Bitmap.Update(data);
}
catch { goto default; }
break;
case "RT_MENU":
if(BitConverter.ToUInt32(data, 0) == 40)
{
// Some OS/2 executables contain Windows "RT_ICON" resources, in OS/2 NE format
pnlResource.Content = panelWindowsIcon;
panelWindowsIcon.Update(data);
break;
}
goto default;
default:
pnlResource.Content = panelHexDump;
panelHexDump.Update(data);
break;
}
}
}
}

65
exeinfogui/MainForm.xeto Normal file
View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<Form xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="ExeInfo GUI" ClientSize="400, 350" Padding="10">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Stretch">
<StackLayout Orientation="Horizontal">
<Label ID="lblFile">File:</Label>
<StackLayoutItem Expand="True">
<TextBox ID="txtFile" ReadOnly="True" />
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Right">
<Button ID="btnLoad" Click="OnBtnLoadClick">Load</Button>
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch">
<StackLayout Orientation="Horizontal">
<Label ID="lblType">Type:</Label>
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<TextBox ID="txtType" ReadOnly="True" />
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch">
<StackLayout Orientation="Horizontal">
<Label ID="lblArch">Architectures:</Label>
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<ComboBox ID="cmbArch" ReadOnly="True" />
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch">
<StackLayout Orientation="Horizontal">
<Label ID="lblOs">Required operating system:</Label>
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<TextBox ID="txtOs" ReadOnly="True" />
</StackLayoutItem>
<Label ID="lblSubsystem" Visible="False">Subsystem:</Label>
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<TextBox ID="txtSubsystem" ReadOnly="True" Visible="False" />
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<TabControl ID="tabMain">
<TabPage Text="Information">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<TextArea ID="txtInformation" ReadOnly="True" />
</StackLayoutItem>
</StackLayout>
</TabPage>
</TabControl>
</StackLayoutItem>
</StackLayout>
<Form.Menu>
<MenuBar>
<MenuBar.QuitItem>
<ButtonMenuItem ID="mnuQuit" Text="Quit" Shortcut="CommonModifier+Q" Click="OnMnuQuitClick" />
</MenuBar.QuitItem>
<MenuBar.AboutItem>
<ButtonMenuItem ID="mnuAbout" Text="About..." Click="OnMnuAboutClick" />
</MenuBar.AboutItem>
</MenuBar>
</Form.Menu>
</Form>

228
exeinfogui/MainForm.xeto.cs Normal file
View File

@@ -0,0 +1,228 @@
//
// MainForm.xeto.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Linq;
using exeinfogui.BeOS;
using exeinfogui.GEM;
using exeinfogui.LE;
using exeinfogui.LX;
using exeinfogui.NE;
using exeinfogui.PE;
using Eto.Forms;
using Eto.Serialization.Xaml;
using libexeinfo;
namespace exeinfogui
{
public class MainForm : Form
{
ComboBox cmbArch;
Label lblSubsystem;
TabBeResources tabBeResources;
TabGemResources tabGemResources;
TabLeVxdVersion tabLeVxdVersion;
TabLxResources tabLxResources;
TabControl tabMain;
TabNeResources tabNeResources;
TabPeResources tabPeResources;
TabPageSegments tabSegments;
TabPageStrings tabStrings;
TextBox txtFile;
TextArea txtInformation;
TextBox txtOs;
TextBox txtSubsystem;
TextBox txtType;
public MainForm()
{
XamlReader.Load(this);
tabSegments = new TabPageSegments {Visible = false};
tabStrings = new TabPageStrings {Visible = false};
tabGemResources = new TabGemResources {Visible = false};
tabNeResources = new TabNeResources {Visible = false};
tabLeVxdVersion = new TabLeVxdVersion {Visible = false};
tabLxResources = new TabLxResources {Visible = false};
tabPeResources = new TabPeResources {Visible = false};
tabBeResources = new TabBeResources {Visible = false};
tabMain.Pages.Add(tabSegments);
tabMain.Pages.Add(tabStrings);
tabMain.Pages.Add(tabGemResources);
tabMain.Pages.Add(tabNeResources);
tabMain.Pages.Add(tabLeVxdVersion);
tabMain.Pages.Add(tabLxResources);
tabMain.Pages.Add(tabPeResources);
tabMain.Pages.Add(tabBeResources);
}
protected void OnBtnLoadClick(object sender, EventArgs e)
{
txtFile.Text = "";
txtType.Text = "";
txtInformation.Text = "";
cmbArch.Items.Clear();
lblSubsystem.Visible = false;
txtSubsystem.Visible = false;
tabStrings.Visible = false;
tabGemResources.Visible = false;
tabSegments.Visible = false;
tabNeResources.Visible = false;
tabLeVxdVersion.Visible = false;
tabLxResources.Visible = false;
tabPeResources.Visible = false;
tabBeResources.Visible = false;
OpenFileDialog dlgOpen = new OpenFileDialog {Title = "Choose executable file", MultiSelect = false};
if(dlgOpen.ShowDialog(this) != DialogResult.Ok) return;
txtFile.Text = dlgOpen.FileName;
txtInformation.Text = "";
txtOs.Text = "";
txtSubsystem.Text = "";
txtType.Text = "";
IExecutable mzExe = new MZ(dlgOpen.FileName);
IExecutable neExe = new libexeinfo.NE(dlgOpen.FileName);
IExecutable stExe = new AtariST(dlgOpen.FileName);
IExecutable lxExe = new libexeinfo.LX(dlgOpen.FileName);
IExecutable coffExe = new COFF(dlgOpen.FileName);
IExecutable peExe = new libexeinfo.PE(dlgOpen.FileName);
IExecutable geosExe = new Geos(dlgOpen.FileName);
IExecutable elfExe = new ELF(dlgOpen.FileName);
IExecutable recognizedExe = null;
if(mzExe.Recognized)
{
recognizedExe = mzExe;
if(((MZ)mzExe).ResourceObjectRoots != null && ((MZ)mzExe).ResourceObjectRoots.Any())
{
tabGemResources.Update(((MZ)mzExe).ResourceObjectRoots, ((MZ)mzExe).GemColorIcons);
tabGemResources.Visible = true;
}
}
if(neExe.Recognized)
{
recognizedExe = neExe;
if(((libexeinfo.NE)neExe).Resources.types != null && ((libexeinfo.NE)neExe).Resources.types.Any())
{
tabNeResources.Update(((libexeinfo.NE)neExe).Resources.types,
((libexeinfo.NE)neExe).Header.target_os);
tabNeResources.Visible = true;
}
}
else if(lxExe.Recognized)
{
recognizedExe = lxExe;
if(((libexeinfo.LX)lxExe).WinVersion != null)
{
tabLeVxdVersion.Visible = true;
tabLeVxdVersion.Update(((libexeinfo.LX)lxExe).WinVersion);
}
if(((libexeinfo.LX)lxExe).neFormatResourceTable.types != null &&
((libexeinfo.LX)lxExe).neFormatResourceTable.types.Any())
{
tabLxResources.Update(((libexeinfo.LX)lxExe).neFormatResourceTable.types);
tabLxResources.Visible = true;
}
}
else if(peExe.Recognized)
{
recognizedExe = peExe;
if(((libexeinfo.PE)peExe).WindowsResourcesRoot?.children != null)
{
tabPeResources.Update(((libexeinfo.PE)peExe).WindowsResourcesRoot);
tabPeResources.Visible = true;
}
if(((libexeinfo.PE)peExe).BeosResources != null)
{
tabBeResources.Update(((libexeinfo.PE)peExe).BeosResources, peExe.IsBigEndian);
tabBeResources.Visible = true;
}
}
else if(stExe.Recognized)
{
recognizedExe = stExe;
if(((AtariST)stExe).ResourceObjectRoots != null && ((AtariST)stExe).ResourceObjectRoots.Any())
{
tabGemResources.Update(((AtariST)stExe).ResourceObjectRoots, ((AtariST)stExe).GemColorIcons);
tabGemResources.Visible = true;
}
}
else if(coffExe.Recognized) recognizedExe = coffExe;
else if(elfExe.Recognized) recognizedExe = elfExe;
else if(geosExe.Recognized) recognizedExe = geosExe;
else txtType.Text = "Format not recognized";
if(recognizedExe == null) return;
txtType.Text = recognizedExe.Type;
txtInformation.Text = recognizedExe.Information;
foreach(Architecture arch in recognizedExe.Architectures)
cmbArch.Items.Add(Enums.ArchitectureName.FirstOrDefault(ar => ar.arch == arch).longName);
cmbArch.SelectedIndex = 0;
if(recognizedExe.RequiredOperatingSystem.MajorVersion > 0)
txtOs.Text = $"{recognizedExe.RequiredOperatingSystem.Name}" +
$" {recognizedExe.RequiredOperatingSystem.MajorVersion}" +
$".{recognizedExe.RequiredOperatingSystem.MinorVersion}";
else txtOs.Text = recognizedExe.RequiredOperatingSystem.Name;
if(!string.IsNullOrEmpty(recognizedExe.RequiredOperatingSystem.Subsystem))
{
lblSubsystem.Visible = true;
txtSubsystem.Visible = true;
txtSubsystem.Text = recognizedExe.RequiredOperatingSystem.Subsystem;
}
if(recognizedExe.Strings != null && recognizedExe.Strings.Any())
{
tabStrings.Update(recognizedExe.Strings);
tabStrings.Visible = true;
}
if(recognizedExe.Segments != null && recognizedExe.Segments.Any())
{
tabSegments.Update(recognizedExe.Segments);
tabSegments.Visible = true;
}
}
protected void OnMnuAboutClick(object sender, EventArgs e)
{
new AboutDialog().ShowDialog(this);
}
protected void OnMnuQuitClick(object sender, EventArgs e)
{
Application.Instance.Quit();
}
}
}

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<Panel xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackLayout Orientation="Vertical">
<StackLayout Orientation="Horizontal">
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Right" Expand="True">
<Label ID="lblCodepage">Codepage</Label>
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<TextBox ID="txtCodepage" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
</StackLayout>
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<StackLayout Orientation="Vertical" ID="stkString">
<StackLayoutItem HorizontalAlignment="Center">
<Label ID="lblAccelerators">Accelerators</Label>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<GridView ID="grdAccelerators"/>
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
</StackLayout>
</Panel>

View File

@@ -0,0 +1,80 @@
using System.Collections.Generic;
using System.Linq;
using Eto.Forms;
using Eto.Serialization.Xaml;
namespace exeinfogui.NE
{
public class PanelNeAccelerators : Panel
{
GridView grdAccelerators;
Label lblCodepage;
TextBox txtCodepage;
public PanelNeAccelerators()
{
XamlReader.Load(this);
grdAccelerators.Columns.Add(new GridColumn
{
DataCell = new TextBoxCell {Binding = Binding.Property<Accelerator, string>(a => $"{a.Type}")},
HeaderText = "Type"
});
grdAccelerators.Columns.Add(new GridColumn
{
DataCell = new TextBoxCell {Binding = Binding.Property<Accelerator, string>(a => $"{a.Key}")},
HeaderText = "Key"
});
grdAccelerators.Columns.Add(new GridColumn
{
DataCell = new TextBoxCell {Binding = Binding.Property<Accelerator, string>(a => $"{a.Command}")},
HeaderText = "Command"
});
}
public void Update(byte[] data, libexeinfo.NE.TargetOS targetOs)
{
grdAccelerators.DataStore = null;
List<Accelerator> accelerators = new List<Accelerator>();
if(targetOs == libexeinfo.NE.TargetOS.OS2)
{
libexeinfo.NE.Os2AcceleratorTable table = libexeinfo.NE.GetOs2Accelerators(data);
lblCodepage.Visible = true;
txtCodepage.Visible = true;
txtCodepage.Text = $"{table.CodePage}";
accelerators.AddRange(table.Accelerators.Select(accel => new Accelerator
{
Type = $"{accel.Type}",
Key = accel.Type.HasFlag(libexeinfo.NE.Os2AcceleratorFlags.AF_VIRTUALKEY) ? $"{accel.Key}" :
$"'{(char)(byte)accel.Key}'",
Command = accel.Command
}));
}
else
{
lblCodepage.Visible = false;
txtCodepage.Visible = false;
accelerators.AddRange(libexeinfo.NE.GetWinAccelerators(data)
.Select(accel => new Accelerator
{
Type = $"{accel.Flags}",
Key = accel.Flags.HasFlag(libexeinfo.NE.WinAcceleratorFlags.VirtualKey) ? $"{accel.Key}" :
$"'{(char)(byte)accel.Key}'",
Command = accel.Command
}));
}
if(accelerators.Count > 0) grdAccelerators.DataStore = accelerators.OrderBy(r => r.Command).ThenBy(r=>r.Key);
}
class Accelerator
{
public ushort Command;
public string Key;
public string Type;
}
}
}

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<Panel xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<GridView ID="treeStrings" ShowHeader="False"/>
</StackLayoutItem>
</StackLayout>
</Panel>

View File

@@ -0,0 +1,54 @@
//
// PanelNeStrings.xeto.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using Eto.Forms;
using Eto.Serialization.Xaml;
namespace exeinfogui.NE
{
public class PanelNeStrings : Panel
{
GridView treeStrings;
public PanelNeStrings()
{
XamlReader.Load(this);
treeStrings.Columns.Add(new GridColumn
{
DataCell = new TextBoxCell {Binding = Binding.Property<string, string>(r => r)},
HeaderText = "String"
});
}
public void Update(byte[] data, libexeinfo.NE.TargetOS targetOs)
{
treeStrings.DataStore = targetOs == libexeinfo.NE.TargetOS.OS2
? libexeinfo.NE.GetOs2Strings(data)
: libexeinfo.NE.GetWindowsStrings(data);
}
}
}

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<TabPage Text="NE Resources" xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<StackLayout Orientation="Horizontal">
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<TreeGridView ID="treeResources"/>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<Panel ID="pnlResource"/>
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
</StackLayout>
</TabPage>

View File

@@ -0,0 +1,159 @@
//
// TabNeResources.xeto.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using exeinfogui.Os2;
using exeinfogui.Win16;
using exeinfogui.Windows;
using Eto.Forms;
using Eto.Serialization.Xaml;
namespace exeinfogui.NE
{
public class TabNeResources : TabPage
{
PanelHexDump panelHexDump;
PanelNeAccelerators panelNeAccelerators;
PanelNeStrings panelNeStrings;
PanelOs2Bitmap panelOs2Bitmap;
PanelWin16Version panelWin16Version;
PanelWindowsIcon panelWindowsIcon;
Panel pnlResource;
TreeGridView treeResources;
public TabNeResources()
{
XamlReader.Load(this);
treeResources.Columns.Add(new GridColumn {HeaderText = "Type", DataCell = new TextBoxCell(0)});
treeResources.Columns.Add(new GridColumn {HeaderText = "Size", DataCell = new TextBoxCell(1)});
treeResources.Columns.Add(new GridColumn {HeaderText = "Flags", DataCell = new TextBoxCell(2)});
treeResources.AllowMultipleSelection = false;
treeResources.SelectionChanged += TreeResourcesOnSelectionChanged;
panelWin16Version = new PanelWin16Version();
panelNeStrings = new PanelNeStrings();
panelNeAccelerators = new PanelNeAccelerators();
panelHexDump = new PanelHexDump();
panelOs2Bitmap = new PanelOs2Bitmap();
panelWindowsIcon = new PanelWindowsIcon();
}
public void Update(IEnumerable<libexeinfo.NE.ResourceType> resourceTypes, libexeinfo.NE.TargetOS os)
{
TreeGridItemCollection treeData = new TreeGridItemCollection();
foreach(libexeinfo.NE.ResourceType resourceType in resourceTypes.OrderBy(r => r.name))
{
TreeGridItem root = new TreeGridItem
{
Values = new object[] {$"{resourceType.name}", null, null, null, os, null}
};
foreach(libexeinfo.NE.Resource resource in resourceType.resources.OrderBy(r => r.name))
root.Children.Add(new TreeGridItem
{
Values = new object[]
{
$"{resource.name}", $"{resource.data.Length}",
$"{(libexeinfo.NE.ResourceFlags)((ushort)resource.flags & libexeinfo.NE.KNOWN_RSRC_FLAGS)}",
$"{resourceType.name}", os, resource
}
});
treeData.Add(root);
}
treeResources.DataStore = treeData;
}
void TreeResourcesOnSelectionChanged(object sender, EventArgs eventArgs)
{
if(!(((TreeGridItem)treeResources.SelectedItem)?.Values[5] is libexeinfo.NE.Resource resource))
{
pnlResource.Content = null;
return;
}
byte[] data = ((libexeinfo.NE.Resource)((TreeGridItem)treeResources.SelectedItem).Values[5]).data;
switch(((TreeGridItem)treeResources.SelectedItem).Values[3])
{
case "RT_VERSION":
pnlResource.Content = panelWin16Version;
panelWin16Version.Update(data);
break;
case "RT_STRING":
pnlResource.Content = panelNeStrings;
panelNeStrings.Update(data,
(libexeinfo.NE.TargetOS)((TreeGridItem)treeResources.SelectedItem).Values[4]);
break;
case "RT_ACCELERATOR":
pnlResource.Content = panelNeAccelerators;
panelNeAccelerators.Update(data, libexeinfo.NE.TargetOS.Windows);
break;
case "RT_ACCELTABLE":
pnlResource.Content = panelNeAccelerators;
panelNeAccelerators.Update(data, libexeinfo.NE.TargetOS.OS2);
break;
case "RT_BITMAP" when (libexeinfo.NE.TargetOS)((TreeGridItem)treeResources.SelectedItem).Values[4] ==
libexeinfo.NE.TargetOS.OS2:
case "RT_POINTER":
// TODO: Some do not contain valid OS/2 bitmaps
try
{
pnlResource.Content = panelOs2Bitmap;
panelOs2Bitmap.Update(data);
}
catch { goto default; }
break;
case "RT_MENU" when (libexeinfo.NE.TargetOS)((TreeGridItem)treeResources.SelectedItem).Values[4] ==
libexeinfo.NE.TargetOS.OS2:
if(BitConverter.ToUInt32(data, 0) == 40)
{
// Some OS/2 executables contain Windows "RT_ICON" resources, in OS/2 NE format
pnlResource.Content = panelWindowsIcon;
panelWindowsIcon.Update(data);
break;
}
goto default;
case "RT_ICON":
pnlResource.Content = panelWindowsIcon;
panelWindowsIcon.Update(data);
break;
default:
pnlResource.Content = panelHexDump;
panelHexDump.Update(data);
break;
}
}
}
}

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<Panel xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackLayout Orientation="Horizontal">
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True" VerticalAlignment="Stretch">
<GridView ID="grdIcons"/>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<StackLayout Orientation="Vertical">
<StackLayout Orientation="Horizontal">
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<Label ID="lblType">Type</Label>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<TextBox ID="txtType" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<Label ID="lblSize">Size</Label>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<TextBox ID="txtSize" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<Label ID="lblColors">Colors</Label>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<TextBox ID="txtColors" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<ImageView ID="imgIcon"/>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<Panel ID="pnlPanel"/>
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
</StackLayout>
</Panel>

View File

@@ -0,0 +1,152 @@
using System;
using Eto.Drawing;
using Eto.Forms;
using Eto.Serialization.Xaml;
using libexeinfo.Os2;
using Bitmap = libexeinfo.Os2.Bitmap;
namespace exeinfogui.Os2
{
public class PanelOs2Bitmap : Panel
{
GridView grdIcons;
ImageView imgIcon;
Label lblColors;
Label lblSize;
Label lblType;
PanelHexDump panelHexDump;
Panel pnlPanel;
TextBox txtColors;
TextBox txtSize;
TextBox txtType;
public PanelOs2Bitmap()
{
XamlReader.Load(this);
grdIcons.Columns.Add(new GridColumn
{
DataCell =
new TextBoxCell {Binding = Binding.Property<DecodedBitmap, string>(b => $"{b.Type}")},
HeaderText = "Command"
});
grdIcons.Columns.Add(new GridColumn
{
DataCell = new TextBoxCell
{
Binding = Binding.Property<DecodedBitmap, string>(b => $"{b.Width}x{b.Height}")
},
HeaderText = "Size"
});
grdIcons.Columns.Add(new GridColumn
{
DataCell = new TextBoxCell
{
Binding = Binding.Property<DecodedBitmap, string>(b => $"{1 << (int)b.BitsPerPixel}")
},
HeaderText = "Colors"
});
grdIcons.AllowMultipleSelection = false;
grdIcons.SelectionChanged += GrdIconsOnSelectionChanged;
panelHexDump = new PanelHexDump();
pnlPanel.Content = panelHexDump;
}
void GrdIconsOnSelectionChanged(object sender, EventArgs eventArgs)
{
if(!(grdIcons.SelectedItem is DecodedBitmap icon))
{
imgIcon.Image = null;
return;
}
txtType.Text = icon.Type;
txtSize.Text = $"{icon.Width}x{icon.Height} pixels";
txtColors.Text = $"{1 << (int)icon.BitsPerPixel} ({icon.BitsPerPixel} bpp)";
imgIcon.Image =
new Eto.Drawing.Bitmap((int)icon.Width, (int)icon.Height, PixelFormat.Format32bppRgba, icon.Pixels);
}
public void Update(byte[] data)
{
if(data == null)
{
imgIcon.Image = null;
grdIcons.Visible = false;
lblType.Text = "No data";
lblColors.Visible = false;
lblSize.Visible = false;
txtType.Visible = false;
txtColors.Visible = false;
txtSize.Visible = false;
pnlPanel.Visible = false;
return;
}
DecodedBitmap[] icons = Bitmap.DecodeBitmap(data);
if(icons == null || icons.Length == 0)
try
{
libexeinfo.Windows.DecodedBitmap winIcon = null;
if(BitConverter.ToUInt32(data, 4) == 40)
{
byte[] cursor = new byte[data.Length - 4];
Array.Copy(data, 4, cursor, 0, cursor.Length);
winIcon = libexeinfo.Windows.Bitmap.DecodeIcon(cursor);
}
else if(BitConverter.ToUInt32(data, 0) == 40)
winIcon = libexeinfo.Windows.Bitmap.DecodeIcon(data);
if(winIcon != null)
icons = new[]
{
new DecodedBitmap
{
BitsPerPixel = winIcon.BitsPerPixel,
Height = winIcon.Height,
Pixels = winIcon.Pixels,
Type = "Windows cursor",
Width = winIcon.Width
}
};
}
catch { icons = null; }
if(icons == null || icons.Length == 0)
{
imgIcon.Image = null;
grdIcons.Visible = false;
lblType.Text = "Undecoded";
lblColors.Visible = false;
lblSize.Visible = false;
txtType.Visible = false;
txtColors.Visible = false;
txtSize.Visible = false;
pnlPanel.Visible = true;
panelHexDump.Update(data);
return;
}
txtType.Text = icons[0].Type;
txtSize.Text = $"{icons[0].Width}x{icons[0].Height} pixels";
txtColors.Text = $"{1 << (int)icons[0].BitsPerPixel} ({icons[0].BitsPerPixel} bpp)";
imgIcon.Image = new Eto.Drawing.Bitmap((int)icons[0].Width, (int)icons[0].Height,
PixelFormat.Format32bppRgba, icons[0].Pixels);
grdIcons.DataStore = icons;
grdIcons.SelectedRow = 0;
grdIcons.Visible = icons.Length != 1;
lblType.Text = "Type";
lblColors.Visible = true;
lblSize.Visible = true;
txtType.Visible = true;
txtColors.Visible = true;
txtSize.Visible = true;
pnlPanel.Visible = false;
}
}
}

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<Panel xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<GridView ID="treeStrings" ShowHeader="False"/>
</StackLayoutItem>
</StackLayout>
</Panel>

View File

@@ -0,0 +1,52 @@
//
// PanelPeStrings.xeto.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using Eto.Forms;
using Eto.Serialization.Xaml;
namespace exeinfogui.PE
{
public class PanelPeStrings : Panel
{
GridView treeStrings;
public PanelPeStrings()
{
XamlReader.Load(this);
treeStrings.Columns.Add(new GridColumn
{
DataCell = new TextBoxCell {Binding = Binding.Property<string, string>(r => r)},
HeaderText = "String"
});
}
public void Update(byte[] data)
{
treeStrings.DataStore = libexeinfo.PE.GetStrings(data);
}
}
}

View File

@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<Panel xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackLayout Orientation="Vertical" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Top">
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblFileVersion">File version</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtFileVersion" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblProductVersion">Product version</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtProductVersion" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblFileType">File type</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtFileType" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblFileSubtype">File subtype</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtFileSubtype" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblFileFlags">File flags</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtFileFlags" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblFileOs">File OS</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtFileOs" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblFileDate">File date</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtFileDate" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<StackLayout Orientation="Horizontal" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Center" VerticalAlignment="Top">
<Label ID="lblLanguages">Language</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<GridView ID="treeLanguages" ShowHeader="False"/>
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Center" VerticalAlignment="Top">
<Label ID="lblStrings">Strings</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<GridView ID="treeStrings"/>
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
</StackLayout>
</Panel>

View File

@@ -0,0 +1,151 @@
//
// PanelPeVersion.xeto.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Text;
using Eto.Forms;
using Eto.Serialization.Xaml;
using libexeinfo.Windows;
using Version = libexeinfo.Windows.Version;
namespace exeinfogui.PE
{
public class PanelPeVersion : Panel
{
ObservableCollection<StrByLang> stringsByLanguage;
GridView treeLanguages;
GridView treeStrings;
TextBox txtFileDate;
TextBox txtFileFlags;
TextBox txtFileOs;
TextBox txtFileSubtype;
TextBox txtFileType;
TextBox txtFileVersion;
TextBox txtProductVersion;
public PanelPeVersion()
{
XamlReader.Load(this);
treeLanguages.Columns.Add(new GridColumn
{
DataCell = new TextBoxCell {Binding = Binding.Property<StrByLang, string>(r => r.Name)},
HeaderText = "Language (codepage)"
});
treeStrings.Columns.Add(new GridColumn
{
DataCell = new TextBoxCell {Binding = Binding.Property<Strings, string>(r => r.Key)},
HeaderText = "Key"
});
treeStrings.Columns.Add(new GridColumn
{
DataCell = new TextBoxCell {Binding = Binding.Property<Strings, string>(r => r.Value)},
HeaderText = "Value"
});
stringsByLanguage = new ObservableCollection<StrByLang>();
treeLanguages.SelectionChanged += TreeLanguagesOnSelectionChanged;
treeLanguages.AllowMultipleSelection = false;
}
void TreeLanguagesOnSelectionChanged(object sender, EventArgs eventArgs)
{
treeStrings.DataStore = null;
if(!(treeLanguages.SelectedItem is StrByLang strs)) return;
List<Strings> strings = new List<Strings>();
foreach(KeyValuePair<string, string> kvp in strs.Strings)
strings.Add(new Strings {Key = kvp.Key, Value = kvp.Value});
treeStrings.DataStore = strings;
}
public void Update(byte[] data)
{
Update(new libexeinfo.PE.Version(data));
}
public void Update(libexeinfo.PE.Version version)
{
txtFileDate.Text = version.FileDate != new DateTime(1601, 1, 1) ? $"{version.FileDate}" : "Not set";
txtFileFlags.Text = version.FileFlags == 0 ? "Normal" : $"{version.FileFlags}";
txtFileOs.Text = Version.OsToString(version.FileOs);
if(version.FileType == VersionFileType.VFT_DRV)
txtFileSubtype.Text = $"{Version.DriverToString(version.FileSubtype)} driver";
else if(version.FileType == VersionFileType.VFT_DRV)
txtFileSubtype.Text = $"{Version.FontToString(version.FileSubtype)} font";
else if(version.FileSubtype > 0) txtFileSubtype.Text = $"{(uint)version.FileSubtype}";
else txtFileSubtype.Text = "None";
txtFileType.Text = Version.TypeToString(version.FileType);
txtFileVersion.Text = $"{version.FileVersion}";
txtProductVersion.Text = $"{version.ProductVersion}";
stringsByLanguage.Clear();
foreach(KeyValuePair<string, Dictionary<string, string>> strByLang in version.StringsByLanguage)
{
string cultureName;
string encodingName;
try { cultureName = new CultureInfo(Convert.ToInt32(strByLang.Key.Substring(0, 4), 16)).DisplayName; }
catch { cultureName = $"0x{Convert.ToInt32(strByLang.Key.Substring(0, 4), 16):X4}"; }
try
{
encodingName = Encoding.GetEncoding(Convert.ToInt32(strByLang.Key.Substring(4), 16)).EncodingName;
}
catch { encodingName = $"0x{Convert.ToInt32(strByLang.Key.Substring(4), 16):X4}"; }
stringsByLanguage.Add(new StrByLang
{
Name = $"{cultureName} ({encodingName})",
Strings = strByLang.Value
});
}
treeLanguages.DataStore = stringsByLanguage;
}
class StrByLang
{
public Dictionary<string, string> Strings;
public string Name { get; set; }
}
class Strings
{
public string Key { get; set; }
public string Value { get; set; }
}
}
}

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<TabPage Text="PE Resources" xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<StackLayout Orientation="Horizontal">
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<TreeGridView ID="treeResources"/>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<Panel ID="pnlResource"/>
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
</StackLayout>
</TabPage>

View File

@@ -0,0 +1,121 @@
//
// TabPeResources.xeto.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Text;
using exeinfogui.Windows;
using Eto.Forms;
using Eto.Serialization.Xaml;
namespace exeinfogui.PE
{
public class TabPeResources : TabPage
{
PanelHexDump panelHexDump;
PanelPeStrings panelPeStrings;
PanelPeVersion panelPeVersion;
PanelText panelText;
PanelWindowsIcon panelWindowsIcon;
Panel pnlResource;
TreeGridView treeResources;
public TabPeResources()
{
XamlReader.Load(this);
treeResources.Columns.Add(new GridColumn {HeaderText = "Identifier", DataCell = new TextBoxCell(0)});
treeResources.Columns.Add(new GridColumn {HeaderText = "Size", DataCell = new TextBoxCell(1)});
treeResources.AllowMultipleSelection = false;
treeResources.SelectionChanged += TreeResourcesOnSelectionChanged;
panelPeVersion = new PanelPeVersion();
panelPeStrings = new PanelPeStrings();
panelHexDump = new PanelHexDump();
panelWindowsIcon = new PanelWindowsIcon();
panelText = new PanelText();
}
public void Update(libexeinfo.PE.ResourceNode root)
{
TreeGridItemCollection treeData = new TreeGridItemCollection();
foreach(libexeinfo.PE.ResourceNode rootChild in root.children)
treeData.Add(GetChildren(rootChild, rootChild.name));
treeResources.DataStore = treeData;
}
static TreeGridItem GetChildren(libexeinfo.PE.ResourceNode node, string type)
{
string sizeStr = node.data == null ? null : $"{node.data.Length}";
TreeGridItem item = new TreeGridItem {Values = new object[] {$"{node.name}", sizeStr, type, node.data}};
if(node.children == null) return item;
foreach(libexeinfo.PE.ResourceNode child in node.children) item.Children.Add(GetChildren(child, type));
return item;
}
void TreeResourcesOnSelectionChanged(object sender, EventArgs eventArgs)
{
if(((TreeGridItem)treeResources.SelectedItem)?.Values[3] == null)
{
pnlResource.Content = null;
return;
}
byte[] data = ((TreeGridItem)treeResources.SelectedItem)?.Values[3] as byte[];
string type = ((TreeGridItem)treeResources.SelectedItem)?.Values[2] as string;
switch(type)
{
case "RT_STRING":
pnlResource.Content = panelPeStrings;
panelPeStrings.Update(data);
break;
case "RT_ICON":
pnlResource.Content = panelWindowsIcon;
panelWindowsIcon.Update(data);
break;
case "RT_VERSION":
pnlResource.Content = panelPeVersion;
panelPeVersion.Update(data);
break;
case "RT_MANIFEST":
pnlResource.Content = panelText;
panelText.Update(data, Encoding.UTF8);
break;
default:
pnlResource.Content = panelHexDump;
panelHexDump.Update(data);
break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<Panel xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Center">
<Label>Hex dump</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<TextArea ID="txtHexDump" ReadOnly="True" Wrap="True"/>
</StackLayoutItem>
</StackLayout>
</Panel>

View File

@@ -0,0 +1,55 @@
//
// PanelHexDump.xeto.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System.Text;
using Eto.Forms;
using Eto.Serialization.Xaml;
namespace exeinfogui
{
public class PanelHexDump : Panel
{
TextArea txtHexDump;
public PanelHexDump()
{
XamlReader.Load(this);
}
public void Update(byte[] data)
{
txtHexDump.Text = "";
StringBuilder sb = new StringBuilder();
for(long pos = 0; pos < data.LongLength; pos++)
{
if(pos > 0 && pos % 4 == 0) sb.Append(" ");
sb.Append($"{data[pos]:X2} ");
}
txtHexDump.Text = sb.ToString();
}
}
}

11
exeinfogui/PanelText.xeto Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<Panel xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Center">
<Label>Text</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<TextArea ID="txtText" ReadOnly="True" Wrap="True"/>
</StackLayoutItem>
</StackLayout>
</Panel>

View File

@@ -0,0 +1,47 @@
//
// PanelText.xeto.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System.Text;
using Eto.Forms;
using Eto.Serialization.Xaml;
namespace exeinfogui
{
public class PanelText : Panel
{
TextArea txtText;
public PanelText()
{
XamlReader.Load(this);
}
public void Update(byte[] data, Encoding encoding)
{
txtText.Text = encoding.GetString(data);
}
}
}

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<TabPage Text="Segments" xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<GridView ID="treeSegments"/>
</StackLayoutItem>
</StackLayout>
</TabPage>

View File

@@ -0,0 +1,69 @@
//
// TabPageSegments.xeto.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System.Collections.Generic;
using Eto.Forms;
using Eto.Serialization.Xaml;
using libexeinfo;
namespace exeinfogui
{
public class TabPageSegments : TabPage
{
GridView treeSegments;
public TabPageSegments()
{
XamlReader.Load(this);
treeSegments.Columns.Add(new GridColumn
{
DataCell = new TextBoxCell {Binding = Binding.Property<Segment, string>(s => $"{s.Name}")},
HeaderText = "Name"
});
treeSegments.Columns.Add(new GridColumn
{
DataCell = new TextBoxCell {Binding = Binding.Property<Segment, string>(s => s.Offset != 0 ? $"{s.Offset}" : "N/A")},
HeaderText = "Offset"
});
treeSegments.Columns.Add(new GridColumn
{
DataCell = new TextBoxCell {Binding = Binding.Property<Segment, string>(s => $"{s.Size}")},
HeaderText = "Size"
});
treeSegments.Columns.Add(new GridColumn
{
DataCell = new TextBoxCell {Binding = Binding.Property<Segment, string>(s => $"{s.Flags}")},
HeaderText = "Flags"
});
}
public void Update(IEnumerable<Segment> segments)
{
treeSegments.DataStore = segments;
}
}
}

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<TabPage Text="Strings" xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<GridView ID="treeStrings" ShowHeader="False"/>
</StackLayoutItem>
</StackLayout>
</TabPage>

View File

@@ -0,0 +1,53 @@
//
// TabPageStrings.xeto.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System.Collections.Generic;
using Eto.Forms;
using Eto.Serialization.Xaml;
namespace exeinfogui
{
public class TabPageStrings : TabPage
{
GridView treeStrings;
public TabPageStrings()
{
XamlReader.Load(this);
treeStrings.Columns.Add(new GridColumn
{
DataCell = new TextBoxCell {Binding = Binding.Property<string, string>(r => r)},
HeaderText = "String"
});
}
public void Update(IEnumerable<string> strings)
{
treeStrings.DataStore = strings;
}
}
}

View File

@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<Panel xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackLayout Orientation="Vertical" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Top">
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblFileVersion">File version</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtFileVersion" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblProductVersion">Product version</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtProductVersion" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblFileType">File type</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtFileType" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblFileSubtype">File subtype</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtFileSubtype" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblFileFlags">File flags</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtFileFlags" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblFileOs">File OS</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtFileOs" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem>
<Label ID="lblFileDate">File date</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<TextBox ID="txtFileDate" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch">
<StackLayout Orientation="Horizontal" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Center" VerticalAlignment="Top">
<Label ID="lblLanguages">Language</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<GridView ID="treeLanguages" ShowHeader="False"/>
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Center" VerticalAlignment="Top">
<Label ID="lblStrings">Strings</Label>
</StackLayoutItem>
<StackLayoutItem Expand="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<GridView ID="treeStrings"/>
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
</StackLayout>
</Panel>

View File

@@ -0,0 +1,151 @@
//
// PanelWin16Version.xeto.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Text;
using Eto.Forms;
using Eto.Serialization.Xaml;
using libexeinfo.Windows;
using Version = libexeinfo.Windows.Version;
namespace exeinfogui.Win16
{
public class PanelWin16Version : Panel
{
ObservableCollection<StrByLang> stringsByLanguage;
GridView treeLanguages;
GridView treeStrings;
TextBox txtFileDate;
TextBox txtFileFlags;
TextBox txtFileOs;
TextBox txtFileSubtype;
TextBox txtFileType;
TextBox txtFileVersion;
TextBox txtProductVersion;
public PanelWin16Version()
{
XamlReader.Load(this);
treeLanguages.Columns.Add(new GridColumn
{
DataCell = new TextBoxCell {Binding = Binding.Property<StrByLang, string>(r => r.Name)},
HeaderText = "Language (codepage)"
});
treeStrings.Columns.Add(new GridColumn
{
DataCell = new TextBoxCell {Binding = Binding.Property<Strings, string>(r => r.Key)},
HeaderText = "Key"
});
treeStrings.Columns.Add(new GridColumn
{
DataCell = new TextBoxCell {Binding = Binding.Property<Strings, string>(r => r.Value)},
HeaderText = "Value"
});
stringsByLanguage = new ObservableCollection<StrByLang>();
treeLanguages.SelectionChanged += TreeLanguagesOnSelectionChanged;
treeLanguages.AllowMultipleSelection = false;
}
void TreeLanguagesOnSelectionChanged(object sender, EventArgs eventArgs)
{
treeStrings.DataStore = null;
if(!(treeLanguages.SelectedItem is StrByLang strs)) return;
List<Strings> strings = new List<Strings>();
foreach(KeyValuePair<string, string> kvp in strs.Strings)
strings.Add(new Strings {Key = kvp.Key, Value = kvp.Value});
treeStrings.DataStore = strings;
}
public void Update(byte[] data)
{
Update(new libexeinfo.NE.Version(data));
}
public void Update(libexeinfo.NE.Version version)
{
txtFileDate.Text = version.FileDate != new DateTime(1601, 1, 1) ? $"{version.FileDate}" : "Not set";
txtFileFlags.Text = version.FileFlags == 0 ? "Normal" : $"{version.FileFlags}";
txtFileOs.Text = Version.OsToString(version.FileOs);
if(version.FileType == VersionFileType.VFT_DRV)
txtFileSubtype.Text = $"{Version.DriverToString(version.FileSubtype)} driver";
else if(version.FileType == VersionFileType.VFT_DRV)
txtFileSubtype.Text = $"{Version.FontToString(version.FileSubtype)} font";
else if(version.FileSubtype > 0) txtFileSubtype.Text = $"{(uint)version.FileSubtype}";
else txtFileSubtype.Text = "None";
txtFileType.Text = Version.TypeToString(version.FileType);
txtFileVersion.Text = $"{version.FileVersion}";
txtProductVersion.Text = $"{version.ProductVersion}";
stringsByLanguage.Clear();
foreach(KeyValuePair<string, Dictionary<string, string>> strByLang in version.StringsByLanguage)
{
string cultureName;
string encodingName;
try { cultureName = new CultureInfo(Convert.ToInt32(strByLang.Key.Substring(0, 4), 16)).DisplayName; }
catch { cultureName = $"0x{Convert.ToInt32(strByLang.Key.Substring(0, 4), 16):X4}"; }
try
{
encodingName = Encoding.GetEncoding(Convert.ToInt32(strByLang.Key.Substring(4), 16)).EncodingName;
}
catch { encodingName = $"0x{Convert.ToInt32(strByLang.Key.Substring(4), 16):X4}"; }
stringsByLanguage.Add(new StrByLang
{
Name = $"{cultureName} ({encodingName})",
Strings = strByLang.Value
});
}
treeLanguages.DataStore = stringsByLanguage;
}
class StrByLang
{
public Dictionary<string, string> Strings;
public string Name { get; set; }
}
class Strings
{
public string Key { get; set; }
public string Value { get; set; }
}
}
}

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<Panel xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackLayout Orientation="Vertical">
<StackLayout Orientation="Horizontal">
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<Label ID="lblSize">Size</Label>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<TextBox ID="txtSize" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayout Orientation="Horizontal">
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<Label ID="lblColors">Colors</Label>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<TextBox ID="txtColors" ReadOnly="True"/>
</StackLayoutItem>
</StackLayout>
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<ImageView ID="imgIcon"/>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<Panel ID="pnlPanel"/>
</StackLayoutItem>
</StackLayout>
</Panel>

View File

@@ -0,0 +1,70 @@
using Eto.Drawing;
using Eto.Forms;
using Eto.Serialization.Xaml;
using Bitmap = libexeinfo.Windows.Bitmap;
namespace exeinfogui.Windows
{
public class PanelWindowsIcon : Panel
{
ImageView imgIcon;
Label lblColors;
Label lblSize;
PanelHexDump panelHexDump;
Panel pnlPanel;
TextBox txtColors;
TextBox txtSize;
public PanelWindowsIcon()
{
XamlReader.Load(this);
panelHexDump = new PanelHexDump();
pnlPanel.Content = panelHexDump;
}
public void Update(byte[] data)
{
if(data == null)
{
imgIcon.Image = null;
lblSize.Text = "No data";
lblColors.Visible = false;
lblSize.Visible = false;
txtColors.Visible = false;
txtSize.Visible = false;
pnlPanel.Visible = false;
return;
}
libexeinfo.Windows.DecodedBitmap icon;
try { icon = Bitmap.DecodeIcon(data); }
catch { icon = null; }
if(icon == null)
{
imgIcon.Image = null;
lblSize.Text = "Undecoded";
lblColors.Visible = false;
lblSize.Visible = false;
txtColors.Visible = false;
txtSize.Visible = false;
pnlPanel.Visible = true;
panelHexDump.Update(data);
return;
}
txtSize.Text = $"{icon.Width}x{icon.Height} pixels";
txtColors.Text = $"{1 << (int)icon.BitsPerPixel} ({icon.BitsPerPixel} bpp)";
imgIcon.Image =
new Eto.Drawing.Bitmap((int)icon.Width, (int)icon.Height, PixelFormat.Format32bppRgba, icon.Pixels);
lblSize.Text = "Size";
lblColors.Visible = true;
lblSize.Visible = true;
txtColors.Visible = true;
txtSize.Visible = true;
pnlPanel.Visible = false;
}
}
}

View File

@@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net461</TargetFramework>
<RootNamespace>exeinfogui</RootNamespace>
<PackageVersion>1.0</PackageVersion>
<Title>exeinfogui</Title>
<Copyright>Copyright © 2018</Copyright>
<Description>Description of exeinfogui</Description>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Claunia.Encoding" Version="1.6.1" />
<PackageReference Include="Eto.Forms" Version="2.4.1" />
<PackageReference Include="Eto.Serialization.Xaml" Version="2.4.1" />
<PackageReference Include="System.ValueTuple" Version="4.4.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\libexeinfo\libexeinfo.csproj">
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="GEM\" />
<Folder Include="LE" />
<Folder Include="NE" />
<Folder Include="NE\" />
<Folder Include="Win16\" />
<Folder Include="Os2\" />
<Folder Include="Windows\" />
<Folder Include="LE\" />
<Folder Include="LX\" />
<Folder Include="PE\" />
<Folder Include="BeOS\" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>iconviewer</string>
<key>CFBundleIdentifier</key>
<string>com.example.iconviewer</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>LSMinimumSystemVersion</key>
<string>10.7</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>NSHumanReadableCopyright</key>
<string></string>
<key>CFBundleIconFile</key>
<string>MacIcon.icns</string>
</dict>
</plist>

Binary file not shown.

View File

@@ -0,0 +1,15 @@
using System;
using Eto.Forms;
using Eto.Drawing;
namespace iconviewer.Desktop
{
class Program
{
[STAThread]
static void Main(string[] args)
{
new Application(Eto.Platform.Detect).Run(new MainForm());
}
}
}

View File

@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net461</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Eto.Platform.Wpf" Version="2.4.1" />
<PackageReference Include="Eto.Platform.Gtk" Version="2.4.1" />
<PackageReference Include="Eto.Platform.Mac64" Version="2.4.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\iconviewer\iconviewer.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<Form xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Icon Viewer" ClientSize="500, 500" Padding="10">
<StackLayout Orientation="Vertical">
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Top">
<StackLayout Orientation="Horizontal">
<StackLayoutItem HorizontalAlignment="Left">
<Label>Path</Label>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<TextBox ID="txtPath" ReadOnly="True"/>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Right">
<Button ID="btnPath" Click="OnBtnPathClick">Open</Button>
</StackLayoutItem>
</StackLayout>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" Expand="True">
<GridView ID="grdIcons"/>
</StackLayoutItem>
<StackLayoutItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Expand="True">
<ImageView ID="imgIcon"/>
</StackLayoutItem>
</StackLayout>
<Form.Menu>
<MenuBar>
<MenuBar.QuitItem>
<ButtonMenuItem Text="Quit" Shortcut="CommonModifier+Q" Click="HandleQuit" />
</MenuBar.QuitItem>
<MenuBar.AboutItem>
<ButtonMenuItem Text="About..." Click="HandleAbout" />
</MenuBar.AboutItem>
</MenuBar>
</Form.Menu>
</Form>

View File

@@ -0,0 +1,99 @@
using System;
using System.IO;
using Eto.Drawing;
using Eto.Forms;
using Eto.Serialization.Xaml;
using libexeinfo.Os2;
using Bitmap = libexeinfo.Os2.Bitmap;
namespace iconviewer
{
public class MainForm : Form
{
GridView grdIcons;
ImageView imgIcon;
TextBox txtPath;
public MainForm()
{
XamlReader.Load(this);
grdIcons.Columns.Add(new GridColumn
{
DataCell =
new TextBoxCell {Binding = Binding.Property<DecodedBitmap, string>(b => $"{b.Type}")},
HeaderText = "Command"
});
grdIcons.Columns.Add(new GridColumn
{
DataCell = new TextBoxCell
{
Binding = Binding.Property<DecodedBitmap, string>(b => $"{b.Width}x{b.Height}")
},
HeaderText = "Size"
});
grdIcons.Columns.Add(new GridColumn
{
DataCell = new TextBoxCell
{
Binding = Binding.Property<DecodedBitmap, string>(b => $"{1 << (int)b.BitsPerPixel}")
},
HeaderText = "Colors"
});
grdIcons.AllowMultipleSelection = false;
grdIcons.SelectionChanged += GrdIconsOnSelectionChanged;
}
void GrdIconsOnSelectionChanged(object sender, EventArgs eventArgs)
{
if(!(grdIcons.SelectedItem is DecodedBitmap icon))
{
imgIcon.Image = null;
return;
}
imgIcon.Image =
new Eto.Drawing.Bitmap((int)icon.Width, (int)icon.Height, PixelFormat.Format32bppRgba, icon.Pixels);
}
protected void OnBtnPathClick(object sender, EventArgs e)
{
OpenFileDialog dlgOpenFileDialog = new OpenFileDialog {MultiSelect = false};
dlgOpenFileDialog.Filters.Add(new FileFilter {Extensions = new[] {".ico", ".ptr", ".bmp"}});
DialogResult result = dlgOpenFileDialog.ShowDialog(this);
if(result != DialogResult.Ok)
{
txtPath.Text = "";
imgIcon.Image = null;
grdIcons.DataStore = null;
return;
}
txtPath.Text = dlgOpenFileDialog.FileName;
FileStream fstream = new FileStream(dlgOpenFileDialog.FileName, FileMode.Open);
byte[] data = new byte[fstream.Length];
fstream.Read(data, 0, data.Length);
fstream.Dispose();
DecodedBitmap[] icons = Bitmap.DecodeBitmap(data);
imgIcon.Image = new Eto.Drawing.Bitmap((int)icons[0].Width, (int)icons[0].Height,
PixelFormat.Format32bppRgba, icons[0].Pixels);
grdIcons.DataStore = icons;
grdIcons.Visible = icons.Length != 1;
}
protected void HandleAbout(object sender, EventArgs e)
{
new AboutDialog().ShowDialog(this);
}
protected void HandleQuit(object sender, EventArgs e)
{
Application.Instance.Quit();
}
}
}

View File

@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>iconviewer</RootNamespace>
<PackageVersion>1.0</PackageVersion>
<Title>iconviewer</Title>
<Copyright>Copyright © 2018</Copyright>
<Description>Description of iconviewer</Description>
<ReleaseVersion>0.2</ReleaseVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<NoStdLib>false</NoStdLib>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<NoStdLib>false</NoStdLib>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Eto.Forms" Version="2.4.1" />
<PackageReference Include="Eto.Serialization.Xaml" Version="2.4.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\libexeinfo\libexeinfo.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,10 +1,20 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "exeinfo", "exeinfo\exeinfo.csproj", "{504F0A15-25DC-42B1-81FE-BA22A8EF24B5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "libexeinfo", "libexeinfo\libexeinfo.csproj", "{5DD22357-AEA1-4B1D-9CAB-F51873A3A5D0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "exeinfogui", "exeinfogui\exeinfogui.csproj", "{8628775A-F351-4B1C-9EA6-ED836980C9B2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "exeinfogui.Desktop", "exeinfogui.Desktop\exeinfogui.Desktop.csproj", "{65F985F1-E73C-4515-93B3-25F49C22F1AC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "exeinfogui.XamMac", "exeinfogui.XamMac\exeinfogui.XamMac.csproj", "{E2DC1857-A942-419B-849E-58AC8BBB94CD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iconviewer", "iconviewer\iconviewer\iconviewer.csproj", "{D6282B50-9A8D-44C5-8674-43BED27B5B53}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iconviewer.Desktop", "iconviewer\iconviewer.Desktop\iconviewer.Desktop.csproj", "{3206160A-B6AB-4B90-AC29-888C7E64A2CE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
@@ -19,6 +29,26 @@ Global
{5DD22357-AEA1-4B1D-9CAB-F51873A3A5D0}.Debug|x86.Build.0 = Debug|Any CPU
{5DD22357-AEA1-4B1D-9CAB-F51873A3A5D0}.Release|x86.ActiveCfg = Release|Any CPU
{5DD22357-AEA1-4B1D-9CAB-F51873A3A5D0}.Release|x86.Build.0 = Release|Any CPU
{8628775A-F351-4B1C-9EA6-ED836980C9B2}.Debug|x86.ActiveCfg = Debug|Any CPU
{8628775A-F351-4B1C-9EA6-ED836980C9B2}.Debug|x86.Build.0 = Debug|Any CPU
{8628775A-F351-4B1C-9EA6-ED836980C9B2}.Release|x86.ActiveCfg = Release|Any CPU
{8628775A-F351-4B1C-9EA6-ED836980C9B2}.Release|x86.Build.0 = Release|Any CPU
{65F985F1-E73C-4515-93B3-25F49C22F1AC}.Debug|x86.ActiveCfg = Debug|Any CPU
{65F985F1-E73C-4515-93B3-25F49C22F1AC}.Debug|x86.Build.0 = Debug|Any CPU
{65F985F1-E73C-4515-93B3-25F49C22F1AC}.Release|x86.ActiveCfg = Release|Any CPU
{65F985F1-E73C-4515-93B3-25F49C22F1AC}.Release|x86.Build.0 = Release|Any CPU
{E2DC1857-A942-419B-849E-58AC8BBB94CD}.Debug|x86.ActiveCfg = Debug|Any CPU
{E2DC1857-A942-419B-849E-58AC8BBB94CD}.Debug|x86.Build.0 = Debug|Any CPU
{E2DC1857-A942-419B-849E-58AC8BBB94CD}.Release|x86.ActiveCfg = Release|Any CPU
{E2DC1857-A942-419B-849E-58AC8BBB94CD}.Release|x86.Build.0 = Release|Any CPU
{D6282B50-9A8D-44C5-8674-43BED27B5B53}.Debug|x86.ActiveCfg = Debug|Any CPU
{D6282B50-9A8D-44C5-8674-43BED27B5B53}.Debug|x86.Build.0 = Debug|Any CPU
{D6282B50-9A8D-44C5-8674-43BED27B5B53}.Release|x86.ActiveCfg = Release|Any CPU
{D6282B50-9A8D-44C5-8674-43BED27B5B53}.Release|x86.Build.0 = Release|Any CPU
{3206160A-B6AB-4B90-AC29-888C7E64A2CE}.Debug|x86.ActiveCfg = Debug|Any CPU
{3206160A-B6AB-4B90-AC29-888C7E64A2CE}.Debug|x86.Build.0 = Debug|Any CPU
{3206160A-B6AB-4B90-AC29-888C7E64A2CE}.Release|x86.ActiveCfg = Release|Any CPU
{3206160A-B6AB-4B90-AC29-888C7E64A2CE}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
version = 0.2

View File

@@ -0,0 +1,297 @@
//
// AtariST.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using Claunia.Encoding;
namespace libexeinfo
{
/// <summary>
/// Represents an Atari ST executable
/// </summary>
public partial class AtariST : IExecutable
{
public GEM.ColorIcon[] GemColorIcons;
public GEM.GemResourceExtension ResourceExtension;
public GEM.MagiCResourceHeader ResourceHeader;
public GEM.TreeObjectNode[] ResourceObjectRoots;
public Stream ResourceStream;
SymbolEntry[] symbols;
/// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.AtariST" /> class.
/// </summary>
/// <param name="path">Executable path.</param>
public AtariST(string path)
{
BaseStream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
string pathDir = Path.GetDirectoryName(path);
string filename = Path.GetFileNameWithoutExtension(path);
string testPath = Path.Combine(pathDir, filename);
string resourceFilePath = null;
if(File.Exists(testPath + ".rsc")) resourceFilePath = testPath + ".rsc";
else if(File.Exists(testPath + ".rsC"))
resourceFilePath = testPath + ".rsC";
else if(File.Exists(testPath + ".rSc"))
resourceFilePath = testPath + ".rSc";
else if(File.Exists(testPath + ".rSC"))
resourceFilePath = testPath + ".rSC";
else if(File.Exists(testPath + ".Rsc"))
resourceFilePath = testPath + ".Rsc";
else if(File.Exists(testPath + ".RsC"))
resourceFilePath = testPath + ".RsC";
else if(File.Exists(testPath + ".RSc"))
resourceFilePath = testPath + ".RSc";
else if(File.Exists(testPath + ".RSC"))
resourceFilePath = testPath + ".RSC";
if(resourceFilePath != null)
ResourceStream = File.Open(resourceFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
Initialize();
}
/// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.AtariST" /> class.
/// </summary>
/// <param name="stream">Stream containing the executable.</param>
public AtariST(Stream stream)
{
BaseStream = stream;
Initialize();
}
/// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.AtariST" /> class.
/// </summary>
/// <param name="data">Byte array containing the executable.</param>
public AtariST(byte[] data)
{
BaseStream = new MemoryStream(data);
Initialize();
}
/// <summary>
/// Header for this executable
/// </summary>
public AtariHeader Header { get; private set; }
public Stream BaseStream { get; }
public bool IsBigEndian => true;
public bool Recognized { get; private set; }
public string Type { get; private set; }
public IEnumerable<Architecture> Architectures => new[] {Architecture.M68K};
public OperatingSystem RequiredOperatingSystem { get; private set; }
public IEnumerable<string> Strings { get; private set; }
public IEnumerable<Segment> Segments { get; private set; }
void Initialize()
{
Recognized = false;
if(BaseStream == null) return;
byte[] buffer = new byte[Marshal.SizeOf(typeof(AtariHeader))];
BaseStream.Position = 0;
BaseStream.Read(buffer, 0, buffer.Length);
Header = BigEndianMarshal.ByteArrayToStructureBigEndian<AtariHeader>(buffer);
Recognized = Header.signature == SIGNATURE;
List<string> strings = new List<string>();
if(!Recognized) return;
Type = "Atari ST executable";
if(Header.symb_len != 0)
{
BaseStream.Position = 0x1C + Header.text_len + Header.data_len;
buffer = new byte[Marshal.SizeOf(typeof(SymbolEntry))];
symbols = new SymbolEntry[Header.symb_len / Marshal.SizeOf(typeof(SymbolEntry))];
for(int i = 0; i < symbols.Length; i++)
{
BaseStream.Read(buffer, 0, buffer.Length);
symbols[i] = new SymbolEntry();
symbols[i] = BigEndianMarshal.ByteArrayToStructureBigEndian<SymbolEntry>(buffer);
symbols[i].type = (SymbolType)Swapping.Swap((ushort)symbols[i].type);
strings.Add(StringHandlers.CToString(symbols[i].name, Encoding.AtariSTEncoding));
}
}
Segments = new []
{
new Segment
{
Name = ".text",
Flags = $"{(PrgFlags)(Header.flags & 0xFFCF)} {(PrgSharing)(Header.flags & PF_SHARE_MASK)}",
Offset = 0x1C,
Size = Header.text_len
},
new Segment
{
Name = ".data",
Flags = "",
Offset = 0x1C + Header.text_len,
Size = Header.data_len
},
new Segment
{
Name = ".bss",
Flags = "",
Offset = 0,
Size = Header.bss_len
}
};
RequiredOperatingSystem = new OperatingSystem {Name = Header.mint == MINT_SIGNATURE ? "MiNT" : "Atari TOS"};
if(ResourceStream == null) return;
buffer = new byte[Marshal.SizeOf(typeof(GEM.GemResourceHeader))];
ResourceStream.Position = 0;
ResourceStream.Read(buffer, 0, buffer.Length);
GEM.GemResourceHeader gemResourceHeader =
BigEndianMarshal.ByteArrayToStructureBigEndian<GEM.GemResourceHeader>(buffer);
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);
RequiredOperatingSystem = new OperatingSystem {Name = "MagiC"};
}
else ResourceHeader = GEM.GemToMagiC(gemResourceHeader);
if((ResourceHeader.rsh_vrsn & 4) == 4)
{
buffer = new byte[Marshal.SizeOf(typeof(GEM.GemResourceExtension))];
ResourceStream.Position = ResourceHeader.rsh_rssize;
ResourceStream.Read(buffer, 0, buffer.Length);
ResourceExtension = BigEndianMarshal.ByteArrayToStructureBigEndian<GEM.GemResourceExtension>(buffer);
GemColorIcons = GEM.GetColorIcons(ResourceStream, ResourceExtension.color_ic, true,
Encoding.AtariSTEncoding);
}
if(ResourceHeader.rsh_ntree > 0)
{
ResourceStream.Position = ResourceHeader.rsh_trindex;
int[] treeOffsets = new int[ResourceHeader.rsh_ntree];
byte[] tmp = new byte[4];
for(int i = 0; i < ResourceHeader.rsh_ntree; i++)
{
ResourceStream.Read(tmp, 0, 4);
treeOffsets[i] = BitConverter.ToInt32(tmp.Reverse().ToArray(), 0);
}
ResourceObjectRoots = new GEM.TreeObjectNode[ResourceHeader.rsh_ntree];
for(int i = 0; i < ResourceHeader.rsh_ntree; i++)
{
if(treeOffsets[i] <= 0 || treeOffsets[i] >= ResourceStream.Length) continue;
ResourceStream.Position = treeOffsets[i];
List<GEM.ObjectNode> nodes = new List<GEM.ObjectNode>();
while(true)
{
buffer = new byte[Marshal.SizeOf(typeof(GEM.ObjectNode))];
ResourceStream.Read(buffer, 0, buffer.Length);
GEM.ObjectNode node = BigEndianMarshal.ByteArrayToStructureBigEndian<GEM.ObjectNode>(buffer);
nodes.Add(node);
if(((GEM.ObjectFlags)node.ob_flags).HasFlag(GEM.ObjectFlags.Lastob)) break;
}
List<short> knownNodes = new List<short>();
ResourceObjectRoots[i] =
GEM.ProcessResourceObject(nodes, ref knownNodes, 0, ResourceStream, strings, true,
Encoding.AtariSTEncoding);
}
}
else if(ResourceHeader.rsh_nobs > 0)
{
GEM.ObjectNode[] nodes = new GEM.ObjectNode[ResourceHeader.rsh_nobs];
ResourceStream.Position = ResourceHeader.rsh_object;
for(short i = 0; i < ResourceHeader.rsh_nobs; i++)
{
buffer = new byte[Marshal.SizeOf(typeof(GEM.ObjectNode))];
ResourceStream.Read(buffer, 0, buffer.Length);
nodes[i] = BigEndianMarshal.ByteArrayToStructureBigEndian<GEM.ObjectNode>(buffer);
}
List<short> knownNodes = new List<short>();
ResourceObjectRoots = new GEM.TreeObjectNode[1];
ResourceObjectRoots[0] =
GEM.ProcessResourceObject(nodes, ref knownNodes, 0, ResourceStream, strings, true,
Encoding.AtariSTEncoding);
}
if(strings.Count > 0)
{
strings.Sort();
Strings = strings.Distinct();
}
}
/// <summary>
/// Identifies if the specified executable is a Atari ST executable
/// </summary>
/// <returns><c>true</c> if the specified executable is a Atari ST executable, <c>false</c> otherwise.</returns>
/// <param name="path">Executable path.</param>
public static bool Identify(string path)
{
FileStream exeFs = File.Open(path, FileMode.Open, FileAccess.Read);
return Identify(exeFs);
}
/// <summary>
/// Identifies if the specified executable is a Atari ST executable
/// </summary>
/// <returns><c>true</c> if the specified executable is a Atari ST executable, <c>false</c> otherwise.</returns>
/// <param name="stream">Stream containing the executable.</param>
public static bool Identify(Stream stream)
{
byte[] buffer = new byte[Marshal.SizeOf(typeof(AtariHeader))];
stream.Position = 0;
stream.Read(buffer, 0, buffer.Length);
AtariHeader hdr = BigEndianMarshal.ByteArrayToStructureBigEndian<AtariHeader>(buffer);
return hdr.signature == SIGNATURE;
}
}
}

View File

@@ -0,0 +1,36 @@
//
// Consts.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
namespace libexeinfo
{
public partial class AtariST
{
const ushort SIGNATURE = 0x601A;
const uint MINT_SIGNATURE = 0x4D694E54;
const ushort PF_FLAGS_MASK = 0xFFCF;
const ushort PF_SHARE_MASK = 0x30;
}
}

View File

@@ -0,0 +1,85 @@
//
// Enums.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
namespace libexeinfo
{
public partial class AtariST
{
[Flags]
public enum PrgFlags : ushort
{
/// <summary>
/// If set clear only the BSS area on program load, otherwise clear the entire heap.
/// </summary>
PF_FASTLOAD = 0x01,
/// <summary>
/// If set, the program may be loaded into alternative RAM, otherwise it muse be loaded into standard RAM.
/// </summary>
PF_TTRAMLOAD = 0x02,
/// <summary>
/// If set, the program's malloc() requests may be satisfied from alternative RAM, otherwise they must be satisfied
/// from standard RAM.
/// </summary>
PF_TTRAMMEM = 0x04
}
public enum PrgSharing : ushort
{
/// <summary>
/// The processes' entire memory space will be considered private.
/// </summary>
PF_PRIVATE = 0,
/// <summary>
/// The processes' entire memory space will be readable and writable by any process.
/// </summary>
PF_GLOBAL = 1,
/// <summary>
/// The processes' entire memory space will only be readable and writable by itself and any other process in supervisor
/// mode.
/// </summary>
PF_SUPERVISOR = 2,
/// <summary>
/// The processes' entire memory space will be readable by any application but only writable by itself.
/// </summary>
PF_READABLE = 3
}
[Flags]
public enum SymbolType : ushort
{
Bss = 0x0100,
Text = 0x0200,
Data = 0x0400,
External = 0x0800,
EquatedRegister = 0x1000,
Global = 0x2000,
Equated = 0x4000,
Defined = 0x8000
}
}
}

View File

@@ -0,0 +1,72 @@
//
// Info.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System.Text;
using Encoding = Claunia.Encoding.Encoding;
namespace libexeinfo
{
public partial class AtariST
{
/// <summary>
/// Gets a string with human readable information for the Atari ST executable represented by this instance
/// </summary>
/// <value>Human readable information for this instance.</value>
public string Information => GetInfo(Header, symbols);
/// <summary>
/// Gets a string with human readable information for a given Atari ST header
/// </summary>
/// <returns>Human readable information for given Atari ST header.</returns>
/// <param name="header">Atari ST executable header.</param>
static string GetInfo(AtariHeader header, SymbolEntry[] symbols)
{
PrgFlags flags = (PrgFlags)(header.flags & PF_FLAGS_MASK);
PrgSharing sharing = (PrgSharing)((header.flags & PF_SHARE_MASK) >> 4);
StringBuilder sb = new StringBuilder();
sb.AppendLine("Atari ST executable:");
if(header.mint == MINT_SIGNATURE) sb.AppendLine("\tMiNT executable.");
sb.AppendFormat("\t{0} bytes in text segment", header.text_len).AppendLine();
sb.AppendFormat("\t{0} bytes in data segment", header.data_len).AppendLine();
sb.AppendFormat("\t{0} bytes in BSS segment", header.bss_len).AppendLine();
sb.AppendFormat("\t{0} bytes in symbol table", header.symb_len).AppendLine();
sb.AppendFormat("\tFlags: {0}", flags).AppendLine();
sb.AppendFormat("\tProcess sharing: {0}", sharing).AppendLine();
sb.AppendFormat("\t{0} fixups", header.absflags == 0 ? "Has" : "Doesn't have").AppendLine();
if(symbols == null || symbols.Length <= 0)
return sb.ToString();
sb.AppendLine("\tSymbol table:");
for(int i = 0; i < symbols.Length; i++)
sb.AppendFormat("\t\tSymbol {0}: \"{1}\", type {2}, value {3}", i,
StringHandlers.CToString(symbols[i].name, Encoding.AtariSTEncoding), symbols[i].type,
symbols[i].value).AppendLine();
return sb.ToString();
}
}
}

View File

@@ -0,0 +1,55 @@
//
// Structs.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System.Runtime.InteropServices;
namespace libexeinfo
{
public partial class AtariST
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct AtariHeader
{
public ushort signature;
public int text_len;
public int data_len;
public int bss_len;
public int symb_len;
public uint mint;
public uint flags;
public ushort absflags;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct SymbolEntry
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] name;
public SymbolType type;
public uint value;
}
}
}

126
libexeinfo/BeOS/Consts.cs Normal file
View File

@@ -0,0 +1,126 @@
//
// Consts.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
namespace libexeinfo.BeOS
{
// TODO: Find examples of 'CSTR', 'TEXT', and 'MMSG' with data
public static class Consts
{
internal const int RESOURCES_HEADER_MAGIC = 0x444F1000;
// String enums not supported in C# *sad*
public const string B_AFFINE_TRANSFORM_TYPE = "AMTX";
public const string B_ALIGNMENT_TYPE = "ALGN";
public const string B_ANY_TYPE = "ANYT";
public const string B_ATOM_TYPE = "ATOM";
public const string B_ATOMREF_TYPE = "ATMR";
public const string B_BOOL_TYPE = "BOOL";
public const string B_CHAR_TYPE = "CHAR";
public const string B_COLOR_8_BIT_TYPE = "CLRB";
public const string B_DOUBLE_TYPE = "DBLE";
public const string B_FLOAT_TYPE = "FLOT";
public const string B_GRAYSCALE_8_BIT_TYPE = "GRYB";
public const string B_INT16_TYPE = "SHRT";
public const string B_INT32_TYPE = "LONG";
public const string B_INT64_TYPE = "LLNG";
public const string B_INT8_TYPE = "BYTE";
public const string B_LARGE_ICON_TYPE = "ICON";
public const string B_MEDIA_PARAMETER_GROUP_TYPE = "BMCG";
public const string B_MEDIA_PARAMETER_TYPE = "BMCT";
public const string B_MEDIA_PARAMETER_WEB_TYPE = "BMCW";
public const string B_MESSAGE_TYPE = "MSGG";
public const string B_MESSENGER_TYPE = "MSNG";
public const string B_MIME_TYPE = "MIME";
public const string B_MINI_ICON_TYPE = "MICN";
public const string B_MONOCHROME_1_BIT_TYPE = "MNOB";
public const string B_OBJECT_TYPE = "OPTR";
public const string B_OFF_T_TYPE = "OFFT";
public const string B_PATTERN_TYPE = "PATN";
public const string B_POINTER_TYPE = "PNTR";
public const string B_POINT_TYPE = "BPNT";
public const string B_PROPERTY_INFO_TYPE = "SCTD";
public const string B_RAW_TYPE = "RAWT";
public const string B_RECT_TYPE = "RECT";
public const string B_REF_TYPE = "RREF";
public const string B_RGB_32_BIT_TYPE = "RGBB";
public const string B_RGB_COLOR_TYPE = "RGBC";
public const string B_SIZE_TYPE = "SIZE";
public const string B_SIZE_T_TYPE = "SIZT";
public const string B_SSIZE_T_TYPE = "SSZT";
public const string B_STRING_TYPE = "CSTR";
public const string B_STRING_LIST_TYPE = "STRL";
public const string B_TIME_TYPE = "TIME";
public const string B_UINT16_TYPE = "USHT";
public const string B_UINT32_TYPE = "ULNG";
public const string B_UINT64_TYPE = "ULLG";
public const string B_UINT8_TYPE = "UBYT";
public const string B_VECTOR_ICON_TYPE = "VICN";
public const string B_XATTR_TYPE = "XATR";
public const string B_NETWORK_ADDRESS_TYPE = "NWAD";
public const string B_MIME_STRING_TYPE = "MIMS";
public const string B_ASCII_TYPE = "TEXT";
public const string B_VERSION_INFO_TYPE = "APPV";
public const string B_APP_FLAGS_TYPE = "APPF";
public const string B_PICT_FORMAT = "PICT";
public const string B_PNG_FORMAT = "PNG ";
/// <summary>
/// BeOS system palette as ARGB values
/// </summary>
public static readonly uint[] ArgbSystemPalette =
{
0xFF000000, 0xFF080808, 0xFF101010, 0xFF181818, 0xFF202020, 0xFF282828, 0xFF303030, 0xFF383838, 0xFF404040,
0xFF484848, 0xFF505050, 0xFF585858, 0xFF606060, 0xFF686868, 0xFF707070, 0xFF787878, 0xFF808080, 0xFF888888,
0xFF909090, 0xFF989898, 0xFFA0A0A0, 0xFFA8A8A8, 0xFFB0B0B0, 0xFFB8B8B8, 0xFFC0C0C0, 0xFFC8C8C8, 0xFFD0D0D0,
0xFFD8D8D8, 0xFFE0E0E0, 0xFFE8E8E8, 0xFFF0F0F0, 0xFFF8F8F8, 0xFF0000FF, 0xFF0000E5, 0xFF0000CC, 0xFF0000B3,
0xFF00009A, 0xFF000081, 0xFF000069, 0xFF000050, 0xFF000037, 0xFF00001E, 0xFFFF0000, 0xFFE40000, 0xFFCB0000,
0xFFB20000, 0xFF990000, 0xFF800000, 0xFF690000, 0xFF500000, 0xFF370000, 0xFF1E0000, 0xFF00FF00, 0xFF00E400,
0xFF00CB00, 0xFF00B200, 0xFF009900, 0xFF008000, 0xFF006900, 0xFF005000, 0xFF003700, 0xFF001E00, 0xFF009833,
0xFFFFFFFF, 0xFFCBFFFF, 0xFFCBFFCB, 0xFFCBFF98, 0xFFCBFF66, 0xFFCBFF33, 0xFFCBFF00, 0xFF98FFFF, 0xFF98FFCB,
0xFF98FF98, 0xFF98FF66, 0xFF98FF33, 0xFF98FF00, 0xFF66FFFF, 0xFF66FFCB, 0xFF66FF98, 0xFF66FF66, 0xFF66FF33,
0xFF66FF00, 0xFF33FFFF, 0xFF33FFCB, 0xFF33FF98, 0xFF33FF66, 0xFF33FF33, 0xFF33FF00, 0xFFFF98FF, 0xFFFF98CB,
0xFFFF9898, 0xFFFF9866, 0xFFFF9833, 0xFFFF9800, 0xFF0066FF, 0xFF0066CB, 0xFFCBCBFF, 0xFFCBCBCB, 0xFFCBCB98,
0xFFCBCB66, 0xFFCBCB33, 0xFFCBCB00, 0xFF98CBFF, 0xFF98CBCB, 0xFF98CB98, 0xFF98CB66, 0xFF98CB33, 0xFF98CB00,
0xFF66CBFF, 0xFF66CBCB, 0xFF66CB98, 0xFF66CB66, 0xFF66CB33, 0xFF66CB00, 0xFF33CBFF, 0xFF33CBCB, 0xFF33CB98,
0xFF33CB66, 0xFF33CB33, 0xFF33CB00, 0xFFFF66FF, 0xFFFF66CB, 0xFFFF6698, 0xFFFF6666, 0xFFFF6633, 0xFFFF6600,
0xFF006698, 0xFF006666, 0xFFCB98FF, 0xFFCB98CB, 0xFFCB9898, 0xFFCB9866, 0xFFCB9833, 0xFFCB9800, 0xFF9898FF,
0xFF9898CB, 0xFF989898, 0xFF989866, 0xFF989833, 0xFF989800, 0xFF6698FF, 0xFF6698CB, 0xFF669898, 0xFF669866,
0xFF669833, 0xFF669800, 0xFF3398FF, 0xFF3398CB, 0xFF339898, 0xFF339866, 0xFF339833, 0xFF339800, 0xFFE68600,
0xFFFF33CB, 0xFFFF3398, 0xFFFF3366, 0xFFFF3333, 0xFFFF3300, 0xFF006633, 0xFF006600, 0xFFCB66FF, 0xFFCB66CB,
0xFFCB6698, 0xFFCB6666, 0xFFCB6633, 0xFFCB6600, 0xFF9866FF, 0xFF9866CB, 0xFF986698, 0xFF986666, 0xFF986633,
0xFF986600, 0xFF6666FF, 0xFF6666CB, 0xFF666698, 0xFF666666, 0xFF666633, 0xFF666600, 0xFF3366FF, 0xFF3366CB,
0xFF336698, 0xFF336666, 0xFF336633, 0xFF336600, 0xFFFF00FF, 0xFFFF00CB, 0xFFFF0098, 0xFFFF0066, 0xFFFF0033,
0xFFFFAF13, 0xFF0033FF, 0xFF0033CB, 0xFFCB33FF, 0xFFCB33CB, 0xFFCB3398, 0xFFCB3366, 0xFFCB3333, 0xFFCB3300,
0xFF9833FF, 0xFF9833CB, 0xFF983398, 0xFF983366, 0xFF983333, 0xFF983300, 0xFF6633FF, 0xFF6633CB, 0xFF663398,
0xFF663366, 0xFF663333, 0xFF663300, 0xFF3333FF, 0xFF3333CB, 0xFF333398, 0xFF333366, 0xFF333333, 0xFF333300,
0xFFFFCB66, 0xFFFFCB98, 0xFFFFCBCB, 0xFFFFCBFF, 0xFF003398, 0xFF003366, 0xFF003333, 0xFF003300, 0xFFCB00FF,
0xFFCB00CB, 0xFFCB0098, 0xFFCB0066, 0xFFCB0033, 0xFFFFE346, 0xFF9800FF, 0xFF9800CB, 0xFF980098, 0xFF980066,
0xFF980033, 0xFF980000, 0xFF6600FF, 0xFF6600CB, 0xFF660098, 0xFF660066, 0xFF660033, 0xFF660000, 0xFF3300FF,
0xFF3300CB, 0xFF330098, 0xFF330066, 0xFF330033, 0xFF330000, 0xFFFFCB33, 0xFFFFCB00, 0xFFFFFF00, 0xFFFFFF33,
0xFFFFFF66, 0xFFFFFF98, 0xFFFFFFCB, 0x00FFFFFF
};
}
}

38
libexeinfo/BeOS/Enums.cs Normal file
View File

@@ -0,0 +1,38 @@
//
// Enums.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
namespace libexeinfo.BeOS
{
public enum InfoVariety : uint
{
B_DEVELOPMENT_VERSION = 0,
B_ALPHA_VERSION,
B_BETA_VERSION,
B_GAMMA_VERSION,
B_GOLDEN_MASTER_VERSION,
B_FINAL_VERSION
}
}

View File

@@ -0,0 +1,212 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace libexeinfo.BeOS
{
public static class Resources
{
public static ResourceTypeBlock[] Decode(byte[] data, bool bigEndian = false)
{
return bigEndian ? ResourceEdoced(data) : ResourceDecode(data);
}
static ResourceTypeBlock[] ResourceDecode(byte[] data)
{
uint pos = 0;
byte[] buffer = new byte[Marshal.SizeOf(typeof(ResourcesHeader))];
Array.Copy(data, pos, buffer, 0, buffer.Length);
ResourcesHeader header = BigEndianMarshal.ByteArrayToStructureLittleEndian<ResourcesHeader>(buffer);
if(header.magic != Consts.RESOURCES_HEADER_MAGIC) return null;
pos = header.index_section_offset;
buffer = new byte[Marshal.SizeOf(typeof(ResourceIndexSectionHeader))];
if(pos + buffer.Length > data.Length) return null;
Array.Copy(data, pos, buffer, 0, buffer.Length);
ResourceIndexSectionHeader indexHeader =
BigEndianMarshal.ByteArrayToStructureLittleEndian<ResourceIndexSectionHeader>(buffer);
pos += (uint)buffer.Length;
ResourceIndexEntry[] indexes =
new ResourceIndexEntry[(indexHeader.index_section_size -
Marshal.SizeOf(typeof(ResourceIndexSectionHeader))) /
Marshal.SizeOf(typeof(ResourceIndexEntry))];
for(int i = 0; i < indexes.Length; i++)
{
buffer = new byte[Marshal.SizeOf(typeof(ResourceIndexEntry))];
Array.Copy(data, pos, buffer, 0, buffer.Length);
indexes[i] = BigEndianMarshal.ByteArrayToStructureLittleEndian<ResourceIndexEntry>(buffer);
pos += (uint)buffer.Length;
}
pos = indexHeader.info_table_offset;
string[] types = new string[header.resource_count];
bool terminated = true;
string currentType = null;
string[] names = new string[header.resource_count];
ResourceInfo[] infos = new ResourceInfo[header.resource_count];
for(int i = 0; i < header.resource_count; i++)
{
if(terminated)
{
buffer = new byte[4];
Array.Copy(data, pos, buffer, 0, 4);
currentType = Encoding.ASCII.GetString(buffer.Reverse().ToArray());
terminated = false;
pos += 4;
}
buffer = new byte[Marshal.SizeOf(typeof(ResourceInfo))];
Array.Copy(data, pos, buffer, 0, buffer.Length);
infos[i] = BigEndianMarshal.ByteArrayToStructureLittleEndian<ResourceInfo>(buffer);
pos += (uint)buffer.Length;
buffer = new byte[infos[i].name_size - 1];
Array.Copy(data, pos, buffer, 0, buffer.Length);
names[i] = Encoding.ASCII.GetString(buffer);
pos += (uint)(buffer.Length + 1);
types[i] = currentType;
if(BitConverter.ToInt32(data, (int)pos) != -1 ||
BitConverter.ToInt32(data, (int)pos + 4) != -1) continue;
terminated = true;
pos += 8;
}
Dictionary<string, List<Resource>> rezzes = new Dictionary<string, List<Resource>>();
for(int i = 0; i < header.resource_count; i++)
{
rezzes.TryGetValue(types[i], out List<Resource> thisRezzes);
if(thisRezzes == null) thisRezzes = new List<Resource>();
Resource rez = new Resource
{
id = infos[i].id,
index = infos[i].index,
name = names[i],
data = new byte[indexes[infos[i].index - 1].size]
};
Array.Copy(data, indexes[infos[i].index - 1].offset, rez.data, 0, rez.data.Length);
thisRezzes.Add(rez);
rezzes.Remove(types[i]);
rezzes.Add(types[i], thisRezzes);
}
List<ResourceTypeBlock> result = new List<ResourceTypeBlock>();
foreach(KeyValuePair<string, List<Resource>> kvp in rezzes)
{
ResourceTypeBlock block = new ResourceTypeBlock {type = kvp.Key, resources = kvp.Value.ToArray()};
result.Add(block);
}
return result.ToArray();
}
static ResourceTypeBlock[] ResourceEdoced(byte[] data)
{
uint pos = 0;
byte[] buffer = new byte[Marshal.SizeOf(typeof(ResourcesHeader))];
Array.Copy(data, pos, buffer, 0, buffer.Length);
ResourcesHeader header = BigEndianMarshal.ByteArrayToStructureBigEndian<ResourcesHeader>(buffer);
if(header.magic != Consts.RESOURCES_HEADER_MAGIC) return null;
pos = header.index_section_offset;
buffer = new byte[Marshal.SizeOf(typeof(ResourceIndexSectionHeader))];
if(pos + buffer.Length > data.Length) return null;
Array.Copy(data, pos, buffer, 0, buffer.Length);
ResourceIndexSectionHeader indexHeader =
BigEndianMarshal.ByteArrayToStructureBigEndian<ResourceIndexSectionHeader>(buffer);
pos += (uint)buffer.Length;
ResourceIndexEntry[] indexes =
new ResourceIndexEntry[(indexHeader.index_section_size -
Marshal.SizeOf(typeof(ResourceIndexSectionHeader))) /
Marshal.SizeOf(typeof(ResourceIndexEntry))];
for(int i = 0; i < indexes.Length; i++)
{
buffer = new byte[Marshal.SizeOf(typeof(ResourceIndexEntry))];
Array.Copy(data, pos, buffer, 0, buffer.Length);
indexes[i] = BigEndianMarshal.ByteArrayToStructureBigEndian<ResourceIndexEntry>(buffer);
pos += (uint)buffer.Length;
}
pos = indexHeader.info_table_offset;
string[] types = new string[header.resource_count];
bool terminated = true;
string currentType = null;
string[] names = new string[header.resource_count];
ResourceInfo[] infos = new ResourceInfo[header.resource_count];
for(int i = 0; i < header.resource_count; i++)
{
if(terminated)
{
buffer = new byte[4];
Array.Copy(data, pos, buffer, 0, 4);
currentType = Encoding.ASCII.GetString(buffer.ToArray());
terminated = false;
pos += 4;
}
buffer = new byte[Marshal.SizeOf(typeof(ResourceInfo))];
Array.Copy(data, pos, buffer, 0, buffer.Length);
infos[i] = BigEndianMarshal.ByteArrayToStructureBigEndian<ResourceInfo>(buffer);
pos += (uint)buffer.Length;
buffer = new byte[infos[i].name_size - 1];
Array.Copy(data, pos, buffer, 0, buffer.Length);
names[i] = Encoding.ASCII.GetString(buffer);
pos += (uint)(buffer.Length + 1);
types[i] = currentType;
if(BitConverter.ToInt32(data, (int)pos) != -1 ||
BitConverter.ToInt32(data, (int)pos + 4) != -1) continue;
terminated = true;
pos += 8;
}
Dictionary<string, List<Resource>> rezzes = new Dictionary<string, List<Resource>>();
for(int i = 0; i < header.resource_count; i++)
{
rezzes.TryGetValue(types[i], out List<Resource> thisRezzes);
if(thisRezzes == null) thisRezzes = new List<Resource>();
Resource rez = new Resource
{
id = infos[i].id,
index = infos[i].index,
name = names[i],
data = new byte[indexes[infos[i].index - 1].size]
};
Array.Copy(data, indexes[infos[i].index - 1].offset, rez.data, 0, rez.data.Length);
thisRezzes.Add(rez);
rezzes.Remove(types[i]);
rezzes.Add(types[i], thisRezzes);
}
List<ResourceTypeBlock> result = new List<ResourceTypeBlock>();
foreach(KeyValuePair<string, List<Resource>> kvp in rezzes)
{
ResourceTypeBlock block = new ResourceTypeBlock {type = kvp.Key, resources = kvp.Value.ToArray()};
result.Add(block);
}
return result.ToArray();
}
}
}

219
libexeinfo/BeOS/Structs.cs Normal file
View File

@@ -0,0 +1,219 @@
//
// Structs.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System.Runtime.InteropServices;
// Structures thanks to Ingo Weinhold and Haiku
namespace libexeinfo.BeOS
{
/// <summary>
/// Header of resource data
/// </summary>
[StructLayout(LayoutKind.Sequential)]
struct ResourcesHeader
{
/// <summary>
/// <see cref="Consts.RESOURCES_HEADER_MAGIC" />
/// </summary>
public uint magic;
/// <summary>
/// How many resources are present
/// </summary>
public uint resource_count;
/// <summary>
/// Offset to <see cref="ResourceIndexSectionHeader" />
/// </summary>
public uint index_section_offset;
/// <summary>
/// Size of the admin section
/// </summary>
public uint admin_section_size;
/// <summary>
/// Padding
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 13)]
public uint[] pad;
}
/// <summary>
/// Header of the resource index, followed by as many <see cref="ResourceIndexEntry" /> as resources are in the file
/// </summary>
[StructLayout(LayoutKind.Sequential)]
struct ResourceIndexSectionHeader
{
/// <summary>
/// Offset to itself
/// </summary>
public uint index_section_offset;
/// <summary>
/// Size in bytes of the whole index section
/// </summary>
public uint index_section_size;
/// <summary>
/// Unused
/// </summary>
public uint unused_data1;
/// <summary>
/// Offset to an unknown section
/// </summary>
public uint unknown_section_offset;
/// <summary>
/// Size in bytes of the unknown section
/// </summary>
public uint unknown_section_size;
/// <summary>
/// Unused
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 25)]
public uint[] unused_data2;
/// <summary>
/// Offset to <see cref="ResourceInfoBlock" /> table
/// </summary>
public uint info_table_offset;
/// <summary>
/// Sizee of <see cref="ResourceInfoBlock" /> table
/// </summary>
public uint info_table_size;
/// <summary>
/// Unused
/// </summary>
public uint unused_data3;
}
/// <summary>
/// A resource index entry
/// </summary>
[StructLayout(LayoutKind.Sequential)]
struct ResourceIndexEntry
{
/// <summary>
/// Offset to resource
/// </summary>
public uint offset;
/// <summary>
/// Size of resource
/// </summary>
public uint size;
/// <summary>
/// Padding
/// </summary>
public uint pad;
}
/// <summary>
/// Resource information, followed by <see cref="name_size" /> ASCII characters with the name
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 2)]
struct ResourceInfo
{
/// <summary>
/// Resource ID
/// </summary>
public int id;
/// <summary>
/// Resource index, not related to index table
/// </summary>
public int index;
/// <summary>
/// Size of name following this structure
/// </summary>
public ushort name_size;
}
/// <summary>
/// Separator between resource types
/// </summary>
[StructLayout(LayoutKind.Sequential)]
struct ResourceInfoSeparator
{
/// <summary>
/// Must be 0xFFFFFFFF
/// </summary>
public uint value1;
/// <summary>
/// Must be 0xFFFFFFFF
/// </summary>
public uint value2;
}
/// <summary>
/// Resource info block, followed by <see cref="ResourceInfoSeparator" /> when the <see cref="info" /> array ends
/// </summary>
struct ResourceInfoBlock
{
/// <summary>
/// OSType code
/// </summary>
public uint type;
/// <summary>
/// Array of <see cref="ResourceInfo" />. Unless a <see cref="ResourceInfoSeparator" /> is found.
/// </summary>
public ResourceInfo[] info;
}
/// <summary>
/// End of the resource info table
/// </summary>
struct ResourceInfoTableEnd
{
/// <summary>
/// Resource info table checksum
/// </summary>
public uint checksum;
/// <summary>
/// Must be 0
/// </summary>
public uint terminator;
}
public class ResourceTypeBlock
{
public Resource[] resources;
public string type;
}
public class Resource
{
public byte[] data;
public int id;
public int index;
public string name;
}
[StructLayout(LayoutKind.Sequential)]
public struct VersionInfo
{
public uint major;
public uint middle;
public uint minor;
public InfoVariety variety;
public uint interna1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
public byte[] short_info;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public byte[] long_info;
}
}

View File

@@ -0,0 +1,137 @@
//
// BigEndianMarshal.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
namespace libexeinfo
{
public static class BigEndianMarshal
{
/// <summary>
/// Marshals a big endian structure from a byte array.
/// Nested structures are still marshalled as little endian.
/// </summary>
/// <returns>The structure.</returns>
/// <param name="bytes">Byte array.</param>
/// <typeparam name="T">Structure type.</typeparam>
public static T ByteArrayToStructureBigEndian<T>(byte[] bytes) where T : struct
{
GCHandle ptr = GCHandle.Alloc(bytes, GCHandleType.Pinned);
T str = (T)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(T));
ptr.Free();
return SwapStructureMembersEndian(str);
}
/// <summary>
/// Marshals a little endian structure from a byte array.
/// </summary>
/// <returns>The structure.</returns>
/// <param name="bytes">Byte array.</param>
/// <typeparam name="T">Structure type.</typeparam>
public static T ByteArrayToStructureLittleEndian<T>(byte[] bytes) where T : struct
{
GCHandle ptr = GCHandle.Alloc(bytes, GCHandleType.Pinned);
T str = (T)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(T));
ptr.Free();
return str;
}
/// <summary>
/// Swaps endian of structure members that correspond to numerical types.
/// Does not traverse nested structures.
/// </summary>
/// <returns>The structure with its members endian swapped.</returns>
/// <param name="str">The structure.</param>
/// <typeparam name="T">Structure type.</typeparam>
public static T SwapStructureMembersEndian<T>(T str) where T : struct
{
Type t = str.GetType();
FieldInfo[] fieldInfo = t.GetFields();
foreach(FieldInfo fi in fieldInfo)
if(fi.FieldType == typeof(short))
{
short int16 = (short)fi.GetValue(str);
byte[] int16_b = BitConverter.GetBytes(int16);
byte[] int16_r = int16_b.Reverse().ToArray();
fi.SetValueDirect(__makeref(str), BitConverter.ToInt16(int16_r, 0));
}
else if(fi.FieldType == typeof(int))
{
int int32 = (int)fi.GetValue(str);
byte[] int32_b = BitConverter.GetBytes(int32);
byte[] int32_r = int32_b.Reverse().ToArray();
fi.SetValueDirect(__makeref(str), BitConverter.ToInt32(int32_r, 0));
}
else if(fi.FieldType == typeof(long))
{
long int64 = (long)fi.GetValue(str);
byte[] int64_b = BitConverter.GetBytes(int64);
byte[] int64_r = int64_b.Reverse().ToArray();
fi.SetValueDirect(__makeref(str), BitConverter.ToInt64(int64_r, 0));
}
else if(fi.FieldType == typeof(ushort))
{
ushort uint16 = (ushort)fi.GetValue(str);
byte[] uint16_b = BitConverter.GetBytes(uint16);
byte[] uint16_r = uint16_b.Reverse().ToArray();
fi.SetValueDirect(__makeref(str), BitConverter.ToInt16(uint16_r, 0));
}
else if(fi.FieldType == typeof(uint))
{
uint uint32 = (uint)fi.GetValue(str);
byte[] uint32_b = BitConverter.GetBytes(uint32);
byte[] uint32_r = uint32_b.Reverse().ToArray();
fi.SetValueDirect(__makeref(str), BitConverter.ToInt32(uint32_r, 0));
}
else if(fi.FieldType == typeof(ulong))
{
ulong uint64 = (ulong)fi.GetValue(str);
byte[] uint64_b = BitConverter.GetBytes(uint64);
byte[] uint64_r = uint64_b.Reverse().ToArray();
fi.SetValueDirect(__makeref(str), BitConverter.ToInt64(uint64_r, 0));
}
else if(fi.FieldType == typeof(float))
{
float flt = (float)fi.GetValue(str);
byte[] flt_b = BitConverter.GetBytes(flt);
byte[] flt_r = flt_b.Reverse().ToArray();
fi.SetValueDirect(__makeref(str), BitConverter.ToSingle(flt_r, 0));
}
else if(fi.FieldType == typeof(double))
{
double dbl = (double)fi.GetValue(str);
byte[] dbl_b = BitConverter.GetBytes(dbl);
byte[] dbl_r = dbl_b.Reverse().ToArray();
fi.SetValueDirect(__makeref(str), BitConverter.ToDouble(dbl_r, 0));
}
return str;
}
}
}

161
libexeinfo/COFF/COFF.cs Normal file
View File

@@ -0,0 +1,161 @@
//
// COFF.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017-2018 Copyright © Claunia.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
namespace libexeinfo
{
/// <summary>
/// Represents a Common Object File Format
/// </summary>
public partial class COFF : IExecutable
{
/// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.COFF" /> class.
/// </summary>
/// <param name="path">Executable path.</param>
public COFF(string path)
{
BaseStream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
Initialize();
}
/// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.COFF" /> class.
/// </summary>
/// <param name="stream">Stream containing the executable.</param>
public COFF(Stream stream)
{
BaseStream = stream;
Initialize();
}
/// <summary>
/// Initializes a new instance of the <see cref="T:libexeinfo.COFF" /> class.
/// </summary>
/// <param name="data">Byte array containing the executable.</param>
public COFF(byte[] data)
{
BaseStream = new MemoryStream(data);
Initialize();
}
/// <summary>
/// Header for this executable
/// </summary>
public COFFHeader Header { get; private set; }
public Stream BaseStream { get; }
public bool IsBigEndian { get; private set; }
public bool Recognized { get; private set; }
public string Type { get; private set; }
public IEnumerable<Architecture> Architectures => new[] {MachineTypeToArchitecture(Header.machine)};
public OperatingSystem RequiredOperatingSystem =>
new OperatingSystem {Name = "Unknown"}; // TODO: Know
public IEnumerable<string> Strings { get; }
public IEnumerable<Segment> Segments { get; }
void Initialize()
{
Recognized = false;
if(BaseStream == null) return;
byte[] buffer = new byte[Marshal.SizeOf(typeof(COFFHeader))];
BaseStream.Position = 0;
BaseStream.Read(buffer, 0, buffer.Length);
IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length);
Marshal.Copy(buffer, 0, hdrPtr, buffer.Length);
Header = (COFFHeader)Marshal.PtrToStructure(hdrPtr, typeof(COFFHeader));
Marshal.FreeHGlobal(hdrPtr);
Recognized = Header.optionalHeader.magic == STMAGIC || Header.optionalHeader.magic == OMAGIC ||
Header.optionalHeader.magic == JMAGIC || Header.optionalHeader.magic == DMAGIC ||
Header.optionalHeader.magic == ZMAGIC || Header.optionalHeader.magic == SHMAGIC;
IsBigEndian = false;
if(!Recognized)
{
Header = SwapHeader(Header);
Recognized = Header.optionalHeader.magic == STMAGIC || Header.optionalHeader.magic == OMAGIC ||
Header.optionalHeader.magic == JMAGIC || Header.optionalHeader.magic == DMAGIC ||
Header.optionalHeader.magic == ZMAGIC || Header.optionalHeader.magic == SHMAGIC;
IsBigEndian = !Recognized;
}
if(!Recognized) return;
Type = "Common Object File Format (COFF)";
}
/// <summary>
/// Identifies if the specified executable is a Common Object File Format
/// </summary>
/// <returns><c>true</c> if the specified executable is a Common Object File Format, <c>false</c> otherwise.</returns>
/// <param name="path">Executable path.</param>
public static bool Identify(string path)
{
FileStream exeFs = File.Open(path, FileMode.Open, FileAccess.Read);
return Identify(exeFs);
}
/// <summary>
/// Identifies if the specified executable is a Common Object File Format
/// </summary>
/// <returns><c>true</c> if the specified executable is a Common Object File Format, <c>false</c> otherwise.</returns>
/// <param name="stream">Stream containing the executable.</param>
public static bool Identify(FileStream stream)
{
byte[] buffer = new byte[Marshal.SizeOf(typeof(COFFHeader))];
stream.Position = 0;
stream.Read(buffer, 0, buffer.Length);
IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length);
Marshal.Copy(buffer, 0, hdrPtr, buffer.Length);
COFFHeader coffHdr = (COFFHeader)Marshal.PtrToStructure(hdrPtr, typeof(COFFHeader));
Marshal.FreeHGlobal(hdrPtr);
if(coffHdr.optionalHeader.magic == STMAGIC || coffHdr.optionalHeader.magic == OMAGIC ||
coffHdr.optionalHeader.magic == JMAGIC || coffHdr.optionalHeader.magic == DMAGIC ||
coffHdr.optionalHeader.magic == ZMAGIC || coffHdr.optionalHeader.magic == SHMAGIC) return true;
coffHdr = SwapHeader(coffHdr);
return coffHdr.optionalHeader.magic == STMAGIC || coffHdr.optionalHeader.magic == OMAGIC ||
coffHdr.optionalHeader.magic == JMAGIC || coffHdr.optionalHeader.magic == DMAGIC ||
coffHdr.optionalHeader.magic == ZMAGIC || coffHdr.optionalHeader.magic == SHMAGIC;
}
static COFFHeader SwapHeader(COFFHeader header)
{
COFFHeader swapped = BigEndianMarshal.SwapStructureMembersEndian(header);
swapped.characteristics = (Characteristics)Swapping.Swap((ushort)header.characteristics);
swapped.machine = (MachineTypes)Swapping.Swap((ushort)header.machine);
swapped.optionalHeader = BigEndianMarshal.SwapStructureMembersEndian(header.optionalHeader);
return swapped;
}
}
}

Some files were not shown because too many files have changed in this diff Show More