Last active
July 6, 2019 10:55
-
-
Save Kittoes0124/0e936d97a0bc57c8d8a0ce16406231cb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Runtime.ConstrainedExecution; | |
using System.Runtime.InteropServices; | |
using System.Security; | |
namespace ByteTerrace.Windows.Api | |
{ | |
static class BitwiseHelpers | |
{ | |
public static uint ConcatBits(ushort highPart, ushort lowPart) => ((((uint)highPart) << 16) | lowPart); | |
} | |
public static class Constants | |
{ | |
public const string Kernel32Dll = "Kernel32.dll"; | |
} | |
[Flags] | |
public enum VirtualMemoryAllocationType : uint | |
{ | |
COMMIT = 0x1000, | |
RESERVE = 0x2000, | |
} | |
[Flags] | |
public enum VirtualMemoryFreeType : uint | |
{ | |
RELEASE = 0x8000, | |
} | |
[Flags] | |
public enum VirtualMemoryProtectionType : uint | |
{ | |
EXECUTE = 0x10, | |
READWRITE = 0x04, | |
} | |
public enum WindowShowType : int | |
{ | |
HIDE = 0, | |
SHOW = 5, | |
} | |
[Flags] | |
public enum WindowStyleBasic : uint | |
{ | |
OVERLAPPED = 0x00, | |
} | |
[Flags] | |
public enum WindowStyleExtended : uint | |
{ | |
EX_LEFT = 0x00, | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public readonly struct Atom | |
{ | |
public static Atom Null => New(0); | |
public static Atom New(ushort value) => new Atom(value); | |
public static bool operator ==(Atom left, Atom right) => (left.m_value == right.m_value); | |
public static bool operator !=(Atom left, Atom right) => (left.m_value != right.m_value); | |
private readonly ushort m_value; | |
private Atom(ushort value) { | |
m_value = value; | |
} | |
public bool Equals(Atom other) => (this == other); | |
public override bool Equals(object other) => ((other != null) && ((other is Atom) && Equals(other))); | |
public override int GetHashCode() => m_value.GetHashCode(); | |
public ushort ToUInt16() => m_value; | |
} | |
public abstract class SafeHandleZeroIsInvalid : SafeHandle | |
{ | |
protected SafeHandleZeroIsInvalid(bool ownsHandle) : base(IntPtr.Zero, ownsHandle) { } | |
public override bool IsInvalid { | |
[PrePrepareMethod] | |
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] | |
get => (IntPtr.Zero == handle); | |
} | |
} | |
public static class Library | |
{ | |
[Flags] | |
public enum LoadLibraryType : uint | |
{ | |
NONE = 0x00000000, | |
} | |
[Flags] | |
public enum ModuleHandleType : uint | |
{ | |
NONE = 0x00000000, | |
} | |
public sealed class LoadLibrarySafeHandle : SafeHandleZeroIsInvalid | |
{ | |
[SuppressUnmanagedCodeSecurity] | |
private static class UnsafeNativeMethods | |
{ | |
[DllImport(Constants.Kernel32Dll, BestFitMapping = false, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true, ThrowOnUnmappableChar = true)] | |
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] | |
[SecurityCritical] | |
[return: MarshalAs(UnmanagedType.Bool)] | |
public static extern bool FreeLibrary(IntPtr libraryHandle); | |
[DllImport(Constants.Kernel32Dll, BestFitMapping = false, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true, ThrowOnUnmappableChar = true)] | |
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] | |
[SecurityCritical] | |
[return: MarshalAs(UnmanagedType.Bool)] | |
public static extern bool GetModuleHandleExW(ModuleHandleType moduleHandleType, [MarshalAs(UnmanagedType.LPWStr)] string libraryName, out IntPtr libraryHandle); | |
[DllImport(Constants.Kernel32Dll, BestFitMapping = false, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true, ThrowOnUnmappableChar = true)] | |
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] | |
[SecurityCritical] | |
public static extern IntPtr GetProcAddress(IntPtr libraryHandle, IntPtr procedureName); | |
[DllImport(Constants.Kernel32Dll, BestFitMapping = false, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true, ThrowOnUnmappableChar = true)] | |
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] | |
[SecurityCritical] | |
public static extern IntPtr LoadLibraryExW([MarshalAs(UnmanagedType.LPWStr)] string libraryName, IntPtr fileHandle, LoadLibraryType loadLibraryType); | |
} | |
public static LoadLibrarySafeHandle New(IntPtr address) => new LoadLibrarySafeHandle(address); | |
public static LoadLibrarySafeHandle New(string name, IntPtr fileHandle, LoadLibraryType loadLibraryType) { | |
if (UnsafeNativeMethods.GetModuleHandleExW(ModuleHandleType.NONE, name, out IntPtr libraryHandle)) { | |
return New(libraryHandle); | |
} | |
else { | |
libraryHandle = UnsafeNativeMethods.LoadLibraryExW(name, fileHandle, loadLibraryType); | |
if (IntPtr.Zero == libraryHandle) { | |
throw new DllNotFoundException(message: $"unable to find a library named {name}", inner: Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error())); | |
} | |
return New(libraryHandle); | |
} | |
} | |
public static LoadLibrarySafeHandle New(string name) => New(name, IntPtr.Zero, LoadLibraryType.NONE); | |
private LoadLibrarySafeHandle(IntPtr address) : base(true) { | |
SetHandle(address); | |
} | |
[PrePrepareMethod] | |
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] | |
protected override bool ReleaseHandle() => UnsafeNativeMethods.FreeLibrary(handle); | |
public TDelegate GetDelegateForProcedure<TDelegate>(string name) { | |
var nameHandle = Marshal.StringToHGlobalAnsi(name); | |
try { | |
var functionHandle = UnsafeNativeMethods.GetProcAddress(handle, nameHandle); | |
if (IntPtr.Zero == functionHandle) { | |
throw new EntryPointNotFoundException(message: $"unable to find a procedure named {name}", inner: Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error())); | |
} | |
else { | |
return Marshal.GetDelegateForFunctionPointer<TDelegate>(functionHandle); | |
} | |
} | |
finally { | |
Marshal.FreeHGlobal(nameHandle); | |
} | |
} | |
} | |
} | |
public static class Memory | |
{ | |
[DllImport("Kernel32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] | |
public static extern IntPtr VirtualAllocEx(IntPtr handle, IntPtr address, UIntPtr length, VirtualMemoryAllocationType allocationType, VirtualMemoryProtectionType protectionType); | |
[DllImport("Kernel32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] | |
public static extern bool VirtualFreeEx(IntPtr handle, IntPtr address, UIntPtr length, VirtualMemoryFreeType freeType); | |
[DllImport("Kernel32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] | |
public static extern bool VirtualProtectEx(IntPtr handle, IntPtr address, UIntPtr length, VirtualMemoryProtectionType newProtectionType, out VirtualMemoryProtectionType oldProtectionType); | |
} | |
public static class Process | |
{ | |
[DllImport("Kernel32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = false)] | |
public static extern IntPtr GetCurrentProcess(); | |
} | |
public static class Window | |
{ | |
public delegate IntPtr WindowProcWDelegate(IntPtr windowHandle, uint message, IntPtr wParam, IntPtr lParam); | |
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] | |
public readonly struct WndClassExW | |
{ | |
public static WndClassExW New(WindowProcWDelegate lpfnWndProc, IntPtr hInstance, string lpszClassName) => new WndClassExW(lpfnWndProc, hInstance, lpszClassName); | |
public static WndClassExW New(IntPtr hInstance, string lpszClassName) => new WndClassExW(DefWindowProcW, hInstance, lpszClassName); | |
public static WndClassExW New() => new WndClassExW(null, IntPtr.Zero, null); | |
private readonly uint m_cbSize; | |
private readonly uint m_style; | |
private readonly IntPtr m_lpfnWndProc; | |
private readonly int m_cbClsExtra; | |
private readonly int m_cbWndExtra; | |
private readonly IntPtr m_hInstance; | |
private readonly IntPtr m_hIcon; | |
private readonly IntPtr m_hCursor; | |
private readonly IntPtr m_hbrBackground; | |
[MarshalAs(UnmanagedType.LPWStr)] private readonly string m_lpszMenuName; | |
[MarshalAs(UnmanagedType.LPWStr)] private readonly string m_lpszClassName; | |
private readonly IntPtr m_hIconSm; | |
private WndClassExW(WindowProcWDelegate lpfnWndProc, IntPtr hInstance, string lpszClassName) { | |
m_cbSize = ((uint)Marshal.SizeOf(typeof(WndClassExW))); | |
m_style = 0U; | |
m_lpfnWndProc = ((lpfnWndProc != null) ? Marshal.GetFunctionPointerForDelegate(lpfnWndProc) : IntPtr.Zero); | |
m_cbClsExtra = 0; | |
m_cbWndExtra = 0; | |
m_hInstance = hInstance; | |
m_hIcon = IntPtr.Zero; | |
m_hCursor = IntPtr.Zero; | |
m_hbrBackground = IntPtr.Zero; | |
m_lpszMenuName = string.Empty; | |
m_lpszClassName = lpszClassName; | |
m_hIconSm = IntPtr.Zero; | |
} | |
} | |
[DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] | |
public static extern IntPtr CreateWindowExW(WindowStyleExtended extendedWindowStyle, [MarshalAs(UnmanagedType.LPWStr)] string className, [MarshalAs(UnmanagedType.LPWStr)] string windowName, WindowStyleBasic baseWindowStyle, int x, int y, int width, int height, IntPtr parentHandle, IntPtr menuHandle, IntPtr moduleHandle, IntPtr createParameters); | |
[DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] | |
public static extern IntPtr DefWindowProcW(IntPtr windowHandle, uint message, IntPtr wParam, IntPtr lParam); | |
[DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] | |
public static extern bool DestroyWindow(IntPtr windowHandle); | |
[DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] | |
public static extern bool GetClassInfoExW(IntPtr instanceHandle, IntPtr className, ref WndClassExW windowClass); | |
[DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] | |
public static extern Atom RegisterClassExW(ref WndClassExW windowClass); | |
[DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] | |
public static extern bool ShowWindow(IntPtr windowHandle, WindowShowType windowShowType); | |
[DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] | |
public static extern bool UnregisterClassW(IntPtr classAtom, IntPtr instanceHandle); | |
public static bool UnregisterClassW(Atom classAtom, IntPtr instanceHandle) => UnregisterClassW(new IntPtr(BitwiseHelpers.ConcatBits(0, classAtom.ToUInt16())), instanceHandle); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment