Add code to write .resources files
This commit is contained in:
parent
c815592f10
commit
76d9e87c3c
|
@ -44,6 +44,7 @@
|
|||
<HintPath>..\ICSharpCode.SharpZipLib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Runtime.Remoting" />
|
||||
<Reference Include="System.XML" />
|
||||
</ItemGroup>
|
||||
|
@ -230,6 +231,15 @@
|
|||
<Compile Include="renamer\TypeNames.cs" />
|
||||
<Compile Include="renamer\TypeRenamerState.cs" />
|
||||
<Compile Include="renamer\VariableNameState.cs" />
|
||||
<Compile Include="resources\BuiltInResourceData.cs" />
|
||||
<Compile Include="resources\IResourceData.cs" />
|
||||
<Compile Include="resources\ResourceElement.cs" />
|
||||
<Compile Include="resources\ResourceElementSet.cs" />
|
||||
<Compile Include="resources\ResourceTypeCode.cs" />
|
||||
<Compile Include="resources\ResourceDataCreator.cs" />
|
||||
<Compile Include="resources\ResourceWriter.cs" />
|
||||
<Compile Include="resources\UserResourceData.cs" />
|
||||
<Compile Include="resources\UserResourceType.cs" />
|
||||
<Compile Include="StringInliner.cs" />
|
||||
<Compile Include="UserException.cs" />
|
||||
<Compile Include="Utils.cs" />
|
||||
|
|
118
de4dot.code/resources/BuiltInResourceData.cs
Normal file
118
de4dot.code/resources/BuiltInResourceData.cs
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
Copyright (C) 2011-2012 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace de4dot.code.resources {
|
||||
class BuiltInResourceData : IResourceData {
|
||||
readonly ResourceTypeCode code;
|
||||
readonly object data;
|
||||
|
||||
public ResourceTypeCode Code {
|
||||
get { return code; }
|
||||
}
|
||||
|
||||
public BuiltInResourceData(ResourceTypeCode code, object data) {
|
||||
this.code = code;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public void writeData(BinaryWriter writer, IFormatter formatter) {
|
||||
switch (code) {
|
||||
case ResourceTypeCode.Null:
|
||||
return;
|
||||
|
||||
case ResourceTypeCode.String:
|
||||
writer.Write((string)data);
|
||||
break;
|
||||
|
||||
case ResourceTypeCode.Boolean:
|
||||
writer.Write((bool)data);
|
||||
break;
|
||||
|
||||
case ResourceTypeCode.Char:
|
||||
writer.Write((ushort)(char)data);
|
||||
break;
|
||||
|
||||
case ResourceTypeCode.Byte:
|
||||
writer.Write((byte)data);
|
||||
break;
|
||||
|
||||
case ResourceTypeCode.SByte:
|
||||
writer.Write((sbyte)data);
|
||||
break;
|
||||
|
||||
case ResourceTypeCode.Int16:
|
||||
writer.Write((short)data);
|
||||
break;
|
||||
|
||||
case ResourceTypeCode.UInt16:
|
||||
writer.Write((ushort)data);
|
||||
break;
|
||||
|
||||
case ResourceTypeCode.Int32:
|
||||
writer.Write((int)data);
|
||||
break;
|
||||
|
||||
case ResourceTypeCode.UInt32:
|
||||
writer.Write((uint)data);
|
||||
break;
|
||||
|
||||
case ResourceTypeCode.Int64:
|
||||
writer.Write((long)data);
|
||||
break;
|
||||
|
||||
case ResourceTypeCode.UInt64:
|
||||
writer.Write((ulong)data);
|
||||
break;
|
||||
|
||||
case ResourceTypeCode.Single:
|
||||
writer.Write((float)data);
|
||||
break;
|
||||
|
||||
case ResourceTypeCode.Double:
|
||||
writer.Write((double)data);
|
||||
break;
|
||||
|
||||
case ResourceTypeCode.Decimal:
|
||||
writer.Write((decimal)data);
|
||||
break;
|
||||
|
||||
case ResourceTypeCode.DateTime:
|
||||
writer.Write(((DateTime)data).ToBinary());
|
||||
break;
|
||||
|
||||
case ResourceTypeCode.TimeSpan:
|
||||
writer.Write(((TimeSpan)data).Ticks);
|
||||
break;
|
||||
|
||||
case ResourceTypeCode.ByteArray:
|
||||
var ary = (byte[])data;
|
||||
writer.Write(ary.Length);
|
||||
writer.Write(ary);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ApplicationException("Unknown resource type code");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
28
de4dot.code/resources/IResourceData.cs
Normal file
28
de4dot.code/resources/IResourceData.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
Copyright (C) 2011-2012 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace de4dot.code.resources {
|
||||
interface IResourceData {
|
||||
ResourceTypeCode Code { get; }
|
||||
void writeData(BinaryWriter writer, IFormatter formatter);
|
||||
}
|
||||
}
|
226
de4dot.code/resources/ResourceDataCreator.cs
Normal file
226
de4dot.code/resources/ResourceDataCreator.cs
Normal file
|
@ -0,0 +1,226 @@
|
|||
/*
|
||||
Copyright (C) 2011-2012 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace de4dot.code.resources {
|
||||
class ResourceDataCreator {
|
||||
ModuleDefinition module;
|
||||
Dictionary<string, UserResourceType> dict = new Dictionary<string, UserResourceType>(StringComparer.Ordinal);
|
||||
Dictionary<string, string> asmNameToAsmFullName = new Dictionary<string, string>(StringComparer.Ordinal);
|
||||
|
||||
public ResourceDataCreator(ModuleDefinition module) {
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
public int Count {
|
||||
get { return dict.Count; }
|
||||
}
|
||||
|
||||
public BuiltInResourceData createNull() {
|
||||
return new BuiltInResourceData(ResourceTypeCode.Null, null);
|
||||
}
|
||||
|
||||
public BuiltInResourceData create(string value) {
|
||||
return new BuiltInResourceData(ResourceTypeCode.String, value);
|
||||
}
|
||||
|
||||
public BuiltInResourceData create(bool value) {
|
||||
return new BuiltInResourceData(ResourceTypeCode.Boolean, value);
|
||||
}
|
||||
|
||||
public BuiltInResourceData create(char value) {
|
||||
return new BuiltInResourceData(ResourceTypeCode.Char, value);
|
||||
}
|
||||
|
||||
public BuiltInResourceData create(byte value) {
|
||||
return new BuiltInResourceData(ResourceTypeCode.Byte, value);
|
||||
}
|
||||
|
||||
public BuiltInResourceData create(sbyte value) {
|
||||
return new BuiltInResourceData(ResourceTypeCode.SByte, value);
|
||||
}
|
||||
|
||||
public BuiltInResourceData create(short value) {
|
||||
return new BuiltInResourceData(ResourceTypeCode.Int16, value);
|
||||
}
|
||||
|
||||
public BuiltInResourceData create(ushort value) {
|
||||
return new BuiltInResourceData(ResourceTypeCode.UInt16, value);
|
||||
}
|
||||
|
||||
public BuiltInResourceData create(int value) {
|
||||
return new BuiltInResourceData(ResourceTypeCode.Int32, value);
|
||||
}
|
||||
|
||||
public BuiltInResourceData create(uint value) {
|
||||
return new BuiltInResourceData(ResourceTypeCode.UInt32, value);
|
||||
}
|
||||
|
||||
public BuiltInResourceData create(long value) {
|
||||
return new BuiltInResourceData(ResourceTypeCode.Int64, value);
|
||||
}
|
||||
|
||||
public BuiltInResourceData create(ulong value) {
|
||||
return new BuiltInResourceData(ResourceTypeCode.UInt64, value);
|
||||
}
|
||||
|
||||
public BuiltInResourceData create(float value) {
|
||||
return new BuiltInResourceData(ResourceTypeCode.Single, value);
|
||||
}
|
||||
|
||||
public BuiltInResourceData create(double value) {
|
||||
return new BuiltInResourceData(ResourceTypeCode.Double, value);
|
||||
}
|
||||
|
||||
public BuiltInResourceData create(decimal value) {
|
||||
return new BuiltInResourceData(ResourceTypeCode.Decimal, value);
|
||||
}
|
||||
|
||||
public BuiltInResourceData create(DateTime value) {
|
||||
return new BuiltInResourceData(ResourceTypeCode.DateTime, value);
|
||||
}
|
||||
|
||||
public BuiltInResourceData create(TimeSpan value) {
|
||||
return new BuiltInResourceData(ResourceTypeCode.TimeSpan, value);
|
||||
}
|
||||
|
||||
public BuiltInResourceData create(byte[] value) {
|
||||
return new BuiltInResourceData(ResourceTypeCode.ByteArray, value);
|
||||
}
|
||||
|
||||
public CharArrayResourceData create(char[] value) {
|
||||
return new CharArrayResourceData(createUserResourceType(CharArrayResourceData.typeName), value);
|
||||
}
|
||||
|
||||
public IconResourceData createIcon(byte[] value) {
|
||||
return new IconResourceData(createUserResourceType(IconResourceData.typeName), value);
|
||||
}
|
||||
|
||||
public ImageResourceData createImage(byte[] value) {
|
||||
return new ImageResourceData(createUserResourceType(ImageResourceData.typeName), value);
|
||||
}
|
||||
|
||||
public BinaryResourceData createSerialized(byte[] value) {
|
||||
string assemblyName, typeName;
|
||||
if (!getSerializedTypeAndAssemblyName(value, out assemblyName, out typeName))
|
||||
throw new ApplicationException("Could not get serialized type name");
|
||||
string fullName = string.Format("{0},{1}", typeName, assemblyName);
|
||||
return new BinaryResourceData(createUserResourceType(fullName), value);
|
||||
}
|
||||
|
||||
class MyBinder : SerializationBinder {
|
||||
public string assemblyName;
|
||||
public string typeName;
|
||||
|
||||
public class OkException : Exception {
|
||||
}
|
||||
|
||||
public override Type BindToType(string assemblyName, string typeName) {
|
||||
this.assemblyName = assemblyName;
|
||||
this.typeName = typeName;
|
||||
throw new OkException();
|
||||
}
|
||||
}
|
||||
|
||||
bool getSerializedTypeAndAssemblyName(byte[] value, out string assemblyName, out string typeName) {
|
||||
var binder = new MyBinder();
|
||||
try {
|
||||
var formatter = new BinaryFormatter();
|
||||
formatter.Binder = binder;
|
||||
formatter.Deserialize(new MemoryStream(value));
|
||||
}
|
||||
catch (MyBinder.OkException) {
|
||||
assemblyName = binder.assemblyName;
|
||||
typeName = binder.typeName;
|
||||
return true;
|
||||
}
|
||||
catch {
|
||||
}
|
||||
|
||||
assemblyName = null;
|
||||
typeName = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public UserResourceType createUserResourceType(string fullName) {
|
||||
UserResourceType type;
|
||||
if (dict.TryGetValue(fullName, out type))
|
||||
return type;
|
||||
|
||||
var newFullName = fullName;
|
||||
string typeName, assemblyName;
|
||||
splitTypeFullName(fullName, out typeName, out assemblyName);
|
||||
if (!string.IsNullOrEmpty(assemblyName)) {
|
||||
string newAsmName;
|
||||
if (!asmNameToAsmFullName.TryGetValue(assemblyName, out newAsmName))
|
||||
asmNameToAsmFullName[assemblyName] = newAsmName = getRealAssemblyName(assemblyName);
|
||||
assemblyName = newAsmName;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(assemblyName))
|
||||
newFullName = string.Format("{0}, {1}", typeName, assemblyName);
|
||||
|
||||
type = new UserResourceType(newFullName, ResourceTypeCode.UserTypes + dict.Count);
|
||||
dict[fullName] = type;
|
||||
dict[newFullName] = type;
|
||||
return type;
|
||||
}
|
||||
|
||||
static void splitTypeFullName(string fullName, out string typeName, out string assemblyName) {
|
||||
int index = fullName.IndexOf(',');
|
||||
if (index < 0) {
|
||||
typeName = fullName;
|
||||
assemblyName = null;
|
||||
}
|
||||
else {
|
||||
typeName = fullName.Substring(0, index);
|
||||
assemblyName = fullName.Substring(index + 1).Trim();
|
||||
}
|
||||
}
|
||||
|
||||
string getRealAssemblyName(string assemblyName) {
|
||||
var simpleName = Utils.getAssemblySimpleName(assemblyName);
|
||||
|
||||
foreach (var asmRef in module.AssemblyReferences) {
|
||||
if (asmRef.Name == simpleName)
|
||||
return asmRef.FullName;
|
||||
}
|
||||
|
||||
try {
|
||||
return AssemblyResolver.Instance.Resolve(simpleName).FullName;
|
||||
}
|
||||
catch (ResolutionException) {
|
||||
}
|
||||
catch (AssemblyResolutionException) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<UserResourceType> getSortedTypes() {
|
||||
var list = new List<UserResourceType>(dict.Values);
|
||||
list.Sort((a, b) => Utils.compareInt32((int)a.Code, (int)b.Code));
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
25
de4dot.code/resources/ResourceElement.cs
Normal file
25
de4dot.code/resources/ResourceElement.cs
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
Copyright (C) 2011-2012 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace de4dot.code.resources {
|
||||
class ResourceElement {
|
||||
public string Name { get; set; }
|
||||
public IResourceData ResourceData { get; set; }
|
||||
}
|
||||
}
|
39
de4dot.code/resources/ResourceElementSet.cs
Normal file
39
de4dot.code/resources/ResourceElementSet.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
Copyright (C) 2011-2012 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace de4dot.code.resources {
|
||||
class ResourceElementSet {
|
||||
Dictionary<string, ResourceElement> dict = new Dictionary<string, ResourceElement>(StringComparer.Ordinal);
|
||||
|
||||
public int Count {
|
||||
get { return dict.Count; }
|
||||
}
|
||||
|
||||
public IEnumerable<ResourceElement> ResourceElements {
|
||||
get { return dict.Values; }
|
||||
}
|
||||
|
||||
public void add(ResourceElement elem) {
|
||||
dict[elem.Name] = elem;
|
||||
}
|
||||
}
|
||||
}
|
42
de4dot.code/resources/ResourceTypeCode.cs
Normal file
42
de4dot.code/resources/ResourceTypeCode.cs
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
Copyright (C) 2011-2012 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace de4dot.code.resources {
|
||||
enum ResourceTypeCode {
|
||||
Null,
|
||||
String,
|
||||
Boolean,
|
||||
Char,
|
||||
Byte,
|
||||
SByte,
|
||||
Int16,
|
||||
UInt16,
|
||||
Int32,
|
||||
UInt32,
|
||||
Int64,
|
||||
UInt64,
|
||||
Single,
|
||||
Double,
|
||||
Decimal,
|
||||
DateTime,
|
||||
TimeSpan,
|
||||
ByteArray = 0x20,
|
||||
UserTypes = 0x40,
|
||||
}
|
||||
}
|
154
de4dot.code/resources/ResourceWriter.cs
Normal file
154
de4dot.code/resources/ResourceWriter.cs
Normal file
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
Copyright (C) 2011-2012 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using System.Text;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace de4dot.code.resources {
|
||||
class ResourceWriter {
|
||||
ModuleDefinition module;
|
||||
BinaryWriter writer;
|
||||
ResourceElementSet resources;
|
||||
ResourceDataCreator typeCreator;
|
||||
Dictionary<UserResourceData, UserResourceType> dataToNewType = new Dictionary<UserResourceData, UserResourceType>();
|
||||
|
||||
ResourceWriter(ModuleDefinition module, Stream stream, ResourceElementSet resources) {
|
||||
this.module = module;
|
||||
this.typeCreator = new ResourceDataCreator(module);
|
||||
this.writer = new BinaryWriter(stream);
|
||||
this.resources = resources;
|
||||
}
|
||||
|
||||
public static void write(ModuleDefinition module, Stream stream, ResourceElementSet resources) {
|
||||
new ResourceWriter(module, stream, resources).write();
|
||||
}
|
||||
|
||||
void write() {
|
||||
initializeUserTypes();
|
||||
|
||||
writer.Write(0xBEEFCACE);
|
||||
writer.Write(1);
|
||||
writeReaderType();
|
||||
writer.Write(2);
|
||||
writer.Write(resources.Count);
|
||||
writer.Write(typeCreator.Count);
|
||||
foreach (var userType in typeCreator.getSortedTypes())
|
||||
writer.Write(userType.Name);
|
||||
int extraBytes = 8 - ((int)writer.BaseStream.Position & 7);
|
||||
if (extraBytes != 8) {
|
||||
for (int i = 0; i < extraBytes; i++)
|
||||
writer.Write((byte)'X');
|
||||
}
|
||||
|
||||
var nameOffsetStream = new MemoryStream();
|
||||
var nameOffsetWriter = new BinaryWriter(nameOffsetStream, Encoding.Unicode);
|
||||
var dataStream = new MemoryStream();
|
||||
var dataWriter = new BinaryWriter(dataStream);
|
||||
var hashes = new int[resources.Count];
|
||||
var offsets = new int[resources.Count];
|
||||
var formatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.File | StreamingContextStates.Persistence));
|
||||
int index = 0;
|
||||
foreach (var info in resources.ResourceElements) {
|
||||
offsets[index] = (int)nameOffsetWriter.BaseStream.Position;
|
||||
hashes[index] = (int)hash(info.Name);
|
||||
index++;
|
||||
nameOffsetWriter.Write(info.Name);
|
||||
nameOffsetWriter.Write((int)dataWriter.BaseStream.Position);
|
||||
writeData(dataWriter, info, formatter);
|
||||
}
|
||||
|
||||
Array.Sort(hashes, offsets);
|
||||
foreach (var hash in hashes)
|
||||
writer.Write(hash);
|
||||
foreach (var offset in offsets)
|
||||
writer.Write(offset);
|
||||
writer.Write((int)writer.BaseStream.Position + (int)nameOffsetStream.Length + 4);
|
||||
writer.Write(nameOffsetStream.ToArray());
|
||||
writer.Write(dataStream.ToArray());
|
||||
}
|
||||
|
||||
void writeData(BinaryWriter writer, ResourceElement info, IFormatter formatter) {
|
||||
var code = getResourceType(info.ResourceData);
|
||||
writeUInt32(writer, (uint)code);
|
||||
info.ResourceData.writeData(writer, formatter);
|
||||
}
|
||||
|
||||
static void writeUInt32(BinaryWriter writer, uint value) {
|
||||
while (value >= 0x80) {
|
||||
writer.Write((byte)(value | 0x80));
|
||||
value >>= 7;
|
||||
}
|
||||
writer.Write((byte)value);
|
||||
}
|
||||
|
||||
ResourceTypeCode getResourceType(IResourceData data) {
|
||||
if (data is BuiltInResourceData)
|
||||
return data.Code;
|
||||
|
||||
var userData = (UserResourceData)data;
|
||||
return dataToNewType[userData].Code;
|
||||
}
|
||||
|
||||
static uint hash(string key) {
|
||||
uint val = 0x1505;
|
||||
foreach (var c in key)
|
||||
val = ((val << 5) + val) ^ (uint)c;
|
||||
return val;
|
||||
}
|
||||
|
||||
void initializeUserTypes() {
|
||||
foreach (var resource in resources.ResourceElements) {
|
||||
var data = resource.ResourceData as UserResourceData;
|
||||
if (data == null)
|
||||
continue;
|
||||
var newType = typeCreator.createUserResourceType(data.TypeName);
|
||||
dataToNewType[data] = newType;
|
||||
}
|
||||
}
|
||||
|
||||
void writeReaderType() {
|
||||
var memStream = new MemoryStream();
|
||||
var headerWriter = new BinaryWriter(memStream);
|
||||
var mscorlibFullName = getMscorlibFullname();
|
||||
headerWriter.Write("System.Resources.ResourceReader, " + mscorlibFullName);
|
||||
headerWriter.Write("System.Resources.RuntimeResourceSet");
|
||||
writer.Write((int)memStream.Position);
|
||||
writer.Write(memStream.ToArray());
|
||||
}
|
||||
|
||||
string getMscorlibFullname() {
|
||||
AssemblyNameReference mscorlibRef = null;
|
||||
foreach (var asmRef in module.AssemblyReferences) {
|
||||
if (asmRef.Name != "mscorlib")
|
||||
continue;
|
||||
if (mscorlibRef == null || mscorlibRef.Version == null || asmRef.Version >= mscorlibRef.Version)
|
||||
mscorlibRef = asmRef;
|
||||
}
|
||||
if (mscorlibRef != null)
|
||||
return mscorlibRef.FullName;
|
||||
|
||||
return "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
|
||||
}
|
||||
}
|
||||
}
|
97
de4dot.code/resources/UserResourceData.cs
Normal file
97
de4dot.code/resources/UserResourceData.cs
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
Copyright (C) 2011-2012 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace de4dot.code.resources {
|
||||
abstract class UserResourceData : IResourceData {
|
||||
readonly UserResourceType type;
|
||||
|
||||
public string TypeName {
|
||||
get { return type.Name; }
|
||||
}
|
||||
|
||||
public ResourceTypeCode Code {
|
||||
get { return type.Code; }
|
||||
}
|
||||
|
||||
public UserResourceData(UserResourceType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public abstract void writeData(BinaryWriter writer, IFormatter formatter);
|
||||
}
|
||||
|
||||
class CharArrayResourceData : UserResourceData {
|
||||
public static readonly string typeName = "System.Char[],mscorlib";
|
||||
char[] data;
|
||||
|
||||
public CharArrayResourceData(UserResourceType type, char[] data)
|
||||
: base(type) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public override void writeData(BinaryWriter writer, IFormatter formatter) {
|
||||
formatter.Serialize(writer.BaseStream, data);
|
||||
}
|
||||
}
|
||||
|
||||
class IconResourceData : UserResourceData {
|
||||
public static readonly string typeName = "System.Drawing.Icon,System.Drawing";
|
||||
Icon icon;
|
||||
|
||||
public IconResourceData(UserResourceType type, byte[] data)
|
||||
: base(type) {
|
||||
icon = new Icon(new MemoryStream(data));
|
||||
}
|
||||
|
||||
public override void writeData(BinaryWriter writer, IFormatter formatter) {
|
||||
formatter.Serialize(writer.BaseStream, icon);
|
||||
}
|
||||
}
|
||||
|
||||
class ImageResourceData : UserResourceData {
|
||||
public static readonly string typeName = "System.Drawing.Bitmap,System.Drawing";
|
||||
Bitmap bitmap;
|
||||
|
||||
public ImageResourceData(UserResourceType type, byte[] data)
|
||||
: base(type) {
|
||||
bitmap = new Bitmap(Image.FromStream(new MemoryStream(data)));
|
||||
}
|
||||
|
||||
public override void writeData(BinaryWriter writer, IFormatter formatter) {
|
||||
formatter.Serialize(writer.BaseStream, bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
class BinaryResourceData : UserResourceData {
|
||||
byte[] data;
|
||||
|
||||
public BinaryResourceData(UserResourceType type, byte[] data)
|
||||
: base(type) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public override void writeData(BinaryWriter writer, IFormatter formatter) {
|
||||
writer.Write(data);
|
||||
}
|
||||
}
|
||||
}
|
42
de4dot.code/resources/UserResourceType.cs
Normal file
42
de4dot.code/resources/UserResourceType.cs
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
Copyright (C) 2011-2012 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace de4dot.code.resources {
|
||||
class UserResourceType {
|
||||
readonly string name;
|
||||
readonly ResourceTypeCode code;
|
||||
|
||||
public string Name {
|
||||
get { return name; }
|
||||
}
|
||||
|
||||
public ResourceTypeCode Code {
|
||||
get { return code; }
|
||||
}
|
||||
|
||||
public UserResourceType(string name, ResourceTypeCode code) {
|
||||
this.name = name;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format("{0:X2} {1}", (int)code, name);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user