From 01bd8f02d6723e58f86c621252455c24bb46656b Mon Sep 17 00:00:00 2001 From: dEajL3kA Date: Wed, 3 May 2023 12:05:28 +0200 Subject: [PATCH] Added version info to the EXE file. --- compatibility.manifest | 17 +++++++++++ tee.c | 83 ++++++++++++++++++++++++++++++++++++++++++++------ tee.rc | 71 ++++++++++++++++++++++++++++++++++++++++++ tee.vcxproj | 11 +++++++ tee.vcxproj.filters | 10 ++++++ 5 files changed, 182 insertions(+), 10 deletions(-) create mode 100644 compatibility.manifest create mode 100644 tee.rc diff --git a/compatibility.manifest b/compatibility.manifest new file mode 100644 index 0000000..fce5b0f --- /dev/null +++ b/compatibility.manifest @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/tee.c b/tee.c index b8ed916..2099d43 100644 --- a/tee.c +++ b/tee.c @@ -32,15 +32,19 @@ static BOOL is_terminal(const HANDLE handle) return GetConsoleMode(handle, &mode); } +#define APPEND_STRING(X) \ + do { lstrcpyW(ptr, str##X); ptr += len##X; } while(0) + static wchar_t *concat_3(const wchar_t *const strA, const wchar_t *const strB, const wchar_t *const strC) { const size_t lenA = lstrlenW(strA), lenB = lstrlenW(strB), lenC = lstrlenW(strC); wchar_t *const buffer = (wchar_t*) LocalAlloc(LPTR, sizeof(wchar_t) * (lenA + lenB + lenC + 1U)); if (buffer) { - lstrcpyW(buffer, strA); - lstrcpyW(buffer + lenA, strB); - lstrcpyW(buffer + lenA + lenB, strC); + wchar_t *ptr = buffer; + APPEND_STRING(A); + APPEND_STRING(B); + APPEND_STRING(C); } return buffer; } @@ -75,6 +79,57 @@ static BOOL WINAPI console_handler(const DWORD ctrlType) } // -------------------------------------------------------------------------- +// Version +// -------------------------------------------------------------------------- + +static ULONGLONG get_version(void) +{ + const HRSRC hVersion = FindResourceW(NULL, MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION); + if (hVersion) + { + const HGLOBAL hResource = LoadResource(NULL, hVersion); + if (hResource) + { + const DWORD sizeOfResource = SizeofResource(NULL, hResource); + if (sizeOfResource >= sizeof(VS_FIXEDFILEINFO)) + { + const PVOID addrResourceBlock = LockResource(hResource); + if (addrResourceBlock) + { + VS_FIXEDFILEINFO *fileInfoData; + UINT fileInfoSize; + if (VerQueryValueW(addrResourceBlock, L"\\", &fileInfoData, &fileInfoSize)) + { + ULARGE_INTEGER fileVersion; + fileVersion.LowPart = fileInfoData->dwFileVersionLS; + fileVersion.HighPart = fileInfoData->dwFileVersionMS; + return fileVersion.QuadPart; + } + } + } + } + } + + return 0U; +} + +static const wchar_t *get_version_string(void) +{ + static wchar_t text[64U] = { '\0' }; + lstrcpyW(text, L"tee for Windows v#.#.# [" TEXT(__DATE__) L"]\n"); + + const ULONGLONG version = get_version(); + if (version) + { + text[17U] = L'0' + ((version >> 48) & 0xFFFF); + text[19U] = L'0' + ((version >> 32) & 0xFFFF); + text[21U] = L'0' + ((version >> 16) & 0xFFFF); + } + + return text; +} + +// -------------------------------------------------------------------------- // Text output // -------------------------------------------------------------------------- @@ -196,16 +251,24 @@ int wmain(const int argc, const wchar_t *const argv[]) /* Set up CRTL+C handler */ SetConsoleCtrlHandler(console_handler, TRUE); + /* Print version */ + if ((argc > 1) && (lstrcmpiW(argv[1], L"--version") == 0)) + { + write_text(hStdErr, get_version_string()); + return 0; + } + /* Print manpage */ if ((argc < 2) || (lstrcmpiW(argv[1], L"/?") == 0) || (lstrcmpiW(argv[1], L"--help") == 0)) { - write_text(hStdErr, L"tee for Windows [" TEXT(__DATE__) L"]\n\n"); - write_text(hStdErr, L"Usage:\n"); - write_text(hStdErr, L" your_program.exe [...] | tee.exe [options] \n\n"); - write_text(hStdErr, L"Options:\n"); - write_text(hStdErr, L" --append Append to the existing file, instead of truncating\n"); - write_text(hStdErr, L" --flush Flush output file after each write operation\n"); - write_text(hStdErr, L" --ignore Ignore the interrupt signal (SIGINT), e.g. CTRL+C\n\n"); + write_text(hStdErr, get_version_string()); + write_text(hStdErr, L"\n" + L"Usage:\n" + L" your_program.exe [...] | tee.exe [options] \n\n" + L"Options:\n" + L" --append Append to the existing file, instead of truncating\n" + L" --flush Flush output file after each write operation\n" + L" --ignore Ignore the interrupt signal (SIGINT), e.g. CTRL+C\n\n"); return 1; } diff --git a/tee.rc b/tee.rc new file mode 100644 index 0000000..386463c --- /dev/null +++ b/tee.rc @@ -0,0 +1,71 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Microsoft Visual C++ generated resource script. +// +#define APSTUDIO_READONLY_SYMBOLS +#include "WinResrc.h" +#undef APSTUDIO_READONLY_SYMBOLS + +#define MY_VERSION_MAJOR 1 +#define MY_VERSION_MINOR 1 +#define MY_VERSION_PATCH 0 + +#define MY_VERSION_NUMBER MY_VERSION_MAJOR, MY_VERSION_MINOR, MY_VERSION_PATCH, 0 +#define ___MY_VERSION_STRING(X) #X +#define __MY_VERSION_STRING(X,Y,Z) ___MY_VERSION_STRING(X.Y.Z) +#define _MY_VERSION_STRING(X,Y,Z) __MY_VERSION_STRING(X,Y,Z) +#define MY_VERSION_STRING _MY_VERSION_STRING(MY_VERSION_MAJOR, MY_VERSION_MINOR, MY_VERSION_PATCH) + +#ifdef _WIN64 +#define MY_ARCH_SUFFIX "(x64)" +#else +#define MY_ARCH_SUFFIX "(x86)" +#endif + +///////////////////////////////////////////////////////////////////////////// +// +// Neutral resources +// +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// +VS_VERSION_INFO VERSIONINFO + FILEVERSION MY_VERSION_NUMBER + PRODUCTVERSION MY_VERSION_NUMBER + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x3L +#else + FILEFLAGS 0x2L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "ProductName", "tee for Windows" + VALUE "FileDescription", "tee for Windows " MY_ARCH_SUFFIX + VALUE "ProductVersion", MY_VERSION_STRING + VALUE "FileVersion", MY_VERSION_STRING + VALUE "InternalName", "tee" + VALUE "OriginalFilename", "tee.exe" + VALUE "LegalCopyright", "Copyright (c) 2023 dEajL3kA " + VALUE "CompanyName", "dEajL3kA" + VALUE "LegalTrademarks", "dEajL3kA" + VALUE "Comments", "Released under the MIT license" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END diff --git a/tee.vcxproj b/tee.vcxproj index e1c7373..040ec2f 100644 --- a/tee.vcxproj +++ b/tee.vcxproj @@ -130,6 +130,7 @@ true UseLinkTimeCodeGeneration 5.1 + Version.lib;%(AdditionalDependencies) @@ -172,11 +173,21 @@ true UseLinkTimeCodeGeneration 5.2 + Version.lib;%(AdditionalDependencies) + + + _WIN32;%(PreprocessorDefinitions) + _WIN64;%(PreprocessorDefinitions) + + + + + diff --git a/tee.vcxproj.filters b/tee.vcxproj.filters index 191f149..82c07a9 100644 --- a/tee.vcxproj.filters +++ b/tee.vcxproj.filters @@ -19,4 +19,14 @@ Quelldateien + + + Ressourcendateien + + + + + Ressourcendateien + + \ No newline at end of file -- 2.11.4.GIT