Example #1
0
        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);
        }
Example #2
0
        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
            });
        }
Example #3
0
        /// <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);
        }
Example #4
0
        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);
            }
        }