// Thin Windows CLI_PATH executable. Runtime and original are owner-provisioned, // absolute, SHA-pinned; never consult PATH or CODEX_CLI_PATH. using System; using System.IO; using System.Text; using System.Diagnostics; using System.Security.Cryptography; using System.Collections.Generic; using System.Threading; using System.Runtime.InteropServices; using System.Web.Script.Serialization; class NativeWatchBootstrap { // Assign this bootstrap BEFORE creating Python. Descendants inherit job // membership atomically; the non-inheritable handle belongs only to us. // Windows closes it even on TerminateProcess, killing Python and native. static IntPtr ownedJob; [StructLayout(LayoutKind.Sequential)] struct BasicLimits { public long ProcessTime, JobTime; public uint Flags; public UIntPtr MinWorkingSet, MaxWorkingSet; public uint ActiveProcesses; public UIntPtr Affinity; public uint Priority, Scheduling; } [StructLayout(LayoutKind.Sequential)] struct IoCounters { public ulong ReadOps, WriteOps, OtherOps, ReadBytes, WriteBytes, OtherBytes; } [StructLayout(LayoutKind.Sequential)] struct ExtendedLimits { public BasicLimits Basic; public IoCounters Io; public UIntPtr ProcessMemory, JobMemory, PeakProcessMemory, PeakJobMemory; } [DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)] static extern IntPtr CreateJobObject(IntPtr attributes, string name); [DllImport("kernel32.dll", SetLastError=true)] static extern bool SetInformationJobObject(IntPtr job, int kind, ref ExtendedLimits limits, uint size); [DllImport("kernel32.dll", SetLastError=true)] static extern bool AssignProcessToJobObject(IntPtr job, IntPtr process); static void OwnProcessTree() { ownedJob=CreateJobObject(IntPtr.Zero,null); var limits=new ExtendedLimits(); limits.Basic.Flags=0x2000; // KILL_ON_JOB_CLOSE if(ownedJob==IntPtr.Zero || !SetInformationJobObject(ownedJob,9,ref limits,(uint)Marshal.SizeOf(typeof(ExtendedLimits))) || !AssignProcessToJobObject(ownedJob,Process.GetCurrentProcess().Handle)) throw new Exception(); // Do not close here or in finally: the bootstrap is itself a member. // The OS closes this handle at exit, preserving our native exit code. } static string Quote(string s) { var b=new StringBuilder("\""); int slashes=0; foreach(char c in s) { if(c=='\\') {slashes++; continue;} if(c=='"') { b.Append('\\',slashes*2+1); b.Append(c); } else {b.Append('\\',slashes); b.Append(c);} slashes=0; } b.Append('\\',slashes*2); b.Append('"'); return b.ToString(); } static string Pin(Dictionary c,string field) { string p=(string)c[field], expected=(string)c[field+"_sha256"]; if(!Path.IsPathRooted(p) || String.Equals(Path.GetFullPath(p),Process.GetCurrentProcess().MainModule.FileName,StringComparison.OrdinalIgnoreCase)) throw new Exception(); using(var f=File.OpenRead(p)) using(var sha=SHA256.Create()) { string actual=BitConverter.ToString(sha.ComputeHash(f)).Replace("-","").ToLowerInvariant(); if(actual!=expected.ToLowerInvariant()) throw new Exception(); } return p; } static void Pump(Stream source, Stream target) { byte[] buffer=new byte[8192]; int count; while((count=source.Read(buffer,0,buffer.Length))>0) { target.Write(buffer,0,count); target.Flush(); } } static int Main(string[] args) { try { string manifest=Path.ChangeExtension(Process.GetCurrentProcess().MainModule.FileName,".json"); var c=new JavaScriptSerializer().Deserialize>(File.ReadAllText(manifest)); string original=Pin(c,"original"); string python=Pin(c,"python"); string script=Pin(c,"script"); OwnProcessTree(); var argv=new List{"-u",script,manifest}; argv.AddRange(args); var quoted=new List(); foreach(var a in argv) quoted.Add(Quote(a)); var p=Process.Start(new ProcessStartInfo(python,String.Join(" ",quoted.ToArray())) { UseShellExecute=false, CreateNoWindow=true, RedirectStandardInput=true, RedirectStandardOutput=true, RedirectStandardError=true }); var input=new Thread(()=> { try { Pump(Console.OpenStandardInput(),p.StandardInput.BaseStream); p.StandardInput.Close(); } catch(IOException) {} }); input.IsBackground=true; input.Start(); var output=new Thread(()=>Pump(p.StandardOutput.BaseStream,Console.OpenStandardOutput())); var error=new Thread(()=>Pump(p.StandardError.BaseStream,Console.OpenStandardError())); output.Start(); error.Start(); p.WaitForExit(); output.Join(); error.Join(); return p.ExitCode; } catch { Console.Error.WriteLine("Owned native launcher integrity/configuration failure."); return 78; } } }