Add code to write .resources files
This commit is contained in:
parent
c815592f10
commit
76d9e87c3c
|
@ -44,6 +44,7 @@
|
||||||
<HintPath>..\ICSharpCode.SharpZipLib.dll</HintPath>
|
<HintPath>..\ICSharpCode.SharpZipLib.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
<Reference Include="System.Runtime.Remoting" />
|
<Reference Include="System.Runtime.Remoting" />
|
||||||
<Reference Include="System.XML" />
|
<Reference Include="System.XML" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -230,6 +231,15 @@
|
||||||
<Compile Include="renamer\TypeNames.cs" />
|
<Compile Include="renamer\TypeNames.cs" />
|
||||||
<Compile Include="renamer\TypeRenamerState.cs" />
|
<Compile Include="renamer\TypeRenamerState.cs" />
|
||||||
<Compile Include="renamer\VariableNameState.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="StringInliner.cs" />
|
||||||
<Compile Include="UserException.cs" />
|
<Compile Include="UserException.cs" />
|
||||||
<Compile Include="Utils.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