version.cpp

 // version.cpp file
//---------------------------------------------------------------------------
#include "version.h"
#include <assert.h>
#include <tchar.h>
//---------------------------------------------------------------------------

#pragma comment(lib, "version.lib")

CVersionInfo::CVersionInfo(void)
{
    // Set the file path variable equal to the current application path
    m_pszFilePath = new _TCHAR[MAX_PATH];

    unsigned int nLength = GetModuleFileName(NULL, m_pszFilePath, MAX_PATH);
    m_bValidPath = (nLength > 0);

    // A valid filepath must exist
    if(!m_bValidPath)
        return;

    m_bVersionInfoExists = GetLanguageCodes();
}

bool CVersionInfo::SetFilePath(LPCTSTR szPath)
{
    bool bReturn = false;

    // Make sure the path parameter points to a valid file
    GET_FILEEX_INFO_LEVELS fxInfoLevels;
fxInfoLevels = GetFileExInfoStandard;
    WIN32_FILE_ATTRIBUTE_DATA fileAttribs;

    // Copy path parameter to internal variable (handling Unicode reqs)
#ifdef _UNICODE
    _tcscpy(m_pszFilePath, _T("\\\\?\"));
    _tcscat(m_pszFilePath, szPath);
#else
    strcpy(m_pszFilePath, szPath);
#endif

    // Verify existance of file
    m_bValidPath = (GetFileAttributesEx(m_pszFilePath, fxInfoLevels,
        (void*)&fileAttribs) ? true : false);

    // A valid filepath must be passed in
    if(m_bValidPath)
    {
        m_bVersionInfoExists = GetLanguageCodes();
        bReturn = m_bVersionInfoExists;
    }

    return bReturn;
}

CVersionInfo::~CVersionInfo(void)
{
    // Free allocated memory
    if(m_pszFilePath)
        delete [] m_pszFilePath;
    while(m_lstLangCode.size() > 0)
{
delete *(m_lstLangCode.begin());
m_lstLangCode.pop_front();
}
}

bool CVersionInfo::GetLanguageCodes(void)
{
    bool bReturn = false;

    // Determine if version info exists for selected application
    DWORD dwVerHnd = 0;
    LPVOID  lpvMem = NULL;

    DWORD dwVerInfoSize = GetFileVersionInfoSize(m_pszFilePath, &dwVerHnd);

    // If version info exists...
    if (dwVerInfoSize)
    { 
        bReturn = true;
        HANDLE  hMem;
        LPVOID  lpvMem;

        hMem = GlobalAlloc(GMEM_MOVEABLE, dwVerInfoSize);
        lpvMem = GlobalLock(hMem);
        GetFileVersionInfo(m_pszFilePath, dwVerHnd, dwVerInfoSize, lpvMem);

        // Structure used to store enumerated languages and code pages.
        struct LANGANDCODEPAGE {
            WORD wLanguage;
            WORD wCodePage;
        } *lpTranslate;
        UINT cbTranslate = 0;

        // Read the list of languages and code pages.
        VerQueryValue(lpvMem, _T("\\VarFileInfo\\Translation"),
        (void**)&lpTranslate, &cbTranslate);

        // Store the code for each language in version info.
        if(m_lstLangCode.size() > 0)
            m_lstLangCode.clear();
        int nLang = 0;
        for( ;nLang<(cbTranslate/sizeof(struct LANGANDCODEPAGE));nLang++ )
        {
            LPTSTR szLangCode = new _TCHAR[26];
            wsprintf(szLangCode, _T("\\StringFileInfo\\%04x%04x\"),
                lpTranslate[nLang].wLanguage, lpTranslate[nLang].wCodePage);
            m_lstLangCode.push_back(szLangCode);
        }
        m_nLangCount = nLang;

        GlobalUnlock(hMem);
        GlobalFree(hMem);
    }
    else
    {           
        m_nLangCount = 0;
    }

    // Set default language
    m_nLanguage = 0;

    return bReturn;
}

bool CVersionInfo::SetLanguage(int nLanguage)
{
    bool bReturn = false;

    if(nLanguage >= 0 && nLanguage < m_nLangCount && m_nLangCount > 0)
    {         
        bReturn = true;
        m_nLanguage = nLanguage;
    }

    return bReturn;
}

int CVersionInfo::GetLanguageCount(void)
{
    return m_nLangCount;
}

LPTSTR CVersionInfo::GetData(LPCTSTR szData)
{
    LPTSTR szReturn = NULL;

    // Create query string
    LPTSTR szRequest = new _TCHAR[_tcsclen(szData) + 26];
    list<LPTSTR>::iterator itr = m_lstLangCode.begin();

    for(int nPos=0;nPos<m_nLanguage;nPos++)
        itr++;
    _tcscpy(szRequest, *itr);
    _tcscat(szRequest, szData);

    // Get version information from the application
    DWORD dwVerHnd = 0;
    DWORD dwVerInfoSize = GetFileVersionInfoSize(m_pszFilePath, &dwVerHnd);
    if (dwVerInfoSize)
    {
        // If we were able to get the information, process it:
        HANDLE  hMem;
        LPVOID  lpvMem;

        hMem = GlobalAlloc(GMEM_MOVEABLE, dwVerInfoSize);
        lpvMem = GlobalLock(hMem);
        GetFileVersionInfo(m_pszFilePath, dwVerHnd, dwVerInfoSize, lpvMem);

        LPSTR pszReturn = NULL;
        UINT nVerSize = 0;

        if(VerQueryValue(lpvMem, szRequest,
            (void**)&pszReturn, &nVerSize))
        {
            szReturn = new _TCHAR[_tcsclen(pszReturn) + 1];
            _tcscpy(szReturn, pszReturn);
delete [] szRequest;
        }

        GlobalUnlock(hMem);
        GlobalFree(hMem);
    }
    return szReturn;
}

LPTSTR CVersionInfo::GetComments(void)
{
    return GetData(_T("Comments"));
}

LPTSTR CVersionInfo::GetCompanyName(void)
{
    return GetData(_T("CompanyName"));
}

LPTSTR CVersionInfo::GetFileDescription(void)
{
    return GetData(_T("FileDescription"));
}

LPTSTR CVersionInfo::GetFileVersion(void)
{
    return GetData(_T("FileVersion"));
}

LPTSTR CVersionInfo::GetInternalName(void)
{
    return GetData(_T("InternalName"));
}

LPTSTR CVersionInfo::GetLegalCopyright(void)
{
    return GetData(_T("LegalCopyright"));
}

LPTSTR CVersionInfo::GetLegalTrademarks(void)
{
    return GetData(_T("LegalTrademarks"));
}

LPTSTR CVersionInfo::GetOriginalFilename(void)
{
    return GetData(_T("OriginalFilename"));
}

LPTSTR CVersionInfo::GetProductName(void)
{
    return GetData(_T("ProductName"));
}

LPTSTR CVersionInfo::GetProductVersion(void)
{
    return GetData(_T("ProductVersion"));
}

LPTSTR CVersionInfo::GetPrivateBuild(void)
{
    return GetData(_T("PrivateBuild"));
}

LPTSTR CVersionInfo::GetSpecialBuild(void)
{
    return GetData(_T("SpecialBuild"));
}

Project Homepage: