OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // This file contains the implementation for an iterator over a portable | 5 // This file contains the implementation for an iterator over a portable |
6 // executable file's resources. | 6 // executable file's resources. |
7 | 7 |
8 #include "chrome/installer/test/pe_image_resources.h" | 8 #include "chrome/installer/test/pe_image_resources.h" |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/win/pe_image.h" | 11 #include "base/win/pe_image.h" |
12 | 12 |
13 namespace { | 13 namespace { |
14 | 14 |
15 // Performs a cast to type |T| of |data| iff |data_size| is sufficient to hold | 15 // Performs a cast to type |T| of |data| iff |data_size| is sufficient to hold |
16 // an instance of type |T|. Returns true on success. | 16 // an instance of type |T|. Returns true on success. |
17 template<class T> | 17 template <class T> |
18 bool StructureAt(const uint8* data, size_t data_size, const T** structure) { | 18 bool StructureAt(const uint8_t* data, size_t data_size, const T** structure) { |
19 if (sizeof(T) <= data_size) { | 19 if (sizeof(T) <= data_size) { |
20 *structure = reinterpret_cast<const T*>(data); | 20 *structure = reinterpret_cast<const T*>(data); |
21 return true; | 21 return true; |
22 } | 22 } |
23 return false; | 23 return false; |
24 } | 24 } |
25 | 25 |
26 // Recursive function for enumerating entries in an image's resource segment. | 26 // Recursive function for enumerating entries in an image's resource segment. |
27 // static | 27 // static |
28 bool EnumResourcesWorker( | 28 bool EnumResourcesWorker(const base::win::PEImage& image, |
29 const base::win::PEImage& image, const uint8* tree_base, DWORD tree_size, | 29 const uint8_t* tree_base, |
30 DWORD directory_offset, upgrade_test::EntryPath* path, | 30 DWORD tree_size, |
31 upgrade_test::EnumResource_Fn callback, uintptr_t context) { | 31 DWORD directory_offset, |
| 32 upgrade_test::EntryPath* path, |
| 33 upgrade_test::EnumResource_Fn callback, |
| 34 uintptr_t context) { |
32 bool success = true; | 35 bool success = true; |
33 const IMAGE_RESOURCE_DIRECTORY* resource_directory; | 36 const IMAGE_RESOURCE_DIRECTORY* resource_directory; |
34 | 37 |
35 if (!StructureAt(tree_base + directory_offset, tree_size - directory_offset, | 38 if (!StructureAt(tree_base + directory_offset, tree_size - directory_offset, |
36 &resource_directory) || | 39 &resource_directory) || |
37 directory_offset + sizeof(IMAGE_RESOURCE_DIRECTORY) + | 40 directory_offset + sizeof(IMAGE_RESOURCE_DIRECTORY) + |
38 (resource_directory->NumberOfNamedEntries + | 41 (resource_directory->NumberOfNamedEntries + |
39 resource_directory->NumberOfIdEntries) * | 42 resource_directory->NumberOfIdEntries) * |
40 sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY) > tree_size) { | 43 sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY) > tree_size) { |
41 LOG(DFATAL) << "Insufficient room in resource segment for directory entry."; | 44 LOG(DFATAL) << "Insufficient room in resource segment for directory entry."; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 path->push_back(upgrade_test::EntryId(scan->Id)); | 79 path->push_back(upgrade_test::EntryId(scan->Id)); |
77 } | 80 } |
78 if (scan->DataIsDirectory) { | 81 if (scan->DataIsDirectory) { |
79 success = EnumResourcesWorker(image, tree_base, tree_size, | 82 success = EnumResourcesWorker(image, tree_base, tree_size, |
80 scan->OffsetToDirectory, path, callback, | 83 scan->OffsetToDirectory, path, callback, |
81 context); | 84 context); |
82 } else { | 85 } else { |
83 const IMAGE_RESOURCE_DATA_ENTRY* data_entry; | 86 const IMAGE_RESOURCE_DATA_ENTRY* data_entry; |
84 if (StructureAt(tree_base + scan->OffsetToData, | 87 if (StructureAt(tree_base + scan->OffsetToData, |
85 tree_size - scan->OffsetToData, &data_entry) && | 88 tree_size - scan->OffsetToData, &data_entry) && |
86 reinterpret_cast<uint8*>( | 89 reinterpret_cast<uint8_t*>( |
87 image.RVAToAddr(data_entry->OffsetToData)) + data_entry->Size <= | 90 image.RVAToAddr(data_entry->OffsetToData)) + |
88 tree_base + tree_size) { | 91 data_entry->Size <= |
| 92 tree_base + tree_size) { |
89 // Despite what winnt.h says, OffsetToData is an RVA. | 93 // Despite what winnt.h says, OffsetToData is an RVA. |
90 callback( | 94 callback(*path, reinterpret_cast<uint8_t*>( |
91 *path, | 95 image.RVAToAddr(data_entry->OffsetToData)), |
92 reinterpret_cast<uint8*>(image.RVAToAddr(data_entry->OffsetToData)), | 96 data_entry->Size, data_entry->CodePage, context); |
93 data_entry->Size, data_entry->CodePage, context); | |
94 } else { | 97 } else { |
95 LOG(DFATAL) << "Insufficient room in resource segment for data entry."; | 98 LOG(DFATAL) << "Insufficient room in resource segment for data entry."; |
96 success = false; | 99 success = false; |
97 } | 100 } |
98 } | 101 } |
99 path->pop_back(); | 102 path->pop_back(); |
100 } | 103 } |
101 | 104 |
102 return success; | 105 return success; |
103 } | 106 } |
104 | 107 |
105 } // namespace | 108 } // namespace |
106 | 109 |
107 namespace upgrade_test { | 110 namespace upgrade_test { |
108 | 111 |
109 // static | 112 // static |
110 bool EnumResources(const base::win::PEImage& image, EnumResource_Fn callback, | 113 bool EnumResources(const base::win::PEImage& image, EnumResource_Fn callback, |
111 uintptr_t context) { | 114 uintptr_t context) { |
112 DWORD resources_size = | 115 DWORD resources_size = |
113 image.GetImageDirectoryEntrySize(IMAGE_DIRECTORY_ENTRY_RESOURCE); | 116 image.GetImageDirectoryEntrySize(IMAGE_DIRECTORY_ENTRY_RESOURCE); |
114 if (resources_size != 0) { | 117 if (resources_size != 0) { |
115 EntryPath path_storage; | 118 EntryPath path_storage; |
116 return EnumResourcesWorker( | 119 return EnumResourcesWorker( |
117 image, | 120 image, reinterpret_cast<uint8_t*>(image.GetImageDirectoryEntryAddr( |
118 reinterpret_cast<uint8*>( | 121 IMAGE_DIRECTORY_ENTRY_RESOURCE)), |
119 image.GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_RESOURCE)), | |
120 resources_size, 0, &path_storage, callback, context); | 122 resources_size, 0, &path_storage, callback, context); |
121 } | 123 } |
122 return true; | 124 return true; |
123 } | 125 } |
124 | 126 |
125 } // namespace upgrade_test | 127 } // namespace upgrade_test |
OLD | NEW |