1// Copyright 2013 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#include "chrome/browser/install_verification/win/loaded_modules_snapshot.h" 6 7#include <Psapi.h> 8 9#include "base/logging.h" 10 11bool GetLoadedModulesSnapshot(std::vector<HMODULE>* snapshot) { 12 DCHECK(snapshot); 13 DCHECK_EQ(0u, snapshot->size()); 14 snapshot->resize(1); 15 16 HANDLE process = ::GetCurrentProcess(); 17 18 // We will retry at least once after first determining |bytes_required|. If 19 // the list of modules changes after we receive |bytes_required| we may retry 20 // more than once. 21 int retries_remaining = 5; 22 do { 23 DWORD bytes_required = 0; 24 // EnumProcessModules returns 'success' even if the buffer size is too 25 // small. 26 if (!::EnumProcessModules(process, 27 &(*snapshot)[0], 28 snapshot->size() * sizeof(HMODULE), 29 &bytes_required)) { 30 DPLOG(ERROR) << "::EnumProcessModules failed."; 31 return false; 32 } 33 DCHECK_EQ(0u, bytes_required % sizeof(HMODULE)); 34 size_t num_modules = bytes_required / sizeof(HMODULE); 35 if (num_modules <= snapshot->size()) { 36 // Buffer size was too big, presumably because a module was unloaded. 37 snapshot->erase(snapshot->begin() + num_modules, snapshot->end()); 38 return true; 39 } else if (num_modules == 0) { 40 DLOG(ERROR) << "Can't determine the module list size."; 41 return false; 42 } else { 43 // Buffer size was too small. Try again with a larger buffer. 44 snapshot->resize(num_modules, NULL); 45 } 46 } while (--retries_remaining); 47 48 DLOG(ERROR) << "Failed to enumerate modules."; 49 return false; 50} 51