public DisplayDetectData DetectDisplay(string id) { setutxent(); IntPtr utxp; string user = null; while ((utxp = getutxent()) != IntPtr.Zero) { utmpx utx = (utmpx)Marshal.PtrToStructure(utxp, typeof(utmpx)); if (utx.ut_type == USER_PROCESS && utx.ut_host[0] == '\0') { user = new string(utx.ut_user, 0, Array.IndexOf(utx.ut_user, '\0')); } } endutxent(); if (user == null) { return(new DisplayDetectData()); } else { return(new DisplayDetectData() { Detected = true, User = user }); } }
public DisplayDetectData DetectDisplay(string id) { setutxent(); IntPtr utxp; List <DisplayDetectData> displays = new List <DisplayDetectData>(); while ((utxp = getutxent()) != IntPtr.Zero) { utmpx utx = (utmpx)Marshal.PtrToStructure(utxp, typeof(utmpx)); if (utx.ut_type == USER_PROCESS && utx.ut_host[0] != 0) { string authority = GetAuthority(utx.ut_pid); if (authority != null) { displays.Add(new DisplayDetectData() { User = new string(utx.ut_user, 0, Array.IndexOf(utx.ut_user, '\0')), Display = new string(utx.ut_host, 0, Array.IndexOf(utx.ut_host, '\0')), Authority = authority }); } } } endutxent(); switch (displays.Count) { case 0: Console.Error.WriteLine("No displays found"); return(new DisplayDetectData()); case 1: DisplayDetectData data = displays[0]; data.Detected = true; return(data); default: List <VerificationState> verification; if (VerificationStates.ContainsKey(id)) { verification = VerificationStates[id]; } else { verification = VerificationStates[id] = new List <VerificationState>(); } if (verification.Any(s => !s.HasDenied)) { VerificationState confirmed = verification.FirstOrDefault(s => s.HasConfirmed); if (confirmed == null) { return(new DisplayDetectData() { Token = verification.First().Display.Token }); } else { VerificationStates.Remove(id); return(new DisplayDetectData() { Detected = true, User = confirmed.Display.User, Display = confirmed.Display.Display, Authority = confirmed.Display.Authority }); } } else { verification.Clear(); string token = new Random().Next(1000000).ToString().PadLeft(6, '0'); ProcessStartInfo psi = new ProcessStartInfo(); psi.FileName = Assembly.GetEntryAssembly().CodeBase; psi.Arguments = string.Concat("confirm ", token); foreach (DisplayDetectData display in displays) { VerificationState state = new VerificationState() { Display = display, SessionId = id, HasConfirmed = false, HasDenied = false }; display.Token = token; Process proc = Start(psi, display); proc.EnableRaisingEvents = true; proc.Exited += (sender, e) => { if (proc.ExitCode == 0) { state.HasConfirmed = true; foreach (VerificationState s in verification) { if (!s.Process.HasExited) { s.Process.Kill(); } } } else { state.HasDenied = true; } }; state.Process = proc; verification.Add(state); } return(new DisplayDetectData() { Token = token }); } } }