forked from dragouf/ExcelDnaUnPacker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathResourceHelper.cs
144 lines (125 loc) · 4.83 KB
/
ResourceHelper.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
using SevenZip.Compression.LZMA;
using System.Reflection;
using System.IO;
using System.Collections.Generic;
[Flags]
enum LoadLibraryFlags : uint
{
DONT_RESOLVE_DLL_REFERENCES = 0x00000001,
LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010,
LOAD_LIBRARY_AS_DATAFILE = 0x00000002,
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040,
LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020,
LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008
}
internal unsafe static class ResourceHelper
{
// TODO: Learn about locales
private const ushort localeNeutral = 0;
private const ushort localeEnglishUS = 1033;
private const ushort localeEnglishSA = 7177;
[DllImport("kernel32.dll")]
private static extern IntPtr BeginUpdateResource(
string pFileName,
bool bDeleteExistingResources);
[DllImport("kernel32.dll")]
private static extern bool EndUpdateResource(
IntPtr hUpdate,
bool fDiscard);
//, EntryPoint="UpdateResourceA", CharSet=CharSet.Ansi,
[DllImport("kernel32.dll", SetLastError=true)]
private static extern bool UpdateResource(
IntPtr hUpdate,
string lpType,
string lpName,
ushort wLanguage,
IntPtr lpData,
uint cbData);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr FindResource(
IntPtr hModule,
string lpName,
string lpType);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr LoadResource(
IntPtr hModule,
IntPtr hResInfo);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern uint SizeofResource(
IntPtr hModule,
IntPtr hResInfo);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr LockResource(
IntPtr hResData);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, LoadLibraryFlags dwFlags);
[DllImport("kernel32.DLL")]
private static extern uint GetLastError();
// Load the resource, trying also as compressed if no uncompressed version is found.
// If the resource type ends with "_LZMA", we decompress from the LZMA format.
internal static byte[] LoadResourceBytes(IntPtr hModule, string typeName, string resourceName)
{
Debug.Print("LoadResourceBytes for resource {0} of type {1}", resourceName, typeName);
IntPtr hResInfo = FindResource(hModule, resourceName, typeName);
if (hResInfo == IntPtr.Zero)
{
// We expect this null result value when the resource does not exists.
if (!typeName.EndsWith("_LZMA"))
{
// Try the compressed name.
typeName += "_LZMA";
hResInfo = FindResource(hModule, resourceName, typeName);
}
if (hResInfo == IntPtr.Zero)
{
Debug.Print("Resource not found - resource {0} of type {1}", resourceName, typeName);
// Return null to indicate that the resource was not found.
return null;
}
}
IntPtr hResData = LoadResource(hModule, hResInfo);
if (hResData == IntPtr.Zero)
{
// Unexpected error - this should not happen
Debug.Print("Unexpected errror loading resource {0} of type {1}", resourceName, typeName);
throw new Win32Exception();
}
uint size = SizeofResource(hModule, hResInfo);
IntPtr pResourceBytes = LockResource(hResData);
byte[] resourceBytes = new byte[size];
Marshal.Copy(pResourceBytes, resourceBytes, 0, (int)size);
if (typeName.EndsWith("_LZMA"))
return Decompress(resourceBytes);
else
return resourceBytes;
}
private static byte[] Decompress(byte[] inputBytes)
{
MemoryStream newInStream = new MemoryStream(inputBytes);
Decoder decoder = new Decoder();
newInStream.Seek(0, 0);
MemoryStream newOutStream = new MemoryStream();
byte[] properties2 = new byte[5];
if (newInStream.Read(properties2, 0, 5) != 5)
throw (new Exception("input .lzma is too short"));
long outSize = 0;
for (int i = 0; i < 8; i++)
{
int v = newInStream.ReadByte();
if (v < 0)
throw (new Exception("Can't Read 1"));
outSize |= ((long)(byte)v) << (8 * i);
}
decoder.SetDecoderProperties(properties2);
long compressedSize = newInStream.Length - newInStream.Position;
decoder.Code(newInStream, newOutStream, compressedSize, outSize, null);
byte[] b = newOutStream.ToArray();
return b;
}
}