forked from goupviet/ManagedWin32
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Library.cs
129 lines (99 loc) · 4.02 KB
/
Library.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
using ManagedWin32.Api;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
namespace ManagedWin32
{
public class Library : IDisposable
{
public IntPtr Handle { get; private set; }
public static bool IsLoaded(string libraryName)
{
var process = Process.GetCurrentProcess();
return process.Modules.Cast<ProcessModule>().
Any(m => string.Compare(m.ModuleName, libraryName, StringComparison.InvariantCultureIgnoreCase) == 0);
}
#region Factory
Library(IntPtr Handle)
{
if (Handle == IntPtr.Zero)
switch ((Win32Error)Marshal.GetLastWin32Error())
{
case Win32Error.FileNotFound:
throw new FileNotFoundException();
case Win32Error.BadFormat:
throw new ArgumentException("The file is not a valid win32 executable or dll.");
default:
throw new Exception("Failed to Load the Dll");
}
this.Handle = Handle;
}
public Library(string Path) : this(Kernel32.LoadLibrary(Path)) { FileName = Path; }
public Library(string Path, LoadLibraryFlags Flags)
: this(Kernel32.LoadLibrary(Path, IntPtr.Zero, Flags)) { FileName = Path; }
public void Dispose()
{
Kernel32.FreeLibrary(Handle);
Handle = IntPtr.Zero;
}
#endregion
public T FindFunction<T>(string Name) where T : DelegateConstraint
{
if (!typeof(T).IsSubclassOf(typeof(Delegate))) throw new ArgumentException(typeof(T).Name);
var ptr = Kernel32.GetProcAddress(Handle, Name);
if (ptr == IntPtr.Zero) throw new EntryPointNotFoundException(Name + " was not found in " + Path.GetFileName(FileName));
return (T)(object)Marshal.GetDelegateForFunctionPointer(ptr, typeof(T));
}
public bool HasMethod(string Name) => Kernel32.GetProcAddress(Handle, Name) != IntPtr.Zero;
#region Resources
public LibraryResource FindResource(IntPtr ResourceID, ResourceType RType)
{
return new LibraryResource(Kernel32.FindResource(Handle, ResourceID, RType), Handle, RType, ResourceID);
}
public LibraryResource[] EnumerateResources(ResourceType RType)
{
var FoundResources = new List<LibraryResource>();
EnumResNameProc Callback = (h, t, name, l) =>
{
FoundResources.Add(FindResource(name, RType));
return true;
};
Kernel32.EnumResourceNames(Handle, RType, Callback, IntPtr.Zero);
return FoundResources.ToArray();
}
public bool HasResource(ResourceType RType) => EnumerateResources(RType).Length != 0;
#endregion
public string FileName { get; }
}
public class LibraryResource
{
public IntPtr Handle { get; private set; }
IntPtr LibraryHandle;
public IntPtr ResourceId { get; }
public ResourceType ResourceType { get; }
public LibraryResource(IntPtr Handle, IntPtr LibraryHandle, ResourceType RType, IntPtr ResourceId)
{
this.Handle = Handle;
this.LibraryHandle = LibraryHandle;
ResourceType = RType;
this.ResourceId = ResourceId;
if (Handle == IntPtr.Zero || LibraryHandle == IntPtr.Zero)
throw new Exception();
}
public int Size => Kernel32.SizeofResource(LibraryHandle, Handle);
public byte[] Data
{
get
{
var hRes = Kernel32.LoadResource(LibraryHandle, Handle);
var LockedRes = Kernel32.LockResource(hRes);
var buffer = new byte[Size];
Marshal.Copy(LockedRes, buffer, 0, Size);
return buffer;
}
}
}
}