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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/installer/test/pe_image_resources.cc
===================================================================
--- chrome/installer/test/pe_image_resources.cc (revision 0)
+++ chrome/installer/test/pe_image_resources.cc (revision 0)
@@ -0,0 +1,124 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file contains the implementation for an iterator over a portable
+// executable file's resources.
+
+#include "chrome/installer/test/pe_image_resources.h"
+
+#include "base/logging.h"
+#include "base/win/pe_image.h"
+
+namespace {
+
+// Performs a cast to type |T| of |data| iff |data_size| is sufficient to hold
+// an instance of type |T|. Returns true on success.
+template<class T>
+bool StructureAt(const uint8* data, size_t data_size, const T** structure) {
+ if (sizeof(T) <= data_size) {
+ *structure = reinterpret_cast<const T*>(data);
+ return true;
+ }
+ return false;
+}
+
+// Recursive function for enumerating entries in an image's resource segment.
+// static
+bool EnumResourcesWorker(
+ const base::win::PEImage& image, const uint8* tree_base, DWORD tree_size,
+ DWORD directory_offset, upgrade_test::EntryPath &path,
+ upgrade_test::EnumResource_Fn callback, uintptr_t context) {
+ bool success = true;
+ const IMAGE_RESOURCE_DIRECTORY* resource_directory;
+
+ if (!StructureAt(tree_base + directory_offset, tree_size - directory_offset,
+ &resource_directory) ||
+ directory_offset + sizeof(IMAGE_RESOURCE_DIRECTORY) +
+ (resource_directory->NumberOfNamedEntries +
+ resource_directory->NumberOfIdEntries) *
+ sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY) > tree_size) {
+ LOG(DFATAL) << "Insufficient room in resource segment for directory entry.";
+ return false;
+ }
+
+ const IMAGE_RESOURCE_DIRECTORY_ENTRY* scan =
+ reinterpret_cast<const IMAGE_RESOURCE_DIRECTORY_ENTRY*>(
+ tree_base + directory_offset +
+ sizeof(IMAGE_RESOURCE_DIRECTORY));
+ const IMAGE_RESOURCE_DIRECTORY_ENTRY* end = scan +
+ resource_directory->NumberOfNamedEntries +
+ resource_directory->NumberOfIdEntries;
+ for (; success && scan != end; ++scan) {
+ if ((scan->NameIsString != 0) !=
+ (scan - reinterpret_cast<const IMAGE_RESOURCE_DIRECTORY_ENTRY*>(
+ tree_base + directory_offset +
+ sizeof(IMAGE_RESOURCE_DIRECTORY)) <
+ resource_directory->NumberOfNamedEntries)) {
+ LOG(DFATAL) << "Inconsistent number of named or numbered entries.";
+ success = false;
+ break;
+ }
+ if (scan->NameIsString) {
+ const IMAGE_RESOURCE_DIR_STRING_U* dir_string;
+ if (!StructureAt(tree_base + scan->NameOffset,
+ tree_size - scan->NameOffset, &dir_string) ||
+ scan->NameOffset + sizeof(WORD) +
+ dir_string->Length * sizeof(wchar_t) > tree_size) {
+ LOG(DFATAL) << "Insufficient room in resource segment for entry name.";
+ success = false;
+ break;
+ }
+ path.push_back(
+ upgrade_test::EntryId(std::wstring(&dir_string->NameString[0],
+ dir_string->Length)));
+ } else {
+ path.push_back(upgrade_test::EntryId(scan->Id));
+ }
+ if (scan->DataIsDirectory) {
+ success = EnumResourcesWorker(image, tree_base, tree_size,
+ scan->OffsetToDirectory, path, callback,
+ context);
+ } else {
+ const IMAGE_RESOURCE_DATA_ENTRY* data_entry;
+ if (StructureAt(tree_base + scan->OffsetToData,
+ tree_size - scan->OffsetToData, &data_entry) &&
+ reinterpret_cast<uint8*>(
+ image.RVAToAddr(data_entry->OffsetToData)) + data_entry->Size <=
+ tree_base + tree_size) {
+ // Despite what winnt.h says, OffsetToData is an RVA.
+ callback(
+ path,
+ reinterpret_cast<uint8*>(image.RVAToAddr(data_entry->OffsetToData)),
+ data_entry->Size, data_entry->CodePage, context);
+ } else {
+ LOG(DFATAL) << "Insufficient room in resource segment for data entry.";
+ success = false;
+ }
+ }
+ path.pop_back();
+ }
+
+ return success;
+}
+
+} // namespace
+
+namespace upgrade_test {
+
+// static
+bool EnumResources(const base::win::PEImage& image, EnumResource_Fn callback,
+ uintptr_t context) {
+ DWORD resources_size =
+ image.GetImageDirectoryEntrySize(IMAGE_DIRECTORY_ENTRY_RESOURCE);
+ if (resources_size != 0) {
+ return EnumResourcesWorker(
+ image,
+ reinterpret_cast<uint8*>(
+ image.GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_RESOURCE)),
+ resources_size, 0, EntryPath(), callback, context);
+ }
+ return true;
+}
+
+} // namespace upgrade_test
Property changes on: chrome\installer\test\pe_image_resources.cc
___________________________________________________________________
Added: svn:eol-style
+ LF

Powered by Google App Engine
This is Rietveld 408576698