mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-11-10 00:40:09 +01:00
78 lines
2.8 KiB
C
78 lines
2.8 KiB
C
#include "common/debug.h"
|
|
#include "common/mallocHelper.h"
|
|
#include "common/windows/version.h"
|
|
#include "common/windows/unicode.h"
|
|
|
|
#include <windows.h>
|
|
|
|
bool ffGetFileVersion(const wchar_t* filePath, const wchar_t* stringName, FFstrbuf* version) {
|
|
FF_DEBUG("ffGetFileVersion: enter filePath=%ls stringName=%ls", filePath, stringName);
|
|
|
|
DWORD handle;
|
|
DWORD size = GetFileVersionInfoSizeW(filePath, &handle);
|
|
if (size == 0) {
|
|
FF_DEBUG("GetFileVersionInfoSizeW failed: %s", ffDebugWin32Error(GetLastError()));
|
|
return false;
|
|
}
|
|
|
|
FF_DEBUG("GetFileVersionInfoSizeW ok: size=%lu handle=%lu",
|
|
(unsigned long) size,
|
|
(unsigned long) handle);
|
|
|
|
FF_AUTO_FREE void* versionData = malloc(size);
|
|
if (!versionData) {
|
|
FF_DEBUG("malloc failed: size=%lu", (unsigned long) size);
|
|
return false;
|
|
}
|
|
|
|
if (!GetFileVersionInfoW(filePath, handle, size, versionData)) {
|
|
FF_DEBUG("GetFileVersionInfoW failed: %s", ffDebugWin32Error(GetLastError()));
|
|
return false;
|
|
}
|
|
|
|
FF_DEBUG("GetFileVersionInfoW ok");
|
|
|
|
if (!stringName) {
|
|
VS_FIXEDFILEINFO* verInfo;
|
|
UINT len;
|
|
if (VerQueryValueW(versionData, L"\\", (void**) &verInfo, &len) &&
|
|
len &&
|
|
verInfo->dwSignature == 0xFEEF04BD) {
|
|
ffStrbufSetF(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));
|
|
FF_DEBUG("fixed version resolved: %s", version->chars);
|
|
return true;
|
|
}
|
|
|
|
FF_DEBUG("fixed version query failed or invalid signature");
|
|
return false;
|
|
}
|
|
|
|
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);
|
|
FF_DEBUG("query version string with translation: %ls", subBlock);
|
|
|
|
wchar_t* value;
|
|
UINT valueLen; // Number of characters, including null terminator
|
|
if (VerQueryValueW(versionData, subBlock, (void**) &value, &valueLen) && valueLen > 0) {
|
|
ffStrbufSetNWS(version, valueLen - 1, value);
|
|
FF_DEBUG("version string resolved (translation fallback): %s", version->chars);
|
|
return true;
|
|
}
|
|
|
|
FF_DEBUG("translation fallback query failed");
|
|
} else {
|
|
FF_DEBUG("no translation table found in version resource");
|
|
}
|
|
|
|
FF_DEBUG("ffGetFileVersion failed");
|
|
return false;
|
|
}
|