Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / install_verification / win / loaded_modules_snapshot.cc
blob33d620f139de212d064d77800cc3619ce26736d4
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.
5 #include "chrome/browser/install_verification/win/loaded_modules_snapshot.h"
7 #include <Psapi.h>
9 #include "base/logging.h"
11 bool GetLoadedModulesSnapshot(std::vector<HMODULE>* snapshot) {
12 DCHECK(snapshot);
13 DCHECK_EQ(0u, snapshot->size());
14 snapshot->resize(1);
16 HANDLE process = ::GetCurrentProcess();
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;
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);
46 } while (--retries_remaining);
48 DLOG(ERROR) << "Failed to enumerate modules.";
49 return false;