24f3f43457
add version_info and icon sections in "export to windows platform". add version_info and icon to godot exe file (editor & template exe). fix an problem in image class. change all default icons to android export icon (a little more rounded). create an python script for convert file to cpp byte array for use in 'splash.h'.
110 lines
4.8 KiB
C++
110 lines
4.8 KiB
C++
#include "resource_message_list_reader.h"
|
|
#include "pe_resource_viewer.h"
|
|
|
|
namespace pe_bliss
|
|
{
|
|
using namespace pe_win;
|
|
|
|
resource_message_list_reader::resource_message_list_reader(const pe_resource_viewer& res)
|
|
:res_(res)
|
|
{}
|
|
|
|
//Helper function of parsing message list table
|
|
const resource_message_list resource_message_list_reader::parse_message_list(const std::string& resource_data)
|
|
{
|
|
resource_message_list ret;
|
|
|
|
//Check resource data length
|
|
if(resource_data.length() < sizeof(message_resource_data))
|
|
throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
|
|
|
|
const message_resource_data* message_data = reinterpret_cast<const message_resource_data*>(resource_data.data());
|
|
|
|
//Check resource data length more carefully and some possible overflows
|
|
if(message_data->NumberOfBlocks >= pe_utils::max_dword / sizeof(message_resource_block)
|
|
|| !pe_utils::is_sum_safe(message_data->NumberOfBlocks * sizeof(message_resource_block), sizeof(message_resource_data))
|
|
|| resource_data.length() < message_data->NumberOfBlocks * sizeof(message_resource_block) + sizeof(message_resource_data))
|
|
throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
|
|
|
|
//Iterate over all message resource blocks
|
|
for(unsigned long i = 0; i != message_data->NumberOfBlocks; ++i)
|
|
{
|
|
//Get block
|
|
const message_resource_block* block =
|
|
reinterpret_cast<const message_resource_block*>(resource_data.data() + sizeof(message_resource_data) - sizeof(message_resource_block) + sizeof(message_resource_block) * i);
|
|
|
|
//Check resource data length and IDs
|
|
if(resource_data.length() < block->OffsetToEntries || block->LowId > block->HighId)
|
|
throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
|
|
|
|
unsigned long current_pos = 0;
|
|
static const unsigned long size_of_entry_headers = 4;
|
|
//List all message resource entries in block
|
|
for(uint32_t curr_id = block->LowId; curr_id <= block->HighId; curr_id++)
|
|
{
|
|
//Check resource data length and some possible overflows
|
|
if(!pe_utils::is_sum_safe(block->OffsetToEntries, current_pos)
|
|
|| !pe_utils::is_sum_safe(block->OffsetToEntries + current_pos, size_of_entry_headers)
|
|
|| resource_data.length() < block->OffsetToEntries + current_pos + size_of_entry_headers)
|
|
throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
|
|
|
|
//Get entry
|
|
const message_resource_entry* entry = reinterpret_cast<const message_resource_entry*>(resource_data.data() + block->OffsetToEntries + current_pos);
|
|
|
|
//Check resource data length and entry length and some possible overflows
|
|
if(entry->Length < size_of_entry_headers
|
|
|| !pe_utils::is_sum_safe(block->OffsetToEntries + current_pos, entry->Length)
|
|
|| resource_data.length() < block->OffsetToEntries + current_pos + entry->Length
|
|
|| entry->Length < size_of_entry_headers)
|
|
throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
|
|
|
|
if(entry->Flags & message_resource_unicode)
|
|
{
|
|
//If string is UNICODE
|
|
//Check its length
|
|
if(entry->Length % 2)
|
|
throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
|
|
|
|
//Add ID and string to message table
|
|
#ifdef PE_BLISS_WINDOWS
|
|
ret.insert(std::make_pair(curr_id, message_table_item(
|
|
std::wstring(reinterpret_cast<const wchar_t*>(resource_data.data() + block->OffsetToEntries + current_pos + size_of_entry_headers),
|
|
(entry->Length - size_of_entry_headers) / 2)
|
|
)));
|
|
#else
|
|
ret.insert(std::make_pair(curr_id, message_table_item(
|
|
pe_utils::from_ucs2(u16string(reinterpret_cast<const unicode16_t*>(resource_data.data() + block->OffsetToEntries + current_pos + size_of_entry_headers),
|
|
(entry->Length - size_of_entry_headers) / 2))
|
|
)));
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
//If string is ANSI
|
|
//Add ID and string to message table
|
|
ret.insert(std::make_pair(curr_id, message_table_item(
|
|
std::string(resource_data.data() + block->OffsetToEntries + current_pos + size_of_entry_headers,
|
|
entry->Length - size_of_entry_headers)
|
|
)));
|
|
}
|
|
|
|
//Go to next entry
|
|
current_pos += entry->Length;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
//Returns message table data by ID and index in language directory (instead of language)
|
|
const resource_message_list resource_message_list_reader::get_message_table_by_id(uint32_t id, uint32_t index) const
|
|
{
|
|
return parse_message_list(res_.get_resource_data_by_id(pe_resource_viewer::resource_message_table, id, index).get_data());
|
|
}
|
|
|
|
//Returns message table data by ID and language
|
|
const resource_message_list resource_message_list_reader::get_message_table_by_id_lang(uint32_t language, uint32_t id) const
|
|
{
|
|
return parse_message_list(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_message_table, id).get_data());
|
|
}
|
|
}
|