Skip to content

Commit

Permalink
String tables containing unicode strings are now properly displayed.
Browse files Browse the repository at this point in the history
  • Loading branch information
JusticeRage committed May 23, 2016
1 parent 346ca36 commit 891f3f7
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 22 deletions.
6 changes: 3 additions & 3 deletions docs/writing-plugins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -660,10 +660,10 @@ Most of the time, you'll want to look at the actual resource bytes. A ``get_raw_
if (*resource->get_type() != "RT_STRING") {
return;
}
auto string_table = resource->interpret_as<const_shared_strings>();
std::cout << "Dumping a RT_STRING resource:" << std::endl;
auto string_table = resource->interpret_as<const_shared_wstrings>();
std::wcout << L"Dumping a RT_STRING resource:" << std::endl;
for (auto it = string_table->begin() ; it != string_table->end() ; ++it) {
std::cout << *it << std::endl;
std::wcout << *it << std::endl;
}

* ``pgroup_icon_directory`` for ``RT_GROUP_ICON`` and ``RT_GROUP_CURSOR``. Because of the way icons and cursors are stored in resources, an additional function ``reconstruct_icon`` was added to recreate a valid ICO file. Here is how you'd do it::
Expand Down
2 changes: 1 addition & 1 deletion include/manacommons/color.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ void set_color(Color c);

// TODO: Add these macros to all errors and warnings.
#ifdef _DEBUG
#define DEBUG_INFO " (" << __FILE__ << ":" << std::dec << std::dec << __LINE__ << ")"
#define DEBUG_INFO " (" << __FILE__ << ":" << std::dec << __LINE__ << ")"
#define DEBUG_INFO_PE " (" << __FILE__ << ":" << std::dec << __LINE__ << ", " << *pe.get_path() << ")"
#define DEBUG_INFO_INSIDEPE " (" << __FILE__ << ":" << std::dec << __LINE__ << ", " << *get_path() << ")"
#else
Expand Down
1 change: 1 addition & 0 deletions include/manape/pe.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ namespace mana {
typedef boost::shared_ptr<Section> pSection;
typedef boost::shared_ptr<std::vector<std::string> > shared_strings;
typedef boost::shared_ptr<const std::vector<std::string> > const_shared_strings;
typedef boost::shared_ptr<const std::vector<std::wstring> > const_shared_wstrings;
typedef boost::shared_ptr<std::vector<pSection> > shared_sections;
typedef boost::shared_ptr<std::vector<pResource> > shared_resources;
typedef boost::shared_ptr<const std::vector<boost::uint8_t> > shared_bytes;
Expand Down
5 changes: 5 additions & 0 deletions include/manape/resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
#include <vector>
#include <sstream>

// Used to write unicode STRING_TABLEs to files.
#include <fstream>
#include <codecvt>
#include <locale>

#include <boost/cstdint.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_array.hpp>
Expand Down
11 changes: 11 additions & 0 deletions include/manape/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,17 @@ std::string read_ascii_string(FILE* f, unsigned int max_bytes = 0);
*/
std::string read_prefixed_unicode_string(FILE* f);

/**
* @brief Reads a unicode string prefixed by its length in a file.
*
* /!\ The file cursor will be updated accordingly!
*
* @param FILE* f The file from which to read. The read will occur at the cursor's current position!
*
* @return The string at the current location in the file.
*/
std::wstring read_prefixed_unicode_wstring(FILE* f);

/**
* @brief Reads a (double-)null-terminated unicode string.
*
Expand Down
22 changes: 11 additions & 11 deletions manape/resources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,9 @@ DECLSPEC pString Resource::interpret_as()
// ----------------------------------------------------------------------------

template<>
DECLSPEC const_shared_strings Resource::interpret_as()
DECLSPEC const_shared_wstrings Resource::interpret_as()
{
auto res = boost::make_shared<std::vector<std::string> >();
auto res = boost::make_shared<std::vector<std::wstring> >();
if (_type != "RT_STRING")
{
PRINT_WARNING << "Resources of type " << _type << " cannot be interpreted as vectors of strings." << DEBUG_INFO << std::endl;
Expand All @@ -291,7 +291,7 @@ DECLSPEC const_shared_strings Resource::interpret_as()

// RT_STRING resources are made of 16 contiguous "unicode" strings.
for (int i = 0; i < 16; ++i) {
res->push_back(utils::read_prefixed_unicode_string(f));
res->push_back(utils::read_prefixed_unicode_wstring(f));
}

END:
Expand Down Expand Up @@ -686,27 +686,27 @@ bool Resource::extract(const boost::filesystem::path& destination)
{
// RT_STRINGs are written immediately to the file instead of trying to reconstruct
// an original byte stream.
auto strings = interpret_as<const_shared_strings>();
auto strings = interpret_as<const_shared_wstrings>();
if (strings->size() == 0) {
return true;
}

FILE* out = fopen(destination.string().c_str(), "w");
if (out == nullptr)
std::wofstream out(destination.wstring(), std::ios_base::out | std::ios_base::app);
const std::locale utf8_locale = std::locale(std::locale(), new std::codecvt_utf8<wchar_t>());
out.imbue(utf8_locale);
if (out.fail())
{
PRINT_ERROR << "Could not open/create " << destination << "!" << std::endl;
return false;
}

for (auto it2 = strings->begin(); it2 != strings->end(); ++it2)
{
if ((*it2) != "")
{
fwrite(it2->c_str(), 1, it2->size(), out);
fputc('\n', out);
if (*it2 != L"") {
out << *it2 << std::endl;
}
}
fclose(out);
out.close();
return true;
}
else {
Expand Down
15 changes: 11 additions & 4 deletions manape/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,13 @@ std::string read_unicode_string(FILE* f, unsigned int max_bytes)

// ----------------------------------------------------------------------------

std::string read_prefixed_unicode_string(FILE* f)
std::wstring read_prefixed_unicode_wstring(FILE* f)
{
std::wstring s = std::wstring();
wchar_t c = 0;
boost::uint16_t size;
if (2 !=fread(&size, 1, 2, f)) {
return "";
if (2 != fread(&size, 1, 2, f)) {
return L"";
}

// Microsoft's "unicode" strings are word aligned.
Expand All @@ -87,7 +87,14 @@ std::string read_prefixed_unicode_string(FILE* f)
}
s += c;
}
s += L'\0';
return s;
}

// ----------------------------------------------------------------------------

std::string read_prefixed_unicode_string(FILE* f)
{
std::wstring s = read_prefixed_unicode_wstring(f);

// Convert the wstring into a string
auto conv = boost::shared_array<char>(new char[s.size() + 1]);
Expand Down
6 changes: 3 additions & 3 deletions test/resources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,10 @@ BOOST_AUTO_TEST_CASE(interpret_stringtable)
mana::PE pe("testfiles/manatest2.exe");
auto resources = pe.get_resources();
BOOST_ASSERT(resources->size() == 14);
auto string_table = resources->at(10)->interpret_as<const_shared_strings>();
auto string_table = resources->at(10)->interpret_as<mana::const_shared_wstrings>();
BOOST_ASSERT(string_table && string_table->size() == 16);
BOOST_CHECK_EQUAL(string_table->at(7), "Test 1");
BOOST_CHECK_EQUAL(string_table->at(8), "Test 2");
BOOST_CHECK(string_table->at(7) == L"Test 1");
BOOST_CHECK(string_table->at(8) == L"Test 2");
}

// ----------------------------------------------------------------------------
Expand Down

0 comments on commit 891f3f7

Please sign in to comment.