From ff6f40d953b83c7cf82ed2abb06ca669c3633142 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Fri, 14 Oct 2022 19:45:41 +1100 Subject: [PATCH] Windows: Change working directory to executable directory if working directory is system folder (Thanks LegoSpaceGuy) This can happen when e.g. launching the game via clicking on a search result in Windows 10 start menu This results in the game being launched directly via shell process, which defaults to a working directory of system32 folder See https://social.msdn.microsoft.com/Forums/sqlserver/en-US/ba590643-528b-44a5-b379-8a1e3e4250d0/windows-launches-my-app-in-system32-on-windows-startup for more details --- src/Platform_WinApi.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/Platform_WinApi.c b/src/Platform_WinApi.c index ea2e94efa..a7f929721 100644 --- a/src/Platform_WinApi.c +++ b/src/Platform_WinApi.c @@ -930,5 +930,42 @@ int Platform_GetCommandLineArgs(int argc, STRING_REF char** argv, cc_string* arg return i; } -cc_result Platform_SetDefaultCurrentDirectory(int argc, char** argv) { return 0; } +/* Detects if the game is running in Windows directory */ +/* This happens when ClassiCube is launched directly from shell process */ +/* (e.g. via clicking a search result in Windows 10 start menu) */ +static cc_bool IsProblematicWorkingDirectory(void) { + cc_string curDir, winDir; + char curPath[2048] = { 0 }; + char winPath[2048] = { 0 }; + + GetCurrentDirectoryA(2048, curPath); + GetSystemDirectoryA(winPath, 2048); + + curDir = String_FromReadonly(curPath); + winDir = String_FromReadonly(winPath); + + if (String_Equals(&curDir, &winDir)) { + Platform_LogConst("Working directory is System32! Changing to executable directory.."); + return true; + } + return false; +} + +cc_result Platform_SetDefaultCurrentDirectory(int argc, char** argv) { + WCHAR path[NATIVE_STR_LEN + 1]; + int i, len; + cc_result res; + if (!IsProblematicWorkingDirectory()) return 0; + + res = Process_RawGetExePath(path, &len); + if (res) return res; + + /* Get rid of filename at end of directory */ + for (i = len - 1; i >= 0; i--, len--) { + if (path[i] == '/' || path[i] == '\\') break; + } + + path[len] = '\0'; + return SetCurrentDirectoryW(path) ? 0 : GetLastError(); +} #endif