/* *(C) 2006 Roku LLC * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License Version 2 as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * without any warranty; without even the implied warranty of * merchantability or fitness for a particular purpose. See the GNU General * Public License for more details. * * Please read README.txt in the same directory as this source file for * further license information. */ #include "stdafx.h" #include "VersionInfo.h" bool VersionInfo::Open(const TCHAR *filename) { Close(); DWORD useless; m_size = GetFileVersionInfoSize(filename, &useless); if (m_size) { m_buffer = operator new(m_size); ::ZeroMemory(m_buffer, m_size); if (GetFileVersionInfo(filename, 0, static_cast(m_size), m_buffer)) { return IdentifySubBlock(); } else Close(); } return false; } bool VersionInfo::IdentifySubBlock() { m_subblock.Empty(); WORD required_langid = LANGIDFROMLCID(GetUserDefaultLCID()); UINT cbTranslate; struct LANGANDCODEPAGE { WORD wLanguage; WORD wCodePage; } *lpTranslate; if (VerQueryValue(m_buffer, _T("\\VarFileInfo\\Translation"), reinterpret_cast(&lpTranslate), &cbTranslate)) { // Try and find the user's language, but if we can't then just use the // first one in the file. int lang_index = -1; for(unsigned i=0; i < (cbTranslate/sizeof(struct LANGANDCODEPAGE)); i++ ) { // If we have an exact match then great. if (lpTranslate[i].wLanguage == required_langid) { lang_index = i; break; } // Otherwise settle for a primary language match and keep looking else if ((PRIMARYLANGID(lpTranslate[i].wLanguage) == PRIMARYLANGID(required_langid)) && (lang_index < 0)) { lang_index = i; } } if (lang_index < 0) { ATLTRACE("Failed to find a matching language. Just using the first one.\n"); lang_index = 0; } m_subblock.Format(_T("\\StringFileInfo\\%04x%04x\\"), lpTranslate[lang_index].wLanguage, lpTranslate[lang_index].wCodePage); return true; } return false; } void VersionInfo::Close() { if (m_buffer) { delete m_buffer; m_buffer = NULL; } } CString VersionInfo::GetString(const TCHAR *name) const { CString path = m_subblock + name; LPVOID buffer; UINT cb; if (VerQueryValue(m_buffer, const_cast(static_cast(path)), &buffer, &cb)) { return CString(static_cast(buffer), cb); } return CString(); } //CString VersionInfo::GetStringFileVersion() //{ // VerQueryValue(m_buffer, //}