#region References using System; using System.IO; #endregion namespace Ultima { public abstract unsafe class ProcessStream : Stream { private const int ProcessAllAccess = 0x1F0FFF; protected bool m_Open; protected ClientProcessHandle m_Process; protected int m_Position; public abstract ClientProcessHandle ProcessID { get; } public virtual bool BeginAccess() { if (m_Open) { return false; } m_Process = NativeMethods.OpenProcess(ProcessAllAccess, 0, ProcessID); m_Open = true; return true; } public virtual void EndAccess() { if (!m_Open) { return; } m_Process.Close(); m_Open = false; } public override void Flush() { } public override int Read(byte[] buffer, int offset, int count) { bool end = !BeginAccess(); int res = 0; fixed (byte* p = buffer) { NativeMethods.ReadProcessMemory(m_Process, m_Position, p + offset, count, ref res); } m_Position += count; if (end) { EndAccess(); } return res; } public override void Write(byte[] buffer, int offset, int count) { bool end = !BeginAccess(); fixed (byte* p = buffer) { NativeMethods.WriteProcessMemory(m_Process, m_Position, p + offset, count, 0); } m_Position += count; if (end) { EndAccess(); } } public override bool CanRead { get { return true; } } public override bool CanWrite { get { return true; } } public override bool CanSeek { get { return true; } } public override long Length { get { throw new NotSupportedException(); } } public override long Position { get { return m_Position; } set { m_Position = (int)value; } } public override void SetLength(long value) { throw new NotSupportedException(); } public override long Seek(long offset, SeekOrigin origin) { switch (origin) { case SeekOrigin.Begin: m_Position = (int)offset; break; case SeekOrigin.Current: m_Position += (int)offset; break; case SeekOrigin.End: throw new NotSupportedException(); } return m_Position; } } }