Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Side by Side Diff: chrome/installer/test/pe_image_resources.cc

Issue 5236002: Add infrastructure enabling tests of installer upgrade scenarios.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 // This file contains the implementation for an iterator over a portable
6 // executable file's resources.
7
8 #include "chrome/installer/test/pe_image_resources.h"
9
10 #include "base/logging.h"
11 #include "base/win/pe_image.h"
12
13 namespace {
14
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.
17 template<class T>
18 bool StructureAt(const uint8* data, size_t data_size, const T** structure) {
19 if (sizeof(T) <= data_size) {
20 *structure = reinterpret_cast<const T*>(data);
21 return true;
22 }
23 return false;
24 }
25
26 // Recursive function for enumerating entries in an image's resource segment.
27 // static
28 bool EnumResourcesWorker(
29 const base::win::PEImage& image, const uint8* tree_base, DWORD tree_size,
30 DWORD directory_offset, upgrade_test::EntryPath &path,
31 upgrade_test::EnumResource_Fn function, uintptr_t context) {
tommi (sloooow) - chröme 2010/11/19 20:14:38 function -> callback
grt (UTC plus 2) 2010/11/22 17:53:29 Done.
32 bool success = true;
33 const IMAGE_RESOURCE_DIRECTORY* resource_directory;
34
35 if (!StructureAt(tree_base + directory_offset, tree_size - directory_offset,
36 &resource_directory) ||
37 directory_offset + sizeof(IMAGE_RESOURCE_DIRECTORY) +
38 (resource_directory->NumberOfNamedEntries +
39 resource_directory->NumberOfIdEntries) *
40 sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY) > tree_size) {
41 LOG(DFATAL) << "Insufficient room in resource segment for directory entry.";
42 return false;
43 }
44
45 for (const IMAGE_RESOURCE_DIRECTORY_ENTRY* scan =
46 reinterpret_cast<const IMAGE_RESOURCE_DIRECTORY_ENTRY*>(
47 tree_base + directory_offset +
48 sizeof(IMAGE_RESOURCE_DIRECTORY)),
49 *end = scan + resource_directory->NumberOfNamedEntries +
50 resource_directory->NumberOfIdEntries;
tommi (sloooow) - chröme 2010/11/19 20:14:38 that's a pretty big initialization of scan and end
grt (UTC plus 2) 2010/11/22 17:53:29 Done.
51 success && scan != end; ++scan) {
52 if ((scan->NameIsString != 0) !=
53 (scan - reinterpret_cast<const IMAGE_RESOURCE_DIRECTORY_ENTRY*>(
54 tree_base + directory_offset +
55 sizeof(IMAGE_RESOURCE_DIRECTORY)) <
56 resource_directory->NumberOfNamedEntries)) {
57 LOG(DFATAL) << "Inconsistent number of named or numbered entries.";
58 success = false;
59 break;
60 }
61 if (scan->NameIsString) {
62 const IMAGE_RESOURCE_DIR_STRING_U* dir_string;
63 if (!StructureAt(tree_base + scan->NameOffset,
64 tree_size - scan->NameOffset, &dir_string) ||
65 scan->NameOffset + sizeof(WORD) +
66 dir_string->Length * sizeof(wchar_t) > tree_size) {
67 LOG(DFATAL) << "Insufficient room in resource segment for entry name.";
68 success = false;
69 break;
70 }
71 path.push_back(
72 upgrade_test::EntryId(std::wstring(&dir_string->NameString[0],
73 dir_string->Length)));
74 } else {
75 path.push_back(upgrade_test::EntryId(scan->Id));
76 }
77 if (scan->DataIsDirectory) {
78 success = EnumResourcesWorker(image, tree_base, tree_size,
79 scan->OffsetToDirectory, path, function,
80 context);
81 } else {
82 const IMAGE_RESOURCE_DATA_ENTRY* data_entry;
83 if (StructureAt(tree_base + scan->OffsetToData,
84 tree_size - scan->OffsetToData, &data_entry) &&
85 reinterpret_cast<uint8*>(
86 image.RVAToAddr(data_entry->OffsetToData)) + data_entry->Size <=
87 tree_base + tree_size) {
88 // Despite what winnt.h says, OffsetToData is an RVA.
89 function(
90 path,
91 reinterpret_cast<uint8*>(image.RVAToAddr(data_entry->OffsetToData)),
92 data_entry->Size, data_entry->CodePage, context);
93 } else {
94 LOG(DFATAL) << "Insufficient room in resource segment for data entry.";
95 success = false;
96 }
97 }
98 path.pop_back();
99 }
100
101 return success;
102 }
103
104 } // namespace
105
106 namespace upgrade_test {
107
108 // static
109 bool EnumResources(const base::win::PEImage& image, EnumResource_Fn function,
tommi (sloooow) - chröme 2010/11/19 20:14:38 function -> callback
grt (UTC plus 2) 2010/11/22 17:53:29 Done.
110 uintptr_t context) {
111 DWORD resources_size =
112 image.GetImageDirectoryEntrySize(IMAGE_DIRECTORY_ENTRY_RESOURCE);
113 if (resources_size != 0) {
114 return EnumResourcesWorker(
115 image,
116 reinterpret_cast<uint8*>(
117 image.GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_RESOURCE)),
118 resources_size, 0, EntryPath(), function, context);
119 }
120 return true;
121 }
122
123 } // namespace upgrade_test
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698