using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Text;

namespace MoonlitShadow {
    // Read-only, limited-query handle. No VM access, injection, privilege changes or process control.
    public static class ProcessImage {
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern IntPtr OpenProcess(uint access, bool inheritHandle, uint processId);
        [DllImport("kernel32.dll", EntryPoint = "QueryFullProcessImageNameW", CharSet = CharSet.Unicode, SetLastError = true)]
        private static extern bool QueryImage(IntPtr process, uint flags, StringBuilder name, ref uint size);
        [DllImport("kernel32.dll")]
        private static extern bool CloseHandle(IntPtr handle);

        public static string Read(uint processId) {
            IntPtr handle = OpenProcess(0x1000, false, processId); // PROCESS_QUERY_LIMITED_INFORMATION
            if (handle == IntPtr.Zero) throw new Win32Exception(Marshal.GetLastWin32Error());
            try {
                var name = new StringBuilder(32768);
                uint size = 32768;
                if (!QueryImage(handle, 0, name, ref size)) throw new Win32Exception(Marshal.GetLastWin32Error());
                if (size == 0) throw new InvalidOperationException("Empty process image path.");
                return name.ToString();
            } finally { CloseHandle(handle); }
        }
    }
}
