using System.Runtime.InteropServices;
namespace WhiteMagic.Native;
///
/// P/Invoke declarations for the Win32 process, memory, thread, and module
/// APIs that WhiteMagic uses. Every declaration uses
/// (source-generated interop). SetLastError is enabled on all calls that the
/// Win32 API documents as setting a thread-local last-error value.
///
internal static partial class NativeMethods
{
// ── Process ──────────────────────────────────────────────────────────────
/// Opens an existing process and returns a handle to it.
[LibraryImport("kernel32.dll", SetLastError = true)]
internal static partial SafeMemoryHandle OpenProcess(
ProcessAccess desiredAccess,
[MarshalAs(UnmanagedType.Bool)] bool inheritHandle,
int processId);
/// Opens an existing thread and returns a handle to it.
[LibraryImport("kernel32.dll", SetLastError = true)]
internal static partial SafeMemoryHandle OpenThread(
ThreadAccess desiredAccess,
[MarshalAs(UnmanagedType.Bool)] bool inheritHandle,
int threadId);
/// Closes an open object handle.
[LibraryImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool CloseHandle(IntPtr handle);
/// Determines whether the specified process is running under WOW64.
[LibraryImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool IsWow64Process(
SafeMemoryHandle process,
[MarshalAs(UnmanagedType.Bool)] out bool wow64Process);
/// Retrieves the termination status of the specified thread.
[LibraryImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool GetExitCodeThread(
SafeMemoryHandle thread,
out uint exitCode);
// ── Memory ───────────────────────────────────────────────────────────────
/// Reads memory from a process.
[LibraryImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool ReadProcessMemory(
SafeMemoryHandle process,
IntPtr baseAddress,
Span buffer,
int size,
out nint bytesRead);
/// Writes memory to a process.
[LibraryImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool WriteProcessMemory(
SafeMemoryHandle process,
IntPtr baseAddress,
ReadOnlySpan buffer,
int size,
out nint bytesWritten);
/// Reserves or commits a region of memory in a process.
[LibraryImport("kernel32.dll", SetLastError = true)]
internal static partial IntPtr VirtualAllocEx(
SafeMemoryHandle process,
IntPtr address,
nint size,
MemoryAllocationType allocationType,
MemoryProtectionType protect);
/// Changes the protection on a committed region of memory.
[LibraryImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool VirtualProtectEx(
SafeMemoryHandle process,
IntPtr address,
nint size,
MemoryProtectionType newProtect,
out MemoryProtectionType oldProtect);
/// Releases or decommits a region of memory in a process.
[LibraryImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool VirtualFreeEx(
SafeMemoryHandle process,
IntPtr address,
nint size,
MemoryFreeType freeType);
// ── Threading ────────────────────────────────────────────────────────────
/// Creates a thread that runs in the virtual address space of a process.
[LibraryImport("kernel32.dll", SetLastError = true)]
internal static partial SafeMemoryHandle CreateRemoteThread(
SafeMemoryHandle process,
IntPtr threadAttributes,
nint stackSize,
IntPtr startAddress,
IntPtr parameter,
ThreadCreationFlags creationFlags,
out uint threadId);
/// Suspends the specified thread.
[LibraryImport("kernel32.dll", SetLastError = true)]
internal static partial uint SuspendThread(SafeMemoryHandle thread);
/// Resumes the specified thread.
[LibraryImport("kernel32.dll", SetLastError = true)]
internal static partial uint ResumeThread(SafeMemoryHandle thread);
/// Returns the thread identifier of the specified thread.
[LibraryImport("kernel32.dll", SetLastError = true)]
internal static partial uint GetThreadId(SafeMemoryHandle thread);
/// Returns the identifier of the calling thread.
[LibraryImport("kernel32.dll", SetLastError = true)]
internal static partial uint GetCurrentThreadId();
/// Sets a 64-bit thread context (AMD64).
[LibraryImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool SetThreadContext(
SafeMemoryHandle thread,
ref Context64 context);
/// Gets a 64-bit thread context (AMD64).
[LibraryImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool GetThreadContext(
SafeMemoryHandle thread,
ref Context64 context);
/// Sets a 32-bit (WOW64) thread context.
[LibraryImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool Wow64SetThreadContext(
SafeMemoryHandle thread,
ref Context32 context);
/// Gets a 32-bit (WOW64) thread context.
[LibraryImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool Wow64GetThreadContext(
SafeMemoryHandle thread,
ref Context32 context);
// ── Modules ──────────────────────────────────────────────────────────────
/// Loads a module into the calling process.
[LibraryImport("kernel32.dll", SetLastError = true, EntryPoint = "LoadLibraryW")]
internal static partial IntPtr LoadLibrary(
[MarshalAs(UnmanagedType.LPWStr)] string lpFileName);
/// Returns the address of a function or variable from a loaded module.
[LibraryImport("kernel32.dll", SetLastError = true)]
internal static partial IntPtr GetProcAddress(
IntPtr hModule,
[MarshalAs(UnmanagedType.LPStr)] string lpProcName);
/// Waits until an object is signaled or the timeout elapses. Returns a
/// WAIT_* status (DWORD); WAIT_FAILED is 0xFFFFFFFF.
[LibraryImport("kernel32.dll", SetLastError = true)]
internal static partial uint WaitForSingleObject(
SafeMemoryHandle handle,
uint milliseconds);
}