steam-deck-tools/CommonHelpers/InpOut.cs

112 lines
4.3 KiB
C#
Raw Normal View History

2022-10-15 16:53:24 +02:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace CommonHelpers
2022-10-15 16:53:24 +02:00
{
public class InpOut : IDisposable
2022-10-15 16:53:24 +02:00
{
public const String LibraryName = "inpoutx64.dll";
2022-10-15 16:53:24 +02:00
private IntPtr libraryHandle;
public MapPhysToLinDelegate MapPhysToLin;
public UnmapPhysicalMemoryDelegate UnmapPhysicalMemory;
public DlPortReadPortUcharDelegate DlPortReadPortUchar;
public DlPortWritePortUcharDelegate DlPortWritePortUchar;
public InpOut()
{
libraryHandle = LoadLibrary(LibraryName);
try
{
var addr = GetProcAddress(libraryHandle, "MapPhysToLin");
if (addr == IntPtr.Zero)
throw new ArgumentException("Missing MapPhysToLin");
MapPhysToLin = Marshal.GetDelegateForFunctionPointer<MapPhysToLinDelegate>(addr);
addr = GetProcAddress(libraryHandle, "UnmapPhysicalMemory");
if (addr == IntPtr.Zero)
throw new ArgumentException("Missing UnmapPhysicalMemory");
UnmapPhysicalMemory = Marshal.GetDelegateForFunctionPointer<UnmapPhysicalMemoryDelegate>(addr);
2022-10-15 16:53:24 +02:00
addr = GetProcAddress(libraryHandle, "UnmapPhysicalMemory");
if (addr == IntPtr.Zero)
throw new ArgumentException("Missing UnmapPhysicalMemory");
UnmapPhysicalMemory = Marshal.GetDelegateForFunctionPointer<UnmapPhysicalMemoryDelegate>(addr);
2022-10-15 16:53:24 +02:00
addr = GetProcAddress(libraryHandle, "DlPortReadPortUchar");
if (addr == IntPtr.Zero)
throw new ArgumentException("Missing DlPortReadPortUchar");
DlPortReadPortUchar = Marshal.GetDelegateForFunctionPointer<DlPortReadPortUcharDelegate>(addr);
2022-10-15 16:53:24 +02:00
addr = GetProcAddress(libraryHandle, "DlPortWritePortUchar");
if (addr == IntPtr.Zero)
throw new ArgumentException("Missing DlPortWritePortUchar");
DlPortWritePortUchar = Marshal.GetDelegateForFunctionPointer<DlPortWritePortUcharDelegate>(addr);
}
catch
{
FreeLibrary(libraryHandle);
libraryHandle = IntPtr.Zero;
throw;
}
}
~InpOut()
{
Dispose();
}
public void Dispose()
{
GC.SuppressFinalize(this);
FreeLibrary(libraryHandle);
libraryHandle = IntPtr.Zero;
}
public byte[]? ReadMemory(IntPtr baseAddress, uint size)
2022-10-15 16:53:24 +02:00
{
IntPtr pdwLinAddr = MapPhysToLin(baseAddress, size, out IntPtr pPhysicalMemoryHandle);
if (pdwLinAddr != IntPtr.Zero)
{
byte[] bytes = new byte[size];
Marshal.Copy(pdwLinAddr, bytes, 0, bytes.Length);
UnmapPhysicalMemory(pPhysicalMemoryHandle, pdwLinAddr);
return bytes;
}
return null;
}
public bool WriteMemory(IntPtr baseAddress, byte[] data)
2022-10-15 16:53:24 +02:00
{
IntPtr pdwLinAddr = MapPhysToLin(baseAddress, (uint)data.Length, out IntPtr pPhysicalMemoryHandle);
if (pdwLinAddr != IntPtr.Zero)
{
Marshal.Copy(data, 0, pdwLinAddr, data.Length);
UnmapPhysicalMemory(pPhysicalMemoryHandle, pdwLinAddr);
return true;
}
return false;
}
public delegate IntPtr MapPhysToLinDelegate(IntPtr pbPhysAddr, uint dwPhysSize, out IntPtr pPhysicalMemoryHandle);
public delegate bool UnmapPhysicalMemoryDelegate(IntPtr PhysicalMemoryHandle, IntPtr pbLinAddr);
public delegate byte DlPortReadPortUcharDelegate(ushort port);
public delegate byte DlPortWritePortUcharDelegate(ushort port, byte value);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("kernel32.dll", ExactSpelling = true)]
private static extern IntPtr GetProcAddress(IntPtr module, string methodName);
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool FreeLibrary(IntPtr module);
2022-10-15 16:53:24 +02:00
}
}