diff --git a/de4dot.code/de4dot.code.csproj b/de4dot.code/de4dot.code.csproj
index 9ce9308a..5c5ce3c5 100644
--- a/de4dot.code/de4dot.code.csproj
+++ b/de4dot.code/de4dot.code.csproj
@@ -44,6 +44,7 @@
..\ICSharpCode.SharpZipLib.dll
+
@@ -230,6 +231,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/de4dot.code/resources/BuiltInResourceData.cs b/de4dot.code/resources/BuiltInResourceData.cs
new file mode 100644
index 00000000..d13489fc
--- /dev/null
+++ b/de4dot.code/resources/BuiltInResourceData.cs
@@ -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 .
+*/
+
+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");
+ }
+ }
+ }
+}
diff --git a/de4dot.code/resources/IResourceData.cs b/de4dot.code/resources/IResourceData.cs
new file mode 100644
index 00000000..04eff9b6
--- /dev/null
+++ b/de4dot.code/resources/IResourceData.cs
@@ -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 .
+*/
+
+using System.IO;
+using System.Runtime.Serialization;
+
+namespace de4dot.code.resources {
+ interface IResourceData {
+ ResourceTypeCode Code { get; }
+ void writeData(BinaryWriter writer, IFormatter formatter);
+ }
+}
diff --git a/de4dot.code/resources/ResourceDataCreator.cs b/de4dot.code/resources/ResourceDataCreator.cs
new file mode 100644
index 00000000..db832045
--- /dev/null
+++ b/de4dot.code/resources/ResourceDataCreator.cs
@@ -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 .
+*/
+
+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 dict = new Dictionary(StringComparer.Ordinal);
+ Dictionary asmNameToAsmFullName = new Dictionary(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 getSortedTypes() {
+ var list = new List(dict.Values);
+ list.Sort((a, b) => Utils.compareInt32((int)a.Code, (int)b.Code));
+ return list;
+ }
+ }
+}
diff --git a/de4dot.code/resources/ResourceElement.cs b/de4dot.code/resources/ResourceElement.cs
new file mode 100644
index 00000000..f80ed9c9
--- /dev/null
+++ b/de4dot.code/resources/ResourceElement.cs
@@ -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 .
+*/
+
+namespace de4dot.code.resources {
+ class ResourceElement {
+ public string Name { get; set; }
+ public IResourceData ResourceData { get; set; }
+ }
+}
diff --git a/de4dot.code/resources/ResourceElementSet.cs b/de4dot.code/resources/ResourceElementSet.cs
new file mode 100644
index 00000000..19a820c0
--- /dev/null
+++ b/de4dot.code/resources/ResourceElementSet.cs
@@ -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 .
+*/
+
+using System;
+using System.Collections.Generic;
+
+namespace de4dot.code.resources {
+ class ResourceElementSet {
+ Dictionary dict = new Dictionary(StringComparer.Ordinal);
+
+ public int Count {
+ get { return dict.Count; }
+ }
+
+ public IEnumerable ResourceElements {
+ get { return dict.Values; }
+ }
+
+ public void add(ResourceElement elem) {
+ dict[elem.Name] = elem;
+ }
+ }
+}
diff --git a/de4dot.code/resources/ResourceTypeCode.cs b/de4dot.code/resources/ResourceTypeCode.cs
new file mode 100644
index 00000000..4644074e
--- /dev/null
+++ b/de4dot.code/resources/ResourceTypeCode.cs
@@ -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 .
+*/
+
+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,
+ }
+}
diff --git a/de4dot.code/resources/ResourceWriter.cs b/de4dot.code/resources/ResourceWriter.cs
new file mode 100644
index 00000000..49db069d
--- /dev/null
+++ b/de4dot.code/resources/ResourceWriter.cs
@@ -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 .
+*/
+
+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 dataToNewType = new Dictionary();
+
+ 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";
+ }
+ }
+}
diff --git a/de4dot.code/resources/UserResourceData.cs b/de4dot.code/resources/UserResourceData.cs
new file mode 100644
index 00000000..367ca549
--- /dev/null
+++ b/de4dot.code/resources/UserResourceData.cs
@@ -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 .
+*/
+
+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);
+ }
+ }
+}
diff --git a/de4dot.code/resources/UserResourceType.cs b/de4dot.code/resources/UserResourceType.cs
new file mode 100644
index 00000000..1e38442f
--- /dev/null
+++ b/de4dot.code/resources/UserResourceType.cs
@@ -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 .
+*/
+
+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);
+ }
+ }
+}