#pragma once
// WAC.com Class Liblary for Visual C++
// Copyright (C) WAC.com Inc. All rights reserved.
//
// This file is a part of the WAC.com Class Liblary.
// The use and distribution terms for this software are covered by the
// Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
// which can be found in the file CPL.TXT at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license. You must not remove this notice, or
// any other, from this software.
// '06.09.12 : UNICODE対応 (sha)
#include <WinVer.h>
#pragma comment(lib, "Version.lib")
#include <vector>
////////////////////////////////////////////////////////////////////////////////
// 言語&コードページ
struct LANGANDCODEPAGE
{
WORD wLanguage;
WORD wCodePage;
};
class CLangAndCodePage : public LANGANDCODEPAGE
{
public:
CLangAndCodePage()
{
wLanguage = 0;
wCodePage = 0;
}
CLangAndCodePage(const LANGANDCODEPAGE& wLangAndCodePageSrc)
{
wLanguage = wLangAndCodePageSrc.wLanguage;
wCodePage = wLangAndCodePageSrc.wCodePage;
}
CLangAndCodePage(WORD wLanguageSrc, WORD wCodePageSrc)
{
wLanguage = wLanguageSrc;
wCodePage = wCodePageSrc;
}
};
////////////////////////////////////////////////////////////////////////////////
// CFileVersionInfo
class CFileVersionInfo
{
protected:
typedef CFileVersionInfo thisClass;
public:
CFileVersionInfo()
{
}
CFileVersionInfo(LPCTSTR szFileName, CLangAndCodePage LangAndCodePage)
{
HRESULT hr = S_OK;
hr = this->Load(szFileName, LangAndCodePage);
if (FAILED(hr))
{
// 無視する。。
}
}
CFileVersionInfo(LPCTSTR szFileName)
{
HRESULT hr = S_OK;
hr = this->Load(szFileName);
if (FAILED(hr))
{
// 無視する。。
}
}
virtual ~CFileVersionInfo()
{
}
public:
CString GetComments()
{
return m_strComments;
}
CString GetCompanyName()
{
return m_strCompanyName;
}
CString GetFileDescription()
{
return m_strFileDescription;
}
CString GetFileVersion()
{
return m_strFileVersion;
}
CString GetInternalName()
{
return m_strInternalName;
}
CString GetLegalCopyright()
{
return m_strLegalCopyright;
}
CString GetLegalTrademarks()
{
return m_strLegalTrademarks;
}
CString GetOriginalTrademarks()
{
return m_strOriginalFilename;
}
CString GetPrivateBuild()
{
return m_strPrivateBuild;
}
CString GetProductName()
{
return m_strProductName;
}
CString GetProductVersion()
{
return m_strProductVersion;
}
CString GetSpecialBuild()
{
return m_strSpecialBuild;
}
public:
HRESULT Load(LPCTSTR szFileName, CLangAndCodePage LangAndCodePage)
{
if (szFileName == NULL)
{
return E_FAIL;
}
HRESULT hr = S_OK;
LPVOID lpBlock = thisClass::_AllocFileVersionInfoBlock(szFileName);
if (lpBlock == NULL)
{
return E_OUTOFMEMORY;
}
hr = thisClass::InternalGetStringFileInfo(lpBlock, LangAndCodePage, _T("Comments"), m_strComments);
hr = thisClass::InternalGetStringFileInfo(lpBlock, LangAndCodePage, _T("CompanyName"), m_strCompanyName);
hr = thisClass::InternalGetStringFileInfo(lpBlock, LangAndCodePage, _T("FileDescription"), m_strFileDescription);
hr = thisClass::InternalGetStringFileInfo(lpBlock, LangAndCodePage, _T("FileVersion"), m_strFileVersion);
hr = thisClass::InternalGetStringFileInfo(lpBlock, LangAndCodePage, _T("InternalName"), m_strInternalName);
hr = thisClass::InternalGetStringFileInfo(lpBlock, LangAndCodePage, _T("LegalCopyright"), m_strLegalCopyright);
hr = thisClass::InternalGetStringFileInfo(lpBlock, LangAndCodePage, _T("LegalTrademarks"), m_strLegalTrademarks);
hr = thisClass::InternalGetStringFileInfo(lpBlock, LangAndCodePage, _T("OriginalFilename"), m_strOriginalFilename);
hr = thisClass::InternalGetStringFileInfo(lpBlock, LangAndCodePage, _T("PrivateBuild"), m_strPrivateBuild);
hr = thisClass::InternalGetStringFileInfo(lpBlock, LangAndCodePage, _T("ProductName"), m_strProductName);
hr = thisClass::InternalGetStringFileInfo(lpBlock, LangAndCodePage, _T("ProductVersion"), m_strProductVersion);
hr = thisClass::InternalGetStringFileInfo(lpBlock, LangAndCodePage, _T("SpecialBuild"), m_strSpecialBuild);
thisClass::_FreeFileVersionInfoBlock(lpBlock);
return S_OK;
}
HRESULT Load(LPCTSTR szFileName)
{
if (szFileName == NULL)
{
return E_FAIL;
}
HRESULT hr = S_OK;
std::vector<CLangAndCodePage> LangAndCodePages;
hr = thisClass::EnumLangAndCodePages(szFileName, LangAndCodePages);
if (FAILED(hr))
{
return hr;
}
return this->Load(szFileName, LangAndCodePages[0]);
}
public:
static HRESULT EnumLangAndCodePages(LPCTSTR szFileName, std::vector<CLangAndCodePage>& LangAndCodePages)
{
if (szFileName == NULL)
{
return E_FAIL;
}
HRESULT hr = S_OK;
LPVOID lpBlock = _AllocFileVersionInfoBlock(szFileName);
if (lpBlock == NULL)
{
// return E_OUTOFMEMORY;
return E_FAIL;
}
hr = InternalEnumLangAndCodePages(lpBlock, LangAndCodePages);
_FreeFileVersionInfoBlock(lpBlock);
return hr;
}
static HRESULT GetFileInfo(LPCTSTR szFileName, VS_FIXEDFILEINFO* pFileInfo)
{
if (szFileName == NULL)
{
return E_FAIL;
}
if (pFileInfo == NULL)
{
return E_FAIL;
}
HRESULT hr = S_OK;
LPVOID lpBlock = thisClass::_AllocFileVersionInfoBlock(szFileName);
if (lpBlock == NULL)
{
// return E_OUTOFMEMORY;
return E_FAIL;
}
hr = thisClass::InternalGetFileInfo(lpBlock, pFileInfo);
thisClass::_FreeFileVersionInfoBlock(lpBlock);
return hr;
}
static HRESULT GetStringFileInfo(LPCTSTR szFileName, CLangAndCodePage LangAndCodePage, LPCTSTR szName, CString& strValue)
{
if (szFileName == NULL)
{
return E_FAIL;
}
HRESULT hr = S_OK;
LPVOID lpBlock = thisClass::_AllocFileVersionInfoBlock(szFileName);
if (lpBlock == NULL)
{
// return E_OUTOFMEMORY;
return E_FAIL;
}
hr = thisClass::InternalGetStringFileInfo(lpBlock, LangAndCodePage, szName, strValue);
thisClass::_FreeFileVersionInfoBlock(lpBlock);
return hr;
}
protected:
// ファイルバージョン情報ブロック
// http://support.microsoft.com/default.aspx?scid=kb;ja;826496
static LPVOID _AllocFileVersionInfoBlock(LPCTSTR szFileName)
{
if (szFileName == NULL)
{
return NULL;
}
DWORD dwHandle = 0;
DWORD dwBlockSize = ::GetFileVersionInfoSize((LPTSTR)szFileName, &dwHandle);
if (dwBlockSize <= 0)
{
return NULL;
}
LPVOID lpBlock = ::CoTaskMemAlloc(dwBlockSize);
if (lpBlock == NULL)
{
return NULL;
}
BOOL br = ::GetFileVersionInfo((LPTSTR)szFileName, dwHandle, dwBlockSize, lpBlock);
if (br == FALSE)
{
::CoTaskMemFree(lpBlock);
return NULL;
}
return lpBlock;
}
static void _FreeFileVersionInfoBlock(LPVOID lpBlock)
{
::CoTaskMemFree(lpBlock);
}
protected:
static HRESULT InternalEnumLangAndCodePages(const LPVOID lpBlock, std::vector<CLangAndCodePage>& LangAndCodePages)
{
if (lpBlock == NULL)
{
return E_FAIL;
}
// クリアする
LangAndCodePages.clear();
CString strSubBlock = _T("\\VarFileInfo\\Translation");
LPVOID lpBuffer = NULL;
UINT uLen = 0;
BOOL br = ::VerQueryValue(lpBlock, (LPTSTR)(LPCTSTR)strSubBlock, (LPVOID*)&lpBuffer, &uLen);
if (br == 0)
{
DWORD dwError = ::GetLastError();
return HRESULT_FROM_WIN32(dwError);
}
for (int i = 0; i < (int)(uLen / sizeof(struct LANGANDCODEPAGE)); i++)
{
LANGANDCODEPAGE* pLangAndCodePage = (LANGANDCODEPAGE*)lpBuffer;
ATLASSERT(pLangAndCodePage);
LangAndCodePages.push_back(pLangAndCodePage[i]);
}
return S_OK;
}
static HRESULT InternalGetFileInfo(const LPVOID lpBlock, VS_FIXEDFILEINFO* pFileInfo)
{
if (lpBlock == NULL)
{
return E_FAIL;
}
if (pFileInfo == NULL)
{
return E_FAIL;
}
// クリアする
::ZeroMemory(pFileInfo, sizeof(VS_FIXEDFILEINFO));
CString strSubBlock = _T("\\");
LPVOID lpBuffer = NULL;
UINT uLen = 0;
BOOL br = ::VerQueryValue(lpBlock, (LPTSTR)(LPCTSTR)strSubBlock, &lpBuffer, &uLen);
if (br == 0)
{
DWORD dwError = ::GetLastError();
return HRESULT_FROM_WIN32(dwError);
}
memcpy(pFileInfo, lpBuffer, sizeof(VS_FIXEDFILEINFO));
return S_OK;
}
// szName = "Comments" or "CompanyName" or "FileDescription" or "FileVersion" or
// "InternalName" or "LegalCopyright" or "LegalTrademarks" or "OriginalFilename" or
// "PrivateBuild" or "ProductName" or "ProductVersion" or "SpecialBuild"
static HRESULT InternalGetStringFileInfo(const LPVOID lpBlock, CLangAndCodePage LangAndCodePage, LPCTSTR szName, CString& strValue)
{
if (lpBlock == NULL)
{
return E_FAIL;
}
// クリアする
strValue = _T("");
CString strSubBlock;
strSubBlock.Format(_T("\\StringFileInfo\\%04x%04x\\%s"), LangAndCodePage.wLanguage, LangAndCodePage.wCodePage, szName);
LPVOID lpBuffer = NULL;
UINT uLen = 0;
BOOL br = ::VerQueryValue(lpBlock, (LPTSTR)(LPCTSTR)strSubBlock, &lpBuffer, &uLen);
if (br == 0)
{
DWORD dwError = ::GetLastError();
return HRESULT_FROM_WIN32(dwError);
}
strValue = (LPCTSTR)lpBuffer;
return S_OK;
}
protected:
CString m_strFileName;
CString m_strComments;
CString m_strCompanyName;
CString m_strFileDescription;
CString m_strFileVersion;
CString m_strInternalName;
CString m_strLegalCopyright;
CString m_strLegalTrademarks;
CString m_strOriginalFilename;
CString m_strPrivateBuild;
CString m_strProductName;
CString m_strProductVersion;
CString m_strSpecialBuild;
};