public void StartSuspended() { var pi = new Kernel32.PROCESS_INFORMATION(); var si = new Kernel32.STARTUPINFO() { hStdInput = Kernel32.SafeObjectHandle.Null, hStdOutput = Kernel32.SafeObjectHandle.Null, hStdError = Kernel32.SafeObjectHandle.Null }; var processCreationFlags = Kernel32.CreateProcessFlags.CREATE_SUSPENDED | Kernel32.CreateProcessFlags.CREATE_UNICODE_ENVIRONMENT; if (SpawnNewConsoleWindow) { processCreationFlags |= Kernel32.CreateProcessFlags.CREATE_NEW_CONSOLE; } if (!Kernel32.CreateProcess(null, new StringBuilder(string.Join(" ", args)).ToString(), IntPtr.Zero, IntPtr.Zero, false, processCreationFlags, IntPtr.Zero, null, ref si, out pi)) { throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()); } hProcess = new Kernel32.SafeObjectHandle(pi.hProcess); pid = pi.dwProcessId; hThread = new Kernel32.SafeObjectHandle(pi.hThread); }
public BetterProcessInfo Start() { // Inspired by https://stackoverflow.com/a/19049930/1834329 var info = new Kernel32.STARTUPINFO(); info.cb = Marshal.SizeOf(info); // TODO: Is this needed? info.dwFlags = Kernel32.StartupInfoFlags.STARTF_USESHOWWINDOW; info.wShowWindow = windowStyleMap[_info.WindowStyle]; var arguments = _info.Arguments != null ? $" {_info.Arguments}" : string.Empty; var processData = Kernel32.CreateProcess(null, $"{_info.FileName}{arguments}", IntPtr.Zero, IntPtr.Zero, true, 0, IntPtr.Zero, null, ref info, out Kernel32.PROCESS_INFORMATION processInfo); Kernel32.CloseHandle(processInfo.hProcess); Kernel32.CloseHandle(processInfo.hThread); return(new BetterProcessInfo { Id = processInfo.dwProcessId, ThreadId = processInfo.dwThreadId }); }
/// <summary> /// /// </summary> /// <param name="message"></param> private void ExecuteFile(ExecuteFileMessage message) { ExecuteSimpleOperation(message.WindowId, -1, "File execution", () => { var si = new Kernel32.STARTUPINFO(); var pi = new Kernel32.PROCESS_INFORMATION(); var sap = new Kernel32.SECURITY_ATTRIBUTES(); var sat = new Kernel32.SECURITY_ATTRIBUTES(); const uint CreateNoWindow = 0x08000000; var directory = Path.GetDirectoryName(message.FilePath); Kernel32.CreateProcess(message.FilePath, "", ref sap, ref sat, false, CreateNoWindow, IntPtr.Zero, directory, ref si, out pi); }, message.FilePath); }
private void cmdLaunch_Click(object sender, EventArgs e) { if (chkControllerCheck.Checked) { //Check if a controller is connected try { XInputState controller = new XInputState(); if (XInput.XInputGetState(0, ref controller).Equals(ERROR_DEVICE_NOT_CONNECTED)) { DirectInput dinput = new DirectInput(); IList <DeviceInstance> joysticks = dinput.GetDevices(DeviceType.Gamepad, DeviceEnumerationFlags.AllDevices); if (joysticks.Count == 0) { joysticks = dinput.GetDevices(DeviceType.Joystick, DeviceEnumerationFlags.AllDevices); if (joysticks.Count == 0) { if (MessageBox.Show(this, "There are no controllers connected. Do you wish to start anyway?", "No controller found", MessageBoxButtons.YesNo, MessageBoxIcon.Question).Equals(DialogResult.No)) { return; } } } } } catch (Exception ex) { MessageBox.Show("Error Detecting controller"); } } /* Don't try to start the game twice... */ bool windowed = chkWindowed.Checked; uint value = 0; if (rdoOnline.Checked) { value = (uint)(ctrlFlagValue | 0x00000010); } else { value = (uint)(ctrlFlagValue & 0xffffffef); } /* Figure out the working directory to set and set the flag in the registry... */ RegistryKey k = Registry.CurrentUser.OpenSubKey(@"Software\SonicTeam\PSOV2", true); k.SetValue("CTRLFLAG1", value, RegistryValueKind.DWord); k.Close(); string dir = psoDir; Kernel32.STARTUPINFO si = new Kernel32.STARTUPINFO(); Kernel32.PROCESS_INFORMATION pi = new Kernel32.PROCESS_INFORMATION(); Directory.SetCurrentDirectory(dir); /* Get the icon from one of the exes that have an icon */ System.Drawing.Icon icon = System.Drawing.Icon.ExtractAssociatedIcon("online.exe"); /* Start PSO... */ bool ran = Kernel32.CreateProcess(null, "pso.exe -online", IntPtr.Zero, IntPtr.Zero, true, (uint)Kernel32.ProcessCreationFlags.CREATE_SUSPENDED, IntPtr.Zero, dir, ref si, out pi); if (!ran) { Console.Out.WriteLine("CANNOT START PSO!"); //k.SetValue("CTRLFLAG1", value, RegistryValueKind.DWord); return; } psoProc = Process.GetProcessById((int)pi.dwProcessId); if (!chkBypassPatch.Checked) { string ChannelName = null; RemoteHooking.IpcCreateServer <YggdrasillInterface>(ref ChannelName, WellKnownObjectMode.SingleCall); try { RemoteHooking.Inject((int)pi.dwProcessId, Path.Combine(Application.StartupPath, "Mithos.dll"), null, ChannelName, chkVista.Checked, windowed); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); psoProc.Kill(); return; } /* Set up for doing the stuff we need to to the binary... */ ProcessHaxxor haxxor = new ProcessHaxxor(psoProc); Kernel32.ResumeThread(pi.hThread); Thread.Sleep(1000); /* Pause it while we hax it up. */ foreach (ProcessThread pT in psoProc.Threads) { IntPtr pOpenThread = Kernel32.OpenThread(Kernel32.ThreadAccess.SUSPEND_RESUME, false, (uint)pT.Id); if (pOpenThread == IntPtr.Zero) { break; } Kernel32.SuspendThread(pOpenThread); } if (chkIpPatch.Checked) { haxxor.PatchPSO(chkWhiteNames.Checked, chkWordFilter.Checked, chkMusicFix.Checked, chkMapFix.Checked, txtServer.Text.Trim()); } else { haxxor.PatchPSO(chkWhiteNames.Checked, chkWordFilter.Checked, chkMusicFix.Checked, chkMapFix.Checked, null); } } /* Wake it up. */ foreach (ProcessThread pT in psoProc.Threads) { IntPtr pOpenThread = Kernel32.OpenThread(Kernel32.ThreadAccess.SUSPEND_RESUME, false, (uint)pT.Id); if (pOpenThread == IntPtr.Zero) { break; } Kernel32.ResumeThread(pOpenThread); } if (windowed) { RECT windowRect = new RECT(); RECT clientRect = new RECT(); int windowHeight = 0; int windowWidth = 0; int clientHeight = 0; int clientWidth = 0; Thread.Sleep(750); wnd = User32.FindWindow("PSO for PC", "PSO for PC"); WinAPI.GetWindowRect(wnd, ref windowRect); windowHeight = windowRect.Bottom - windowRect.Top; windowWidth = windowRect.Right - windowRect.Left; WinAPI.GetClientRect(wnd, ref clientRect); clientHeight = clientRect.Bottom - clientRect.Top; clientWidth = clientRect.Right - clientRect.Left; int startX = 0; int startY = 0; int desiredWidth = 0; int desiredHeight = 0; if (rdoPerfect.Checked) { desiredWidth = (int)((640 * (cboRatio.SelectedIndex + 1)) + (windowWidth - clientWidth)); desiredHeight = (int)((480 * (cboRatio.SelectedIndex + 1)) + (windowHeight - clientHeight)); } else if (rdoScreenHeight.Checked) { desiredHeight = Screen.PrimaryScreen.Bounds.Height + (windowHeight - clientHeight); desiredWidth = ((desiredHeight * 4) / 3) + (windowWidth - clientWidth); } else { desiredWidth = (int)((int)txtW.Value + (windowWidth - clientWidth)); desiredHeight = (int)((int)txtH.Value + (windowHeight - clientHeight)); } if (chkCenterWindow.Checked) { startX = (ScreenWidth - desiredWidth) / 2; startY = (Screen.PrimaryScreen.WorkingArea.Height - desiredHeight) / 2; } if (chkEmbedFullScreen.Checked) { uint lStyle = WinAPI.GetWindowLong(wnd, nIndex.GWL_STYLE); lStyle &= ~(dwNewLong.WS_CAPTION | dwNewLong.WS_THICKFRAME | dwNewLong.WS_MINIMIZE | dwNewLong.WS_MAXIMIZE | dwNewLong.WS_SYSMENU); WinAPI.SetWindowLong(wnd, nIndex.GWL_STYLE, lStyle); int wWidth = 640; int wHeight = 480; if (rdoPerfect.Checked) { wWidth *= (cboRatio.SelectedIndex + 1); wHeight *= (cboRatio.SelectedIndex + 1); } else if (rdoScreenHeight.Checked) { wHeight = Screen.PrimaryScreen.Bounds.Height; wWidth = (wHeight * 4) / 3; } else { wWidth = (int)txtW.Value; wHeight = (int)txtH.Value; } psoForm = new frmPSO(); psoForm.TopMost = true; psoForm.WindowState = FormWindowState.Normal; psoForm.FormBorderStyle = FormBorderStyle.None; psoForm.pnlPSO.Width = wWidth; psoForm.pnlPSO.Height = wHeight; psoForm.Bounds = Screen.PrimaryScreen.Bounds; psoForm.PSOhWnd = wnd; WinAPI.SetWindowPos(wnd, IntPtr.Zero, 0, 0, 0, 0, (SWP.NOSIZE | SWP.SHOWWINDOW)); WinAPI.MoveWindow(wnd, 0, 0, wWidth, wHeight, true); WinAPI.SetParent(wnd, psoForm.pnlPSO.Handle); //WinAPI.ShowWindow(wnd, WindowShowStyle.ShowNormal); psoForm.Show(); psoForm.Activate(); WinAPI.SetForegroundWindow(wnd); } else { User32.SetWindowPos(wnd, IntPtr.Zero, startX, startY, desiredWidth, desiredHeight, 2); WinAPI.MoveWindow(wnd, startX, startY, desiredWidth, desiredHeight, true); User32.SendMessage(wnd, User32.WM_SETICON, User32.ICON_BIG, icon.Handle); } } Properties.Settings.Default.Save(); /* Make a thread to wait until the game exits to clean up. */ ThdArgs args = new ThdArgs(); args.psoProc = psoProc; args.key = k; args.value = value; Thread thd = new Thread(this.WaitThd); thd.Start(args); }
public static void LaunchChildProcess(string ChildProcName, out int pid) { IntPtr ppSessionInfo = IntPtr.Zero; UInt32 SessionCount = 0; string workingDir = Path.GetDirectoryName(ChildProcName); pid = 0; if (Kernel32.WTSEnumerateSessions( (IntPtr)Kernel32.WTS_CURRENT_SERVER_HANDLE, // Current RD Session Host Server handle would be zero. 0, // This reserved parameter must be zero. 1, // The version of the enumeration request must be 1. ref ppSessionInfo, // This would point to an array of session info. ref SessionCount // This would indicate the length of the above array. )) { for (int nCount = 0; nCount < SessionCount; nCount++) { // Extract each session info and check if it is the // "Active Session" of the current logged-on user. Kernel32.WTS_SESSION_INFO tSessionInfo = (Kernel32.WTS_SESSION_INFO)Marshal.PtrToStructure( ppSessionInfo + nCount * Marshal.SizeOf(typeof(Kernel32.WTS_SESSION_INFO)), typeof(Kernel32.WTS_SESSION_INFO) ); if (Kernel32.WTS_CONNECTSTATE_CLASS.WTSActive == tSessionInfo.State) { IntPtr hToken = IntPtr.Zero; if (Kernel32.WTSQueryUserToken(tSessionInfo.SessionID, out hToken)) { // Launch the child process interactively // with the token of the logged-on user. Kernel32.PROCESS_INFORMATION tProcessInfo; Kernel32.STARTUPINFO tStartUpInfo = new Kernel32.STARTUPINFO(); tStartUpInfo.cb = Marshal.SizeOf(typeof(Kernel32.STARTUPINFO)); bool ChildProcStarted = Kernel32.CreateProcessAsUser( hToken, // Token of the logged-on user. ChildProcName, // Name of the process to be started. null, // Any command line arguments to be passed. IntPtr.Zero, // Default Process' attributes. IntPtr.Zero, // Default Thread's attributes. false, // Does NOT inherit parent's handles. 0, // No any specific creation flag. null, // Default environment path. workingDir, // Working directory. ref tStartUpInfo, // Process Startup Info. out tProcessInfo // Process information to be returned. ); if (ChildProcStarted) { // The child process creation is successful! pid = tProcessInfo.dwProcessId; // If the child process is created, it can be controlled via the out // param "tProcessInfo". For now, as we don't want to do any thing // with the child process, closing the child process' handles // to prevent the handle leak. Kernel32.CloseHandle(tProcessInfo.hThread); Kernel32.CloseHandle(tProcessInfo.hProcess); } else { // CreateProcessAsUser failed! log("LaunchChildProcess: CreateProcessAsUser: {0} failed", ChildProcName); } // Whether child process was created or not, close the token handle // and break the loop as processing for current active user has been done. Kernel32.CloseHandle(hToken); break; } else { // WTSQueryUserToken failed! log("LaunchChildProcess: {0} WTSQueryUserToken failed", ChildProcName); } } else { // This Session is not active! log("LaunchChildProcess: {0} Session not active", ChildProcName); } } // Free the memory allocated for the session info array. Kernel32.WTSFreeMemory(ppSessionInfo); } else { // WTSEnumerateSessions failed! log("LaunchChildProcess: {0} Session not active", ChildProcName); } }