Home | History | Annotate | Download | only in win
      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 
     11 bool 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