godot/tools/pe_bliss/version_info_viewer.cpp

181 lines
6.2 KiB
C++

/*************************************************************************/
/* Copyright (c) 2015 dx, http://kaimi.ru */
/* */
/* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following conditions: */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include <iomanip>
#include <sstream>
#include "pe_exception.h"
#include "version_info_viewer.h"
namespace pe_bliss
{
//Default process language, UNICODE
const std::wstring version_info_viewer::default_language_translation(L"040904b0");
//Default constructor
//strings - version info strings with charsets
//translations - version info translations map
version_info_viewer::version_info_viewer(const lang_string_values_map& strings, const translation_values_map& translations)
:strings_(strings), translations_(translations)
{}
//Below functions have parameter translation
//If it's empty, the default language translation will be taken
//If there's no default language translation, the first one will be taken
//Returns company name
const std::wstring version_info_viewer::get_company_name(const std::wstring& translation) const
{
return get_property(L"CompanyName", translation);
}
//Returns file description
const std::wstring version_info_viewer::get_file_description(const std::wstring& translation) const
{
return get_property(L"FileDescription", translation);
}
//Returns file version
const std::wstring version_info_viewer::get_file_version(const std::wstring& translation) const
{
return get_property(L"FileVersion", translation);
}
//Returns internal file name
const std::wstring version_info_viewer::get_internal_name(const std::wstring& translation) const
{
return get_property(L"InternalName", translation);
}
//Returns legal copyright
const std::wstring version_info_viewer::get_legal_copyright(const std::wstring& translation) const
{
return get_property(L"LegalCopyright", translation);
}
//Returns original file name
const std::wstring version_info_viewer::get_original_filename(const std::wstring& translation) const
{
return get_property(L"OriginalFilename", translation);
}
//Returns product name
const std::wstring version_info_viewer::get_product_name(const std::wstring& translation) const
{
return get_property(L"ProductName", translation);
}
//Returns product version
const std::wstring version_info_viewer::get_product_version(const std::wstring& translation) const
{
return get_property(L"ProductVersion", translation);
}
//Returns list of translations in string representation
const version_info_viewer::translation_list version_info_viewer::get_translation_list() const
{
translation_list ret;
//Enumerate all translations
for(translation_values_map::const_iterator it = translations_.begin(); it != translations_.end(); ++it)
{
//Create string representation of translation value
std::wstringstream ss;
ss << std::hex
<< std::setw(4) << std::setfill(L'0') << (*it).first
<< std::setw(4) << std::setfill(L'0') << (*it).second;
//Save it
ret.push_back(ss.str());
}
return ret;
}
//Returns version info property value
//property_name - required property name
//If throw_if_absent = true, will throw exception if property does not exist
//If throw_if_absent = false, will return empty string if property does not exist
const std::wstring version_info_viewer::get_property(const std::wstring& property_name, const std::wstring& translation, bool throw_if_absent) const
{
std::wstring ret;
//If there're no strings
if(strings_.empty())
{
if(throw_if_absent)
throw pe_exception("Version info string does not exist", pe_exception::version_info_string_does_not_exist);
return ret;
}
lang_string_values_map::const_iterator it = strings_.begin();
if(translation.empty())
{
//If no translation was specified
it = strings_.find(default_language_translation); //Find default translation table
if(it == strings_.end()) //If there's no default translation table, take the first one
it = strings_.begin();
}
else
{
it = strings_.find(translation); //Find specified translation table
if(it == strings_.end())
{
if(throw_if_absent)
throw pe_exception("Version info string does not exist", pe_exception::version_info_string_does_not_exist);
return ret;
}
}
//Find value of the required property
string_values_map::const_iterator str_it = (*it).second.find(property_name);
if(str_it == (*it).second.end())
{
if(throw_if_absent)
throw pe_exception("Version info string does not exist", pe_exception::version_info_string_does_not_exist);
return ret;
}
ret = (*str_it).second;
return ret;
}
//Converts translation HEX-string to pair of language ID and codepage ID
const version_info_viewer::translation_pair version_info_viewer::translation_from_string(const std::wstring& translation)
{
uint32_t translation_id = 0;
{
//Convert string to DWORD
std::wstringstream ss;
ss << std::hex << translation;
ss >> translation_id;
}
return std::make_pair(static_cast<uint16_t>(translation_id >> 16), static_cast<uint16_t>(translation_id & 0xFFFF));
}
}