Main Page | Class Hierarchy | Class List | File List | Class Members | Related Pages

ResourceDirectory.h

00001 /* 00002 * ResourceDirectory.cpp - Part of the PeLib library. 00003 * 00004 * Copyright (c) 2004 Sebastian Porst (webmaster@the-interweb.com) 00005 * All rights reserved. 00006 * 00007 * This software is licensed under the zlib/libpng License. 00008 * For more details see http://www.opensource.org/licenses/zlib-license.php 00009 * or the license information file (license.htm) in the root directory 00010 * of PeLib. 00011 */ 00012 00013 #ifndef RESOURCEDIRECTORY_H 00014 #define RESOURCEDIRECTORY_H 00015 00016 #include "PeLibInc.h" 00017 00018 namespace PeLib 00019 { 00020 class ResourceElement; 00021 00023 class ResourceChild 00024 { 00025 friend class ResourceElement; 00026 friend class ResourceDirectory; 00027 friend class ResourceNode; 00028 friend class ResourceLeaf; 00029 00031 PELIB_IMG_RES_DIR_ENTRY entry; 00033 ResourceElement* child; 00034 00035 public: 00037 bool equalId(dword wId) const; 00039 bool equalName(std::string strName) const; 00041 bool isNamedResource() const; 00043 bool operator<(const ResourceChild& rc) const; 00045 // unsigned int size() const; 00046 00048 ResourceChild(); 00050 ResourceChild(const ResourceChild& rhs); 00052 ResourceChild& operator=(const ResourceChild& rhs); 00054 ~ResourceChild(); 00055 }; 00056 00059 class ResourceElement 00060 { 00061 friend class ResourceChild; 00062 friend class ResourceNode; 00063 friend class ResourceLeaf; 00064 00065 protected: 00067 unsigned int uiElementRva; 00068 00070 virtual int read(InputBuffer&, unsigned int, unsigned int/*, const std::string&*/) = 0; 00072 virtual void rebuild(OutputBuffer&, unsigned int&, unsigned int, const std::string&) const = 0; 00073 00074 public: 00076 unsigned int getElementRva() const; 00078 virtual bool isLeaf() const = 0; 00080 virtual void makeValid() = 0; 00082 // virtual unsigned int size() const = 0; 00084 virtual ~ResourceElement() {} 00085 }; 00086 00088 class ResourceLeaf : public ResourceElement 00089 { 00090 friend class ResourceChild; 00091 friend class ResourceDirectory; 00092 template<typename T> friend struct fixNumberOfEntries; 00093 00094 private: 00096 std::vector<byte> m_data; 00098 PELIB_IMAGE_RESOURCE_DATA_ENTRY entry; 00099 00100 protected: 00101 int read(InputBuffer& inpBuffer, unsigned int uiOffset, unsigned int rva/*, const std::string&*/); 00103 void rebuild(OutputBuffer&, unsigned int& uiOffset, unsigned int uiRva, const std::string&) const; 00104 00105 public: 00107 bool isLeaf() const; 00109 void makeValid(); 00112 // unsigned int size() const; 00113 00115 std::vector<byte> getData() const; 00117 void setData(const std::vector<byte>& vData); 00118 00120 dword getOffsetToData() const; 00122 dword getSize() const; 00124 dword getCodePage() const; 00126 dword getReserved() const; 00127 00129 void setOffsetToData(dword dwValue); 00131 void setSize(dword dwValue); 00133 void setCodePage(dword dwValue); 00135 void setReserved(dword dwValue); 00136 }; 00137 00139 class ResourceNode : public ResourceElement 00140 { 00141 friend class ResourceChild; 00142 friend class ResourceDirectory; 00143 template<typename T> friend struct fixNumberOfEntries; 00144 00146 std::vector<ResourceChild> children; 00148 PELIB_IMAGE_RESOURCE_DIRECTORY header; 00149 00150 protected: 00152 int read(InputBuffer& inpBuffer, unsigned int uiOffset, unsigned int rva/*, const std::string&*/); 00154 void rebuild(OutputBuffer&, unsigned int& uiOffset, unsigned int uiRva, const std::string&) const; 00155 00156 public: 00158 bool isLeaf() const; 00160 void makeValid(); 00161 00163 unsigned int getNumberOfChildren() const; 00165 void addChild(); 00167 ResourceElement* getChild(unsigned int uiIndex); 00169 void removeChild(unsigned int uiIndex); 00170 00172 std::string getChildName(unsigned int uiIndex) const; 00174 dword getOffsetToChildName(unsigned int uiIndex) const; 00176 dword getOffsetToChildData(unsigned int uiIndex) const; 00177 00179 void setChildName(unsigned int uiIndex, const std::string& strNewName); 00181 void setOffsetToChildName(unsigned int uiIndex, dword dwNewOffset); 00183 void setOffsetToChildData(unsigned int uiIndex, dword dwNewOffset); 00184 00186 dword getCharacteristics() const; 00188 dword getTimeDateStamp() const; 00190 word getMajorVersion() const; 00192 word getMinorVersion() const; 00194 word getNumberOfNamedEntries() const; 00196 word getNumberOfIdEntries() const; 00197 00199 void setCharacteristics(dword value); 00201 void setTimeDateStamp(dword value); 00203 void setMajorVersion(word value); 00205 void setMinorVersion(word value); 00207 void setNumberOfNamedEntries(word value); 00209 void setNumberOfIdEntries(word value); 00210 00212 // unsigned int size() const; 00213 }; 00214 00216 00221 template<typename T> 00222 struct ResComparer 00223 { 00225 typedef bool(ResourceChild::*CompFunc)(T) const; 00226 00228 static CompFunc comp(); 00229 }; 00230 00232 00235 template<> 00236 struct ResComparer<dword> 00237 { 00239 typedef bool(ResourceChild::*CompFunc)(dword) const; 00240 00242 static CompFunc comp() 00243 { 00244 return &ResourceChild::equalId; 00245 } 00246 }; 00247 00249 00252 template<> 00253 struct ResComparer<std::string> 00254 { 00256 typedef bool(ResourceChild::*CompFunc)(std::string) const; 00257 00259 static CompFunc comp() 00260 { 00261 return &ResourceChild::equalName; 00262 } 00263 }; 00264 00266 template<typename T> 00267 struct fixNumberOfEntries 00268 { 00270 static void fix(ResourceNode*); 00271 }; 00272 00274 template<> 00275 struct fixNumberOfEntries<dword> 00276 { 00278 static void fix(ResourceNode* node) 00279 { 00280 node->header.NumberOfIdEntries = (unsigned int)node->children.size() - std::count_if(node->children.begin(), node->children.end(), std::mem_fun_ref(&ResourceChild::isNamedResource)); 00281 } 00282 }; 00283 00285 template<> 00286 struct fixNumberOfEntries<std::string> 00287 { 00289 static void fix(ResourceNode* node) 00290 { 00291 node->header.NumberOfNamedEntries = static_cast<PeLib::word>(std::count_if(node->children.begin(), node->children.end(), std::mem_fun_ref(&ResourceChild::isNamedResource))); 00292 } 00293 }; 00294 00296 00322 class ResourceDirectory 00323 { 00324 private: 00326 ResourceNode m_rnRoot; 00327 00328 // Prepare for some crazy syntax below to make Digital Mars happy. 00329 00331 template<typename S, typename T> 00332 std::vector<ResourceChild>::const_iterator locateResourceT(S restypeid, T resid) const; 00333 00335 template<typename S, typename T> 00336 std::vector<ResourceChild>::iterator locateResourceT(S restypeid, T resid); 00337 00339 template<typename S, typename T> 00340 int addResourceT(S restypeid, T resid, ResourceChild& rc); 00341 00343 template<typename S, typename T> 00344 int removeResourceT(S restypeid, T resid); 00345 00347 template<typename S, typename T> 00348 int getResourceDataT(S restypeid, T resid, std::vector<byte>& data) const; 00349 00351 template<typename S, typename T> 00352 int setResourceDataT(S restypeid, T resid, std::vector<byte>& data); 00353 00355 template<typename S, typename T> 00356 dword getResourceIdT(S restypeid, T resid) const; 00357 00359 template<typename S, typename T> 00360 int setResourceIdT(S restypeid, T resid, dword dwNewResId); 00361 00363 template<typename S, typename T> 00364 std::string getResourceNameT(S restypeid, T resid) const; 00365 00367 template<typename S, typename T> 00368 int setResourceNameT(S restypeid, T resid, std::string strNewResName); 00369 00370 public: 00371 ResourceNode* getRoot(); 00373 void makeValid(); 00375 int read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize, unsigned int uiResDirRva); 00377 void rebuild(std::vector<byte>& vBuffer, unsigned int uiRva) const; 00379 // unsigned int size() const; 00381 int write(const std::string& strFilename, unsigned int uiOffset, unsigned int uiRva) const; 00382 00384 int addResourceType(dword dwResTypeId); 00386 int addResourceType(const std::string& strResTypeName); 00387 00389 int removeResourceType(dword dwResTypeId); 00391 int removeResourceType(const std::string& strResTypeName); 00392 00394 int removeResourceTypeByIndex(unsigned int uiIndex); 00395 00397 int addResource(dword dwResTypeId, dword dwResId); 00399 int addResource(dword dwResTypeId, const std::string& strResName); 00401 int addResource(const std::string& strResTypeName, dword dwResId); 00403 int addResource(const std::string& strResTypeName, const std::string& strResName); 00404 00406 int removeResource(dword dwResTypeId, dword dwResId); 00408 int removeResource(dword dwResTypeId, const std::string& strResName); 00410 int removeResource(const std::string& strResTypeName, dword dwResId); 00412 int removeResource(const std::string& strResTypeName, const std::string& strResName); 00413 00415 unsigned int getNumberOfResourceTypes() const; 00416 00418 dword getResourceTypeIdByIndex(unsigned int uiIndex) const; 00420 std::string getResourceTypeNameByIndex(unsigned int uiIndex) const; 00421 00423 int resourceTypeIdToIndex(dword dwResTypeId) const; 00425 int resourceTypeNameToIndex(const std::string& strResTypeName) const; 00426 00428 unsigned int getNumberOfResources(dword dwId) const; 00430 unsigned int getNumberOfResources(const std::string& strResTypeName) const; 00431 00433 unsigned int getNumberOfResourcesByIndex(unsigned int uiIndex) const; 00434 00436 void getResourceData(dword dwResTypeId, dword dwResId, std::vector<byte>& data) const; 00438 void getResourceData(dword dwResTypeId, const std::string& strResName, std::vector<byte>& data) const; 00440 void getResourceData(const std::string& strResTypeName, dword dwResId, std::vector<byte>& data) const; 00442 void getResourceData(const std::string& strResTypeName, const std::string& strResName, std::vector<byte>& data) const; 00443 00445 void getResourceDataByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex, std::vector<byte>& data) const; 00446 00448 void setResourceData(dword dwResTypeId, dword dwResId, std::vector<byte>& data); 00450 void setResourceData(dword dwResTypeId, const std::string& strResName, std::vector<byte>& data); 00452 void setResourceData(const std::string& strResTypeName, dword dwResId, std::vector<byte>& data); 00454 void setResourceData(const std::string& strResTypeName, const std::string& strResName, std::vector<byte>& data); 00455 00457 void setResourceDataByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex, std::vector<byte>& data); 00458 00460 dword getResourceId(dword dwResTypeId, const std::string& strResName) const; 00462 dword getResourceId(const std::string& strResTypeName, const std::string& strResName) const; 00463 00465 dword getResourceIdByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex) const; 00466 00468 void setResourceId(dword dwResTypeId, dword dwResId, dword dwNewResId); 00470 void setResourceId(dword dwResTypeId, const std::string& strResName, dword dwNewResId); 00472 void setResourceId(const std::string& strResTypeName, dword dwResId, dword dwNewResId); 00474 void setResourceId(const std::string& strResTypeName, const std::string& strResName, dword dwNewResId); 00475 00477 void setResourceIdByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex, dword dwNewResId); 00478 00480 std::string getResourceName(dword dwResTypeId, dword dwResId) const; 00482 std::string getResourceName(const std::string& strResTypeName, dword dwResId) const; 00483 00485 std::string getResourceNameByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex) const; 00486 00488 void setResourceName(dword dwResTypeId, dword dwResId, const std::string& strNewResName); 00490 void setResourceName(dword dwResTypeId, const std::string& strResName, const std::string& strNewResName); 00492 void setResourceName(const std::string& strResTypeName, dword dwResId, const std::string& strNewResName); 00494 void setResourceName(const std::string& strResTypeName, const std::string& strResName, const std::string& strNewResName); 00495 00497 void setResourceNameByIndex(unsigned int uiResTypeIndex, unsigned int uiResIndex, const std::string& strNewResName); 00498 }; 00499 00507 template<typename S, typename T> 00508 std::vector<ResourceChild>::const_iterator ResourceDirectory::locateResourceT(S restypeid, T resid) const 00509 { 00510 typedef bool(ResourceChild::*CompFunc1)(S) const; 00511 typedef bool(ResourceChild::*CompFunc2)(T) const; 00512 00513 CompFunc1 comp1 = ResComparer<S>::comp(); 00514 CompFunc2 comp2 = ResComparer<T>::comp(); 00515 00516 std::vector<ResourceChild>::const_iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(comp1), restypeid)); 00517 if (Iter == m_rnRoot.children.end()) 00518 { 00519 return Iter; 00520 } 00521 00522 ResourceNode* currNode = static_cast<ResourceNode*>(Iter->child); 00523 std::vector<ResourceChild>::const_iterator ResIter = std::find_if(currNode->children.begin(), currNode->children.end(), std::bind2nd(std::mem_fun_ref(comp2), resid)); 00524 if (ResIter == currNode->children.end()) 00525 { 00526 return ResIter; 00527 } 00528 00529 return ResIter; 00530 } 00531 00539 template<typename S, typename T> 00540 std::vector<ResourceChild>::iterator ResourceDirectory::locateResourceT(S restypeid, T resid) 00541 { 00542 typedef bool(ResourceChild::*CompFunc1)(S) const; 00543 typedef bool(ResourceChild::*CompFunc2)(T) const; 00544 00545 CompFunc1 comp1 = ResComparer<S>::comp(); 00546 CompFunc2 comp2 = ResComparer<T>::comp(); 00547 00548 std::vector<ResourceChild>::iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(comp1), restypeid)); 00549 if (Iter == m_rnRoot.children.end()) 00550 { 00551 return Iter; 00552 } 00553 00554 ResourceNode* currNode = static_cast<ResourceNode*>(Iter->child); 00555 std::vector<ResourceChild>::iterator ResIter = std::find_if(currNode->children.begin(), currNode->children.end(), std::bind2nd(std::mem_fun_ref(comp2), resid)); 00556 if (ResIter == currNode->children.end()) 00557 { 00558 return ResIter; 00559 } 00560 00561 return ResIter; 00562 } 00563 00570 template<typename S, typename T> 00571 int ResourceDirectory::addResourceT(S restypeid, T resid, ResourceChild& rc) 00572 { 00573 typedef bool(ResourceChild::*CompFunc1)(S) const; 00574 typedef bool(ResourceChild::*CompFunc2)(T) const; 00575 00576 CompFunc1 comp1 = ResComparer<S>::comp(); 00577 CompFunc2 comp2 = ResComparer<T>::comp(); 00578 00579 std::vector<ResourceChild>::iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(comp1), restypeid)); 00580 if (Iter == m_rnRoot.children.end()) 00581 { 00582 return 1; 00583 // throw Exceptions::ResourceTypeDoesNotExist(ResourceDirectoryId, __LINE__); 00584 } 00585 00586 ResourceNode* currNode = static_cast<ResourceNode*>(Iter->child); 00587 std::vector<ResourceChild>::iterator ResIter = std::find_if(currNode->children.begin(), currNode->children.end(), std::bind2nd(std::mem_fun_ref(comp2), resid)); 00588 if (ResIter != currNode->children.end()) 00589 { 00590 return 1; 00591 // throw Exceptions::EntryAlreadyExists(ResourceDirectoryId, __LINE__); 00592 } 00593 00594 rc.child = new ResourceNode; 00595 ResourceChild rlnew; 00596 rlnew.child = new ResourceLeaf; 00597 ResourceNode* currNode2 = static_cast<ResourceNode*>(rc.child); 00598 currNode2->children.push_back(rlnew); 00599 currNode->children.push_back(rc); 00600 00601 fixNumberOfEntries<T>::fix(currNode); 00602 fixNumberOfEntries<T>::fix(currNode2); 00603 00604 return 0; 00605 } 00606 00612 template<typename S, typename T> 00613 int ResourceDirectory::removeResourceT(S restypeid, T resid) 00614 { 00615 typedef bool(ResourceChild::*CompFunc1)(S) const; 00616 typedef bool(ResourceChild::*CompFunc2)(T) const; 00617 00618 CompFunc1 comp1 = ResComparer<S>::comp(); 00619 CompFunc2 comp2 = ResComparer<T>::comp(); 00620 00621 std::vector<ResourceChild>::iterator Iter = std::find_if(m_rnRoot.children.begin(), m_rnRoot.children.end(), std::bind2nd(std::mem_fun_ref(comp1), restypeid)); 00622 if (Iter == m_rnRoot.children.end()) 00623 { 00624 return 1; 00625 //throw Exceptions::ResourceTypeDoesNotExist(ResourceDirectoryId, __LINE__); 00626 } 00627 00628 ResourceNode* currNode = static_cast<ResourceNode*>(Iter->child); 00629 std::vector<ResourceChild>::iterator ResIter = std::find_if(currNode->children.begin(), currNode->children.end(), std::bind2nd(std::mem_fun_ref(comp2), resid)); 00630 if (ResIter == currNode->children.end()) 00631 { 00632 return 1; 00633 // throw Exceptions::InvalidName(ResourceDirectoryId, __LINE__); 00634 } 00635 00636 currNode->children.erase(ResIter); 00637 00638 fixNumberOfEntries<T>::fix(currNode); 00639 00640 return 0; 00641 } 00642 00649 template<typename S, typename T> 00650 int ResourceDirectory::getResourceDataT(S restypeid, T resid, std::vector<byte>& data) const 00651 { 00652 std::vector<ResourceChild>::const_iterator ResIter = locateResourceT(restypeid, resid); 00653 ResourceNode* currNode = static_cast<ResourceNode*>(ResIter->child); 00654 ResourceLeaf* currLeaf = static_cast<ResourceLeaf*>(currNode->children[0].child); 00655 data.assign(currLeaf->m_data.begin(), currLeaf->m_data.end()); 00656 00657 return 0; 00658 } 00659 00666 template<typename S, typename T> 00667 int ResourceDirectory::setResourceDataT(S restypeid, T resid, std::vector<byte>& data) 00668 { 00669 std::vector<ResourceChild>::iterator ResIter = locateResourceT(restypeid, resid); 00670 ResourceNode* currNode = static_cast<ResourceNode*>(ResIter->child); 00671 ResourceLeaf* currLeaf = static_cast<ResourceLeaf*>(currNode->children[0].child); 00672 currLeaf->m_data.assign(data.begin(), data.end()); 00673 00674 return 0; 00675 } 00676 00684 template<typename S, typename T> 00685 dword ResourceDirectory::getResourceIdT(S restypeid, T resid) const 00686 { 00687 std::vector<ResourceChild>::const_iterator ResIter = locateResourceT(restypeid, resid); 00688 return ResIter->entry.irde.Name; 00689 } 00690 00697 template<typename S, typename T> 00698 int ResourceDirectory::setResourceIdT(S restypeid, T resid, dword dwNewResId) 00699 { 00700 std::vector<ResourceChild>::iterator ResIter = locateResourceT(restypeid, resid); 00701 ResIter->entry.irde.Name = dwNewResId; 00702 return 0; 00703 } 00704 00712 template<typename S, typename T> 00713 std::string ResourceDirectory::getResourceNameT(S restypeid, T resid) const 00714 { 00715 std::vector<ResourceChild>::const_iterator ResIter = locateResourceT(restypeid, resid); 00716 return ResIter->entry.wstrName; 00717 } 00718 00725 template<typename S, typename T> 00726 int ResourceDirectory::setResourceNameT(S restypeid, T resid, std::string strNewResName) 00727 { 00728 std::vector<ResourceChild>::iterator ResIter = locateResourceT(restypeid, resid); 00729 ResIter->entry.wstrName = strNewResName; 00730 00731 return 0; 00732 } 00733 } 00734 00735 #endif

Generated on Mon Jan 17 20:50:08 2005 for PeLib by doxygen 1.3.7