diff --git a/renderdoc/android/android.cpp b/renderdoc/android/android.cpp index 778180edf..c74da6dff 100644 --- a/renderdoc/android/android.cpp +++ b/renderdoc/android/android.cpp @@ -187,7 +187,7 @@ ExecuteResult StartAndroidPackageForCapture(const char *host, const char *packag ret.status = ReplayStatus::UnknownError; ret.ident = RenderDoc_FirstTargetControlPort + RenderDoc_AndroidPortOffset * (index + 1); - string packageName = basename(string(package)); // Remove leading '/' if any + string packageName = get_basename(string(package)); // Remove leading '/' if any // adb shell cmd package resolve-activity -c android.intent.category.LAUNCHER com.jake.cube1 string activityName = GetDefaultActivityForPackage(deviceID, packageName); @@ -394,7 +394,7 @@ ReplayStatus InstallRenderDocServer(const std::string &deviceID) // Check known paths for RenderDoc server std::string libPath; FileIO::GetLibraryFilename(libPath); - std::string libDir = dirname(FileIO::GetFullPathname(libPath)); + std::string libDir = get_dirname(FileIO::GetFullPathname(libPath)); std::vector paths; diff --git a/renderdoc/android/android_patch.cpp b/renderdoc/android/android_patch.cpp index cae12410b..0bc0a90ce 100644 --- a/renderdoc/android/android_patch.cpp +++ b/renderdoc/android/android_patch.cpp @@ -262,7 +262,7 @@ bool DebugSignAPK(const string &apk, const string &workDir) // otherwise, find and invoke java on the .jar std::string java = getToolPath(ToolDir::Java, "java", false); - std::string signerdir = dirname(FileIO::GetFullPathname(apksigner)); + std::string signerdir = get_dirname(FileIO::GetFullPathname(apksigner)); std::string javaargs; javaargs += " \"-Djava.ext.dirs=" + signerdir + "\""; @@ -533,7 +533,7 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_CheckAndroidPackage(const c // Reset the flags each time we check *flags = AndroidFlags::NoFlags; - if(Android::IsDebuggable(deviceID, basename(std::string(packageName)))) + if(Android::IsDebuggable(deviceID, get_basename(std::string(packageName)))) { *flags |= AndroidFlags::Debuggable; } @@ -555,7 +555,7 @@ extern "C" RENDERDOC_API AndroidFlags RENDERDOC_CC RENDERDOC_MakeDebuggablePacka const char *hostname, const char *packageName, RENDERDOC_ProgressCallback progress) { Process::ProcessResult result = {}; - std::string package(basename(std::string(packageName))); + std::string package(get_basename(std::string(packageName))); int index = 0; std::string deviceID; diff --git a/renderdoc/android/android_tools.cpp b/renderdoc/android/android_tools.cpp index 4ce21eb20..c6eeb6bd3 100644 --- a/renderdoc/android/android_tools.cpp +++ b/renderdoc/android/android_tools.cpp @@ -267,7 +267,7 @@ std::string getToolPath(ToolDir subdir, const std::string &toolname, bool checkE { std::string libpath; FileIO::GetLibraryFilename(libpath); - std::string libdir = dirname(FileIO::GetFullPathname(libpath)); + std::string libdir = get_dirname(FileIO::GetFullPathname(libpath)); toolpath = libdir + "/plugins/android/" + toolname; if(toolExists(toolpath)) @@ -329,7 +329,7 @@ void initAdb() std::string adb = getToolPath(ToolDir::PlatformTools, "adb", false); std::string workdir = "."; if(adb.find('/') != std::string::npos || adb.find('\\') != std::string::npos) - workdir = dirname(adb); + workdir = get_dirname(adb); Process::LaunchProcess(adb.c_str(), workdir.c_str(), "start-server", true); } diff --git a/renderdoc/common/common.cpp b/renderdoc/common/common.cpp index e63c0cb1a..2065e7432 100644 --- a/renderdoc/common/common.cpp +++ b/renderdoc/common/common.cpp @@ -406,7 +406,7 @@ void rdclog_direct(time_t utcTime, uint32_t pid, LogType type, const char *proje char location[64] = {0}; #if ENABLED(INCLUDE_LOCATION_IN_LOG) string loc; - loc = basename(string(file)); + loc = get_basename(string(file)); StringFormat::snprintf(location, 63, "% 20s(%4d) - ", loc.c_str(), line); #endif diff --git a/renderdoc/core/plugins.cpp b/renderdoc/core/plugins.cpp index 6672fb95a..f721b49ff 100644 --- a/renderdoc/core/plugins.cpp +++ b/renderdoc/core/plugins.cpp @@ -32,7 +32,7 @@ std::string LocatePluginFile(const std::string &path, const std::string &fileNam std::string libpath; FileIO::GetLibraryFilename(libpath); - libpath = dirname(libpath); + libpath = get_dirname(libpath); std::vector paths; diff --git a/renderdoc/driver/ihv/amd/amd_isa.cpp b/renderdoc/driver/ihv/amd/amd_isa.cpp index ad173edb3..d764d5fcc 100644 --- a/renderdoc/driver/ihv/amd/amd_isa.cpp +++ b/renderdoc/driver/ihv/amd/amd_isa.cpp @@ -51,7 +51,7 @@ static bool IsSupported(ShaderEncoding encoding) std::string vc = LocatePluginFile(pluginPath, virtualcontext_name); Process::ProcessResult result = {}; - Process::LaunchProcess(vc.c_str(), dirname(vc).c_str(), "", true, &result); + Process::LaunchProcess(vc.c_str(), get_dirname(vc).c_str(), "", true, &result); // running with no parameters produces an error, so if there's no output something went wrong. if(result.strStdout.empty()) @@ -66,7 +66,7 @@ static bool IsSupported(ShaderEncoding encoding) std::string amdspv = LocatePluginFile(pluginPath, amdspv_name); Process::ProcessResult result = {}; - Process::LaunchProcess(amdspv.c_str(), dirname(amdspv).c_str(), "", true, &result); + Process::LaunchProcess(amdspv.c_str(), get_dirname(amdspv).c_str(), "", true, &result); // running with no parameters produces help text, so if there's no output something went wrong. if(result.strStdout.empty()) @@ -200,7 +200,7 @@ std::string DisassembleSPIRV(ShaderStage stage, const bytebuf &shaderBytes, cons std::string amdspv = LocatePluginFile(pluginPath, amdspv_name); Process::ProcessResult result = {}; - Process::LaunchProcess(amdspv.c_str(), dirname(amdspv).c_str(), cmdLine.c_str(), true, &result); + Process::LaunchProcess(amdspv.c_str(), get_dirname(amdspv).c_str(), cmdLine.c_str(), true, &result); if(result.strStdout.find("SUCCESS") == std::string::npos) { @@ -353,7 +353,7 @@ std::string DisassembleGLSL(ShaderStage stage, const bytebuf &shaderBytes, const std::string vc = LocatePluginFile(pluginPath, virtualcontext_name); Process::ProcessResult result = {}; - Process::LaunchProcess(vc.c_str(), dirname(vc).c_str(), cmdLine.c_str(), true, &result); + Process::LaunchProcess(vc.c_str(), get_dirname(vc).c_str(), cmdLine.c_str(), true, &result); if(result.retCode != 0 || result.strStdout.find("Error") != string::npos || result.strStdout.empty() || !FileIO::exists(outPath.c_str())) diff --git a/renderdoc/driver/shaders/dxbc/dxbc_compile.cpp b/renderdoc/driver/shaders/dxbc/dxbc_compile.cpp index 155f62a68..38dd4cbf2 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_compile.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_compile.cpp @@ -60,18 +60,12 @@ HMODULE GetD3DCompiler() // we'll have to loadlibrary the version that ships with // RenderDoc. - HMODULE hModule = NULL; - GetModuleHandleEx( - GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, - (LPCTSTR)&dllLocator, &hModule); - wchar_t curFile[512] = {0}; - GetModuleFileNameW(hModule, curFile, 511); + std::string dllFile; + FileIO::GetLibraryFilename(dllFile); - std::wstring path = std::wstring(curFile); - path = dirname(path); - std::wstring dll = path + L"/d3dcompiler_47.dll"; + std::string dll = get_dirname(dllFile) + "/d3dcompiler_47.dll"; - ret = LoadLibraryW(dll.c_str()); + ret = LoadLibraryW(StringFormat::UTF82Wide(dll.c_str()).c_str()); return ret; } \ No newline at end of file diff --git a/renderdoc/driver/vulkan/vk_apple.cpp b/renderdoc/driver/vulkan/vk_apple.cpp index 65d7a51c6..1bace56ee 100644 --- a/renderdoc/driver/vulkan/vk_apple.cpp +++ b/renderdoc/driver/vulkan/vk_apple.cpp @@ -104,7 +104,7 @@ void *LoadVulkanLibrary() // if not, we fall back to our embedded libvulkan and also force use of our embedded ICD. std::string libpath; FileIO::GetLibraryFilename(libpath); - libpath = dirname(libpath) + "/../plugins/MoltenVK/"; + libpath = get_dirname(libpath) + "/../plugins/MoltenVK/"; RDCLOG("Couldn't load global libvulkan.1.dylib, falling back to bundled MoltenVK in %s", libpath.c_str()); diff --git a/renderdoc/driver/vulkan/vk_posix.cpp b/renderdoc/driver/vulkan/vk_posix.cpp index 5749168e7..f03dd1ceb 100644 --- a/renderdoc/driver/vulkan/vk_posix.cpp +++ b/renderdoc/driver/vulkan/vk_posix.cpp @@ -313,7 +313,7 @@ string LayerRegistrationPath(LayerPath path) void MakeParentDirs(std::string file) { - std::string dir = dirname(file); + std::string dir = get_dirname(file); if(dir == "/" || dir.empty()) return; diff --git a/renderdoc/driver/vulkan/vk_win32.cpp b/renderdoc/driver/vulkan/vk_win32.cpp index 520fdd5ca..4e1e33c05 100644 --- a/renderdoc/driver/vulkan/vk_win32.cpp +++ b/renderdoc/driver/vulkan/vk_win32.cpp @@ -168,7 +168,7 @@ std::wstring GetJSONPath(bool wow6432) { std::string libPath; FileIO::GetLibraryFilename(libPath); - std::string jsonPath = dirname(FileIO::GetFullPathname(libPath)); + std::string jsonPath = get_dirname(FileIO::GetFullPathname(libPath)); std::wstring jsonWide = StringFormat::UTF82Wide(jsonPath); diff --git a/renderdoc/os/posix/apple/apple_hook.cpp b/renderdoc/os/posix/apple/apple_hook.cpp index b72e01258..db06f8a07 100644 --- a/renderdoc/os/posix/apple/apple_hook.cpp +++ b/renderdoc/os/posix/apple/apple_hook.cpp @@ -43,7 +43,7 @@ void *interposed_dlopen(const char *filename, int flag) { void *handle = dlopen(filename, flag); - std::string baseFilename = filename ? basename(std::string(filename)) : ""; + std::string baseFilename = filename ? get_basename(std::string(filename)) : ""; { SCOPED_LOCK(libLock); @@ -149,7 +149,7 @@ void LibraryHooks::RegisterLibraryHook(char const *name, FunctionLoadCallback cb SCOPED_LOCK(libLock); // we match by basename for library hooks - libraryHooks.insert(basename(std::string(name))); + libraryHooks.insert(get_basename(std::string(name))); if(cb) libraryCallbacks[name].push_back(cb); diff --git a/renderdoc/os/posix/linux/linux_hook.cpp b/renderdoc/os/posix/linux/linux_hook.cpp index c89d8bc1d..95c835198 100644 --- a/renderdoc/os/posix/linux/linux_hook.cpp +++ b/renderdoc/os/posix/linux/linux_hook.cpp @@ -144,7 +144,7 @@ void *intercept_dlopen(const char *filename, int flag, void *ret) if(flag & RTLD_DEEPBIND) plthook_lib(ret); - std::string base = basename(filename); + std::string base = get_basename(filename); for(auto it = libraryHooks.begin(); it != libraryHooks.end(); ++it) { diff --git a/renderdoc/os/posix/posix_process.cpp b/renderdoc/os/posix/posix_process.cpp index f28ee92d6..1bc55cefc 100644 --- a/renderdoc/os/posix/posix_process.cpp +++ b/renderdoc/os/posix/posix_process.cpp @@ -235,8 +235,8 @@ static const string GetAbsoluteAppPathFromName(const string &appName) if(appName.find("/") != string::npos) { char realpathBuffer[PATH_MAX]; - string appDir = dirname(appName); - string appBasename = basename(appName); + string appDir = get_dirname(appName); + string appBasename = get_basename(appName); realpath(appDir.c_str(), realpathBuffer); appPath = realpathBuffer; appPath += "/" + appBasename; @@ -419,13 +419,13 @@ static pid_t RunProcess(const char *app, const char *workingDir, const char *cmd return (pid_t)0; string appName = app; - string workDir = (workingDir && workingDir[0]) ? workingDir : dirname(appName); + string workDir = (workingDir && workingDir[0]) ? workingDir : get_dirname(appName); // handle funky apple .app folders that aren't actually executables #if ENABLED(RDOC_APPLE) if(appName.size() > 5 && appName.rfind(".app") == appName.size() - 4) { - std::string realAppName = appName + "/Contents/MacOS/" + basename(appName); + std::string realAppName = appName + "/Contents/MacOS/" + get_basename(appName); realAppName.erase(realAppName.size() - 4); if(FileIO::exists(realAppName.c_str())) @@ -714,7 +714,7 @@ ExecuteResult Process::LaunchAndInjectIntoProcess(const char *app, const char *w string binpath, libpath, ownlibpath; { FileIO::GetExecutableFilename(binpath); - binpath = dirname(binpath); + binpath = get_dirname(binpath); libpath = binpath + "/../lib"; // point to the right customiseable path @@ -728,7 +728,7 @@ ExecuteResult Process::LaunchAndInjectIntoProcess(const char *app, const char *w } FileIO::GetLibraryFilename(ownlibpath); - ownlibpath = dirname(ownlibpath); + ownlibpath = get_dirname(ownlibpath); std::string libfile = "librenderdoc" LIB_SUFFIX; diff --git a/renderdoc/os/posix/posix_stringio.cpp b/renderdoc/os/posix/posix_stringio.cpp index 3c265add5..27ad341fa 100644 --- a/renderdoc/os/posix/posix_stringio.cpp +++ b/renderdoc/os/posix/posix_stringio.cpp @@ -66,7 +66,7 @@ string GetTempFolderFilename() void CreateParentDirectory(const string &filename) { - string fn = dirname(filename); + string fn = get_dirname(filename); // want trailing slash so that we create all directories fn.push_back('/'); @@ -142,7 +142,7 @@ string GetReplayAppFilename() Dl_info info; dladdr((void *)&soLocator, &info); string path = info.dli_fname ? info.dli_fname : ""; - path = dirname(path); + path = get_dirname(path); string replay = path + "/qrenderdoc"; FILE *f = FileIO::fopen(replay.c_str(), "r"); diff --git a/renderdoc/os/win32/sys_win32_hooks.cpp b/renderdoc/os/win32/sys_win32_hooks.cpp index 57ed591f1..e9c7a6c55 100644 --- a/renderdoc/os/win32/sys_win32_hooks.cpp +++ b/renderdoc/os/win32/sys_win32_hooks.cpp @@ -268,21 +268,20 @@ private: // ourselves. if(lpApplicationName) { - wstring app = lpApplicationName; - app = strlower(app); + std::string app = strlower(StringFormat::Wide2UTF8(lpApplicationName)); - if(app.find(L"renderdoccmd.exe") != wstring::npos || app.find(L"qrenderdoc.exe") != string::npos) + if(app.find("renderdoccmd.exe") != std::string::npos || + app.find("qrenderdoc.exe") != std::string::npos) { inject = false; } } if(lpCommandLine) { - wstring cmd = lpCommandLine; - cmd = strlower(cmd); + std::string cmd = strlower(StringFormat::Wide2UTF8(lpCommandLine)); - if(cmd.find(L"renderdoccmd.exe") != wstring::npos || - cmd.find(L"qrenderdoc.exe") != wstring::npos) + if(cmd.find("renderdoccmd.exe") != std::string::npos || + cmd.find("qrenderdoc.exe") != std::string::npos) { inject = false; } diff --git a/renderdoc/os/win32/win32_callstack.cpp b/renderdoc/os/win32/win32_callstack.cpp index 82daa96eb..d0632a01a 100644 --- a/renderdoc/os/win32/win32_callstack.cpp +++ b/renderdoc/os/win32/win32_callstack.cpp @@ -44,9 +44,9 @@ struct AddrInfo { - wchar_t funcName[127]; - wchar_t fileName[127]; - unsigned long lineNum; + std::string funcName; + std::string fileName; + unsigned long lineNum = 0; }; typedef BOOL(CALLBACK *PSYM_ENUMMODULES_CALLBACK64W)(__in PCWSTR ModuleName, __in DWORD64 BaseOfDll, @@ -80,15 +80,15 @@ struct Module vector modules; -wstring GetSymSearchPath() +std::wstring GetSymSearchPath() { PWSTR appDataPath; SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_SIMPLE_IDLIST | KF_FLAG_DONT_UNEXPAND, NULL, &appDataPath); - wstring appdata = appDataPath; + std::wstring appdata = appDataPath; CoTaskMemFree(appDataPath); - wstring sympath = L".;"; + std::wstring sympath = L".;"; sympath += appdata; sympath += L"\\renderdoc\\symbols;SRV*"; sympath += appdata; @@ -97,48 +97,42 @@ wstring GetSymSearchPath() return sympath; } -wstring LookupModule(const wchar_t *modName, GUID guid, DWORD age) +std::string LookupModule(const std::string &modName, GUID guid, DWORD age) { - wstring ret = modName; + std::string ret = modName; - wchar_t *pdbName = &ret[0]; + std::string pdbName = get_basename(ret); - if(wcsrchr(pdbName, L'\\')) - pdbName = wcsrchr(pdbName, L'\\') + 1; - - if(wcsrchr(pdbName, L'/')) - pdbName = wcsrchr(pdbName, L'/') + 1; - - if(wcsstr(pdbName, L".pdb") == NULL && wcsstr(pdbName, L".PDB") == NULL) + if(pdbName.find(".pdb") == std::string::npos && pdbName.find(".PDB") == std::string::npos) { - wchar_t *ext = wcsrchr(pdbName, L'.'); + size_t offs = pdbName.find_last_of('.'); - if(ext) + if(offs != std::string::npos) { - ext[1] = L'p'; - ext[2] = L'd'; - ext[3] = L'b'; + pdbName.erase(offs + 1); + pdbName += "pdb"; } } if(dynSymFindFileInPathW != NULL) { - wstring sympath = GetSymSearchPath(); + std::wstring sympath = GetSymSearchPath(); wchar_t path[MAX_PATH + 1] = {0}; - BOOL found = dynSymFindFileInPathW(GetCurrentProcess(), sympath.c_str(), pdbName, &guid, age, 0, + BOOL found = dynSymFindFileInPathW(GetCurrentProcess(), sympath.c_str(), + StringFormat::UTF82Wide(pdbName).c_str(), &guid, age, 0, SSRVOPT_GUIDPTR, path, NULL, NULL); DWORD err = GetLastError(); (void)err; // for debugging only if(found == TRUE && path[0] != 0) - ret = path; + ret = StringFormat::Wide2UTF8(path); } return ret; } -wstring msdiapath = L"msdia140.dll"; +std::wstring msdiapath = L"msdia140.dll"; HRESULT MakeDiaDataSource(IDiaDataSource **source) { @@ -153,7 +147,7 @@ HRESULT MakeDiaDataSource(IDiaDataSource **source) return hr; // if not registered, try loading the DLL from the given path - HMODULE mod = LoadLibrary((wchar_t *)msdiapath.c_str()); + HMODULE mod = LoadLibraryW(msdiapath.c_str()); if(mod == NULL) { @@ -193,7 +187,7 @@ HRESULT MakeDiaDataSource(IDiaDataSource **source) return S_OK; } -uint32_t GetModule(const wchar_t *pdbName, GUID guid, DWORD age) +uint32_t GetModule(const std::wstring &pdbName, GUID guid, DWORD age) { Module m(NULL, NULL); @@ -207,11 +201,11 @@ uint32_t GetModule(const wchar_t *pdbName, GUID guid, DWORD age) // check this pdb is the one we expected from our chunk if(guid.Data1 == 0 && guid.Data2 == 0) { - hr = m.pSource->loadDataFromPdb(pdbName); + hr = m.pSource->loadDataFromPdb(pdbName.c_str()); } else { - hr = m.pSource->loadAndValidateDataFromPdb(pdbName, &guid, 0, age); + hr = m.pSource->loadAndValidateDataFromPdb(pdbName.c_str(), &guid, 0, age); } if(SUCCEEDED(hr)) @@ -307,19 +301,19 @@ AddrInfo GetAddr(uint32_t module, uint64_t addr) return ret; } - wcsncpy_s(ret.funcName, file, 126); + ret.funcName = StringFormat::Wide2UTF8(file); } else { - wcsncpy_s(ret.funcName, file, 126); + ret.funcName = StringFormat::Wide2UTF8(file); - wchar_t *voidparam = wcsstr(ret.funcName, L"(void)"); + size_t voidoffs = ret.funcName.find("(void)"); // remove stupid (void) for empty parameters - if(voidparam != NULL) + if(voidoffs != std::string::npos) { - *(voidparam + 1) = L')'; - *(voidparam + 2) = 0; + ret.funcName.erase(voidoffs + 1); + ret.funcName.push_back(')'); } } @@ -364,7 +358,7 @@ AddrInfo GetAddr(uint32_t module, uint64_t addr) return ret; } - wcsncpy_s(ret.fileName, file, 126); + ret.fileName = StringFormat::Wide2UTF8(file); SysFreeString(file); @@ -429,19 +423,19 @@ public: Callstack::AddressDetails GetAddr(uint64_t addr); private: - wstring pdbBrowse(wstring startingPoint); + std::string pdbBrowse(std::string startingPoint); struct Module { - wstring name; + std::string name; DWORD64 base; DWORD size; uint32_t moduleId; }; - vector pdbRememberedPaths; - vector pdbIgnores; + std::vector pdbRememberedPaths; + std::vector pdbIgnores; vector modules; char pipeMessageBuf[2048]; @@ -705,13 +699,13 @@ Win32Callstack::~Win32Callstack() { } -wstring Win32CallstackResolver::pdbBrowse(wstring startingPoint) +std::string Win32CallstackResolver::pdbBrowse(std::string startingPoint) { OPENFILENAMEW ofn; RDCEraseMem(&ofn, sizeof(ofn)); wchar_t outBuf[MAX_PATH * 2]; - wcscpy_s(outBuf, startingPoint.c_str()); + wcscpy_s(outBuf, StringFormat::UTF82Wide(startingPoint).c_str()); ofn.lStructSize = sizeof(OPENFILENAME); ofn.lpstrTitle = L"Locate PDB File"; @@ -724,15 +718,15 @@ wstring Win32CallstackResolver::pdbBrowse(wstring startingPoint) BOOL ret = GetOpenFileNameW(&ofn); if(ret == FALSE) - return L""; + return ""; - return outBuf; + return StringFormat::Wide2UTF8(outBuf); } Win32CallstackResolver::Win32CallstackResolver(byte *moduleDB, size_t DBSize, RENDERDOC_ProgressCallback progress) { - wstring configPath = StringFormat::UTF82Wide(FileIO::GetAppFolderFilename("config.ini")); + std::wstring configPath = StringFormat::UTF82Wide(FileIO::GetAppFolderFilename("config.ini")); { FILE *f = NULL; _wfopen_s(&f, configPath.c_str(), L"a"); @@ -758,7 +752,8 @@ Win32CallstackResolver::Win32CallstackResolver(byte *moduleDB, size_t DBSize, break; } - wstring ignores = inputBuf; + + std::string ignores = StringFormat::Wide2UTF8(inputBuf); { DWORD read = @@ -853,7 +848,7 @@ Win32CallstackResolver::Win32CallstackResolver(byte *moduleDB, size_t DBSize, SAFE_RELEASE(source); } - split(ignores, pdbIgnores, L';'); + split(ignores, pdbIgnores, ';'); byte *chunks = moduleDB + 8; byte *end = chunks + DBSize - 8; @@ -872,7 +867,7 @@ Win32CallstackResolver::Win32CallstackResolver(byte *moduleDB, size_t DBSize, Module m; - m.name = modName; + m.name = StringFormat::Wide2UTF8(modName); m.base = chunk->base; m.size = chunk->size; m.moduleId = 0; @@ -887,38 +882,38 @@ Win32CallstackResolver::Win32CallstackResolver(byte *moduleDB, size_t DBSize, // get default pdb (this also looks up symbol server etc) // Always done in unicode - std::wstring defaultPdb = DIA2::LookupModule(modName, chunk->guid, chunk->age); + std::string defaultPdb = DIA2::LookupModule(m.name, chunk->guid, chunk->age); // strip newline - if(defaultPdb != L"" && defaultPdb[defaultPdb.length() - 1] == '\n') + if(defaultPdb != "" && defaultPdb[defaultPdb.length() - 1] == '\n') defaultPdb.pop_back(); // if we didn't even get a default pdb we'll have to prompt first time through bool failed = false; - if(defaultPdb == L"") + if(defaultPdb == "") { - defaultPdb = strlower(basename(m.name)); + defaultPdb = strlower(get_basename(m.name)); - size_t it = defaultPdb.find(L".dll"); - if(it != wstring::npos) + size_t it = defaultPdb.find(".dll"); + if(it != std::string::npos) { - defaultPdb[it + 1] = L'p'; - defaultPdb[it + 2] = L'd'; - defaultPdb[it + 3] = L'b'; + defaultPdb[it + 1] = 'p'; + defaultPdb[it + 2] = 'd'; + defaultPdb[it + 3] = 'b'; } - it = defaultPdb.find(L".exe"); - if(it != wstring::npos) + it = defaultPdb.find(".exe"); + if(it != std::string::npos) { - defaultPdb[it + 1] = L'p'; - defaultPdb[it + 2] = L'd'; - defaultPdb[it + 3] = L'b'; + defaultPdb[it + 1] = 'p'; + defaultPdb[it + 2] = 'd'; + defaultPdb[it + 3] = 'b'; } failed = true; } - std::wstring pdbName = defaultPdb; + std::string pdbName = defaultPdb; int fallbackIdx = -1; @@ -931,28 +926,29 @@ Win32CallstackResolver::Win32CallstackResolver(byte *moduleDB, size_t DBSize, // are there if(fallbackIdx < (int)pdbRememberedPaths.size()) { - pdbName = pdbRememberedPaths[fallbackIdx] + L"\\" + basename(pdbName); + pdbName = pdbRememberedPaths[fallbackIdx] + "\\" + get_basename(pdbName); } else { - pdbName = dirname(defaultPdb) + L"\\" + basename(defaultPdb); + pdbName = get_dirname(defaultPdb) + "\\" + get_basename(defaultPdb); // prompt for new pdbName, unless it's renderdoc or dbghelp - if(pdbName.find(L"renderdoc.") != wstring::npos || - pdbName.find(L"dbghelp.") != wstring::npos || pdbName.find(L"symsrv.") != wstring::npos) - pdbName = L""; + if(pdbName.find("renderdoc.") != std::wstring::npos || + pdbName.find("dbghelp.") != std::wstring::npos || + pdbName.find("symsrv.") != std::wstring::npos) + pdbName = ""; else pdbName = pdbBrowse(pdbName); // user cancelled, just don't load this pdb - if(pdbName == L"") + if(pdbName == "") break; } failed = false; } - m.moduleId = DIA2::GetModule(pdbName.c_str(), chunk->guid, chunk->age); + m.moduleId = DIA2::GetModule(StringFormat::UTF82Wide(pdbName), chunk->guid, chunk->age); if(m.moduleId == 0) { @@ -962,7 +958,7 @@ Win32CallstackResolver::Win32CallstackResolver(byte *moduleDB, size_t DBSize, { if(fallbackIdx >= (int)pdbRememberedPaths.size()) { - wstring dir = dirname(pdbName); + std::string dir = get_dirname(pdbName); if(find(pdbRememberedPaths.begin(), pdbRememberedPaths.end(), dir) == pdbRememberedPaths.end()) { @@ -977,16 +973,17 @@ Win32CallstackResolver::Win32CallstackResolver(byte *moduleDB, size_t DBSize, { modules.push_back(m); // still add the module, with 0 module id - RDCWARN("Couldn't get symbols for %ls", m.name.c_str()); + RDCWARN("Couldn't get symbols for %s", m.name.c_str()); // silently ignore renderdoc.dll, dbghelp.dll, and symsrv.dll without asking to permanently // ignore - if(m.name.find(L"renderdoc.") != wstring::npos || m.name.find(L"dbghelp.") != wstring::npos || - m.name.find(L"symsrv.") != wstring::npos) + if(m.name.find("renderdoc.") != std::wstring::npos || + m.name.find("dbghelp.") != std::wstring::npos || + m.name.find("symsrv.") != std::wstring::npos) continue; wchar_t text[1024]; - wsprintf(text, L"Do you want to permanently ignore this file?\nPath: %ls", m.name.c_str()); + wsprintf(text, L"Do you want to permanently ignore this file?\nPath: %s", m.name.c_str()); int ret = MessageBoxW(NULL, text, L"Ignore this pdb?", MB_YESNO); @@ -1001,15 +998,16 @@ Win32CallstackResolver::Win32CallstackResolver(byte *moduleDB, size_t DBSize, DIA2::SetBaseAddress(m.moduleId, chunk->base); - RDCLOG("Loaded Symbols for %ls", m.name.c_str()); + RDCLOG("Loaded Symbols for %s", m.name.c_str()); modules.push_back(m); } - sort(pdbIgnores.begin(), pdbIgnores.end()); - pdbIgnores.erase(unique(pdbIgnores.begin(), pdbIgnores.end()), pdbIgnores.end()); - merge(pdbIgnores, ignores, L';'); - WritePrivateProfileStringW(L"renderdoc", L"ignores", ignores.c_str(), configPath.c_str()); + std::sort(pdbIgnores.begin(), pdbIgnores.end()); + pdbIgnores.erase(std::unique(pdbIgnores.begin(), pdbIgnores.end()), pdbIgnores.end()); + merge(pdbIgnores, ignores, ';'); + WritePrivateProfileStringW(L"renderdoc", L"ignores", StringFormat::UTF82Wide(ignores).c_str(), + configPath.c_str()); } Win32CallstackResolver::~Win32CallstackResolver() @@ -1022,12 +1020,8 @@ Callstack::AddressDetails Win32CallstackResolver::GetAddr(DWORD64 addr) { AddrInfo info; - info.lineNum = 0; - memset(info.fileName, 0, sizeof(info.fileName)); - memset(info.fileName, 0, sizeof(info.funcName)); - - wcsncpy_s(info.fileName, L"Unknown", 126); - wsprintfW(info.funcName, L"0x%08I64x", addr); + info.fileName = "Unknown"; + info.funcName = StringFormat::Fmt("0x%08llx", addr); for(size_t i = 0; i < modules.size(); i++) { @@ -1040,39 +1034,26 @@ Callstack::AddressDetails Win32CallstackResolver::GetAddr(DWORD64 addr) // if we didn't get a filename, default to the module name if(modules[i].moduleId == 0 || info.fileName[0] == 0) - wcsncpy_s(info.fileName, modules[i].name.c_str(), 126); + info.fileName = modules[i].name; if(modules[i].moduleId == 0 || info.funcName[0] == 0) { // if we didn't get a function name, at least indicate // the module it came from, and an offset - wchar_t *baseName = info.fileName; + info.funcName = get_basename(info.fileName); - wchar_t *c = wcsrchr(baseName, '\\'); - if(c) - baseName = c + 1; + info.funcName = StringFormat::Fmt("%s+0x%08llx", info.funcName.c_str(), addr - base); - c = wcsrchr(baseName, '/'); - if(c) - baseName = c + 1; + size_t offs = info.funcName.find(".pdb"); - wsprintfW(info.funcName, L"%s+0x%08I64x", baseName, addr - base); - - c = wcsstr(info.funcName, L"pdb"); - if(c) + if(offs != std::string::npos) { + info.funcName.erase(offs + 1); + if(i == 0) - { - c[0] = 'e'; - c[1] = 'x'; - c[2] = 'e'; - } + info.funcName += "exe"; else - { - c[0] = 'd'; - c[1] = 'l'; - c[2] = 'l'; - } + info.funcName += "dll"; } } @@ -1081,8 +1062,8 @@ Callstack::AddressDetails Win32CallstackResolver::GetAddr(DWORD64 addr) } Callstack::AddressDetails ret; - ret.filename = StringFormat::Wide2UTF8(wstring(info.fileName)); - ret.function = StringFormat::Wide2UTF8(wstring(info.funcName)); + ret.filename = info.fileName; + ret.function = info.funcName; ret.line = info.lineNum; return ret; diff --git a/renderdoc/os/win32/win32_libentry.cpp b/renderdoc/os/win32/win32_libentry.cpp index ee4f0f0f8..5cc276eaa 100644 --- a/renderdoc/os/win32/win32_libentry.cpp +++ b/renderdoc/os/win32/win32_libentry.cpp @@ -36,11 +36,11 @@ static BOOL add_hooks() wchar_t curFile[512]; GetModuleFileNameW(NULL, curFile, 512); - wstring f = basename(strlower(wstring(curFile))); + std::string f = get_basename(strlower(StringFormat::Wide2UTF8(curFile))); // bail immediately if we're in a system process. We don't want to hook, log, anything - // this instance is being used for a shell extension. - if(f == L"dllhost.exe" || f == L"explorer.exe") + if(f == "dllhost.exe" || f == "explorer.exe") { #ifndef _RELEASE OutputDebugStringA( diff --git a/renderdoc/os/win32/win32_process.cpp b/renderdoc/os/win32/win32_process.cpp index 2e00e137c..20d4d55bb 100644 --- a/renderdoc/os/win32/win32_process.cpp +++ b/renderdoc/os/win32/win32_process.cpp @@ -34,20 +34,19 @@ #include "os/os_specific.h" #include "strings/string_utils.h" -using std::string; - -static wstring lowercase(wstring in) +// add wstring strlower overload since we don't want to always be converting to/from wchars. +static std::wstring strlower(std::wstring in) { - wstring ret; + std::wstring ret; ret.resize(in.size()); for(size_t i = 0; i < ret.size(); i++) ret[i] = towlower(in[i]); return ret; } -static vector &GetEnvModifications() +static std::vector &GetEnvModifications() { - static vector envCallbacks; + static std::vector envCallbacks; return envCallbacks; } @@ -55,11 +54,11 @@ struct InsensitiveComparison { bool operator()(const std::wstring &a, const std::wstring &b) const { - return lowercase(a) < lowercase(b); + return strlower(a) < strlower(b); } }; -typedef map EnvMap; +typedef std::map EnvMap; static EnvMap EnvStringToEnvMap(const wchar_t *envstring) { @@ -71,8 +70,8 @@ static EnvMap EnvStringToEnvMap(const wchar_t *envstring) { const wchar_t *equals = wcschr(e, L'='); - wstring name; - wstring value; + std::wstring name; + std::wstring value; name.assign(e, equals); value = equals + 1; @@ -263,7 +262,7 @@ extern "C" __declspec(dllexport) void __cdecl INTERNAL_ApplyEnvMods(void *ignore Process::ApplyEnvironmentModification(); } -void InjectDLL(HANDLE hProcess, wstring libName) +void InjectDLL(HANDLE hProcess, std::wstring libName) { wchar_t dllPath[MAX_PATH + 1] = {0}; wcscpy_s(dllPath, libName.c_str()); @@ -298,7 +297,7 @@ void InjectDLL(HANDLE hProcess, wstring libName) } } -uintptr_t FindRemoteDLL(DWORD pid, wstring libName) +uintptr_t FindRemoteDLL(DWORD pid, std::wstring libName) { HANDLE hModuleSnap = INVALID_HANDLE_VALUE; @@ -451,25 +450,25 @@ static PROCESS_INFORMATION RunProcess(const char *app, const char *workingDir, c pSec.nLength = sizeof(pSec); tSec.nLength = sizeof(tSec); - wstring workdir = L""; + std::wstring workdir = L""; if(workingDir != NULL && workingDir[0] != 0) - workdir = StringFormat::UTF82Wide(string(workingDir)); + workdir = StringFormat::UTF82Wide(std::string(workingDir)); else - workdir = StringFormat::UTF82Wide(dirname(string(app))); + workdir = StringFormat::UTF82Wide(get_dirname(string(app))); wchar_t *paramsAlloc = NULL; - wstring wapp = StringFormat::UTF82Wide(string(app)); + std::wstring wapp = StringFormat::UTF82Wide(std::string(app)); // CreateProcessW can modify the params, need space. size_t len = wapp.length() + 10; - wstring wcmd = L""; + std::wstring wcmd = L""; if(cmdLine != NULL && cmdLine[0] != 0) { - wcmd = StringFormat::UTF82Wide(string(cmdLine)); + wcmd = StringFormat::UTF82Wide(std::string(cmdLine)); len += wcmd.length(); } @@ -570,7 +569,7 @@ ExecuteResult Process::InjectIntoProcess(uint32_t pid, const rdcarray #include #include "common/globalconfig.h" +#include "os/os_specific.h" uint32_t strhash(const char *str, uint32_t seed) { @@ -59,31 +60,17 @@ char tocupper(char c) return (char)toupper(c); } -string strlower(const string &str) +std::string strlower(const std::string &str) { - string newstr(str); - transform(newstr.begin(), newstr.end(), newstr.begin(), toclower); + std::string newstr(str); + std::transform(newstr.begin(), newstr.end(), newstr.begin(), toclower); return newstr; } -wstring strlower(const wstring &str) +std::string strupper(const std::string &str) { - wstring newstr(str); - transform(newstr.begin(), newstr.end(), newstr.begin(), towlower); - return newstr; -} - -string strupper(const string &str) -{ - string newstr(str); - transform(newstr.begin(), newstr.end(), newstr.begin(), tocupper); - return newstr; -} - -wstring strupper(const wstring &str) -{ - wstring newstr(str); - transform(newstr.begin(), newstr.end(), newstr.begin(), towupper); + std::string newstr(str); + std::transform(newstr.begin(), newstr.end(), newstr.begin(), tocupper); return newstr; } @@ -109,6 +96,88 @@ bool endswith(const std::string &value, const std::string &ending) return (0 == value.compare(value.length() - ending.length(), ending.length(), ending)); } +std::string get_basename(const std::string &path) +{ + std::string base = path; + + if(base.length() == 0) + return base; + + if(base[base.length() - 1] == '/' || base[base.length() - 1] == '\\') + base.erase(base.size() - 1); + + char pathSep[] = {'\\', '/', 0}; + + size_t offset = base.find_last_of(pathSep); + + if(offset == std::string::npos) + return base; + + return base.substr(offset + 1); +} + +std::wstring get_basename(const std::wstring &path) +{ + return StringFormat::UTF82Wide(get_basename(StringFormat::Wide2UTF8(path))); +} + +std::string get_dirname(const std::string &path) +{ + std::string base = path; + + if(base.length() == 0) + return base; + + if(base[base.length() - 1] == '/' || base[base.length() - 1] == '\\') + base.erase(base.size() - 1); + + char pathSep[3] = {'\\', '/', 0}; + + size_t offset = base.find_last_of(pathSep); + + if(offset == std::string::npos) + { + base.resize(1); + base[0] = '.'; + return base; + } + + return base.substr(0, offset); +} + +std::wstring get_dirname(const std::wstring &path) +{ + return StringFormat::UTF82Wide(get_dirname(StringFormat::Wide2UTF8(path))); +} + +void split(const std::string &in, std::vector &out, const char sep) +{ + std::string work = in; + size_t offset = work.find(sep); + + while(offset != std::string::npos) + { + out.push_back(work.substr(0, offset)); + work = work.substr(offset + 1); + + offset = work.find(sep); + } + + if(work.size() && work[0] != 0) + out.push_back(work); +} + +void merge(const std::vector &in, std::string &out, const char sep) +{ + out = std::string(); + for(size_t i = 0; i < in.size(); i++) + { + out += in[i]; + if(i + 1 < in.size()) + out += sep; + } +} + std::string removeFromEnd(const std::string &value, const std::string &ending) { string::size_type pos; @@ -173,6 +242,34 @@ TEST_CASE("String manipulation", "[string]") CHECK(strlower("FOOBAR") == "foobar"); }; + SECTION("basename") + { + CHECK(get_basename("foo") == "foo"); + CHECK(get_basename("/foo") == "foo"); + CHECK(get_basename("/dir/foo") == "foo"); + CHECK(get_basename("/long/path/dir/foo") == "foo"); + CHECK(get_basename("relative/long/path/dir/foo") == "foo"); + CHECK(get_basename("../foo") == "foo"); + CHECK(get_basename("relative/../foo") == "foo"); + CHECK(get_basename("C:/windows/foo") == "foo"); + CHECK(get_basename("C:\\windows\\foo") == "foo"); + CHECK(get_basename("C:\\windows\\path/mixed/slashes\\foo") == "foo"); + }; + + SECTION("dirname") + { + CHECK(get_dirname("foo") == "."); + CHECK(get_dirname("/foo") == ""); + CHECK(get_dirname("/dir/foo") == "/dir"); + CHECK(get_dirname("/long/path/dir/foo") == "/long/path/dir"); + CHECK(get_dirname("relative/long/path/dir/foo") == "relative/long/path/dir"); + CHECK(get_dirname("../foo") == ".."); + CHECK(get_dirname("relative/../foo") == "relative/.."); + CHECK(get_dirname("C:/windows/foo") == "C:/windows"); + CHECK(get_dirname("C:\\windows\\foo") == "C:\\windows"); + CHECK(get_dirname("C:\\windows\\path/mixed/slashes\\foo") == "C:\\windows\\path/mixed/slashes"); + }; + SECTION("strupper") { CHECK(strupper("foobar") == "FOOBAR"); diff --git a/renderdoc/strings/string_utils.h b/renderdoc/strings/string_utils.h index e7575c8ef..84cc80485 100644 --- a/renderdoc/strings/string_utils.h +++ b/renderdoc/strings/string_utils.h @@ -28,14 +28,9 @@ #include #include #include -using std::string; -using std::wstring; -using std::vector; std::string strlower(const std::string &str); -std::wstring strlower(const std::wstring &str); std::string strupper(const std::string &str); -std::wstring strupper(const std::wstring &str); std::string trim(const std::string &str); std::string removeFromEnd(const std::string &value, const std::string &ending); @@ -44,80 +39,8 @@ uint32_t strhash(const char *str, uint32_t existingHash = 5381); bool endswith(const std::string &value, const std::string &ending); -template -strType basename(const strType &path) -{ - strType base = path; +std::string get_basename(const std::string &path); +std::string get_dirname(const std::string &path); - if(base.length() == 0) - return base; - - if(base[base.length() - 1] == '/' || base[base.length() - 1] == '\\') - base.erase(base.size() - 1); - - typename strType::value_type pathSep[3] = {'\\', '/', 0}; - - size_t offset = base.find_last_of(pathSep); - - if(offset == strType::npos) - return base; - - return base.substr(offset + 1); -} - -template -strType dirname(const strType &path) -{ - strType base = path; - - if(base.length() == 0) - return base; - - if(base[base.length() - 1] == '/' || base[base.length() - 1] == '\\') - base.erase(base.size() - 1); - - typename strType::value_type pathSep[3] = {'\\', '/', 0}; - - size_t offset = base.find_last_of(pathSep); - - if(offset == strType::npos) - { - base.resize(1); - base[0] = typename strType::value_type('.'); - return base; - } - - return base.substr(0, offset); -} - -template -void split(const std::basic_string &in, vector > &out, - const CharType sep) -{ - std::basic_string work = in; - typename std::basic_string::size_type offset = work.find(sep); - - while(offset != std::basic_string::npos) - { - out.push_back(work.substr(0, offset)); - work = work.substr(offset + 1); - - offset = work.find(sep); - } - - if(work.size() && work[0] != 0) - out.push_back(work); -} - -template -void merge(const vector > &in, std::basic_string &out, - const CharType sep) -{ - out = std::basic_string(); - for(size_t i = 0; i < in.size(); i++) - { - out += in[i]; - if(i + 1 < in.size()) - out += sep; - } -} +void split(const std::string &in, std::vector &out, const char sep); +void merge(const std::vector &in, std::string &out, const char sep);