1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
// Copyright 2010 Google Inc. All Rights Reserved.
#ifndef TALK_BASE_WIN32TOOLHELP_H_
#define TALK_BASE_WIN32TOOLHELP_H_
#ifndef WIN32
#error WIN32 Only
#endif
#include "talk/base/win32.h"
// Should be included first, but that causes redefinitions.
#include <tlhelp32.h>
#include "talk/base/constructormagic.h"
namespace talk_base {
// The toolhelp api used to enumerate processes and their modules
// on Windows is very repetetive and clunky to use. This little
// template wraps it to make it a little more programmer friendly.
//
// Traits: Traits type that adapts the enumerator to the corresponding
// win32 toolhelp api. Each traits class need to:
// - define the type of the enumerated data as a public symbol Type
//
// - implement bool First(HANDLE, T*) normally calls a
// Xxxx32First method in the toolhelp API. Ex Process32First(...)
//
// - implement bool Next(HANDLE, T*) normally calls a
// Xxxx32Next method in the toolhelp API. Ex Process32Next(...)
//
// - implement bool CloseHandle(HANDLE)
//
template<typename Traits>
class ToolhelpEnumeratorBase {
public:
ToolhelpEnumeratorBase(HANDLE snapshot)
: snapshot_(snapshot), broken_(false), first_(true) {
// Clear out the Traits::Type structure instance.
Zero(¤t_);
}
virtual ~ToolhelpEnumeratorBase() {
Close();
}
// Moves forward to the next object using the First and Next
// pointers. If either First or Next ever indicates an failure
// all subsequent calls to this method will fail; the enumerator
// object is considered broken.
bool Next() {
if (!Valid()) {
return false;
}
// Move the iteration forward.
current_.dwSize = sizeof(typename Traits::Type);
bool incr_ok = false;
if (first_) {
incr_ok = Traits::First(snapshot_, ¤t_);
first_ = false;
} else {
incr_ok = Traits::Next(snapshot_, ¤t_);
}
if (!incr_ok) {
Zero(¤t_);
broken_ = true;
}
return incr_ok;
}
const typename Traits::Type& current() const {
return current_;
}
void Close() {
if (snapshot_ != INVALID_HANDLE_VALUE) {
Traits::CloseHandle(snapshot_);
snapshot_ = INVALID_HANDLE_VALUE;
}
}
private:
// Checks the state of the snapshot handle.
bool Valid() {
return snapshot_ != INVALID_HANDLE_VALUE && !broken_;
}
static void Zero(typename Traits::Type* buff) {
ZeroMemory(buff, sizeof(typename Traits::Type));
}
HANDLE snapshot_;
typename Traits::Type current_;
bool broken_;
bool first_;
};
class ToolhelpTraits {
public:
static HANDLE CreateSnapshot(uint32 flags, uint32 process_id) {
return CreateToolhelp32Snapshot(flags, process_id);
}
static bool CloseHandle(HANDLE handle) {
return ::CloseHandle(handle) == TRUE;
}
};
class ToolhelpProcessTraits : public ToolhelpTraits {
public:
typedef PROCESSENTRY32 Type;
static bool First(HANDLE handle, Type* t) {
return ::Process32First(handle, t) == TRUE;
}
static bool Next(HANDLE handle, Type* t) {
return ::Process32Next(handle, t) == TRUE;
}
};
class ProcessEnumerator : public ToolhelpEnumeratorBase<ToolhelpProcessTraits> {
public:
ProcessEnumerator()
: ToolhelpEnumeratorBase(
ToolhelpProcessTraits::CreateSnapshot(TH32CS_SNAPPROCESS, 0)) {
}
private:
DISALLOW_EVIL_CONSTRUCTORS(ProcessEnumerator);
};
class ToolhelpModuleTraits : public ToolhelpTraits {
public:
typedef MODULEENTRY32 Type;
static bool First(HANDLE handle, Type* t) {
return ::Module32First(handle, t) == TRUE;
}
static bool Next(HANDLE handle, Type* t) {
return ::Module32Next(handle, t) == TRUE;
}
};
class ModuleEnumerator : public ToolhelpEnumeratorBase<ToolhelpModuleTraits> {
public:
explicit ModuleEnumerator(uint32 process_id)
: ToolhelpEnumeratorBase(
ToolhelpModuleTraits::CreateSnapshot(TH32CS_SNAPMODULE,
process_id)) {
}
private:
DISALLOW_EVIL_CONSTRUCTORS(ModuleEnumerator);
};
} // namespace talk_base
#endif // TALK_BASE_WIN32TOOLHELP_H_
|