/* * Copyright (c) 2005 Jason Tishler * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * A copy of the GNU General Public License can be found at * http://www.gnu.org/ * * Written by Jason Tishler * * $Id: version.cc,v 1.6 2005/01/19 14:49:52 jt Exp $ */ #include #include #ifdef __CYGWIN__ #include #endif const char* GetVersionString(const void* aVersionInfo, const char* aVersionName); const VS_FIXEDFILEINFO* GetFixedFileInfo(const void* aVersionInfo); void PrintRequiredVersionInfo(const VS_FIXEDFILEINFO* aFixedFileInfo); void PrintOptionalVersionInfo(char* aVersionInfo); bool GetFullPathName(const char* aFileName, char* aPathName, unsigned int aSize); void PrintUsage(); const char* aVersionNames[] = { "Comments", "CompanyName", "FileDescription", "FileVersion", "InternalName", "LegalCopyright", "LegalTrademarks", "OriginalFilename", "PrivateBuild", "ProductName", "ProductVersion", "SpecialBuild" }; int main(int argc, const char* argv[]) { if (argc < 2) { PrintUsage(); exit(1); } for (int i = 1; i < argc; i++) { char aPathName[MAX_PATH + 1]; const char* aFileName = argv[i]; GetFullPathName(aFileName, aPathName, sizeof(aPathName)); if (argc > 2) { printf("%s%s:\n", (i != 1) ? "\n" : "", aFileName); } DWORD aHandle = 0; DWORD aSize = GetFileVersionInfoSize(aPathName, &aHandle); if (aSize == 0) { exit(2); } char* aVersionInfo = new char[aSize]; BOOL aStatus = GetFileVersionInfo(aPathName, aHandle, aSize, aVersionInfo); if (!aStatus) { delete [] aVersionInfo; exit(3); } const VS_FIXEDFILEINFO* aFixedFileInfo = GetFixedFileInfo(aVersionInfo); PrintRequiredVersionInfo(aFixedFileInfo); PrintOptionalVersionInfo(aVersionInfo); delete [] aVersionInfo; } exit(0); } const char* GetVersionString(const void* aVersionInfo, const char* aVersionName) { const char* aSeparator = "\\"; const char* aPrefix = "StringFileInfo"; const char* aLangCodePage = "040904b0"; char aVersionPath[MAX_PATH + 1]; strcpy(aVersionPath, aSeparator); strcat(aVersionPath, aPrefix); strcat(aVersionPath, aSeparator); strcat(aVersionPath, aLangCodePage); strcat(aVersionPath, aSeparator); strcat(aVersionPath, aVersionName); void* aBuffer = 0; UINT aSize = 0; VerQueryValue((void*) aVersionInfo, aVersionPath, &aBuffer, &aSize); return (const char*) aBuffer; } const VS_FIXEDFILEINFO* GetFixedFileInfo(const void* aVersionInfo) { void* aBuffer = 0; UINT aSize = 0; const char* aRootBlock = "\\"; VerQueryValue((void*) aVersionInfo, (char*) aRootBlock, &aBuffer, &aSize); return (const VS_FIXEDFILEINFO*) aBuffer; } void PrintRequiredVersionInfo(const VS_FIXEDFILEINFO* aFixedFileInfo) { if (!aFixedFileInfo) return; printf("Required Information:\n"); printf(" ProductVersion = %d.%d.%d.%d\n", aFixedFileInfo->dwProductVersionMS >> 16, aFixedFileInfo->dwProductVersionMS & 0xffff, aFixedFileInfo->dwProductVersionLS >> 16, aFixedFileInfo->dwProductVersionLS & 0xffff); printf(" FileVersion = %d.%d.%d.%d\n", aFixedFileInfo->dwFileVersionMS >> 16, aFixedFileInfo->dwFileVersionMS & 0xffff, aFixedFileInfo->dwFileVersionLS >> 16, aFixedFileInfo->dwFileVersionLS & 0xffff); } void PrintOptionalVersionInfo(char* aVersionInfo) { printf("Optional Information:\n"); int aNumVersionNames = sizeof(aVersionNames) / sizeof(const char*); for (int i = 0; i < aNumVersionNames; i++) { const char* aVersionName = aVersionNames[i]; const char* aVersionString = GetVersionString(aVersionInfo, aVersionName); if (aVersionString) printf(" %s: %s\n", aVersionName, aVersionString); } } bool GetFullPathName(const char* aFileName, char* aPathName, unsigned int aSize) { #ifdef __CYGWIN__ cygwin_conv_to_full_win32_path(aFileName, aPathName); return true; #else char *aDummy; DWORD aStatus = GetFullPathName (aFileName, aSize, aPathName, &aDummy); return (aStatus > 0); #endif // __CYGWIN__ } void PrintUsage() { printf("usage: version files...\n"); }