mirror of
https://github.com/crskycode/GARbro.git
synced 2024-11-27 07:34:00 +08:00
(ArcEXE): interpret RT_VERSION resource.
This commit is contained in:
parent
a49710e366
commit
b73bd0fb4d
@ -29,10 +29,12 @@ using System.Collections.Generic;
|
|||||||
using System.ComponentModel.Composition;
|
using System.ComponentModel.Composition;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace GameRes.Formats.Microsoft
|
namespace GameRes.Formats.Microsoft
|
||||||
{
|
{
|
||||||
[Export(typeof(ArchiveFormat))]
|
[Export(typeof(ArchiveFormat))]
|
||||||
|
[ExportMetadata("Priority", -1)]
|
||||||
public class ExeOpener : ArchiveFormat
|
public class ExeOpener : ArchiveFormat
|
||||||
{
|
{
|
||||||
public override string Tag { get => "EXE"; }
|
public override string Tag { get => "EXE"; }
|
||||||
@ -49,6 +51,7 @@ namespace GameRes.Formats.Microsoft
|
|||||||
static readonly Dictionary<string, string> RuntimeTypeMap = new Dictionary<string, string>() {
|
static readonly Dictionary<string, string> RuntimeTypeMap = new Dictionary<string, string>() {
|
||||||
{ "#2", "RT_BITMAP" },
|
{ "#2", "RT_BITMAP" },
|
||||||
{ "#10", "RT_RCDATA" },
|
{ "#10", "RT_RCDATA" },
|
||||||
|
{ "#16", "RT_VERSION" },
|
||||||
};
|
};
|
||||||
|
|
||||||
static readonly Dictionary<string, string> ExtensionTypeMap = new Dictionary<string, string>() {
|
static readonly Dictionary<string, string> ExtensionTypeMap = new Dictionary<string, string>() {
|
||||||
@ -60,6 +63,8 @@ namespace GameRes.Formats.Microsoft
|
|||||||
{ "#10", ".BIN" },
|
{ "#10", ".BIN" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool OpenRtVersionAsText = true;
|
||||||
|
|
||||||
public override ArcFile TryOpen (ArcView file)
|
public override ArcFile TryOpen (ArcView file)
|
||||||
{
|
{
|
||||||
if (!file.View.AsciiEqual (0, "MZ") || VFS.IsVirtual)
|
if (!file.View.AsciiEqual (0, "MZ") || VFS.IsVirtual)
|
||||||
@ -85,7 +90,7 @@ namespace GameRes.Formats.Microsoft
|
|||||||
var entry = Create<ResourceEntry> (full_name);
|
var entry = Create<ResourceEntry> (full_name);
|
||||||
entry.NativeName = name;
|
entry.NativeName = name;
|
||||||
entry.NativeType = type;
|
entry.NativeType = type;
|
||||||
entry.Offset = 0;
|
entry.Offset = 0; // bogus XXX
|
||||||
entry.Size = res.GetResourceSize (name, type);
|
entry.Size = res.GetResourceSize (name, type);
|
||||||
dir.Add (entry);
|
dir.Add (entry);
|
||||||
}
|
}
|
||||||
@ -111,6 +116,8 @@ namespace GameRes.Formats.Microsoft
|
|||||||
var data = rarc.Accessor.GetResource (rent.NativeName, rent.NativeType);
|
var data = rarc.Accessor.GetResource (rent.NativeName, rent.NativeType);
|
||||||
if (null == data)
|
if (null == data)
|
||||||
return Stream.Null;
|
return Stream.Null;
|
||||||
|
if (rent.NativeType == "#16" && OpenRtVersionAsText)
|
||||||
|
return OpenVersion (data, rent.Name);
|
||||||
return new BinMemoryStream (data, rent.Name);
|
return new BinMemoryStream (data, rent.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +137,7 @@ namespace GameRes.Formats.Microsoft
|
|||||||
int bits_length = bitmap.ToInt32 (0x22);
|
int bits_length = bitmap.ToInt32 (0x22);
|
||||||
int bits_pos = length - bits_length;
|
int bits_pos = length - bits_length;
|
||||||
if (bits_length == 0)
|
if (bits_length == 0)
|
||||||
bits_pos = bitmap.ToInt32 (14) + 22;
|
bits_pos = bitmap.ToInt32 (14) + 14;
|
||||||
LittleEndian.Pack (bits_pos, bitmap, 10);
|
LittleEndian.Pack (bits_pos, bitmap, 10);
|
||||||
|
|
||||||
var bm = new BinMemoryStream (bitmap, 0, length, entry.Name);
|
var bm = new BinMemoryStream (bitmap, 0, length, entry.Name);
|
||||||
@ -150,6 +157,70 @@ namespace GameRes.Formats.Microsoft
|
|||||||
id = id.Substring (1).PadLeft (5, '0');
|
id = id.Substring (1).PadLeft (5, '0');
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static readonly byte[] VS_VERSION_INFO = Encoding.Unicode.GetBytes ("VS_VERSION_INFO");
|
||||||
|
|
||||||
|
Stream OpenVersion (byte[] data, string name)
|
||||||
|
{
|
||||||
|
var input = new BinMemoryStream (data, name);
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (input.ReadUInt16() != data.Length)
|
||||||
|
break;
|
||||||
|
int value_length = input.ReadUInt16();
|
||||||
|
int type = input.ReadUInt16();
|
||||||
|
if (0 == value_length || type != 0)
|
||||||
|
break;
|
||||||
|
if (input.ReadCString (Encoding.Unicode) != "VS_VERSION_INFO")
|
||||||
|
break;
|
||||||
|
long pos = (input.Position + 3) & -4L;
|
||||||
|
input.Position = pos;
|
||||||
|
if (input.ReadUInt32() != 0xFEEF04BDu)
|
||||||
|
break;
|
||||||
|
input.Position = pos + value_length;
|
||||||
|
int str_info_length = input.ReadUInt16();
|
||||||
|
value_length = input.ReadUInt16();
|
||||||
|
type = input.ReadUInt16();
|
||||||
|
if (value_length != 0)
|
||||||
|
break;
|
||||||
|
if (input.ReadCString (Encoding.Unicode) != "StringFileInfo")
|
||||||
|
break;
|
||||||
|
pos = (input.Position + 3) & -4L;
|
||||||
|
input.Position = pos;
|
||||||
|
int info_length = input.ReadUInt16();
|
||||||
|
long end_pos = pos + info_length;
|
||||||
|
value_length = input.ReadUInt16();
|
||||||
|
type = input.ReadUInt16();
|
||||||
|
if (value_length != 0)
|
||||||
|
break;
|
||||||
|
var output = new MemoryStream();
|
||||||
|
using (var text = new StreamWriter (output, new UTF8Encoding (false), 512, true))
|
||||||
|
{
|
||||||
|
string block_name = input.ReadCString (Encoding.Unicode);
|
||||||
|
text.WriteLine ("BLOCK \"{0}\"\n{{", block_name);
|
||||||
|
long next_pos = (input.Position + 3) & -4L;
|
||||||
|
while (next_pos < end_pos)
|
||||||
|
{
|
||||||
|
input.Position = next_pos;
|
||||||
|
info_length = input.ReadUInt16();
|
||||||
|
value_length = input.ReadUInt16();
|
||||||
|
type = input.ReadUInt16();
|
||||||
|
next_pos = (next_pos + info_length + 3) & -4L;
|
||||||
|
string key = input.ReadCString (Encoding.Unicode);
|
||||||
|
input.Position = (input.Position + 3) & -4L;
|
||||||
|
string value = value_length != 0 ? input.ReadCString (value_length * 2, Encoding.Unicode)
|
||||||
|
: String.Empty;
|
||||||
|
text.WriteLine ("\tVALUE \"{0}\", \"{1}\"", key, value);
|
||||||
|
}
|
||||||
|
text.WriteLine ("}");
|
||||||
|
}
|
||||||
|
input.Dispose();
|
||||||
|
output.Position = 0;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
input.Position = 0;
|
||||||
|
return input;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ResourceEntry : Entry
|
internal class ResourceEntry : Entry
|
||||||
|
Loading…
Reference in New Issue
Block a user