1 //===-- WindowsResource.h ---------------------------------------*- C++-*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===---------------------------------------------------------------------===//
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:
14 // .rc file(s) ---(rc.exe)---> .res file(s) ---(cvtres.exe)---> COFF file
16 // .rc files are human-readable scripts that list all resources a program uses.
18 // They are compiled into .res files, which are a list of the resources in
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.
25 // Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms648007(v=vs.85).aspx
27 //===---------------------------------------------------------------------===//
29 #ifndef LLVM_INCLUDE_LLVM_OBJECT_RESFILE_H
30 #define LLVM_INCLUDE_LLVM_OBJECT_RESFILE_H
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"
48 class WindowsResource
;
50 const size_t WIN_RES_MAGIC_SIZE
= 16;
51 const size_t WIN_RES_NULL_ENTRY_SIZE
= 16;
52 const uint32_t WIN_RES_HEADER_ALIGNMENT
= 4;
53 const uint32_t WIN_RES_DATA_ALIGNMENT
= 4;
54 const uint16_t WIN_RES_PURE_MOVEABLE
= 0x0030;
56 struct WinResHeaderPrefix
{
57 support::ulittle32_t DataSize
;
58 support::ulittle32_t HeaderSize
;
61 // Type and Name may each either be an integer ID or a string. This struct is
62 // only used in the case where they are both IDs.
65 support::ulittle16_t TypeID
;
67 support::ulittle16_t NameID
;
69 void setType(uint16_t ID
) {
74 void setName(uint16_t ID
) {
80 struct WinResHeaderSuffix
{
81 support::ulittle32_t DataVersion
;
82 support::ulittle16_t MemoryFlags
;
83 support::ulittle16_t Language
;
84 support::ulittle32_t Version
;
85 support::ulittle32_t Characteristics
;
88 class EmptyResError
: public GenericBinaryError
{
90 EmptyResError(Twine Msg
, object_error ECOverride
)
91 : GenericBinaryError(Msg
, ECOverride
) {}
94 class ResourceEntryRef
{
96 Error
moveNext(bool &End
);
97 bool checkTypeString() const { return IsStringType
; }
98 ArrayRef
<UTF16
> getTypeString() const { return Type
; }
99 uint16_t getTypeID() const { return TypeID
; }
100 bool checkNameString() const { return IsStringName
; }
101 ArrayRef
<UTF16
> getNameString() const { return Name
; }
102 uint16_t getNameID() const { return NameID
; }
103 uint16_t getDataVersion() const { return Suffix
->DataVersion
; }
104 uint16_t getLanguage() const { return Suffix
->Language
; }
105 uint16_t getMemoryFlags() const { return Suffix
->MemoryFlags
; }
106 uint16_t getMajorVersion() const { return Suffix
->Version
>> 16; }
107 uint16_t getMinorVersion() const { return Suffix
->Version
; }
108 uint32_t getCharacteristics() const { return Suffix
->Characteristics
; }
109 ArrayRef
<uint8_t> getData() const { return Data
; }
112 friend class WindowsResource
;
114 ResourceEntryRef(BinaryStreamRef Ref
, const WindowsResource
*Owner
);
117 static Expected
<ResourceEntryRef
> create(BinaryStreamRef Ref
,
118 const WindowsResource
*Owner
);
120 BinaryStreamReader Reader
;
122 ArrayRef
<UTF16
> Type
;
125 ArrayRef
<UTF16
> Name
;
127 const WinResHeaderSuffix
*Suffix
= nullptr;
128 ArrayRef
<uint8_t> Data
;
131 class WindowsResource
: public Binary
{
133 Expected
<ResourceEntryRef
> getHeadEntry();
135 static bool classof(const Binary
*V
) { return V
->isWinRes(); }
137 static Expected
<std::unique_ptr
<WindowsResource
>>
138 createWindowsResource(MemoryBufferRef Source
);
141 friend class ResourceEntryRef
;
143 WindowsResource(MemoryBufferRef Source
);
145 BinaryByteStream BBS
;
148 class WindowsResourceParser
{
151 WindowsResourceParser();
152 Error
parse(WindowsResource
*WR
);
153 void printTree(raw_ostream
&OS
) const;
154 const TreeNode
&getTree() const { return Root
; }
155 const ArrayRef
<std::vector
<uint8_t>> getData() const { return Data
; }
156 const ArrayRef
<std::vector
<UTF16
>> getStringTable() const {
162 template <typename T
>
163 using Children
= std::map
<T
, std::unique_ptr
<TreeNode
>>;
165 void print(ScopedPrinter
&Writer
, StringRef Name
) const;
166 uint32_t getTreeSize() const;
167 uint32_t getStringIndex() const { return StringIndex
; }
168 uint32_t getDataIndex() const { return DataIndex
; }
169 uint16_t getMajorVersion() const { return MajorVersion
; }
170 uint16_t getMinorVersion() const { return MinorVersion
; }
171 uint32_t getCharacteristics() const { return Characteristics
; }
172 bool checkIsDataNode() const { return IsDataNode
; }
173 const Children
<uint32_t> &getIDChildren() const { return IDChildren
; }
174 const Children
<std::string
> &getStringChildren() const {
175 return StringChildren
;
179 friend class WindowsResourceParser
;
181 static uint32_t StringCount
;
182 static uint32_t DataCount
;
184 static std::unique_ptr
<TreeNode
> createStringNode();
185 static std::unique_ptr
<TreeNode
> createIDNode();
186 static std::unique_ptr
<TreeNode
> createDataNode(uint16_t MajorVersion
,
187 uint16_t MinorVersion
,
188 uint32_t Characteristics
);
190 explicit TreeNode(bool IsStringNode
);
191 TreeNode(uint16_t MajorVersion
, uint16_t MinorVersion
,
192 uint32_t Characteristics
);
194 void addEntry(const ResourceEntryRef
&Entry
, bool &IsNewTypeString
,
195 bool &IsNewNameString
);
196 TreeNode
&addTypeNode(const ResourceEntryRef
&Entry
, bool &IsNewTypeString
);
197 TreeNode
&addNameNode(const ResourceEntryRef
&Entry
, bool &IsNewNameString
);
198 TreeNode
&addLanguageNode(const ResourceEntryRef
&Entry
);
199 TreeNode
&addChild(uint32_t ID
, bool IsDataNode
= false,
200 uint16_t MajorVersion
= 0, uint16_t MinorVersion
= 0,
201 uint32_t Characteristics
= 0);
202 TreeNode
&addChild(ArrayRef
<UTF16
> NameRef
, bool &IsNewString
);
204 bool IsDataNode
= false;
205 uint32_t StringIndex
;
207 Children
<uint32_t> IDChildren
;
208 Children
<std::string
> StringChildren
;
209 uint16_t MajorVersion
= 0;
210 uint16_t MinorVersion
= 0;
211 uint32_t Characteristics
= 0;
216 std::vector
<std::vector
<uint8_t>> Data
;
217 std::vector
<std::vector
<UTF16
>> StringTable
;
220 Expected
<std::unique_ptr
<MemoryBuffer
>>
221 writeWindowsResourceCOFF(llvm::COFF::MachineTypes MachineType
,
222 const WindowsResourceParser
&Parser
);
224 } // namespace object