1 //===-- WindowsResource.h ---------------------------------------*- C++-*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===---------------------------------------------------------------------===// 9 // 10 // This file declares the .res file class. .res files are intermediate 11 // products of the typical resource-compilation process on Windows. This 12 // process is as follows: 13 // 14 // .rc file(s) ---(rc.exe)---> .res file(s) ---(cvtres.exe)---> COFF file 15 // 16 // .rc files are human-readable scripts that list all resources a program uses. 17 // 18 // They are compiled into .res files, which are a list of the resources in 19 // binary form. 20 // 21 // Finally the data stored in the .res is compiled into a COFF file, where it 22 // is organized in a directory tree structure for optimized access by the 23 // program during runtime. 24 // 25 // Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms648007(v=vs.85).aspx 26 // 27 //===---------------------------------------------------------------------===// 28 29 #ifndef LLVM_INCLUDE_LLVM_OBJECT_RESFILE_H 30 #define LLVM_INCLUDE_LLVM_OBJECT_RESFILE_H 31 32 #include "llvm/ADT/ArrayRef.h" 33 #include "llvm/BinaryFormat/COFF.h" 34 #include "llvm/Object/Binary.h" 35 #include "llvm/Object/Error.h" 36 #include "llvm/Support/BinaryByteStream.h" 37 #include "llvm/Support/BinaryStreamReader.h" 38 #include "llvm/Support/ConvertUTF.h" 39 #include "llvm/Support/Endian.h" 40 #include "llvm/Support/Error.h" 41 #include "llvm/Support/ScopedPrinter.h" 42 43 #include <map> 44 45 namespace llvm { 46 namespace object { 47 48 class WindowsResource; 49 50 class ResourceEntryRef { 51 public: 52 Error moveNext(bool &End); 53 bool checkTypeString() const { return IsStringType; } 54 ArrayRef<UTF16> getTypeString() const { return Type; } 55 uint16_t getTypeID() const { return TypeID; } 56 bool checkNameString() const { return IsStringName; } 57 ArrayRef<UTF16> getNameString() const { return Name; } 58 uint16_t getNameID() const { return NameID; } 59 uint16_t getLanguage() const { return Suffix->Language; } 60 uint16_t getMajorVersion() const { return Suffix->Version >> 16; } 61 uint16_t getMinorVersion() const { return Suffix->Version; } 62 uint32_t getCharacteristics() const { return Suffix->Characteristics; } 63 ArrayRef<uint8_t> getData() const { return Data; } 64 65 private: 66 friend class WindowsResource; 67 68 ResourceEntryRef(BinaryStreamRef Ref, const WindowsResource *Owner, 69 Error &Err); 70 71 Error loadNext(); 72 73 struct HeaderSuffix { 74 support::ulittle32_t DataVersion; 75 support::ulittle16_t MemoryFlags; 76 support::ulittle16_t Language; 77 support::ulittle32_t Version; 78 support::ulittle32_t Characteristics; 79 }; 80 81 BinaryStreamReader Reader; 82 bool IsStringType; 83 ArrayRef<UTF16> Type; 84 uint16_t TypeID; 85 bool IsStringName; 86 ArrayRef<UTF16> Name; 87 uint16_t NameID; 88 const HeaderSuffix *Suffix = nullptr; 89 ArrayRef<uint8_t> Data; 90 const WindowsResource *OwningRes = nullptr; 91 }; 92 93 class WindowsResource : public Binary { 94 public: 95 Expected<ResourceEntryRef> getHeadEntry(); 96 97 static bool classof(const Binary *V) { return V->isWinRes(); } 98 99 static Expected<std::unique_ptr<WindowsResource>> 100 createWindowsResource(MemoryBufferRef Source); 101 102 private: 103 friend class ResourceEntryRef; 104 105 WindowsResource(MemoryBufferRef Source); 106 107 BinaryByteStream BBS; 108 }; 109 110 class WindowsResourceParser { 111 public: 112 class TreeNode; 113 WindowsResourceParser(); 114 Error parse(WindowsResource *WR); 115 void printTree(raw_ostream &OS) const; 116 const TreeNode &getTree() const { return Root; } 117 const ArrayRef<std::vector<uint8_t>> getData() const { return Data; } 118 const ArrayRef<std::vector<UTF16>> getStringTable() const { 119 return StringTable; 120 } 121 122 class TreeNode { 123 public: 124 template <typename T> 125 using Children = std::map<T, std::unique_ptr<TreeNode>>; 126 127 void print(ScopedPrinter &Writer, StringRef Name) const; 128 uint32_t getTreeSize() const; 129 uint32_t getStringIndex() const { return StringIndex; } 130 uint32_t getDataIndex() const { return DataIndex; } 131 uint16_t getMajorVersion() const { return MajorVersion; } 132 uint16_t getMinorVersion() const { return MinorVersion; } 133 uint32_t getCharacteristics() const { return Characteristics; } 134 bool checkIsDataNode() const { return IsDataNode; } 135 const Children<uint32_t> &getIDChildren() const { return IDChildren; } 136 const Children<std::string> &getStringChildren() const { 137 return StringChildren; 138 } 139 140 private: 141 friend class WindowsResourceParser; 142 143 static uint32_t StringCount; 144 static uint32_t DataCount; 145 146 static std::unique_ptr<TreeNode> createStringNode(); 147 static std::unique_ptr<TreeNode> createIDNode(); 148 static std::unique_ptr<TreeNode> createDataNode(uint16_t MajorVersion, 149 uint16_t MinorVersion, 150 uint32_t Characteristics); 151 152 explicit TreeNode(bool IsStringNode); 153 TreeNode(uint16_t MajorVersion, uint16_t MinorVersion, 154 uint32_t Characteristics); 155 156 void addEntry(const ResourceEntryRef &Entry, bool &IsNewTypeString, 157 bool &IsNewNameString); 158 TreeNode &addTypeNode(const ResourceEntryRef &Entry, bool &IsNewTypeString); 159 TreeNode &addNameNode(const ResourceEntryRef &Entry, bool &IsNewNameString); 160 TreeNode &addLanguageNode(const ResourceEntryRef &Entry); 161 TreeNode &addChild(uint32_t ID, bool IsDataNode = false, 162 uint16_t MajorVersion = 0, uint16_t MinorVersion = 0, 163 uint32_t Characteristics = 0); 164 TreeNode &addChild(ArrayRef<UTF16> NameRef, bool &IsNewString); 165 166 bool IsDataNode = false; 167 uint32_t StringIndex; 168 uint32_t DataIndex; 169 Children<uint32_t> IDChildren; 170 Children<std::string> StringChildren; 171 uint16_t MajorVersion = 0; 172 uint16_t MinorVersion = 0; 173 uint32_t Characteristics = 0; 174 }; 175 176 private: 177 TreeNode Root; 178 std::vector<std::vector<uint8_t>> Data; 179 std::vector<std::vector<UTF16>> StringTable; 180 }; 181 182 Error writeWindowsResourceCOFF(std::unique_ptr<MemoryBuffer> &OutputBuffer, 183 llvm::COFF::MachineTypes MachineType, 184 const WindowsResourceParser &Parser); 185 186 } // namespace object 187 } // namespace llvm 188 189 #endif 190