diff --git a/Star Ruler 2.exe b/Star Ruler 2.exe index 3d6eba2b..7e3bc44e 100644 Binary files a/Star Ruler 2.exe and b/Star Ruler 2.exe differ diff --git a/StarRuler2.sh b/StarRuler2.sh index a94968bc..56bf980e 100755 --- a/StarRuler2.sh +++ b/StarRuler2.sh @@ -1,4 +1,6 @@ #!/bin/bash +set -eo pipefail + #Figure out where the script is located if [[ -L "$0" ]]; then script_loc="$(readlink "$0")" @@ -7,15 +9,25 @@ else fi cd "$(dirname "$script_loc")" +bin_folder="bin" +args=() +for arg in "$@"; do + if [ "$arg" = "--legacy" ]; then + bin_folder="bin_legacy" + else + args+=("$arg") + fi +done + #Execute the right binary for this architecture -if [ `uname` == "Darwin" ]; then - chmod +x ./bin/osx64/StarRuler2.bin - DYLD_LIBRARY_PATH="./bin/osx64/:$DYLD_LIBRARY_PATH" exec ./bin/osx64/StarRuler2.bin $@ -elif [ `uname -m` = "x86_64" ]; then - chmod +x ./bin/lin64/StarRuler2.bin - LD_LIBRARY_PATH="./bin/lin64/:$LD_LIBRARY_PATH" exec ./bin/lin64/StarRuler2.bin $@ +if [ "$(uname)" = "Darwin" ]; then + chmod +x ./$bin_folder/osx64/StarRuler2.bin + DYLD_LIBRARY_PATH="./$bin_folder/osx64/:$DYLD_LIBRARY_PATH" exec ./$bin_folder/osx64/StarRuler2.bin "${args[@]}" +elif [ "$(uname -m)" = "x86_64" ]; then + chmod +x ./$bin_folder/lin64/StarRuler2.bin + LD_LIBRARY_PATH="./$bin_folder/lin64/:$LD_LIBRARY_PATH" exec ./$bin_folder/lin64/StarRuler2.bin "${args[@]}" else - chmod +x ./bin/lin32/StarRuler2.bin - LD_LIBRARY_PATH="./bin/lin32/:$LD_LIBRARY_PATH" exec ./bin/lin32/StarRuler2.bin $@ + chmod +x ./$bin_folder/lin32/StarRuler2.bin + LD_LIBRARY_PATH="./$bin_folder/lin32/:$LD_LIBRARY_PATH" exec ./$bin_folder/lin32/StarRuler2.bin "${args[@]}" fi; # vim: set ff=unix: diff --git a/source/loader/SR2Loader/HybridCRT.props b/source/loader/SR2Loader/HybridCRT.props new file mode 100644 index 00000000..3b898d1a --- /dev/null +++ b/source/loader/SR2Loader/HybridCRT.props @@ -0,0 +1,38 @@ + + + + + + $(Configuration) + + + + + + MultiThreadedDebug + + + + %(IgnoreSpecificDefaultLibraries);libucrtd.lib + %(AdditionalOptions) /defaultlib:ucrtd.lib + + + + + + MultiThreaded + + + + %(IgnoreSpecificDefaultLibraries);libucrt.lib + %(AdditionalOptions) /defaultlib:ucrt.lib + + + + diff --git a/source/loader/SR2Loader/SR2Loader.vcxproj b/source/loader/SR2Loader/SR2Loader.vcxproj index bf21c97e..55de656f 100644 --- a/source/loader/SR2Loader/SR2Loader.vcxproj +++ b/source/loader/SR2Loader/SR2Loader.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -11,15 +11,17 @@ - Application - MultiByte - v142 + 17.0 + Win32Proj {93B31A9C-7169-47CA-80DB-CF3BB398291E} - SR2Loader + Application + v143 + Unicode 10.0 + true false @@ -28,6 +30,9 @@ + + + @@ -37,14 +42,15 @@ $(SolutionDir)\..\..\..\ - - Star Ruler 2 Level3 - Disabled + true + _DEBUG;%(PreprocessorDefinitions) + true + stdc17 true @@ -53,23 +59,19 @@ Level3 - MinSpace true - true + MinSpace Size - MultiThreaded + true + true + NDEBUG;%(PreprocessorDefinitions) + true stdc17 - false - false - false - None - false true true - Windows - mainCRTStartup + true @@ -84,6 +86,9 @@ + + + diff --git a/source/loader/SR2Loader/SR2Loader.vcxproj.filters b/source/loader/SR2Loader/SR2Loader.vcxproj.filters index 07f91028..fa0eacc7 100644 --- a/source/loader/SR2Loader/SR2Loader.vcxproj.filters +++ b/source/loader/SR2Loader/SR2Loader.vcxproj.filters @@ -16,6 +16,7 @@ + diff --git a/source/loader/main.c b/source/loader/main.c index a6f9263e..c25c1350 100644 --- a/source/loader/main.c +++ b/source/loader/main.c @@ -1,43 +1,80 @@ -#include - -static inline __forceinline __declspec(allocator) wchar_t* wstrdup(const wchar_t *_String) { - size_t i = 0; - while (_String[i] != 0) - i++; - wchar_t* ret = (wchar_t *)HeapAlloc(GetProcessHeap(), 0, sizeof(wchar_t) * (i + 1)); - wsprintfW(ret, L"%s", _String); - return ret; -} +#include +#include +#include -DWORD __stdcall mainCRTStartup(LPVOID p) { - //Create command, passing all of our arguments - LPWSTR cmdline = GetCommandLineW(); - wchar_t search = ' '; - if (cmdline[0] == '"') { - search = '"'; - cmdline++; - } - while (cmdline[0] != 0) { - cmdline++; - if (cmdline[0] == search) { - cmdline++; - break; +int wmain(int argc, wchar_t* argv[]) { + + STARTUPINFOW startup = {}; + startup.cb = sizeof(startup); + + PROCESS_INFORMATION process = {}; + + wchar_t* path = L"bin\\win64\\Star Ruler 2.exe"; + + size_t size = 0; + for (int i = 0; i < argc; i++) { + if (wcscmp(argv[i], L"--legacy") == 0) { + path = L"bin_legacy\\win64\\Star Ruler 2.exe"; + } + else { + // worst-case estimate of expected escaped argument size, two output characters for every input character + // (to handle quotes and backslashes), one separator space and a leading and trailing quote + // first argument has no space, use it for the null terminator + size += wcslen(argv[i]) * 2 + 3; } } - while (cmdline[0] == ' ') { - cmdline++; - } - STARTUPINFOW startup; - SecureZeroMemory(&startup, sizeof(startup)); - startup.cb = sizeof(startup); + //Create command, passing all of our arguments + + wchar_t* cmdline = malloc(size * sizeof(wchar_t)); + wchar_t* cur = cmdline; - PROCESS_INFORMATION process; - SecureZeroMemory(&process, sizeof(process)); + for (int i = 0; i < argc; i++) { + if (wcscmp(argv[i], L"--legacy") == 0) { + continue; + } + + for (wchar_t* arg = argv[i]; *arg != L'\0'; arg++) { + if (i != 0) { + *cur++ = L' '; + } + *cur++ = L'"'; + switch (*arg) { + case L'"': + *cur++ = L'\\'; + *cur++ = L'"'; + arg++; + break; + case L'\\': + int backslashes = 0; + do { + backslashes++; + } while (arg[backslashes] == L'\\'); + if (arg[backslashes] != 0 && arg[backslashes] != L'"') { + for (int j = 0; j < backslashes; j++) { + *cur++ = L'\\'; + } + } + else { + for (int j = 0; j < backslashes; j++) { + *cur++ = L'\\'; + *cur++ = L'\\'; + } + } + arg += backslashes; + break; + default: + *cur++ = *arg++; + } + *cur++ = L'"'; + } + } + *cur = L'\0'; - if(CreateProcessW(L"bin\\win64\\Star Ruler 2.exe", wstrdup(cmdline), NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &startup, &process) != FALSE) { + if (CreateProcessW(path, cmdline, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &startup, &process) != FALSE) { CloseHandle(process.hProcess); CloseHandle(process.hThread); } + free(cmdline); return 0; } diff --git a/source/msvc/Star Ruler 2/Star Ruler 2.sln b/source/msvc/Star Ruler 2/Star Ruler 2.sln index b2ece365..e9b77e27 100644 --- a/source/msvc/Star Ruler 2/Star Ruler 2.sln +++ b/source/msvc/Star Ruler 2/Star Ruler 2.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.32407.337 +# Visual Studio Version 17 +VisualStudioVersion = 17.12.35527.113 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Star Ruler 2", "Star Ruler 2.vcxproj", "{50CA85BE-6640-4824-8CB6-9D65F77518F6}" ProjectSection(ProjectDependencies) = postProject @@ -89,7 +89,9 @@ Global {A1E1942C-36D2-4824-9ECB-B4727543E958}.Non-Steam Release|x64.ActiveCfg = Release|x64 {A1E1942C-36D2-4824-9ECB-B4727543E958}.Non-Steam Release|x64.Build.0 = Release|x64 {93B31A9C-7169-47CA-80DB-CF3BB398291E}.Debug|x64.ActiveCfg = Debug|x64 + {93B31A9C-7169-47CA-80DB-CF3BB398291E}.Debug|x64.Build.0 = Debug|x64 {93B31A9C-7169-47CA-80DB-CF3BB398291E}.Non-Steam Release|x64.ActiveCfg = Release|x64 + {93B31A9C-7169-47CA-80DB-CF3BB398291E}.Non-Steam Release|x64.Build.0 = Release|x64 {ABEA2C04-40F0-4D98-9191-A026E1D0DF07}.Debug|x64.ActiveCfg = Debug|x64 {ABEA2C04-40F0-4D98-9191-A026E1D0DF07}.Debug|x64.Build.0 = Debug|x64 {ABEA2C04-40F0-4D98-9191-A026E1D0DF07}.Non-Steam Release|x64.ActiveCfg = Release|x64