diff --git a/src/common/win32/InlineFunc.cpp b/src/common/win32/InlineFunc.cpp index 9f0f784da..c560f3c20 100644 --- a/src/common/win32/InlineFunc.cpp +++ b/src/common/win32/InlineFunc.cpp @@ -47,13 +47,13 @@ bool CxbxIsElevated() { return fRet; } -bool CxbxExec(bool useDebugger, HANDLE* hProcess, bool requestHandleProcess) { +std::optional CxbxExec(bool useDebugger, HANDLE* hProcess, bool requestHandleProcess) { STARTUPINFO startupInfo = { 0 }; PROCESS_INFORMATION processInfo = { 0 }; std::string szProcArgsBuffer; if (!cli_config::GenCMD(szProcArgsBuffer)) { - return false; + return std::make_optional("Failed to retrieve the command line arguments to launch the new emulation process"); } // TODO: Set a configuration variable for this. For now it will be within the same folder as Cxbx.exe @@ -69,7 +69,7 @@ bool CxbxExec(bool useDebugger, HANDLE* hProcess, bool requestHandleProcess) { cpu load cycles to get the task done. */ if (CreateProcess(nullptr, const_cast(szProcArgsBuffer.c_str()), nullptr, nullptr, false, 0, nullptr, nullptr, &startupInfo, &processInfo) == 0) { - return 0; + return std::make_optional("Failed to create the new emulation process (another instance of cxbxr is already running?)"); } CloseHandle(processInfo.hThread); @@ -80,7 +80,7 @@ bool CxbxExec(bool useDebugger, HANDLE* hProcess, bool requestHandleProcess) { CloseHandle(processInfo.hProcess); } - return 1; + return std::nullopt; } #endif diff --git a/src/core/kernel/init/CxbxKrnl.h b/src/core/kernel/init/CxbxKrnl.h index d2f14a74e..7d01e4e6a 100644 --- a/src/core/kernel/init/CxbxKrnl.h +++ b/src/core/kernel/init/CxbxKrnl.h @@ -30,6 +30,7 @@ #include "common/ReserveAddressRanges.h" #include "common\xbe\Xbe.h" #include "Logging.h" +#include #include #include @@ -188,8 +189,6 @@ void CxbxInitFilePaths(); bool CxbxLockFilePath(); void CxbxUnlockFilePath(); -bool CxbxExec(bool useDebugger, HANDLE* hProcess, bool requestHandleProcess); - bool CxbxIsElevated(); /*! kernel thunk table */ @@ -229,6 +228,8 @@ extern char szFilePath_Xbe[xbox::max_path*2]; } #endif +std::optional CxbxExec(bool useDebugger, HANDLE *hProcess, bool requestHandleProcess); + // Returns the last Win32 error, in string format. Returns an empty string if there is no error. extern std::string CxbxGetLastErrorString(char * lpszFunction); diff --git a/src/core/kernel/support/EmuFile.cpp b/src/core/kernel/support/EmuFile.cpp index b7b7a54ec..0ca8cb825 100644 --- a/src/core/kernel/support/EmuFile.cpp +++ b/src/core/kernel/support/EmuFile.cpp @@ -1330,9 +1330,9 @@ void CxbxLaunchNewXbe(const std::string& XbePath) { } else { - if (!CxbxExec(false, nullptr, false)) + if (const auto &err = CxbxExec(false, nullptr, false)) { - CxbxKrnlCleanup("Could not launch %s", XbePath.c_str()); + CxbxKrnlCleanup("Could not launch %s\n\nThe reason was: %s", XbePath.c_str(), err->c_str()); } } diff --git a/src/gui/WndMain.cpp b/src/gui/WndMain.cpp index 550d18746..b1146b69f 100644 --- a/src/gui/WndMain.cpp +++ b/src/gui/WndMain.cpp @@ -2261,7 +2261,7 @@ void WndMain::StartEmulation(HWND hwndParent, DebuggerState LocalDebuggerState / // Check then close existing debugger monitor. DebuggerMonitorClose(); - if (!CxbxExec(true, &m_hDebuggerProc, true)) { + if (CxbxExec(true, &m_hDebuggerProc, true)) { PopupError(m_hwnd, "Failed to start emulation with the debugger.\n\nYou will need to build CxbxDebugger manually."); printf("WndMain: %s debugger shell failed.\n", m_Xbe->m_szAsciiTitle); @@ -2274,8 +2274,8 @@ void WndMain::StartEmulation(HWND hwndParent, DebuggerState LocalDebuggerState / } else { - if (!CxbxExec(false, nullptr, false)) { - PopupError(m_hwnd, "Emulation failed.\n\n If this message repeats, the Xbe is not supported."); + if (const auto &err = CxbxExec(false, nullptr, false)) { + PopupError(m_hwnd, err->c_str()); printf("WndMain: %s shell failed.\n", m_Xbe->m_szAsciiTitle); }