From 5d7a1a7685dec2d2a0fefb69d0896787acf2ef42 Mon Sep 17 00:00:00 2001 From: rjkiv <76180273+rjkiv@users.noreply.github.com> Date: Mon, 4 Aug 2025 12:02:28 -0700 Subject: [PATCH] more cl funcs (segfaulting) --- dll/msvcrt.cpp | 186 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 143 insertions(+), 43 deletions(-) diff --git a/dll/msvcrt.cpp b/dll/msvcrt.cpp index e5edd01..731605b 100644 --- a/dll/msvcrt.cpp +++ b/dll/msvcrt.cpp @@ -104,19 +104,19 @@ namespace msvcrt { (*wargv)[argc] = nullptr; // sanity check - for (int i = 0; i < argc; i++) { - wchar_t* warg = (*wargv)[i]; - size_t len = std::wcstombs(nullptr, warg, 0); - if (len != (size_t)-1) { - char* converted = new char[len + 1]; - std::wcstombs(converted, warg, len + 1); - DEBUG_LOG("Input argv[%d]: %s\n", i, argv[i]); - DEBUG_LOG("Output wargv[%d]: %s\n", i, converted); - delete[] converted; - } else { - DEBUG_LOG("Bad wide arg conversion for %d!\n", i); - } - } + // for (int i = 0; i < argc; i++) { + // wchar_t* warg = (*wargv)[i]; + // size_t len = std::wcstombs(nullptr, warg, 0); + // if (len != (size_t)-1) { + // char* converted = new char[len + 1]; + // std::wcstombs(converted, warg, len + 1); + // DEBUG_LOG("Input argv[%d]: %s\n", i, argv[i]); + // DEBUG_LOG("Output wargv[%d]: %s\n", i, converted); + // delete[] converted; + // } else { + // DEBUG_LOG("Bad wide arg conversion for %d!\n", i); + // } + // } } if(wenv){ @@ -141,19 +141,19 @@ namespace msvcrt { (*wenv)[count] = nullptr; // sanity check - for (int i = 0; i < count; i++) { - wchar_t* warg = (*wenv)[i]; - size_t len = std::wcstombs(nullptr, warg, 0); - if (len != (size_t)-1) { - char* converted = new char[len + 1]; - std::wcstombs(converted, warg, len + 1); - DEBUG_LOG("Input env[%d]: %s\n", i, env[i]); - DEBUG_LOG("Output wenv[%d]: %s\n", i, converted); - delete[] converted; - } else { - DEBUG_LOG("Bad wide arg conversion for %d!\n", i); - } - } + // for (int i = 0; i < count; i++) { + // wchar_t* warg = (*wenv)[i]; + // size_t len = std::wcstombs(nullptr, warg, 0); + // if (len != (size_t)-1) { + // char* converted = new char[len + 1]; + // std::wcstombs(converted, warg, len + 1); + // DEBUG_LOG("Input env[%d]: %s\n", i, env[i]); + // DEBUG_LOG("Output wenv[%d]: %s\n", i, converted); + // delete[] converted; + // } else { + // DEBUG_LOG("Bad wide arg conversion for %d!\n", i); + // } + // } __winitenv = *wenv; } @@ -166,28 +166,29 @@ namespace msvcrt { } int WIN_ENTRY _wdupenv_s(wchar_t **buffer, size_t *numberOfElements, const wchar_t *varname){ - // just gonna stub all this out for now - // if it turns out we need this, troubleshoot wscspy + if(!buffer || !varname) return -1; + if(numberOfElements) *numberOfElements = 0; - // if(!buffer || !varname) return -1; - // if(numberOfElements) *numberOfElements = 0; + size_t varnamelen = wcslen(varname); - // size_t varnamelen = wcslen(varname); + for(wchar_t** env = __winitenv; env && *env; ++env){ + wchar_t* cur = *env; + if(wcsncmp(cur, varname, varnamelen) == 0 && cur[varnamelen] == L'='){ + wchar_t* value = cur + varnamelen + 1; + size_t value_len = wcslen(value); - // for(wchar_t** env = __winitenv; env && *env; ++env){ - // wchar_t* cur = *env; - // if(wcsncmp(cur, varname, varnamelen) == 0 && cur[varnamelen] == L'='){ - // wchar_t* value = cur + varnamelen + 1; - // size_t value_len = wcslen(value); + *buffer = (wchar_t*)malloc((value_len + 1) * sizeof(wchar_t)); + if(!*buffer) return -1; - // *buffer = (wchar_t*)malloc((value_len + 1) * sizeof(wchar_t)); - // if(!*buffer) return -1; + for(int i = 0; i <= value_len; i++){ + (*buffer)[i] = value[i]; + } - // wscspy(*buffer, value); // y u no work - // if(numberOfElements) *numberOfElements = value_len + 1; - // return 0; - // } - // } + // wscspy(*buffer, value); // y u no work + if(numberOfElements) *numberOfElements = value_len + 1; + return 0; + } + } return 0; } @@ -196,6 +197,101 @@ namespace msvcrt { std::free(ptr); } + int WIN_ENTRY _get_wpgmptr(wchar_t** pValue){ + DEBUG_LOG("STUB: _get_wpgmptr(%p)\n", pValue); + return 0; + } + + int WIN_ENTRY _wsplitpath_s(const wchar_t * path, wchar_t * drive, size_t driveNumberOfElements, wchar_t *dir, size_t dirNumberOfElements, + wchar_t * fname, size_t nameNumberOfElements, wchar_t * ext, size_t extNumberOfElements){ + + if(!path){ + DEBUG_LOG("no path\n"); + return -1; + } + + { + size_t wlen = std::wcstombs(nullptr, path, 0); + if(wlen != (size_t)-1){ + char* converted = new char[wlen + 1]; + std::wcstombs(converted, path, wlen + 1); + DEBUG_LOG("Path: %s\n", converted); + delete [] converted; + } + else { + DEBUG_LOG("Bad wide arg conversion for path!\n"); + } + } + + if(drive && driveNumberOfElements) drive[0] = L'\0'; + if(dir && dirNumberOfElements) dir[0] = L'\0'; + if(fname && nameNumberOfElements) fname[0] = L'\0'; + if(ext && extNumberOfElements) ext[0] = L'\0'; + + const wchar_t *slash = wcsrchr(path, L'/'); + const wchar_t *dot = wcsrchr(path, L'.'); + const wchar_t *filename_start = slash ? slash + 1 : path; + if (dot && dot < filename_start) dot = nullptr; + + if (dir && dirNumberOfElements && slash) { + size_t dir_len = slash - path + 1; + if (dir_len >= dirNumberOfElements) return -1; + wcsncpy(dir, path, dir_len); + dir[dir_len] = L'\0'; + } + + if (fname && nameNumberOfElements) { + size_t fname_len = dot ? (size_t)(dot - filename_start) : wcslen(filename_start); + if (fname_len >= nameNumberOfElements) return -1; + wcsncpy(fname, filename_start, fname_len); + fname[fname_len] = L'\0'; + } + + if (ext && extNumberOfElements && dot) { + size_t ext_len = wcslen(dot); + if (ext_len >= extNumberOfElements) return -1; + wcsncpy(ext, dot, ext_len); + ext[ext_len] = L'\0'; + } + + if (drive && driveNumberOfElements && path[1] == L':' && path[2] == L'/') { + if (driveNumberOfElements < 3) return -1; + drive[0] = path[0]; + drive[1] = L':'; + drive[2] = L'\0'; + } + + return 0; + } + + int WIN_ENTRY wcscat_s(wchar_t *strDestination, size_t numberOfElements, const wchar_t *strSource){ + if(!strDestination || !strSource || numberOfElements == 0) return -1; + + size_t dest_len = wcslen(strDestination); + size_t src_len = wcslen(strSource); + + if(dest_len + src_len >= numberOfElements) return -1; + + for(int i = 0; i <= src_len; i++){ + strDestination[dest_len + i] = strSource[i]; + } + + return 0; + } + + wchar_t* WIN_ENTRY _wcsdup(const wchar_t *strSource){ + if(!strSource) return nullptr; + size_t strLen = wcslen(strSource); + + wchar_t* dup = (wchar_t*)malloc((strLen + 1) * sizeof(wchar_t)); + + for(int i = 0; i <= strLen; i++){ + dup[i] = strSource[i]; + } + + return dup; + } + } @@ -214,6 +310,10 @@ static void *resolveByName(const char *name) { if (strcmp(name, "setlocale") == 0) return (void*)msvcrt::setlocale; if (strcmp(name, "_wdupenv_s") == 0) return (void*)msvcrt::_wdupenv_s; if (strcmp(name, "free") == 0) return (void*)msvcrt::free; + if (strcmp(name, "_get_wpgmptr") == 0) return (void*)msvcrt::_get_wpgmptr; + if (strcmp(name, "_wsplitpath_s") == 0) return (void*)msvcrt::_wsplitpath_s; + if (strcmp(name, "wcscat_s") == 0) return (void*)msvcrt::wcscat_s; + if (strcmp(name, "_wcsdup") == 0) return (void*)msvcrt::_wcsdup; return nullptr; }