From ca5bb76d2b8f65aa97e50b633f828c1deb241526 Mon Sep 17 00:00:00 2001 From: Nicolas Pennequin Date: Fri, 11 Jul 2008 16:51:25 +0000 Subject: Delete the svn:executable property and set svn:eol-style to native for all those text files. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18012 a1c6a512-1295-4272-9138-f99709370657 --- .../pelib-0.9/pelib/ResourceDirectory.cpp | 2994 ++++++++++---------- 1 file changed, 1497 insertions(+), 1497 deletions(-) mode change 100755 => 100644 utils/zenutils/libraries/pelib-0.9/pelib/ResourceDirectory.cpp (limited to 'utils/zenutils/libraries/pelib-0.9/pelib/ResourceDirectory.cpp') diff --git a/utils/zenutils/libraries/pelib-0.9/pelib/ResourceDirectory.cpp b/utils/zenutils/libraries/pelib-0.9/pelib/ResourceDirectory.cpp old mode 100755 new mode 100644 index 5e4d3010bf..d1e4c59e5a --- a/utils/zenutils/libraries/pelib-0.9/pelib/ResourceDirectory.cpp +++ b/utils/zenutils/libraries/pelib-0.9/pelib/ResourceDirectory.cpp @@ -1,1497 +1,1497 @@ -/* -* ResourceDirectory.h - Part of the PeLib library. -* -* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com) -* All rights reserved. -* -* This software is licensed under the zlib/libpng License. -* For more details see http://www.opensource.org/licenses/zlib-license.php -* or the license information file (license.htm) in the root directory -* of PeLib. -*/ - -#include "ResourceDirectory.h" - -namespace PeLib -{ -// -------------------------------------------------- ResourceChild ------------------------------------------- - - ResourceChild::ResourceChild() - { - } - - ResourceChild::ResourceChild(const ResourceChild& rhs) - { - if (dynamic_cast(rhs.child)) - { - ResourceNode* oldnode = static_cast(rhs.child); - - entry = rhs.entry; - - child = new ResourceNode; - child->uiElementRva = rhs.child->getElementRva(); - static_cast(child)->header = oldnode->header; - static_cast(child)->children = oldnode->children; - } - else - { - ResourceLeaf* oldnode = static_cast(rhs.child); - - child = new ResourceLeaf; - child->uiElementRva = rhs.child->getElementRva(); - static_cast(child)->m_data = oldnode->m_data; - static_cast(child)->entry = oldnode->entry; - } - } - - ResourceChild& ResourceChild::operator=(const ResourceChild& rhs) - { - if (this != &rhs) - { - if (dynamic_cast(rhs.child)) - { - ResourceNode* oldnode = static_cast(rhs.child); - - entry = rhs.entry; - - child = new ResourceNode; - child->uiElementRva = rhs.child->getElementRva(); - static_cast(child)->header = oldnode->header; - static_cast(child)->children = oldnode->children; - } - else - { - ResourceLeaf* oldnode = static_cast(rhs.child); - - child = new ResourceLeaf; - child->uiElementRva = rhs.child->getElementRva(); - static_cast(child)->m_data = oldnode->m_data; - static_cast(child)->entry = oldnode->entry; - } - } - - return *this; - } - - ResourceChild::~ResourceChild() - { - delete child; - } - - /** - * Compares the resource child's id to the parameter dwId. - * @param dwId ID of a resource. - * @return True, if the resource child's id equals the parameter. - **/ - bool ResourceChild::equalId(dword dwId) const - { - return entry.irde.Name == dwId; - } - - /** - * Compares the resource child's name to the parameter strName. - * @param strName ID of a resource. - * @return True, if the resource child's name equals the parameter. - **/ - bool ResourceChild::equalName(std::string strName) const - { - return entry.wstrName == strName; - } - - /** - * Returns true if the resource was given a name. - **/ - bool ResourceChild::isNamedResource() const - { - return entry.wstrName.size() != 0; - } - - /** - * The children of a resource must be ordered in a certain way. First come the named resources - * in sorted order, afterwards followed the unnamed resources in sorted order. - **/ - bool ResourceChild::operator<(const ResourceChild& rc) const - { - if (this->isNamedResource() && !rc.isNamedResource()) - { - return true; - } - else if (!this->isNamedResource() && rc.isNamedResource()) - { - return false; - } - else if (this->isNamedResource() && rc.isNamedResource()) - { - return this->entry.wstrName < rc.entry.wstrName; - } - else - { - return this->entry.irde.Name < rc.entry.irde.Name; - } - } - -/* unsigned int ResourceChild::size() const - { - return PELIB_IMAGE_RESOURCE_DIRECTORY_ENTRY::size() - + child->size() - + (entry.wstrName.size() ? entry.wstrName.size() + 2 : 0); - } -*/ -// -------------------------------------------------- ResourceElement ------------------------------------------- - - /** - * Returns the RVA of a ResourceElement. This is the RVA where the ResourceElement can be - * found in the file. - * @return RVA of the ResourceElement. - **/ - unsigned int ResourceElement::getElementRva() const - { - return uiElementRva; - } - -// -------------------------------------------------- ResourceLeaf ------------------------------------------- - - /** - * Checks if a ResourceElement is a leaf or not. - * @return Always returns true. - **/ - bool ResourceLeaf::isLeaf() const - { - return true; - } - - /** - * Reads the next resource leaf from the InputBuffer. - * @param inpBuffer An InputBuffer that holds the complete resource directory. - * @param uiOffset Offset of the resource leaf that's to be read. - * @param uiRva RVA of the beginning of the resource directory. - * @param pad Used for debugging purposes. - **/ - int ResourceLeaf::read(InputBuffer& inpBuffer, unsigned int uiOffset, unsigned int uiRva/*, const std::string& pad*/) - { -// std::cout << pad << "Leaf:" << std::endl; - - // Invalid leaf. - if (uiOffset + PELIB_IMAGE_RESOURCE_DATA_ENTRY::size() > inpBuffer.size()) - { - return 1; - } - - uiElementRva = uiOffset + uiRva; - - inpBuffer.set(uiOffset); - - inpBuffer >> entry.OffsetToData; - inpBuffer >> entry.Size; - inpBuffer >> entry.CodePage; - inpBuffer >> entry.Reserved; - -/* std::cout << pad << std::hex << "Offset: " << entry.OffsetToData << std::endl; - std::cout << pad << std::hex << "Size: " << entry.Size << std::endl; - std::cout << pad << std::hex << "CodePage: " << entry.CodePage << std::endl; - std::cout << pad << std::hex << "Reserved: " << entry.Reserved << std::endl; -*/ - // Invalid leaf. - if (entry.OffsetToData - uiRva + entry.Size > inpBuffer.size()) - { -// std::cout << entry.OffsetToData << " XXX " << uiRva << " - " << entry.Size << " - " << inpBuffer.size() << std::endl; - return 1; - } - -// std::cout << entry.OffsetToData << " - " << uiRva << " - " << entry.Size << " - " << inpBuffer.size() << std::endl; - inpBuffer.set(entry.OffsetToData - uiRva); - m_data.assign(inpBuffer.data() + inpBuffer.get(), inpBuffer.data() + inpBuffer.get() + entry.Size); -// std::cout << pad << std::hex << "Vector: " << m_data.size() << std::endl; -// std::copy(m_data.begin(), m_data.end(), std::ostream_iterator(std::cout << std::hex, " ")); - return 0; - } - - /** - * Rebuilds the current resource leaf. - * @param obBuffer OutputBuffer where the rebuilt resource leaf is stored. - * @param uiOffset Offset of the resource leaf inside the resource directory. - * @param uiRva RVA of the resource directory. - **/ - void ResourceLeaf::rebuild(OutputBuffer& obBuffer, unsigned int& uiOffset, unsigned int uiRva, const std::string&) const - { -// std::cout << std::hex << pad << "Leaf: " << uiOffset << std::endl; - uiOffset += PELIB_IMAGE_RESOURCE_DATA_ENTRY::size(); - -// obBuffer << entry.OffsetToData; -// obBuffer << uiOffset; - obBuffer << uiRva + uiOffset + (uiOffset % 4); - obBuffer << entry.Size; - obBuffer << entry.CodePage; - obBuffer << entry.Reserved; - - while (uiOffset % 4) - { - uiOffset++; - obBuffer << (byte)0; - } - - uiOffset += static_cast(m_data.size()); - - for (unsigned int i=0;i(m_data.size()); - } - -/* /// Returns the size of a resource leaf. - unsigned int ResourceLeaf::size() const - { - return PELIB_IMAGE_RESOURCE_DATA_ENTRY::size() + m_data.size(); - } -*/ - - /** - * Returns a vector that contains the raw data of a resource leaf. - * @return Raw data of the resource. - **/ - std::vector ResourceLeaf::getData() const - { - return m_data; - } - - /** - * Overwrites the raw data of a resource. - * @param vData New data of the resource. - **/ - void ResourceLeaf::setData(const std::vector& vData) - { - m_data = vData; - } - - /** - * Returns the leaf's OffsetToData value. That's the RVA where the raw data of the resource - * can be found. - * @return The leaf's OffsetToData value. - **/ - dword ResourceLeaf::getOffsetToData() const - { - return entry.OffsetToData; - } - - /** - * Returns the leaf's Size value. That's the size of the raw data of the resource. - * @return The leaf's Size value. - **/ - dword ResourceLeaf::getSize() const - { - return entry.Size; - } - - /** - * Returns the leaf's CodePage value. - * @return The leaf's CodePage value. - **/ - dword ResourceLeaf::getCodePage() const - { - return entry.CodePage; - } - - /** - * Returns the leaf's Reserved value. - * @return The leaf's Reserved value. - **/ - dword ResourceLeaf::getReserved() const - { - return entry.Reserved; - } - - /** - * Sets the leaf's OffsetToData value. - * @param dwValue The leaf's new OffsetToData value. - **/ - void ResourceLeaf::setOffsetToData(dword dwValue) - { - entry.OffsetToData = dwValue; - } - - /** - * Sets the leaf's Size value. - * @param dwValue The leaf's new Size value. - **/ - void ResourceLeaf::setSize(dword dwValue) - { - entry.Size = dwValue; - } - - /** - * Sets the leaf's CodePage value. - * @param dwValue The leaf's new CodePage value. - **/ - void ResourceLeaf::setCodePage(dword dwValue) - { - entry.CodePage = dwValue; - } - - /** - * Sets the leaf's Reserved value. - * @param dwValue The leaf's new Reserved value. - **/ - void ResourceLeaf::setReserved(dword dwValue) - { - entry.Reserved = dwValue; - } - - -// -------------------------------------------------- ResourceNode ------------------------------------------- - - /** - * Checks if a ResourceElement is a leaf or not. - * @return Always returns false. - **/ - bool ResourceNode::isLeaf() const - { - return false; - } - - /** - * Sorts the node's children and corrects the node's header. - **/ - void ResourceNode::makeValid() - { - std::sort(children.begin(), children.end()); - header.NumberOfNamedEntries = static_cast(std::count_if(children.begin(), children.end(), std::mem_fun_ref(&ResourceChild::isNamedResource))); - header.NumberOfIdEntries = static_cast(children.size()) - header.NumberOfNamedEntries; - } - - /** - * Rebuilds the current resource node. - * @param obBuffer OutputBuffer where the rebuilt resource node is stored. - * @param uiOffset Offset of the resource node inside the resource directory. - * @param uiRva RVA of the resource directory. - * @param pad Used for debugging. - **/ - void ResourceNode::rebuild(OutputBuffer& obBuffer, unsigned int& uiOffset, unsigned int uiRva, const std::string& pad) const - { -/* std::cout << std::hex << pad << uiOffset << std::endl; - - std::cout << std::hex << pad << "header.Characteristics: " << header.Characteristics << std::endl; - std::cout << std::hex << pad << "header.TimeDateStamp: " << header.TimeDateStamp << std::endl; - std::cout << std::hex << pad << "header.MajorVersion: " << header.MajorVersion << std::endl; - std::cout << std::hex << pad << "header.MinorVersion: " << header.MinorVersion << std::endl; - std::cout << std::hex << pad << "header.NumberOfNamedEntries: " << header.NumberOfNamedEntries << std::endl; - std::cout << std::hex << pad << "header.NumberOfIdEntries: " << header.NumberOfIdEntries << std::endl; -*/ - obBuffer << header.Characteristics; - obBuffer << header.TimeDateStamp; - obBuffer << header.MajorVersion; - obBuffer << header.MinorVersion; - //std::cout << pad << "Children: " << children.size() << std::endl; - //std::cout << pad << std::count_if(children.begin(), children.end(), std::mem_fun_ref(&ResourceChild::isNamedResource)) << std::endl; - //std::cout << pad << children.size() - std::count_if(children.begin(), children.end(), std::mem_fun_ref(&ResourceChild::isNamedResource)) << std::endl; -// obBuffer << std::count_if(children.begin(), children.end(), std::mem_fun_ref(&ResourceChild::isNamedResource)); -// obBuffer << children.size() - std::count_if(children.begin(), children.end(), std::mem_fun_ref(&ResourceChild::isNamedResource)); - obBuffer << header.NumberOfNamedEntries; - obBuffer << header.NumberOfIdEntries; - - uiOffset += PELIB_IMAGE_RESOURCE_DIRECTORY::size(); - - for (unsigned int i=0;irebuild(obBuffer, newoffs, uiRva, pad + " "); - } - uiOffset = newoffs; - } - - /** - * Reads the next resource node from the InputBuffer. - * @param inpBuffer An InputBuffer that holds the complete resource directory. - * @param uiOffset Offset of the resource node that's to be read. - * @param uiRva RVA of the beginning of the resource directory. - * @param pad Something I need for debugging. Will be removed soon. - **/ - int ResourceNode::read(InputBuffer& inpBuffer, unsigned int uiOffset, unsigned int uiRva/*, const std::string& pad*/) - { - // Not enough space to be a valid node. - if (uiOffset + PELIB_IMAGE_RESOURCE_DIRECTORY::size() > inpBuffer.size()) - { - return 1; - } - - uiElementRva = uiOffset + uiRva; - - inpBuffer.set(uiOffset); - - inpBuffer >> header.Characteristics; - inpBuffer >> header.TimeDateStamp; - inpBuffer >> header.MajorVersion; - inpBuffer >> header.MinorVersion; - inpBuffer >> header.NumberOfNamedEntries; - inpBuffer >> header.NumberOfIdEntries; - - // Not enough space to be a valid node. - if (uiOffset + PELIB_IMAGE_RESOURCE_DIRECTORY::size() - + (header.NumberOfNamedEntries + header.NumberOfIdEntries) * PELIB_IMAGE_RESOURCE_DIRECTORY_ENTRY::size() - > inpBuffer.size()) - { - return 1; - } - -// std::cout << std::hex << pad << "Characteristics: " << header.Characteristics << std::endl; -// std::cout << std::hex << pad << "TimeDateStamp: " << header.TimeDateStamp << std::endl; -// std::cout << std::hex << pad << "MajorVersion: " << header.MajorVersion << std::endl; -// std::cout << std::hex << pad << "MinorVersion: " << header.MinorVersion << std::endl; -// std::cout << std::hex << pad << "NumberOfNamedEntries: " << header.NumberOfNamedEntries << std::endl; -// std::cout << std::hex << pad << "NumberOfIdEntries: " << header.NumberOfIdEntries << std::endl; - - for (int i=0;i> rc.entry.irde.Name; - inpBuffer >> rc.entry.irde.OffsetToData; - - unsigned int lastPos = inpBuffer.get(); - - if (rc.entry.irde.Name & PELIB_IMAGE_RESOURCE_NAME_IS_STRING) - { - // Enough space to read string length? - if ((rc.entry.irde.Name & ~PELIB_IMAGE_RESOURCE_NAME_IS_STRING) + 2 < inpBuffer.size()) - { - inpBuffer.set(rc.entry.irde.Name & ~PELIB_IMAGE_RESOURCE_NAME_IS_STRING); - word strlen; - inpBuffer >> strlen; - - // Enough space to read string? - if ((rc.entry.irde.Name & ~PELIB_IMAGE_RESOURCE_NAME_IS_STRING) + 2 * strlen < inpBuffer.size()) - { - wchar_t c; - for (word i=0;i> c; - rc.entry.wstrName += c; - } - } - } - -// std::wcout << rc.entry.wstrName << std::endl; - -// std::cout << strlen << std::endl; - inpBuffer.set(lastPos); - } - - if (rc.entry.irde.OffsetToData & PELIB_IMAGE_RESOURCE_DATA_IS_DIRECTORY) - { - rc.child = new ResourceNode; - rc.child->read(inpBuffer, rc.entry.irde.OffsetToData & ~PELIB_IMAGE_RESOURCE_DATA_IS_DIRECTORY, uiRva/*, pad + " "*/); - } - else - { - rc.child = new ResourceLeaf; - rc.child->read(inpBuffer, rc.entry.irde.OffsetToData, uiRva/*, pad + " "*/); - } -// std::cout << std::hex << pad << "Entry " << i << "(Name): " << rc.entry.irde.Name << std::endl; -// std::cout << std::hex << pad << "Entry " << i << "(Offset): " << rc.entry.irde.OffsetToData << std::endl; - - children.push_back(rc); - inpBuffer.set(lastPos); - } - - return 0; - } - - /** - * Returns the number of children of the current node. Note that this number is the number - * of defined children, not the value from the header. - * @return Number of node's children. - **/ - unsigned int ResourceNode::getNumberOfChildren() const - { - return static_cast(children.size()); - } - - /** - * Adds another child to the current node. - **/ - void ResourceNode::addChild() - { - ResourceChild c; - c.child = 0; - children.push_back(c); - } - - /** - * Returns a node's child. - * @param uiIndex Index of the child. - * @return The child identified by uiIndex. This child can be either a ResourceNode or a ResourceLeaf. - **/ - ResourceElement* ResourceNode::getChild(unsigned int uiIndex) - { - return children[uiIndex].child; - } - - /** - * Removes a child from the current node. - * @param uiIndex Index of the child. - **/ - void ResourceNode::removeChild(unsigned int uiIndex) - { - children.erase(children.begin() + uiIndex); - } - - /** - * Returns the name of a child. - * @param uiIndex Index of the child. - * @return Either the name of the specified child or an empty string. - **/ - std::string ResourceNode::getChildName(unsigned int uiIndex) const - { - return children[uiIndex].entry.wstrName; - } - - /** - * Returns the Name value of a child. - * @param uiIndex Index of the child. - * @return Name value of a child. - **/ - dword ResourceNode::getOffsetToChildName(unsigned int uiIndex) const - { - return children[uiIndex].entry.irde.Name; - } - - /** - * Returns the OffsetToData value of a child. - * @param uiIndex Index of the child. - * @return OffsetToData value of a child. - **/ - dword ResourceNode::getOffsetToChildData(unsigned int uiIndex) const - { - return children[uiIndex].entry.irde.OffsetToData; - } - - - /** - * Sets the name of a child. - * @param uiIndex Index of the child. - * @param strNewName New name of the resource. - **/ - void ResourceNode::setChildName(unsigned int uiIndex, const std::string& strNewName) - { - children[uiIndex].entry.wstrName = strNewName; - } - - /** - * Sets the Name value of a child. - * @param uiIndex Index of the child. - * @param dwNewOffset New Name value of the resource. - **/ - void ResourceNode::setOffsetToChildName(unsigned int uiIndex, dword dwNewOffset) - { - children[uiIndex].entry.irde.Name = dwNewOffset; - } - - /** - * Sets the OffsetToData value of a child. - * @param uiIndex Index of the child. - * @param dwNewOffset New OffsetToData value of the resource. - **/ - void ResourceNode::setOffsetToChildData(unsigned int uiIndex, dword dwNewOffset) - { - children[uiIndex].entry.irde.OffsetToData = dwNewOffset; - } - - /** - * Returns the Characteristics value of the node. - * @return Characteristics value of the node. - **/ - dword ResourceNode::getCharacteristics() const - { - return header.Characteristics; - } - - /** - * Returns the TimeDateStamp value of the node. - * @return TimeDateStamp value of the node. - **/ - dword ResourceNode::getTimeDateStamp() const - { - return header.TimeDateStamp; - } - - /** - * Returns the MajorVersion value of the node. - * @return MajorVersion value of the node. - **/ - word ResourceNode::getMajorVersion() const - { - return header.MajorVersion; - } - - /** - * Returns the MinorVersion value of the node. - * @return MinorVersion value of the node. - **/ - word ResourceNode::getMinorVersion() const - { - return header.MinorVersion; - } - - /** - * Returns the NumberOfNamedEntries value of the node. - * @return NumberOfNamedEntries value of the node. - **/ - word ResourceNode::getNumberOfNamedEntries() const - { - return header.NumberOfNamedEntries; - } - - /** - * Returns the NumberOfIdEntries value of the node. - * @return NumberOfIdEntries value of the node. - **/ - word ResourceNode::getNumberOfIdEntries() const - { - return header.NumberOfIdEntries; - } - - /** - * Sets the Characteristics value of the node. - * @param value New Characteristics value of the node. - **/ - void ResourceNode::setCharacteristics(dword value) - { - header.Characteristics = value; - } - - /** - * Sets the TimeDateStamp value of the node. - * @param value New TimeDateStamp value of the node. - **/ - void ResourceNode::setTimeDateStamp(dword value) - { - header.TimeDateStamp = value; - } - - /** - * Sets the MajorVersion value of the node. - * @param value New MajorVersion value of the node. - **/ - void ResourceNode::setMajorVersion(word value) - { - header.MajorVersion = value; - } - - /** - * Sets the MinorVersion value of the node. - * @param value New MinorVersion value of the node. - **/ - void ResourceNode::setMinorVersion(word value) - { - header.MinorVersion = value; - } - - /** - * Sets the NumberOfNamedEntries value of the node. - * @param value New NumberOfNamedEntries value of the node. - **/ - void ResourceNode::setNumberOfNamedEntries(word value) - { - header.NumberOfNamedEntries = value; - } - - /** - * Sets the NumberOfIdEntries value of the node. - * @param value New NumberOfIdEntries value of the node. - **/ - void ResourceNode::setNumberOfIdEntries(word value) - { - header.NumberOfIdEntries = value; - } - - -/* /// Returns the size of a resource node. - unsigned int ResourceNode::size() const - { - if (children.size()) - { - std::cout << std::accumulate(children.begin(), children.end(), 0, accumulate) << std::endl; - return PELIB_IMAGE_RESOURCE_DIRECTORY::size() - + std::accumulate(children.begin(), children.end(), 0, accumulate); - } - else - { - return 0; - } - } -*/ -// -------------------------------------------------- ResourceDirectory ------------------------------------------- - - /** - * Returns the root node of the resource directory. - * @return Root node of the resource directory. - **/ - ResourceNode* ResourceDirectory::getRoot() - { - return &m_rnRoot; - } - - /** - * Correctly sorts the resource nodes of the resource tree. This function should be called - * before calling rebuild. - **/ - void ResourceDirectory::makeValid() - { - m_rnRoot.makeValid(); - } - - /** - * Reads the resource directory from a file. - * @param strFilename Name of the file. - * @param uiOffset File offset of the resource directory. - * @param uiSize Raw size of the resource directory. - * @param uiResDirRva RVA of the beginning of the resource directory. - **/ - int ResourceDirectory::read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize, unsigned int uiResDirRva) - { - if (!uiSize || !uiOffset) - { - return 1; - } - - std::ifstream ifFile(strFilename.c_str(), std::ios::binary); - - if (!ifFile) - { -// throw Exceptions::CannotOpenFile(ResourceDirectoryId, __LINE__); - return 1; - } - - if (fileSize(ifFile) < uiOffset + uiSize) - { -// throw Exceptions::InvalidFormat(ResourceDirectoryId, __LINE__); - return 1; - } - - ifFile.seekg(uiOffset, std::ios::beg); - - PELIB_IMAGE_RESOURCE_DIRECTORY irdCurrRoot; - - std::vector vResourceDirectory(uiSize); - ifFile.read(reinterpret_cast(&vResourceDirectory[0]), uiSize); - - InputBuffer inpBuffer(vResourceDirectory); - -// ResourceNode currNode; - return m_rnRoot.read(inpBuffer, 0, uiResDirRva/*, ""*/); -// std::swap(currNode, m_rnRoot); - } - - /** - * Rebuilds the resource directory. - * @param vBuffer Buffer the source directory will be written to. - * @param uiRva RVA of the resource directory. - **/ - void ResourceDirectory::rebuild(std::vector& vBuffer, unsigned int uiRva) const - { - OutputBuffer obBuffer(vBuffer); - unsigned int offs = 0; -// std::cout << "Root: " << m_rnRoot.children.size() << std::endl; - m_rnRoot.rebuild(obBuffer, offs, uiRva, ""); - } - - /** - * Returns the size of the entire rebuilt resource directory. That's the size of the entire - * structure as it's written back to a file. - **/ -/* unsigned int ResourceDirectory::size() const - { - return m_rnRoot.size(); - } -*/ - /** - * Writes the current resource directory back into a file. - * @param strFilename Name of the output file. - * @param uiOffset File offset where the resource directory will be written to. - * @param uiRva RVA of the file offset. - **/ - int ResourceDirectory::write(const std::string& strFilename, unsigned int uiOffset, unsigned int uiRva) const - { - std::fstream ofFile(strFilename.c_str(), std::ios_base::in); - - if (!ofFile) - { - ofFile.clear(); - ofFile.open(strFilename.c_str(), std::ios_base::out | std::ios_base::binary); - } - else - { - ofFile.close(); - ofFile.open(strFilename.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary); - } - - if (!ofFile) - { - return ERROR_OPENING_FILE; - } - - ofFile.seekp(uiOffset, std::ios::beg); - - std::vector vBuffer; - rebuild(vBuffer, uiRva); - - ofFile.write(reinterpret_cast(&vBuffer[0]), static_cast(vBuffer.size())); - - ofFile.close(); - - return 0; - } - - /** - * Adds another resource type. The new resource type is identified by the ID dwResTypeId. - * @param dwResTypeId ID which identifies the resource type. - **/ - int ResourceDirectory::addResourceType(dword dwResTypeId) - { - std::vector::iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(&ResourceChild::equalId), dwResTypeId)); - if (Iter != m_rnRoot.children.end()) - { - return 1; - // throw Exceptions::EntryAlreadyExists(ResourceDirectoryId, __LINE__); - } - - ResourceChild rcCurr; - rcCurr.child = new ResourceNode; - rcCurr.entry.irde.Name = dwResTypeId; - m_rnRoot.children.push_back(rcCurr); - - return 0; - } - - /** - * Adds another resource type. The new resource type is identified by the name strResTypeName. - * @param strResTypeName Name which identifies the resource type. - **/ - int ResourceDirectory::addResourceType(const std::string& strResTypeName) - { - std::vector::iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(&ResourceChild::equalName), strResTypeName)); - if (Iter != m_rnRoot.children.end()) - { - return 1; -// throw Exceptions::EntryAlreadyExists(ResourceDirectoryId, __LINE__); - } - - ResourceChild rcCurr; - rcCurr.entry.wstrName = strResTypeName; - rcCurr.child = new ResourceNode; - m_rnRoot.children.push_back(rcCurr); - - return 0; - } - - /** - * Removes the resource type identified by the ID dwResTypeId. - * @param dwResTypeId ID which identifies the resource type. - **/ - int ResourceDirectory::removeResourceType(dword dwResTypeId) - { - std::vector::iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(&ResourceChild::equalId), dwResTypeId)); - if (Iter == m_rnRoot.children.end()) - { - return 1; -// throw Exceptions::ResourceTypeDoesNotExist(ResourceDirectoryId, __LINE__); - } - - bool isNamed = false; - if (Iter->isNamedResource()) isNamed = true; - - m_rnRoot.children.erase(Iter); - - if (isNamed) m_rnRoot.header.NumberOfNamedEntries = static_cast(m_rnRoot.children.size()); - else m_rnRoot.header.NumberOfIdEntries = static_cast(m_rnRoot.children.size()); - - return 0; - } - - /** - * Removes the resource type identified by the name strResTypeName. - * @param strResTypeName Name which identifies the resource type. - **/ - int ResourceDirectory::removeResourceType(const std::string& strResTypeName) - { - std::vector::iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(&ResourceChild::equalName), strResTypeName)); - if (Iter == m_rnRoot.children.end()) - { - return 1; - // throw Exceptions::ResourceTypeDoesNotExist(ResourceDirectoryId, __LINE__); - } - - bool isNamed = false; - if (Iter->isNamedResource()) isNamed = true; - - m_rnRoot.children.erase(Iter); - - if (isNamed) m_rnRoot.header.NumberOfNamedEntries = static_cast(m_rnRoot.children.size()); - else m_rnRoot.header.NumberOfIdEntries = static_cast(m_rnRoot.children.size()); - - return 0; - } - - /** - * Removes the resource type identified by the index uiIndex. - * @param uiIndex Index which identifies the resource type. - **/ - int ResourceDirectory::removeResourceTypeByIndex(unsigned int uiIndex) - { - bool isNamed = false; - if (m_rnRoot.children[uiIndex].isNamedResource()) isNamed = true; - - m_rnRoot.children.erase(m_rnRoot.children.begin() + uiIndex); - - if (isNamed) m_rnRoot.header.NumberOfNamedEntries = static_cast(m_rnRoot.children.size()); - else m_rnRoot.header.NumberOfIdEntries = static_cast(m_rnRoot.children.size()); - - return 0; - } - - /** - * Adds another resource to the resource tree. The first parameter identifies the resource type - * of the new resource, the second parameter identifies the resource itself. - * @param dwResTypeId ID of the resource type. - * @param dwResId ID of the resource. - **/ - int ResourceDirectory::addResource(dword dwResTypeId, dword dwResId) - { - ResourceChild rcCurr; - rcCurr.entry.irde.Name = dwResId; - return addResourceT(dwResTypeId, dwResId, rcCurr); - } - - /** - * Adds another resource to the resource tree. The first parameter identifies the resource type - * of the new resource, the second parameter identifies the resource itself. - * @param dwResTypeId ID of the resource type. - * @param strResName Name of the resource. - **/ - int ResourceDirectory::addResource(dword dwResTypeId, const std::string& strResName) - { - ResourceChild rcCurr; - rcCurr.entry.wstrName = strResName; - return addResourceT(dwResTypeId, strResName, rcCurr); - } - - /** - * Adds another resource to the resource tree. The first parameter identifies the resource type - * of the new resource, the second parameter identifies the resource itself. - * @param strResTypeName Name of the resource type. - * @param dwResId ID of the resource. - **/ - int ResourceDirectory::addResource(const std::string& strResTypeName, dword dwResId) - { - ResourceChild rcCurr; - rcCurr.entry.irde.Name = dwResId; - return addResourceT(strResTypeName, dwResId, rcCurr); - } - - /** - * Adds another resource to the resource tree. The first parameter identifies the resource type - * of the new resource, the second parameter identifies the resource itself. - * @param strResTypeName Name of the resource type. - * @param strResName Name of the resource. - **/ - int ResourceDirectory::addResource(const std::string& strResTypeName, const std::string& strResName) - { - ResourceChild rcCurr; - rcCurr.entry.wstrName = strResName; - return addResourceT(strResTypeName, strResName, rcCurr); - } - - /** - * Removes a resource from the resource tree. The first parameter identifies the resource type - * of the new resource, the second parameter identifies the resource itself. - * @param dwResTypeIndex ID of the resource type. - * @param dwResId ID of the resource. - **/ - int ResourceDirectory::removeResource(dword dwResTypeIndex, dword dwResId) - { - return removeResourceT(dwResTypeIndex, dwResId); - } - - /** - * Removes a resource from the resource tree. The first parameter identifies the resource type - * of the new resource, the second parameter identifies the resource itself. - * @param dwResTypeIndex ID of the resource type. - * @param strResName Name of the resource. - **/ - int ResourceDirectory::removeResource(dword dwResTypeIndex, const std::string& strResName) - { - return removeResourceT(dwResTypeIndex, strResName); - } - - /** - * Removes a resource from the resource tree. The first parameter identifies the resource type - * of the new resource, the second parameter identifies the resource itself. - * @param strResTypeName Name of the resource type. - * @param dwResId ID of the resource. - **/ - int ResourceDirectory::removeResource(const std::string& strResTypeName, dword dwResId) - { - return removeResourceT(strResTypeName, dwResId); - } - - /** - * Removes a resource from the resource tree. The first parameter identifies the resource type - * of the new resource, the second parameter identifies the resource itself. - * @param strResTypeName Name of the resource type. - * @param strResName Name of the resource. - **/ - int ResourceDirectory::removeResource(const std::string& strResTypeName, const std::string& strResName) - { - return removeResourceT(strResTypeName, strResName); - } - - /** - * Returns the number of resource types. - **/ - unsigned int ResourceDirectory::getNumberOfResourceTypes() const - { - return static_cast(m_rnRoot.children.size()); - } - - /** - * Returns the ID of a resource type which was specified through an index. - * The valid range of the parameter uiIndex is 0...getNumberOfResourceTypes() - 1. - * Leaving the invalid range leads to undefined behaviour. - * @param uiIndex Index which identifies a resource type. - * @return The ID of the specified resource type. - **/ - dword ResourceDirectory::getResourceTypeIdByIndex(unsigned int uiIndex) const - { - return m_rnRoot.children[uiIndex].entry.irde.Name; - } - - /** - * Returns the name of a resource type which was specified through an index. - * The valid range of the parameter uiIndex is 0...getNumberOfResourceTypes() - 1. - * Leaving the invalid range leads to undefined behaviour. - * @param uiIndex Index which identifies a resource type. - * @return The name of the specified resource type. - **/ - std::string ResourceDirectory::getResourceTypeNameByIndex(unsigned int uiIndex) const - { - return m_rnRoot.children[uiIndex].entry.wstrName; - } - - /** - * Converts the ID of a resource type to an index. - * @param dwResTypeId ID of the resource type. - * @return Index of that resource type. - **/ - int ResourceDirectory::resourceTypeIdToIndex(dword dwResTypeId) const - { - std::vector::const_iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(&ResourceChild::equalId), dwResTypeId)); - if (Iter == m_rnRoot.children.end()) return -1; - return static_cast(std::distance(m_rnRoot.children.begin(), Iter)); - } - - /** - * Converts the name of a resource type to an index. - * @param strResTypeName ID of the resource type. - * @return Index of that resource type. - **/ - int ResourceDirectory::resourceTypeNameToIndex(const std::string& strResTypeName) const - { - std::vector::const_iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(&ResourceChild::equalName), strResTypeName)); - if (Iter == m_rnRoot.children.end()) return -1; - return static_cast(std::distance(m_rnRoot.children.begin(), Iter)); - } - - /** - * Returns the number of resources of a specific resource type. - * @param dwId ID of the resource type. - * @return Number of resources of resource type dwId. - **/ - unsigned int ResourceDirectory::getNumberOfResources(dword dwId) const - { -// std::vector::const_iterator IterD = m_rnRoot.children.begin(); -// std::cout << dwId << std::endl; -// while (IterD != m_rnRoot.children.end()) -// { -// std::cout << IterD->entry.irde.Name << std::endl; -// ++IterD; -// } - - std::vector::const_iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(&ResourceChild::equalId), dwId)); - if (Iter == m_rnRoot.children.end()) - { - return 0xFFFFFFFF; - } - else - { - ResourceNode* currNode = static_cast(Iter->child); - return static_cast(currNode->children.size()); - } - } - - /** - * Returns the number of resources of a specific resource type. - * @param strResTypeName Name of the resource type. - * @return Number of resources of resource type strResTypeName. - **/ - unsigned int ResourceDirectory::getNumberOfResources(const std::string& strResTypeName) const - { - std::vector::const_iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(&ResourceChild::equalName), strResTypeName)); - if (Iter == m_rnRoot.children.end()) - { - return 0xFFFFFFFF; - } - else - { - ResourceNode* currNode = static_cast(Iter->child); - return static_cast(currNode->children.size()); - } - } - - /** - * Returns the number of resources of a resource type which was specified through an index. - * The valid range of the parameter uiIndex is 0...getNumberOfResourceTypes() - 1. - * Leaving the invalid range leads to undefined behaviour. - * @param uiIndex Index which identifies a resource type. - * @return The number of resources of the specified resource type. - **/ - unsigned int ResourceDirectory::getNumberOfResourcesByIndex(unsigned int uiIndex) const - { - ResourceNode* currNode = static_cast(m_rnRoot.children[uiIndex].child); - return static_cast(currNode->children.size()); - } - - /** - * Gets the resource data of a specific resource. - * @param dwResTypeId Identifies the resource type of the resource. - * @param dwResId Identifies the resource. - * @param data Vector where the data is stored. - **/ - void ResourceDirectory::getResourceData(dword dwResTypeId, dword dwResId, std::vector& data) const - { - getResourceDataT(dwResTypeId, dwResId, data); - } - - /** - * Gets the resource data of a specific resource. - * @param dwResTypeId Identifies the resource type of the resource. - * @param strResName Identifies the resource. - * @param data Vector where the data is stored. - **/ - void ResourceDirectory::getResourceData(dword dwResTypeId, const std::string& strResName, std::vector& data) const - { - getResourceDataT(dwResTypeId, strResName, data); - } - - /** - * Gets the resource data of a specific resource. - * @param strResTypeName Identifies the resource type of the resource. - * @param dwResId Identifies the resource. - * @param data Vector where the data is stored. - **/ - void ResourceDirectory::getResourceData(const std::string& strResTypeName, dword dwResId, std::vector& data) const - { - getResourceDataT(strResTypeName, dwResId, data); - } - - /** - * Gets the resource data of a specific resource. - * @param strResTypeName Identifies the resource type of the resource. - * @param strResName Identifies the resource. - * @param data Vector where the data is stored. - **/ - void ResourceDirectory::getResourceData(const std::string& strResTypeName, const std::string& strResName, std::vector& data) const - { - getResourceDataT(strResTypeName, strResName, data); - } - - /** - * Gets the resource data of a specific resource by index. - * The valid range of the parameter uiResTypeIndex is 0...getNumberOfResourceTypes() - 1. - * The valid range of the parameter uiResIndex is 0...getNumberOfResources() - 1. - * Leaving the invalid range leads to undefined behaviour. - * @param uiResTypeIndex Identifies the resource type of the resource. - * @param uiResIndex Identifies the resource. - * @param data Vector where the data is stored. - **/ - void ResourceDirectory::getResourceDataByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex, std::vector& data) const - { - ResourceNode* currNode = static_cast(m_rnRoot.children[uiResTypeIndex].child); - currNode = static_cast(currNode->children[uiResIndex].child); - ResourceLeaf* currLeaf = static_cast(currNode->children[0].child); - - data.assign(currLeaf->m_data.begin(), currLeaf->m_data.end()); - } - - /** - * Sets the resource data of a specific resource. - * @param dwResTypeId Identifies the resource type of the resource. - * @param dwResId Identifies the resource. - * @param data The new resource data. - **/ - void ResourceDirectory::setResourceData(dword dwResTypeId, dword dwResId, std::vector& data) - { - setResourceDataT(dwResTypeId, dwResId, data); - } - - /** - * Sets the resource data of a specific resource. - * @param dwResTypeId Identifies the resource type of the resource. - * @param strResName Identifies the resource. - * @param data The new resource data. - **/ - void ResourceDirectory::setResourceData(dword dwResTypeId, const std::string& strResName, std::vector& data) - { - setResourceDataT(dwResTypeId, strResName, data); - } - - /** - * Sets the resource data of a specific resource. - * @param strResTypeName Identifies the resource type of the resource. - * @param dwResId Identifies the resource. - * @param data The new resource data. - **/ - void ResourceDirectory::setResourceData(const std::string& strResTypeName, dword dwResId, std::vector& data) - { - setResourceDataT(strResTypeName, dwResId, data); - } - - /** - * Sets the resource data of a specific resource. - * @param strResTypeName Identifies the resource type of the resource. - * @param strResName Identifies the resource. - * @param data The new resource data. - **/ - void ResourceDirectory::setResourceData(const std::string& strResTypeName, const std::string& strResName, std::vector& data) - { - setResourceDataT(strResTypeName, strResName, data); - } - - /** - * Sets the resource data of a specific resource by index. - * The valid range of the parameter uiResTypeIndex is 0...getNumberOfResourceTypes() - 1. - * The valid range of the parameter uiResIndex is 0...getNumberOfResources() - 1. - * Leaving the invalid range leads to undefined behaviour. - * @param uiResTypeIndex Identifies the resource type of the resource. - * @param uiResIndex Identifies the resource. - * @param data The new resource data. - **/ - void ResourceDirectory::setResourceDataByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex, std::vector& data) - { - ResourceNode* currNode = static_cast(m_rnRoot.children[uiResTypeIndex].child); - currNode = static_cast(currNode->children[uiResIndex].child); - ResourceLeaf* currLeaf = static_cast(currNode->children[0].child); - currLeaf->m_data.assign(data.begin(), data.end()); - } - - /** - * Gets the ID of a specific resource. - * @param dwResTypeId Identifies the resource type of the resource. - * @param strResName Identifies the resource. - * @return ID of the specified resource. - **/ - dword ResourceDirectory::getResourceId(dword dwResTypeId, const std::string& strResName) const - { - return getResourceIdT(dwResTypeId, strResName); - } - - /** - * Gets the ID of a specific resource. - * @param strResTypeName Identifies the resource type of the resource. - * @param strResName Identifies the resource. - * @return ID of the specified resource. - **/ - dword ResourceDirectory::getResourceId(const std::string& strResTypeName, const std::string& strResName) const - { - return getResourceIdT(strResTypeName, strResName); - } - - /** - * Gets the ID of a specific resource by index. - * @param uiResTypeIndex Identifies the resource type of the resource. - * @param uiResIndex Identifies the resource. - * @return ID of the specified resource. - **/ - dword ResourceDirectory::getResourceIdByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex) const - { - ResourceNode* currNode = static_cast(m_rnRoot.children[uiResTypeIndex].child); - return currNode->children[uiResIndex].entry.irde.Name; - } - - /** - * Sets the ID of a specific resource. - * @param dwResTypeId Identifies the resource type of the resource. - * @param dwResId Identifies the resource. - * @param dwNewResId New ID of the resource. - **/ - void ResourceDirectory::setResourceId(dword dwResTypeId, dword dwResId, dword dwNewResId) - { - setResourceIdT(dwResTypeId, dwResId, dwNewResId); - } - - /** - * Sets the ID of a specific resource. - * @param dwResTypeId Identifies the resource type of the resource. - * @param strResName Identifies the resource. - * @param dwNewResId New ID of the resource. - **/ - void ResourceDirectory::setResourceId(dword dwResTypeId, const std::string& strResName, dword dwNewResId) - { - setResourceIdT(dwResTypeId, strResName, dwNewResId); - } - - /** - * Sets the ID of a specific resource. - * @param strResTypeName Identifies the resource type of the resource. - * @param dwResId Identifies the resource. - * @param dwNewResId New ID of the resource. - **/ - void ResourceDirectory::setResourceId(const std::string& strResTypeName, dword dwResId, dword dwNewResId) - { - setResourceIdT(strResTypeName, dwResId, dwNewResId); - } - - /** - * Sets the ID of a specific resource. - * @param strResTypeName Identifies the resource type of the resource. - * @param strResName Identifies the resource. - * @param dwNewResId New ID of the resource. - **/ - void ResourceDirectory::setResourceId(const std::string& strResTypeName, const std::string& strResName, dword dwNewResId) - { - setResourceIdT(strResTypeName, strResName, dwNewResId); - } - - /** - * Sets the ID of a specific resource by index. - * @param uiResTypeIndex Identifies the resource type of the resource. - * @param uiResIndex Identifies the resource. - * @param dwNewResId New ID of the specified resource. - **/ - void ResourceDirectory::setResourceIdByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex, dword dwNewResId) - { - ResourceNode* currNode = static_cast(m_rnRoot.children[uiResTypeIndex].child); - currNode->children[uiResIndex].entry.irde.Name = dwNewResId; - } - - /** - * Gets the Name of a specific resource. - * @param dwResTypeId Identifies the resource type of the resource. - * @param dwResId Identifies the resource. - * @return Name of the specified resource. - **/ - std::string ResourceDirectory::getResourceName(dword dwResTypeId, dword dwResId) const - { - return getResourceNameT(dwResTypeId, dwResId); - } - - /** - * Gets the Name of a specific resource. - * @param strResTypeName Identifies the resource type of the resource. - * @param dwResId Identifies the resource. - * @return Name of the specified resource. - **/ - std::string ResourceDirectory::getResourceName(const std::string& strResTypeName, dword dwResId) const - { - return getResourceNameT(strResTypeName, dwResId); - } - - /** - * Gets the name of a specific resource by index. - * @param uiResTypeIndex Identifies the resource type of the resource. - * @param uiResIndex Identifies the resource. - * @return Name of the specified resource. - **/ - std::string ResourceDirectory::getResourceNameByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex) const - { - ResourceNode* currNode = static_cast(m_rnRoot.children[uiResTypeIndex].child); - return currNode->children[uiResIndex].entry.wstrName; - } - - /** - * Sets the name of a specific resource. - * @param dwResTypeId Identifies the resource type of the resource. - * @param dwResId Identifies the resource. - * @param strNewResName New name of the specified resource. - **/ - void ResourceDirectory::setResourceName(dword dwResTypeId, dword dwResId, const std::string& strNewResName) - { - setResourceNameT(dwResTypeId, dwResId, strNewResName); - } - - /** - * Sets the name of a specific resource. - * @param dwResTypeId Identifies the resource type of the resource. - * @param strResName Identifies the resource. - * @param strNewResName New name of the specified resource. - **/ - void ResourceDirectory::setResourceName(dword dwResTypeId, const std::string& strResName, const std::string& strNewResName) - { - setResourceNameT(dwResTypeId, strResName, strNewResName); - } - - /** - * Sets the name of a specific resource. - * @param strResTypeName Identifies the resource type of the resource. - * @param dwResId Identifies the resource. - * @param strNewResName New name of the specified resource. - **/ - void ResourceDirectory::setResourceName(const std::string& strResTypeName, dword dwResId, const std::string& strNewResName) - { - setResourceNameT(strResTypeName, dwResId, strNewResName); - } - - /** - * Sets the name of a specific resource. - * @param strResTypeName Identifies the resource type of the resource. - * @param strResName Identifies the resource. - * @param strNewResName New name of the specified resource. - **/ - void ResourceDirectory::setResourceName(const std::string& strResTypeName, const std::string& strResName, const std::string& strNewResName) - { - setResourceNameT(strResTypeName, strResName, strNewResName); - } - - /** - * Sets the name of a specific resource by index. - * @param uiResTypeIndex Identifies the resource type of the resource. - * @param uiResIndex Identifies the resource. - * @param strNewResName New name of the specified resource. - **/ - void ResourceDirectory::setResourceNameByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex, const std::string& strNewResName) - { - ResourceNode* currNode = static_cast(m_rnRoot.children[uiResTypeIndex].child); - currNode->children[uiResIndex].entry.wstrName = strNewResName; - } - -} +/* +* ResourceDirectory.h - Part of the PeLib library. +* +* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com) +* All rights reserved. +* +* This software is licensed under the zlib/libpng License. +* For more details see http://www.opensource.org/licenses/zlib-license.php +* or the license information file (license.htm) in the root directory +* of PeLib. +*/ + +#include "ResourceDirectory.h" + +namespace PeLib +{ +// -------------------------------------------------- ResourceChild ------------------------------------------- + + ResourceChild::ResourceChild() + { + } + + ResourceChild::ResourceChild(const ResourceChild& rhs) + { + if (dynamic_cast(rhs.child)) + { + ResourceNode* oldnode = static_cast(rhs.child); + + entry = rhs.entry; + + child = new ResourceNode; + child->uiElementRva = rhs.child->getElementRva(); + static_cast(child)->header = oldnode->header; + static_cast(child)->children = oldnode->children; + } + else + { + ResourceLeaf* oldnode = static_cast(rhs.child); + + child = new ResourceLeaf; + child->uiElementRva = rhs.child->getElementRva(); + static_cast(child)->m_data = oldnode->m_data; + static_cast(child)->entry = oldnode->entry; + } + } + + ResourceChild& ResourceChild::operator=(const ResourceChild& rhs) + { + if (this != &rhs) + { + if (dynamic_cast(rhs.child)) + { + ResourceNode* oldnode = static_cast(rhs.child); + + entry = rhs.entry; + + child = new ResourceNode; + child->uiElementRva = rhs.child->getElementRva(); + static_cast(child)->header = oldnode->header; + static_cast(child)->children = oldnode->children; + } + else + { + ResourceLeaf* oldnode = static_cast(rhs.child); + + child = new ResourceLeaf; + child->uiElementRva = rhs.child->getElementRva(); + static_cast(child)->m_data = oldnode->m_data; + static_cast(child)->entry = oldnode->entry; + } + } + + return *this; + } + + ResourceChild::~ResourceChild() + { + delete child; + } + + /** + * Compares the resource child's id to the parameter dwId. + * @param dwId ID of a resource. + * @return True, if the resource child's id equals the parameter. + **/ + bool ResourceChild::equalId(dword dwId) const + { + return entry.irde.Name == dwId; + } + + /** + * Compares the resource child's name to the parameter strName. + * @param strName ID of a resource. + * @return True, if the resource child's name equals the parameter. + **/ + bool ResourceChild::equalName(std::string strName) const + { + return entry.wstrName == strName; + } + + /** + * Returns true if the resource was given a name. + **/ + bool ResourceChild::isNamedResource() const + { + return entry.wstrName.size() != 0; + } + + /** + * The children of a resource must be ordered in a certain way. First come the named resources + * in sorted order, afterwards followed the unnamed resources in sorted order. + **/ + bool ResourceChild::operator<(const ResourceChild& rc) const + { + if (this->isNamedResource() && !rc.isNamedResource()) + { + return true; + } + else if (!this->isNamedResource() && rc.isNamedResource()) + { + return false; + } + else if (this->isNamedResource() && rc.isNamedResource()) + { + return this->entry.wstrName < rc.entry.wstrName; + } + else + { + return this->entry.irde.Name < rc.entry.irde.Name; + } + } + +/* unsigned int ResourceChild::size() const + { + return PELIB_IMAGE_RESOURCE_DIRECTORY_ENTRY::size() + + child->size() + + (entry.wstrName.size() ? entry.wstrName.size() + 2 : 0); + } +*/ +// -------------------------------------------------- ResourceElement ------------------------------------------- + + /** + * Returns the RVA of a ResourceElement. This is the RVA where the ResourceElement can be + * found in the file. + * @return RVA of the ResourceElement. + **/ + unsigned int ResourceElement::getElementRva() const + { + return uiElementRva; + } + +// -------------------------------------------------- ResourceLeaf ------------------------------------------- + + /** + * Checks if a ResourceElement is a leaf or not. + * @return Always returns true. + **/ + bool ResourceLeaf::isLeaf() const + { + return true; + } + + /** + * Reads the next resource leaf from the InputBuffer. + * @param inpBuffer An InputBuffer that holds the complete resource directory. + * @param uiOffset Offset of the resource leaf that's to be read. + * @param uiRva RVA of the beginning of the resource directory. + * @param pad Used for debugging purposes. + **/ + int ResourceLeaf::read(InputBuffer& inpBuffer, unsigned int uiOffset, unsigned int uiRva/*, const std::string& pad*/) + { +// std::cout << pad << "Leaf:" << std::endl; + + // Invalid leaf. + if (uiOffset + PELIB_IMAGE_RESOURCE_DATA_ENTRY::size() > inpBuffer.size()) + { + return 1; + } + + uiElementRva = uiOffset + uiRva; + + inpBuffer.set(uiOffset); + + inpBuffer >> entry.OffsetToData; + inpBuffer >> entry.Size; + inpBuffer >> entry.CodePage; + inpBuffer >> entry.Reserved; + +/* std::cout << pad << std::hex << "Offset: " << entry.OffsetToData << std::endl; + std::cout << pad << std::hex << "Size: " << entry.Size << std::endl; + std::cout << pad << std::hex << "CodePage: " << entry.CodePage << std::endl; + std::cout << pad << std::hex << "Reserved: " << entry.Reserved << std::endl; +*/ + // Invalid leaf. + if (entry.OffsetToData - uiRva + entry.Size > inpBuffer.size()) + { +// std::cout << entry.OffsetToData << " XXX " << uiRva << " - " << entry.Size << " - " << inpBuffer.size() << std::endl; + return 1; + } + +// std::cout << entry.OffsetToData << " - " << uiRva << " - " << entry.Size << " - " << inpBuffer.size() << std::endl; + inpBuffer.set(entry.OffsetToData - uiRva); + m_data.assign(inpBuffer.data() + inpBuffer.get(), inpBuffer.data() + inpBuffer.get() + entry.Size); +// std::cout << pad << std::hex << "Vector: " << m_data.size() << std::endl; +// std::copy(m_data.begin(), m_data.end(), std::ostream_iterator(std::cout << std::hex, " ")); + return 0; + } + + /** + * Rebuilds the current resource leaf. + * @param obBuffer OutputBuffer where the rebuilt resource leaf is stored. + * @param uiOffset Offset of the resource leaf inside the resource directory. + * @param uiRva RVA of the resource directory. + **/ + void ResourceLeaf::rebuild(OutputBuffer& obBuffer, unsigned int& uiOffset, unsigned int uiRva, const std::string&) const + { +// std::cout << std::hex << pad << "Leaf: " << uiOffset << std::endl; + uiOffset += PELIB_IMAGE_RESOURCE_DATA_ENTRY::size(); + +// obBuffer << entry.OffsetToData; +// obBuffer << uiOffset; + obBuffer << uiRva + uiOffset + (uiOffset % 4); + obBuffer << entry.Size; + obBuffer << entry.CodePage; + obBuffer << entry.Reserved; + + while (uiOffset % 4) + { + uiOffset++; + obBuffer << (byte)0; + } + + uiOffset += static_cast(m_data.size()); + + for (unsigned int i=0;i(m_data.size()); + } + +/* /// Returns the size of a resource leaf. + unsigned int ResourceLeaf::size() const + { + return PELIB_IMAGE_RESOURCE_DATA_ENTRY::size() + m_data.size(); + } +*/ + + /** + * Returns a vector that contains the raw data of a resource leaf. + * @return Raw data of the resource. + **/ + std::vector ResourceLeaf::getData() const + { + return m_data; + } + + /** + * Overwrites the raw data of a resource. + * @param vData New data of the resource. + **/ + void ResourceLeaf::setData(const std::vector& vData) + { + m_data = vData; + } + + /** + * Returns the leaf's OffsetToData value. That's the RVA where the raw data of the resource + * can be found. + * @return The leaf's OffsetToData value. + **/ + dword ResourceLeaf::getOffsetToData() const + { + return entry.OffsetToData; + } + + /** + * Returns the leaf's Size value. That's the size of the raw data of the resource. + * @return The leaf's Size value. + **/ + dword ResourceLeaf::getSize() const + { + return entry.Size; + } + + /** + * Returns the leaf's CodePage value. + * @return The leaf's CodePage value. + **/ + dword ResourceLeaf::getCodePage() const + { + return entry.CodePage; + } + + /** + * Returns the leaf's Reserved value. + * @return The leaf's Reserved value. + **/ + dword ResourceLeaf::getReserved() const + { + return entry.Reserved; + } + + /** + * Sets the leaf's OffsetToData value. + * @param dwValue The leaf's new OffsetToData value. + **/ + void ResourceLeaf::setOffsetToData(dword dwValue) + { + entry.OffsetToData = dwValue; + } + + /** + * Sets the leaf's Size value. + * @param dwValue The leaf's new Size value. + **/ + void ResourceLeaf::setSize(dword dwValue) + { + entry.Size = dwValue; + } + + /** + * Sets the leaf's CodePage value. + * @param dwValue The leaf's new CodePage value. + **/ + void ResourceLeaf::setCodePage(dword dwValue) + { + entry.CodePage = dwValue; + } + + /** + * Sets the leaf's Reserved value. + * @param dwValue The leaf's new Reserved value. + **/ + void ResourceLeaf::setReserved(dword dwValue) + { + entry.Reserved = dwValue; + } + + +// -------------------------------------------------- ResourceNode ------------------------------------------- + + /** + * Checks if a ResourceElement is a leaf or not. + * @return Always returns false. + **/ + bool ResourceNode::isLeaf() const + { + return false; + } + + /** + * Sorts the node's children and corrects the node's header. + **/ + void ResourceNode::makeValid() + { + std::sort(children.begin(), children.end()); + header.NumberOfNamedEntries = static_cast(std::count_if(children.begin(), children.end(), std::mem_fun_ref(&ResourceChild::isNamedResource))); + header.NumberOfIdEntries = static_cast(children.size()) - header.NumberOfNamedEntries; + } + + /** + * Rebuilds the current resource node. + * @param obBuffer OutputBuffer where the rebuilt resource node is stored. + * @param uiOffset Offset of the resource node inside the resource directory. + * @param uiRva RVA of the resource directory. + * @param pad Used for debugging. + **/ + void ResourceNode::rebuild(OutputBuffer& obBuffer, unsigned int& uiOffset, unsigned int uiRva, const std::string& pad) const + { +/* std::cout << std::hex << pad << uiOffset << std::endl; + + std::cout << std::hex << pad << "header.Characteristics: " << header.Characteristics << std::endl; + std::cout << std::hex << pad << "header.TimeDateStamp: " << header.TimeDateStamp << std::endl; + std::cout << std::hex << pad << "header.MajorVersion: " << header.MajorVersion << std::endl; + std::cout << std::hex << pad << "header.MinorVersion: " << header.MinorVersion << std::endl; + std::cout << std::hex << pad << "header.NumberOfNamedEntries: " << header.NumberOfNamedEntries << std::endl; + std::cout << std::hex << pad << "header.NumberOfIdEntries: " << header.NumberOfIdEntries << std::endl; +*/ + obBuffer << header.Characteristics; + obBuffer << header.TimeDateStamp; + obBuffer << header.MajorVersion; + obBuffer << header.MinorVersion; + //std::cout << pad << "Children: " << children.size() << std::endl; + //std::cout << pad << std::count_if(children.begin(), children.end(), std::mem_fun_ref(&ResourceChild::isNamedResource)) << std::endl; + //std::cout << pad << children.size() - std::count_if(children.begin(), children.end(), std::mem_fun_ref(&ResourceChild::isNamedResource)) << std::endl; +// obBuffer << std::count_if(children.begin(), children.end(), std::mem_fun_ref(&ResourceChild::isNamedResource)); +// obBuffer << children.size() - std::count_if(children.begin(), children.end(), std::mem_fun_ref(&ResourceChild::isNamedResource)); + obBuffer << header.NumberOfNamedEntries; + obBuffer << header.NumberOfIdEntries; + + uiOffset += PELIB_IMAGE_RESOURCE_DIRECTORY::size(); + + for (unsigned int i=0;irebuild(obBuffer, newoffs, uiRva, pad + " "); + } + uiOffset = newoffs; + } + + /** + * Reads the next resource node from the InputBuffer. + * @param inpBuffer An InputBuffer that holds the complete resource directory. + * @param uiOffset Offset of the resource node that's to be read. + * @param uiRva RVA of the beginning of the resource directory. + * @param pad Something I need for debugging. Will be removed soon. + **/ + int ResourceNode::read(InputBuffer& inpBuffer, unsigned int uiOffset, unsigned int uiRva/*, const std::string& pad*/) + { + // Not enough space to be a valid node. + if (uiOffset + PELIB_IMAGE_RESOURCE_DIRECTORY::size() > inpBuffer.size()) + { + return 1; + } + + uiElementRva = uiOffset + uiRva; + + inpBuffer.set(uiOffset); + + inpBuffer >> header.Characteristics; + inpBuffer >> header.TimeDateStamp; + inpBuffer >> header.MajorVersion; + inpBuffer >> header.MinorVersion; + inpBuffer >> header.NumberOfNamedEntries; + inpBuffer >> header.NumberOfIdEntries; + + // Not enough space to be a valid node. + if (uiOffset + PELIB_IMAGE_RESOURCE_DIRECTORY::size() + + (header.NumberOfNamedEntries + header.NumberOfIdEntries) * PELIB_IMAGE_RESOURCE_DIRECTORY_ENTRY::size() + > inpBuffer.size()) + { + return 1; + } + +// std::cout << std::hex << pad << "Characteristics: " << header.Characteristics << std::endl; +// std::cout << std::hex << pad << "TimeDateStamp: " << header.TimeDateStamp << std::endl; +// std::cout << std::hex << pad << "MajorVersion: " << header.MajorVersion << std::endl; +// std::cout << std::hex << pad << "MinorVersion: " << header.MinorVersion << std::endl; +// std::cout << std::hex << pad << "NumberOfNamedEntries: " << header.NumberOfNamedEntries << std::endl; +// std::cout << std::hex << pad << "NumberOfIdEntries: " << header.NumberOfIdEntries << std::endl; + + for (int i=0;i> rc.entry.irde.Name; + inpBuffer >> rc.entry.irde.OffsetToData; + + unsigned int lastPos = inpBuffer.get(); + + if (rc.entry.irde.Name & PELIB_IMAGE_RESOURCE_NAME_IS_STRING) + { + // Enough space to read string length? + if ((rc.entry.irde.Name & ~PELIB_IMAGE_RESOURCE_NAME_IS_STRING) + 2 < inpBuffer.size()) + { + inpBuffer.set(rc.entry.irde.Name & ~PELIB_IMAGE_RESOURCE_NAME_IS_STRING); + word strlen; + inpBuffer >> strlen; + + // Enough space to read string? + if ((rc.entry.irde.Name & ~PELIB_IMAGE_RESOURCE_NAME_IS_STRING) + 2 * strlen < inpBuffer.size()) + { + wchar_t c; + for (word i=0;i> c; + rc.entry.wstrName += c; + } + } + } + +// std::wcout << rc.entry.wstrName << std::endl; + +// std::cout << strlen << std::endl; + inpBuffer.set(lastPos); + } + + if (rc.entry.irde.OffsetToData & PELIB_IMAGE_RESOURCE_DATA_IS_DIRECTORY) + { + rc.child = new ResourceNode; + rc.child->read(inpBuffer, rc.entry.irde.OffsetToData & ~PELIB_IMAGE_RESOURCE_DATA_IS_DIRECTORY, uiRva/*, pad + " "*/); + } + else + { + rc.child = new ResourceLeaf; + rc.child->read(inpBuffer, rc.entry.irde.OffsetToData, uiRva/*, pad + " "*/); + } +// std::cout << std::hex << pad << "Entry " << i << "(Name): " << rc.entry.irde.Name << std::endl; +// std::cout << std::hex << pad << "Entry " << i << "(Offset): " << rc.entry.irde.OffsetToData << std::endl; + + children.push_back(rc); + inpBuffer.set(lastPos); + } + + return 0; + } + + /** + * Returns the number of children of the current node. Note that this number is the number + * of defined children, not the value from the header. + * @return Number of node's children. + **/ + unsigned int ResourceNode::getNumberOfChildren() const + { + return static_cast(children.size()); + } + + /** + * Adds another child to the current node. + **/ + void ResourceNode::addChild() + { + ResourceChild c; + c.child = 0; + children.push_back(c); + } + + /** + * Returns a node's child. + * @param uiIndex Index of the child. + * @return The child identified by uiIndex. This child can be either a ResourceNode or a ResourceLeaf. + **/ + ResourceElement* ResourceNode::getChild(unsigned int uiIndex) + { + return children[uiIndex].child; + } + + /** + * Removes a child from the current node. + * @param uiIndex Index of the child. + **/ + void ResourceNode::removeChild(unsigned int uiIndex) + { + children.erase(children.begin() + uiIndex); + } + + /** + * Returns the name of a child. + * @param uiIndex Index of the child. + * @return Either the name of the specified child or an empty string. + **/ + std::string ResourceNode::getChildName(unsigned int uiIndex) const + { + return children[uiIndex].entry.wstrName; + } + + /** + * Returns the Name value of a child. + * @param uiIndex Index of the child. + * @return Name value of a child. + **/ + dword ResourceNode::getOffsetToChildName(unsigned int uiIndex) const + { + return children[uiIndex].entry.irde.Name; + } + + /** + * Returns the OffsetToData value of a child. + * @param uiIndex Index of the child. + * @return OffsetToData value of a child. + **/ + dword ResourceNode::getOffsetToChildData(unsigned int uiIndex) const + { + return children[uiIndex].entry.irde.OffsetToData; + } + + + /** + * Sets the name of a child. + * @param uiIndex Index of the child. + * @param strNewName New name of the resource. + **/ + void ResourceNode::setChildName(unsigned int uiIndex, const std::string& strNewName) + { + children[uiIndex].entry.wstrName = strNewName; + } + + /** + * Sets the Name value of a child. + * @param uiIndex Index of the child. + * @param dwNewOffset New Name value of the resource. + **/ + void ResourceNode::setOffsetToChildName(unsigned int uiIndex, dword dwNewOffset) + { + children[uiIndex].entry.irde.Name = dwNewOffset; + } + + /** + * Sets the OffsetToData value of a child. + * @param uiIndex Index of the child. + * @param dwNewOffset New OffsetToData value of the resource. + **/ + void ResourceNode::setOffsetToChildData(unsigned int uiIndex, dword dwNewOffset) + { + children[uiIndex].entry.irde.OffsetToData = dwNewOffset; + } + + /** + * Returns the Characteristics value of the node. + * @return Characteristics value of the node. + **/ + dword ResourceNode::getCharacteristics() const + { + return header.Characteristics; + } + + /** + * Returns the TimeDateStamp value of the node. + * @return TimeDateStamp value of the node. + **/ + dword ResourceNode::getTimeDateStamp() const + { + return header.TimeDateStamp; + } + + /** + * Returns the MajorVersion value of the node. + * @return MajorVersion value of the node. + **/ + word ResourceNode::getMajorVersion() const + { + return header.MajorVersion; + } + + /** + * Returns the MinorVersion value of the node. + * @return MinorVersion value of the node. + **/ + word ResourceNode::getMinorVersion() const + { + return header.MinorVersion; + } + + /** + * Returns the NumberOfNamedEntries value of the node. + * @return NumberOfNamedEntries value of the node. + **/ + word ResourceNode::getNumberOfNamedEntries() const + { + return header.NumberOfNamedEntries; + } + + /** + * Returns the NumberOfIdEntries value of the node. + * @return NumberOfIdEntries value of the node. + **/ + word ResourceNode::getNumberOfIdEntries() const + { + return header.NumberOfIdEntries; + } + + /** + * Sets the Characteristics value of the node. + * @param value New Characteristics value of the node. + **/ + void ResourceNode::setCharacteristics(dword value) + { + header.Characteristics = value; + } + + /** + * Sets the TimeDateStamp value of the node. + * @param value New TimeDateStamp value of the node. + **/ + void ResourceNode::setTimeDateStamp(dword value) + { + header.TimeDateStamp = value; + } + + /** + * Sets the MajorVersion value of the node. + * @param value New MajorVersion value of the node. + **/ + void ResourceNode::setMajorVersion(word value) + { + header.MajorVersion = value; + } + + /** + * Sets the MinorVersion value of the node. + * @param value New MinorVersion value of the node. + **/ + void ResourceNode::setMinorVersion(word value) + { + header.MinorVersion = value; + } + + /** + * Sets the NumberOfNamedEntries value of the node. + * @param value New NumberOfNamedEntries value of the node. + **/ + void ResourceNode::setNumberOfNamedEntries(word value) + { + header.NumberOfNamedEntries = value; + } + + /** + * Sets the NumberOfIdEntries value of the node. + * @param value New NumberOfIdEntries value of the node. + **/ + void ResourceNode::setNumberOfIdEntries(word value) + { + header.NumberOfIdEntries = value; + } + + +/* /// Returns the size of a resource node. + unsigned int ResourceNode::size() const + { + if (children.size()) + { + std::cout << std::accumulate(children.begin(), children.end(), 0, accumulate) << std::endl; + return PELIB_IMAGE_RESOURCE_DIRECTORY::size() + + std::accumulate(children.begin(), children.end(), 0, accumulate); + } + else + { + return 0; + } + } +*/ +// -------------------------------------------------- ResourceDirectory ------------------------------------------- + + /** + * Returns the root node of the resource directory. + * @return Root node of the resource directory. + **/ + ResourceNode* ResourceDirectory::getRoot() + { + return &m_rnRoot; + } + + /** + * Correctly sorts the resource nodes of the resource tree. This function should be called + * before calling rebuild. + **/ + void ResourceDirectory::makeValid() + { + m_rnRoot.makeValid(); + } + + /** + * Reads the resource directory from a file. + * @param strFilename Name of the file. + * @param uiOffset File offset of the resource directory. + * @param uiSize Raw size of the resource directory. + * @param uiResDirRva RVA of the beginning of the resource directory. + **/ + int ResourceDirectory::read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize, unsigned int uiResDirRva) + { + if (!uiSize || !uiOffset) + { + return 1; + } + + std::ifstream ifFile(strFilename.c_str(), std::ios::binary); + + if (!ifFile) + { +// throw Exceptions::CannotOpenFile(ResourceDirectoryId, __LINE__); + return 1; + } + + if (fileSize(ifFile) < uiOffset + uiSize) + { +// throw Exceptions::InvalidFormat(ResourceDirectoryId, __LINE__); + return 1; + } + + ifFile.seekg(uiOffset, std::ios::beg); + + PELIB_IMAGE_RESOURCE_DIRECTORY irdCurrRoot; + + std::vector vResourceDirectory(uiSize); + ifFile.read(reinterpret_cast(&vResourceDirectory[0]), uiSize); + + InputBuffer inpBuffer(vResourceDirectory); + +// ResourceNode currNode; + return m_rnRoot.read(inpBuffer, 0, uiResDirRva/*, ""*/); +// std::swap(currNode, m_rnRoot); + } + + /** + * Rebuilds the resource directory. + * @param vBuffer Buffer the source directory will be written to. + * @param uiRva RVA of the resource directory. + **/ + void ResourceDirectory::rebuild(std::vector& vBuffer, unsigned int uiRva) const + { + OutputBuffer obBuffer(vBuffer); + unsigned int offs = 0; +// std::cout << "Root: " << m_rnRoot.children.size() << std::endl; + m_rnRoot.rebuild(obBuffer, offs, uiRva, ""); + } + + /** + * Returns the size of the entire rebuilt resource directory. That's the size of the entire + * structure as it's written back to a file. + **/ +/* unsigned int ResourceDirectory::size() const + { + return m_rnRoot.size(); + } +*/ + /** + * Writes the current resource directory back into a file. + * @param strFilename Name of the output file. + * @param uiOffset File offset where the resource directory will be written to. + * @param uiRva RVA of the file offset. + **/ + int ResourceDirectory::write(const std::string& strFilename, unsigned int uiOffset, unsigned int uiRva) const + { + std::fstream ofFile(strFilename.c_str(), std::ios_base::in); + + if (!ofFile) + { + ofFile.clear(); + ofFile.open(strFilename.c_str(), std::ios_base::out | std::ios_base::binary); + } + else + { + ofFile.close(); + ofFile.open(strFilename.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary); + } + + if (!ofFile) + { + return ERROR_OPENING_FILE; + } + + ofFile.seekp(uiOffset, std::ios::beg); + + std::vector vBuffer; + rebuild(vBuffer, uiRva); + + ofFile.write(reinterpret_cast(&vBuffer[0]), static_cast(vBuffer.size())); + + ofFile.close(); + + return 0; + } + + /** + * Adds another resource type. The new resource type is identified by the ID dwResTypeId. + * @param dwResTypeId ID which identifies the resource type. + **/ + int ResourceDirectory::addResourceType(dword dwResTypeId) + { + std::vector::iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(&ResourceChild::equalId), dwResTypeId)); + if (Iter != m_rnRoot.children.end()) + { + return 1; + // throw Exceptions::EntryAlreadyExists(ResourceDirectoryId, __LINE__); + } + + ResourceChild rcCurr; + rcCurr.child = new ResourceNode; + rcCurr.entry.irde.Name = dwResTypeId; + m_rnRoot.children.push_back(rcCurr); + + return 0; + } + + /** + * Adds another resource type. The new resource type is identified by the name strResTypeName. + * @param strResTypeName Name which identifies the resource type. + **/ + int ResourceDirectory::addResourceType(const std::string& strResTypeName) + { + std::vector::iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(&ResourceChild::equalName), strResTypeName)); + if (Iter != m_rnRoot.children.end()) + { + return 1; +// throw Exceptions::EntryAlreadyExists(ResourceDirectoryId, __LINE__); + } + + ResourceChild rcCurr; + rcCurr.entry.wstrName = strResTypeName; + rcCurr.child = new ResourceNode; + m_rnRoot.children.push_back(rcCurr); + + return 0; + } + + /** + * Removes the resource type identified by the ID dwResTypeId. + * @param dwResTypeId ID which identifies the resource type. + **/ + int ResourceDirectory::removeResourceType(dword dwResTypeId) + { + std::vector::iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(&ResourceChild::equalId), dwResTypeId)); + if (Iter == m_rnRoot.children.end()) + { + return 1; +// throw Exceptions::ResourceTypeDoesNotExist(ResourceDirectoryId, __LINE__); + } + + bool isNamed = false; + if (Iter->isNamedResource()) isNamed = true; + + m_rnRoot.children.erase(Iter); + + if (isNamed) m_rnRoot.header.NumberOfNamedEntries = static_cast(m_rnRoot.children.size()); + else m_rnRoot.header.NumberOfIdEntries = static_cast(m_rnRoot.children.size()); + + return 0; + } + + /** + * Removes the resource type identified by the name strResTypeName. + * @param strResTypeName Name which identifies the resource type. + **/ + int ResourceDirectory::removeResourceType(const std::string& strResTypeName) + { + std::vector::iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(&ResourceChild::equalName), strResTypeName)); + if (Iter == m_rnRoot.children.end()) + { + return 1; + // throw Exceptions::ResourceTypeDoesNotExist(ResourceDirectoryId, __LINE__); + } + + bool isNamed = false; + if (Iter->isNamedResource()) isNamed = true; + + m_rnRoot.children.erase(Iter); + + if (isNamed) m_rnRoot.header.NumberOfNamedEntries = static_cast(m_rnRoot.children.size()); + else m_rnRoot.header.NumberOfIdEntries = static_cast(m_rnRoot.children.size()); + + return 0; + } + + /** + * Removes the resource type identified by the index uiIndex. + * @param uiIndex Index which identifies the resource type. + **/ + int ResourceDirectory::removeResourceTypeByIndex(unsigned int uiIndex) + { + bool isNamed = false; + if (m_rnRoot.children[uiIndex].isNamedResource()) isNamed = true; + + m_rnRoot.children.erase(m_rnRoot.children.begin() + uiIndex); + + if (isNamed) m_rnRoot.header.NumberOfNamedEntries = static_cast(m_rnRoot.children.size()); + else m_rnRoot.header.NumberOfIdEntries = static_cast(m_rnRoot.children.size()); + + return 0; + } + + /** + * Adds another resource to the resource tree. The first parameter identifies the resource type + * of the new resource, the second parameter identifies the resource itself. + * @param dwResTypeId ID of the resource type. + * @param dwResId ID of the resource. + **/ + int ResourceDirectory::addResource(dword dwResTypeId, dword dwResId) + { + ResourceChild rcCurr; + rcCurr.entry.irde.Name = dwResId; + return addResourceT(dwResTypeId, dwResId, rcCurr); + } + + /** + * Adds another resource to the resource tree. The first parameter identifies the resource type + * of the new resource, the second parameter identifies the resource itself. + * @param dwResTypeId ID of the resource type. + * @param strResName Name of the resource. + **/ + int ResourceDirectory::addResource(dword dwResTypeId, const std::string& strResName) + { + ResourceChild rcCurr; + rcCurr.entry.wstrName = strResName; + return addResourceT(dwResTypeId, strResName, rcCurr); + } + + /** + * Adds another resource to the resource tree. The first parameter identifies the resource type + * of the new resource, the second parameter identifies the resource itself. + * @param strResTypeName Name of the resource type. + * @param dwResId ID of the resource. + **/ + int ResourceDirectory::addResource(const std::string& strResTypeName, dword dwResId) + { + ResourceChild rcCurr; + rcCurr.entry.irde.Name = dwResId; + return addResourceT(strResTypeName, dwResId, rcCurr); + } + + /** + * Adds another resource to the resource tree. The first parameter identifies the resource type + * of the new resource, the second parameter identifies the resource itself. + * @param strResTypeName Name of the resource type. + * @param strResName Name of the resource. + **/ + int ResourceDirectory::addResource(const std::string& strResTypeName, const std::string& strResName) + { + ResourceChild rcCurr; + rcCurr.entry.wstrName = strResName; + return addResourceT(strResTypeName, strResName, rcCurr); + } + + /** + * Removes a resource from the resource tree. The first parameter identifies the resource type + * of the new resource, the second parameter identifies the resource itself. + * @param dwResTypeIndex ID of the resource type. + * @param dwResId ID of the resource. + **/ + int ResourceDirectory::removeResource(dword dwResTypeIndex, dword dwResId) + { + return removeResourceT(dwResTypeIndex, dwResId); + } + + /** + * Removes a resource from the resource tree. The first parameter identifies the resource type + * of the new resource, the second parameter identifies the resource itself. + * @param dwResTypeIndex ID of the resource type. + * @param strResName Name of the resource. + **/ + int ResourceDirectory::removeResource(dword dwResTypeIndex, const std::string& strResName) + { + return removeResourceT(dwResTypeIndex, strResName); + } + + /** + * Removes a resource from the resource tree. The first parameter identifies the resource type + * of the new resource, the second parameter identifies the resource itself. + * @param strResTypeName Name of the resource type. + * @param dwResId ID of the resource. + **/ + int ResourceDirectory::removeResource(const std::string& strResTypeName, dword dwResId) + { + return removeResourceT(strResTypeName, dwResId); + } + + /** + * Removes a resource from the resource tree. The first parameter identifies the resource type + * of the new resource, the second parameter identifies the resource itself. + * @param strResTypeName Name of the resource type. + * @param strResName Name of the resource. + **/ + int ResourceDirectory::removeResource(const std::string& strResTypeName, const std::string& strResName) + { + return removeResourceT(strResTypeName, strResName); + } + + /** + * Returns the number of resource types. + **/ + unsigned int ResourceDirectory::getNumberOfResourceTypes() const + { + return static_cast(m_rnRoot.children.size()); + } + + /** + * Returns the ID of a resource type which was specified through an index. + * The valid range of the parameter uiIndex is 0...getNumberOfResourceTypes() - 1. + * Leaving the invalid range leads to undefined behaviour. + * @param uiIndex Index which identifies a resource type. + * @return The ID of the specified resource type. + **/ + dword ResourceDirectory::getResourceTypeIdByIndex(unsigned int uiIndex) const + { + return m_rnRoot.children[uiIndex].entry.irde.Name; + } + + /** + * Returns the name of a resource type which was specified through an index. + * The valid range of the parameter uiIndex is 0...getNumberOfResourceTypes() - 1. + * Leaving the invalid range leads to undefined behaviour. + * @param uiIndex Index which identifies a resource type. + * @return The name of the specified resource type. + **/ + std::string ResourceDirectory::getResourceTypeNameByIndex(unsigned int uiIndex) const + { + return m_rnRoot.children[uiIndex].entry.wstrName; + } + + /** + * Converts the ID of a resource type to an index. + * @param dwResTypeId ID of the resource type. + * @return Index of that resource type. + **/ + int ResourceDirectory::resourceTypeIdToIndex(dword dwResTypeId) const + { + std::vector::const_iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(&ResourceChild::equalId), dwResTypeId)); + if (Iter == m_rnRoot.children.end()) return -1; + return static_cast(std::distance(m_rnRoot.children.begin(), Iter)); + } + + /** + * Converts the name of a resource type to an index. + * @param strResTypeName ID of the resource type. + * @return Index of that resource type. + **/ + int ResourceDirectory::resourceTypeNameToIndex(const std::string& strResTypeName) const + { + std::vector::const_iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(&ResourceChild::equalName), strResTypeName)); + if (Iter == m_rnRoot.children.end()) return -1; + return static_cast(std::distance(m_rnRoot.children.begin(), Iter)); + } + + /** + * Returns the number of resources of a specific resource type. + * @param dwId ID of the resource type. + * @return Number of resources of resource type dwId. + **/ + unsigned int ResourceDirectory::getNumberOfResources(dword dwId) const + { +// std::vector::const_iterator IterD = m_rnRoot.children.begin(); +// std::cout << dwId << std::endl; +// while (IterD != m_rnRoot.children.end()) +// { +// std::cout << IterD->entry.irde.Name << std::endl; +// ++IterD; +// } + + std::vector::const_iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(&ResourceChild::equalId), dwId)); + if (Iter == m_rnRoot.children.end()) + { + return 0xFFFFFFFF; + } + else + { + ResourceNode* currNode = static_cast(Iter->child); + return static_cast(currNode->children.size()); + } + } + + /** + * Returns the number of resources of a specific resource type. + * @param strResTypeName Name of the resource type. + * @return Number of resources of resource type strResTypeName. + **/ + unsigned int ResourceDirectory::getNumberOfResources(const std::string& strResTypeName) const + { + std::vector::const_iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(&ResourceChild::equalName), strResTypeName)); + if (Iter == m_rnRoot.children.end()) + { + return 0xFFFFFFFF; + } + else + { + ResourceNode* currNode = static_cast(Iter->child); + return static_cast(currNode->children.size()); + } + } + + /** + * Returns the number of resources of a resource type which was specified through an index. + * The valid range of the parameter uiIndex is 0...getNumberOfResourceTypes() - 1. + * Leaving the invalid range leads to undefined behaviour. + * @param uiIndex Index which identifies a resource type. + * @return The number of resources of the specified resource type. + **/ + unsigned int ResourceDirectory::getNumberOfResourcesByIndex(unsigned int uiIndex) const + { + ResourceNode* currNode = static_cast(m_rnRoot.children[uiIndex].child); + return static_cast(currNode->children.size()); + } + + /** + * Gets the resource data of a specific resource. + * @param dwResTypeId Identifies the resource type of the resource. + * @param dwResId Identifies the resource. + * @param data Vector where the data is stored. + **/ + void ResourceDirectory::getResourceData(dword dwResTypeId, dword dwResId, std::vector& data) const + { + getResourceDataT(dwResTypeId, dwResId, data); + } + + /** + * Gets the resource data of a specific resource. + * @param dwResTypeId Identifies the resource type of the resource. + * @param strResName Identifies the resource. + * @param data Vector where the data is stored. + **/ + void ResourceDirectory::getResourceData(dword dwResTypeId, const std::string& strResName, std::vector& data) const + { + getResourceDataT(dwResTypeId, strResName, data); + } + + /** + * Gets the resource data of a specific resource. + * @param strResTypeName Identifies the resource type of the resource. + * @param dwResId Identifies the resource. + * @param data Vector where the data is stored. + **/ + void ResourceDirectory::getResourceData(const std::string& strResTypeName, dword dwResId, std::vector& data) const + { + getResourceDataT(strResTypeName, dwResId, data); + } + + /** + * Gets the resource data of a specific resource. + * @param strResTypeName Identifies the resource type of the resource. + * @param strResName Identifies the resource. + * @param data Vector where the data is stored. + **/ + void ResourceDirectory::getResourceData(const std::string& strResTypeName, const std::string& strResName, std::vector& data) const + { + getResourceDataT(strResTypeName, strResName, data); + } + + /** + * Gets the resource data of a specific resource by index. + * The valid range of the parameter uiResTypeIndex is 0...getNumberOfResourceTypes() - 1. + * The valid range of the parameter uiResIndex is 0...getNumberOfResources() - 1. + * Leaving the invalid range leads to undefined behaviour. + * @param uiResTypeIndex Identifies the resource type of the resource. + * @param uiResIndex Identifies the resource. + * @param data Vector where the data is stored. + **/ + void ResourceDirectory::getResourceDataByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex, std::vector& data) const + { + ResourceNode* currNode = static_cast(m_rnRoot.children[uiResTypeIndex].child); + currNode = static_cast(currNode->children[uiResIndex].child); + ResourceLeaf* currLeaf = static_cast(currNode->children[0].child); + + data.assign(currLeaf->m_data.begin(), currLeaf->m_data.end()); + } + + /** + * Sets the resource data of a specific resource. + * @param dwResTypeId Identifies the resource type of the resource. + * @param dwResId Identifies the resource. + * @param data The new resource data. + **/ + void ResourceDirectory::setResourceData(dword dwResTypeId, dword dwResId, std::vector& data) + { + setResourceDataT(dwResTypeId, dwResId, data); + } + + /** + * Sets the resource data of a specific resource. + * @param dwResTypeId Identifies the resource type of the resource. + * @param strResName Identifies the resource. + * @param data The new resource data. + **/ + void ResourceDirectory::setResourceData(dword dwResTypeId, const std::string& strResName, std::vector& data) + { + setResourceDataT(dwResTypeId, strResName, data); + } + + /** + * Sets the resource data of a specific resource. + * @param strResTypeName Identifies the resource type of the resource. + * @param dwResId Identifies the resource. + * @param data The new resource data. + **/ + void ResourceDirectory::setResourceData(const std::string& strResTypeName, dword dwResId, std::vector& data) + { + setResourceDataT(strResTypeName, dwResId, data); + } + + /** + * Sets the resource data of a specific resource. + * @param strResTypeName Identifies the resource type of the resource. + * @param strResName Identifies the resource. + * @param data The new resource data. + **/ + void ResourceDirectory::setResourceData(const std::string& strResTypeName, const std::string& strResName, std::vector& data) + { + setResourceDataT(strResTypeName, strResName, data); + } + + /** + * Sets the resource data of a specific resource by index. + * The valid range of the parameter uiResTypeIndex is 0...getNumberOfResourceTypes() - 1. + * The valid range of the parameter uiResIndex is 0...getNumberOfResources() - 1. + * Leaving the invalid range leads to undefined behaviour. + * @param uiResTypeIndex Identifies the resource type of the resource. + * @param uiResIndex Identifies the resource. + * @param data The new resource data. + **/ + void ResourceDirectory::setResourceDataByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex, std::vector& data) + { + ResourceNode* currNode = static_cast(m_rnRoot.children[uiResTypeIndex].child); + currNode = static_cast(currNode->children[uiResIndex].child); + ResourceLeaf* currLeaf = static_cast(currNode->children[0].child); + currLeaf->m_data.assign(data.begin(), data.end()); + } + + /** + * Gets the ID of a specific resource. + * @param dwResTypeId Identifies the resource type of the resource. + * @param strResName Identifies the resource. + * @return ID of the specified resource. + **/ + dword ResourceDirectory::getResourceId(dword dwResTypeId, const std::string& strResName) const + { + return getResourceIdT(dwResTypeId, strResName); + } + + /** + * Gets the ID of a specific resource. + * @param strResTypeName Identifies the resource type of the resource. + * @param strResName Identifies the resource. + * @return ID of the specified resource. + **/ + dword ResourceDirectory::getResourceId(const std::string& strResTypeName, const std::string& strResName) const + { + return getResourceIdT(strResTypeName, strResName); + } + + /** + * Gets the ID of a specific resource by index. + * @param uiResTypeIndex Identifies the resource type of the resource. + * @param uiResIndex Identifies the resource. + * @return ID of the specified resource. + **/ + dword ResourceDirectory::getResourceIdByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex) const + { + ResourceNode* currNode = static_cast(m_rnRoot.children[uiResTypeIndex].child); + return currNode->children[uiResIndex].entry.irde.Name; + } + + /** + * Sets the ID of a specific resource. + * @param dwResTypeId Identifies the resource type of the resource. + * @param dwResId Identifies the resource. + * @param dwNewResId New ID of the resource. + **/ + void ResourceDirectory::setResourceId(dword dwResTypeId, dword dwResId, dword dwNewResId) + { + setResourceIdT(dwResTypeId, dwResId, dwNewResId); + } + + /** + * Sets the ID of a specific resource. + * @param dwResTypeId Identifies the resource type of the resource. + * @param strResName Identifies the resource. + * @param dwNewResId New ID of the resource. + **/ + void ResourceDirectory::setResourceId(dword dwResTypeId, const std::string& strResName, dword dwNewResId) + { + setResourceIdT(dwResTypeId, strResName, dwNewResId); + } + + /** + * Sets the ID of a specific resource. + * @param strResTypeName Identifies the resource type of the resource. + * @param dwResId Identifies the resource. + * @param dwNewResId New ID of the resource. + **/ + void ResourceDirectory::setResourceId(const std::string& strResTypeName, dword dwResId, dword dwNewResId) + { + setResourceIdT(strResTypeName, dwResId, dwNewResId); + } + + /** + * Sets the ID of a specific resource. + * @param strResTypeName Identifies the resource type of the resource. + * @param strResName Identifies the resource. + * @param dwNewResId New ID of the resource. + **/ + void ResourceDirectory::setResourceId(const std::string& strResTypeName, const std::string& strResName, dword dwNewResId) + { + setResourceIdT(strResTypeName, strResName, dwNewResId); + } + + /** + * Sets the ID of a specific resource by index. + * @param uiResTypeIndex Identifies the resource type of the resource. + * @param uiResIndex Identifies the resource. + * @param dwNewResId New ID of the specified resource. + **/ + void ResourceDirectory::setResourceIdByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex, dword dwNewResId) + { + ResourceNode* currNode = static_cast(m_rnRoot.children[uiResTypeIndex].child); + currNode->children[uiResIndex].entry.irde.Name = dwNewResId; + } + + /** + * Gets the Name of a specific resource. + * @param dwResTypeId Identifies the resource type of the resource. + * @param dwResId Identifies the resource. + * @return Name of the specified resource. + **/ + std::string ResourceDirectory::getResourceName(dword dwResTypeId, dword dwResId) const + { + return getResourceNameT(dwResTypeId, dwResId); + } + + /** + * Gets the Name of a specific resource. + * @param strResTypeName Identifies the resource type of the resource. + * @param dwResId Identifies the resource. + * @return Name of the specified resource. + **/ + std::string ResourceDirectory::getResourceName(const std::string& strResTypeName, dword dwResId) const + { + return getResourceNameT(strResTypeName, dwResId); + } + + /** + * Gets the name of a specific resource by index. + * @param uiResTypeIndex Identifies the resource type of the resource. + * @param uiResIndex Identifies the resource. + * @return Name of the specified resource. + **/ + std::string ResourceDirectory::getResourceNameByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex) const + { + ResourceNode* currNode = static_cast(m_rnRoot.children[uiResTypeIndex].child); + return currNode->children[uiResIndex].entry.wstrName; + } + + /** + * Sets the name of a specific resource. + * @param dwResTypeId Identifies the resource type of the resource. + * @param dwResId Identifies the resource. + * @param strNewResName New name of the specified resource. + **/ + void ResourceDirectory::setResourceName(dword dwResTypeId, dword dwResId, const std::string& strNewResName) + { + setResourceNameT(dwResTypeId, dwResId, strNewResName); + } + + /** + * Sets the name of a specific resource. + * @param dwResTypeId Identifies the resource type of the resource. + * @param strResName Identifies the resource. + * @param strNewResName New name of the specified resource. + **/ + void ResourceDirectory::setResourceName(dword dwResTypeId, const std::string& strResName, const std::string& strNewResName) + { + setResourceNameT(dwResTypeId, strResName, strNewResName); + } + + /** + * Sets the name of a specific resource. + * @param strResTypeName Identifies the resource type of the resource. + * @param dwResId Identifies the resource. + * @param strNewResName New name of the specified resource. + **/ + void ResourceDirectory::setResourceName(const std::string& strResTypeName, dword dwResId, const std::string& strNewResName) + { + setResourceNameT(strResTypeName, dwResId, strNewResName); + } + + /** + * Sets the name of a specific resource. + * @param strResTypeName Identifies the resource type of the resource. + * @param strResName Identifies the resource. + * @param strNewResName New name of the specified resource. + **/ + void ResourceDirectory::setResourceName(const std::string& strResTypeName, const std::string& strResName, const std::string& strNewResName) + { + setResourceNameT(strResTypeName, strResName, strNewResName); + } + + /** + * Sets the name of a specific resource by index. + * @param uiResTypeIndex Identifies the resource type of the resource. + * @param uiResIndex Identifies the resource. + * @param strNewResName New name of the specified resource. + **/ + void ResourceDirectory::setResourceNameByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex, const std::string& strNewResName) + { + ResourceNode* currNode = static_cast(m_rnRoot.children[uiResTypeIndex].child); + currNode->children[uiResIndex].entry.wstrName = strNewResName; + } + +} -- cgit v1.2.3