diff --git a/src/detection/terminalshell/terminalshell.c b/src/detection/terminalshell/terminalshell.c index d3c69d63e..92bd7294e 100644 --- a/src/detection/terminalshell/terminalshell.c +++ b/src/detection/terminalshell/terminalshell.c @@ -20,13 +20,14 @@ #include "util/windows/version.h" #include -static bool getFileVersion(const FFstrbuf* exePath, FFstrbuf* version) +static bool getFileVersion(const FFstrbuf* exePath, const wchar_t* stringName, FFstrbuf* version) { wchar_t exePathW[PATH_MAX]; int len = MultiByteToWideChar(CP_UTF8, 0, exePath->chars, (int)exePath->length, exePathW, ARRAY_SIZE(exePathW)); if (len <= 0) return false; - return ffGetFileVersion(exePathW, version); + return ffGetFileVersion(exePathW, stringName, version); } + #elif __HAIKU__ #include "util/haiku/version.h" #endif @@ -98,7 +99,7 @@ static bool getShellVersionPwsh(FFstrbuf* exe, FFstrbuf* version) } #ifdef _WIN32 - if(getFileVersion(exe, version)) + if(getFileVersion(exe, NULL, version)) { ffStrbufSubstrBeforeLastC(version, '.'); return true; @@ -291,7 +292,7 @@ bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* exePath, if(ffStrEqualsIgnCase(exeName, "powershell") || ffStrEqualsIgnCase(exeName, "powershell_ise")) return getShellVersionWinPowerShell(exe, version); - return getFileVersion(exe, version); + return getFileVersion(exe, NULL, version); #endif return false; @@ -737,7 +738,7 @@ static bool getTerminalVersionWindowsTerminal(FFstrbuf* exe, FFstrbuf* version) return true; } - return getFileVersion(exe, version); + return getFileVersion(exe, NULL, version); } static bool getTerminalVersionConEmu(FFstrbuf* exe, FFstrbuf* version) @@ -747,7 +748,7 @@ static bool getTerminalVersionConEmu(FFstrbuf* exe, FFstrbuf* version) if(version->length) return true; - return getFileVersion(exe, version); + return getFileVersion(exe, NULL, version); } #endif @@ -839,6 +840,9 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe if(ffStrbufStartsWithIgnCaseS(processName, "ConEmu")) return getTerminalVersionConEmu(exe, version); + if(ffStrbufIgnCaseEqualS(processName, "warp.exe")) + return getFileVersion(exe, L"ProductVersion", version); + #endif #ifndef _WIN32 @@ -914,7 +918,7 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe #ifdef _WIN32 - return getFileVersion(exe, version); + return getFileVersion(exe, NULL, version); #else diff --git a/src/detection/terminalshell/terminalshell_windows.c b/src/detection/terminalshell/terminalshell_windows.c index 97bfe1820..68043ab28 100644 --- a/src/detection/terminalshell/terminalshell_windows.c +++ b/src/detection/terminalshell/terminalshell_windows.c @@ -87,7 +87,7 @@ static void setShellInfoDetails(FFShellResult* result) if(wcsncmp(module.szModule, L"clink_dll_", strlen("clink_dll_")) == 0) { ffStrbufAppendS(&result->prettyName, " (with Clink "); - ffGetFileVersion(module.szExePath, &result->prettyName); + ffGetFileVersion(module.szExePath, NULL, &result->prettyName); ffStrbufAppendC(&result->prettyName, ')'); break; } diff --git a/src/detection/wm/wm_windows.cpp b/src/detection/wm/wm_windows.cpp index e11196805..62e20a926 100644 --- a/src/detection/wm/wm_windows.cpp +++ b/src/detection/wm/wm_windows.cpp @@ -79,7 +79,7 @@ const char* ffDetectWMVersion(const FFstrbuf* wmName, FFstrbuf* result, FF_MAYBE wchar_t fullPath[MAX_PATH]; wcscpy(fullPath, pPath); wcscat(fullPath, L"\\dwm.exe"); - ffGetFileVersion(fullPath, result); + ffGetFileVersion(fullPath, NULL, result); } CoTaskMemFree(pPath); return NULL; diff --git a/src/util/windows/version.c b/src/util/windows/version.c index e01fe27a1..684a4fcce 100644 --- a/src/util/windows/version.c +++ b/src/util/windows/version.c @@ -1,28 +1,59 @@ #include "util/windows/version.h" #include "util/mallocHelper.h" +#include "util/windows/unicode.h" #include -bool ffGetFileVersion(const wchar_t* filePath, FFstrbuf* version) +bool ffGetFileVersion(const wchar_t* filePath, const wchar_t* stringName, FFstrbuf* version) { DWORD handle; DWORD size = GetFileVersionInfoSizeW(filePath, &handle); - if(size > 0) + if (size > 0) { - FF_AUTO_FREE void* versionData = malloc(size); - if(GetFileVersionInfoW(filePath, handle, size, versionData)) + FF_AUTO_FREE void *versionData = malloc(size); + if (GetFileVersionInfoW(filePath, handle, size, versionData)) { - VS_FIXEDFILEINFO* verInfo; - UINT len; - if(VerQueryValueW(versionData, L"\\", (void**)&verInfo, &len) && len && verInfo->dwSignature == 0xFEEF04BD) + if (!stringName) { - ffStrbufAppendF(version, "%u.%u.%u.%u", - (unsigned)(( verInfo->dwProductVersionMS >> 16 ) & 0xffff), - (unsigned)(( verInfo->dwProductVersionMS >> 0 ) & 0xffff), - (unsigned)(( verInfo->dwProductVersionLS >> 16 ) & 0xffff), - (unsigned)(( verInfo->dwProductVersionLS >> 0 ) & 0xffff) - ); - return true; + VS_FIXEDFILEINFO* verInfo; + UINT len; + if (VerQueryValueW(versionData, L"\\", (void **)&verInfo, &len) && len && verInfo->dwSignature == 0xFEEF04BD) + { + ffStrbufAppendF(version, "%u.%u.%u.%u", + (unsigned)((verInfo->dwProductVersionMS >> 16) & 0xffff), + (unsigned)((verInfo->dwProductVersionMS >> 0) & 0xffff), + (unsigned)((verInfo->dwProductVersionLS >> 16) & 0xffff), + (unsigned)((verInfo->dwProductVersionLS >> 0) & 0xffff)); + return true; + } + } + else + { + struct + { + WORD language; + WORD codePage; + }* translations; + + UINT translationsLen; + + if (VerQueryValueW(versionData, L"\\VarFileInfo\\Translation", + (void **) &translations, &translationsLen) && + translationsLen >= sizeof(*translations)) + { + wchar_t subBlock[128]; + snwprintf(subBlock, ARRAY_SIZE(subBlock), L"\\StringFileInfo\\%04x%04x\\%ls", + translations[0].language, translations[0].codePage, stringName); + + wchar_t* value; + UINT valueLen; + + if (VerQueryValueW(versionData, subBlock, (void **)&value, &valueLen) && valueLen > 0) + { + ffStrbufSetWS(version, value); + return true; + } + } } } } diff --git a/src/util/windows/version.h b/src/util/windows/version.h index c6206fa5b..73e7cc1e5 100644 --- a/src/util/windows/version.h +++ b/src/util/windows/version.h @@ -1,3 +1,15 @@ #include "fastfetch.h" -bool ffGetFileVersion(const wchar_t* filePath, FFstrbuf* version); + +/** + * @brief Retrieves a specific version string for a Windows file. + * + * This function gets a version string from a Windows file's version information. + * + * @param filePath The path to the file for which version information is requested. + * @param stringName The name of the specific version string to retrieve (e.g., "FileVersion", "ProductVersion"). + * @param version Pointer to an FFstrbuf where the version string will be stored. + * + * @return true if the version string was successfully retrieved, false otherwise. + */ +bool ffGetFileVersion(const wchar_t* filePath, const wchar_t* stringName, FFstrbuf* version);