OLD | NEW |
| (Empty) |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // *** File comments | |
6 | |
7 #include "third_party/courgette/ensemble.h" | |
8 | |
9 #include "base/basictypes.h" | |
10 #include "base/logging.h" | |
11 #include "base/string_util.h" | |
12 | |
13 #include "third_party/courgette/image_info.h" | |
14 #include "third_party/courgette/region.h" | |
15 #include "third_party/courgette/streams.h" | |
16 #include "third_party/courgette/simple_delta.h" | |
17 | |
18 namespace courgette { | |
19 | |
20 Element::Element(Kind kind, Ensemble* ensemble, const Region& region) | |
21 : kind_(kind), ensemble_(ensemble), region_(region) { | |
22 } | |
23 | |
24 std::string Element::Name() const { | |
25 return ensemble_->name() + "(" | |
26 + IntToString(kind()) + "," | |
27 + Uint64ToString(offset_in_ensemble()) + "," | |
28 + Uint64ToString(region().length()) + ")"; | |
29 } | |
30 | |
31 // A subclass of Element that has a PEInfo. | |
32 class ElementWinPE : public Element { | |
33 public: | |
34 ElementWinPE(Kind kind, Ensemble* ensemble, const Region& region, | |
35 PEInfo* info) | |
36 : Element(kind, ensemble, region), | |
37 pe_info_(info) { | |
38 } | |
39 | |
40 virtual PEInfo* GetPEInfo() const { return pe_info_; } | |
41 | |
42 protected: | |
43 ~ElementWinPE() { delete pe_info_; } | |
44 | |
45 private: | |
46 PEInfo* pe_info_; // Owned by |this|. | |
47 }; | |
48 | |
49 // Scans the Ensemble's region, sniffing out Elements. We assume that the | |
50 // elements do not overlap. | |
51 Status Ensemble::FindEmbeddedElements() { | |
52 size_t length = region_.length(); | |
53 const uint8* start = region_.start(); | |
54 | |
55 size_t position = 0; | |
56 while (position < length) { | |
57 // Quick test; Windows executables begin with 'MZ'. | |
58 if (start[position] == 'M' && | |
59 position + 1 < length && start[position + 1] == 'Z') { | |
60 courgette::PEInfo *info = new courgette::PEInfo(); | |
61 info->Init(start + position, length - position); | |
62 if (info->ParseHeader()) { | |
63 Region region(start + position, info->length()); | |
64 | |
65 if (info->has_text_section()) { | |
66 Element* element = new ElementWinPE(Element::WIN32_X86_WITH_CODE, | |
67 this, region, info); | |
68 owned_elements_.push_back(element); | |
69 elements_.push_back(element); | |
70 position += region.length(); | |
71 continue; | |
72 } | |
73 | |
74 // If we had a clever transformation for resource-only executables we | |
75 // should identify the suitable elements here: | |
76 if (!info->has_text_section() && false) { | |
77 Element* element = new ElementWinPE(Element::WIN32_NOCODE, | |
78 this, region, info); | |
79 owned_elements_.push_back(element); | |
80 elements_.push_back(element); | |
81 position += region.length(); | |
82 continue; | |
83 } | |
84 } | |
85 delete info; | |
86 } | |
87 | |
88 // This is where to add new formats, e.g. Linux executables, Dalvik | |
89 // executables etc. | |
90 | |
91 // No Element found at current position. | |
92 ++position; | |
93 } | |
94 return C_OK; | |
95 } | |
96 | |
97 Ensemble::~Ensemble() { | |
98 for (size_t i = 0; i < owned_elements_.size(); ++i) | |
99 delete owned_elements_[i]; | |
100 } | |
101 | |
102 } // namespace | |
OLD | NEW |