1 // Copyright 2010 Google Inc. All Rights Reserved.
4 #ifndef TALK_BASE_WIN32TOOLHELP_H_
5 #define TALK_BASE_WIN32TOOLHELP_H_
11 #include "talk/base/win32.h"
13 // Should be included first, but that causes redefinitions.
16 #include "talk/base/constructormagic.h"
20 // The toolhelp api used to enumerate processes and their modules
21 // on Windows is very repetetive and clunky to use. This little
22 // template wraps it to make it a little more programmer friendly.
24 // Traits: Traits type that adapts the enumerator to the corresponding
25 // win32 toolhelp api. Each traits class need to:
26 // - define the type of the enumerated data as a public symbol Type
28 // - implement bool First(HANDLE, T*) normally calls a
29 // Xxxx32First method in the toolhelp API. Ex Process32First(...)
31 // - implement bool Next(HANDLE, T*) normally calls a
32 // Xxxx32Next method in the toolhelp API. Ex Process32Next(...)
34 // - implement bool CloseHandle(HANDLE)
36 template<typename Traits>
37 class ToolhelpEnumeratorBase {
39 ToolhelpEnumeratorBase(HANDLE snapshot)
40 : snapshot_(snapshot), broken_(false), first_(true) {
42 // Clear out the Traits::Type structure instance.
46 virtual ~ToolhelpEnumeratorBase() {
50 // Moves forward to the next object using the First and Next
51 // pointers. If either First or Next ever indicates an failure
52 // all subsequent calls to this method will fail; the enumerator
53 // object is considered broken.
59 // Move the iteration forward.
60 current_.dwSize = sizeof(typename Traits::Type);
63 incr_ok = Traits::First(snapshot_, ¤t_);
66 incr_ok = Traits::Next(snapshot_, ¤t_);
77 const typename Traits::Type& current() const {
82 if (snapshot_ != INVALID_HANDLE_VALUE) {
83 Traits::CloseHandle(snapshot_);
84 snapshot_ = INVALID_HANDLE_VALUE;
89 // Checks the state of the snapshot handle.
91 return snapshot_ != INVALID_HANDLE_VALUE && !broken_;
94 static void Zero(typename Traits::Type* buff) {
95 ZeroMemory(buff, sizeof(typename Traits::Type));
99 typename Traits::Type current_;
104 class ToolhelpTraits {
106 static HANDLE CreateSnapshot(uint32 flags, uint32 process_id) {
107 return CreateToolhelp32Snapshot(flags, process_id);
110 static bool CloseHandle(HANDLE handle) {
111 return ::CloseHandle(handle) == TRUE;
115 class ToolhelpProcessTraits : public ToolhelpTraits {
117 typedef PROCESSENTRY32 Type;
119 static bool First(HANDLE handle, Type* t) {
120 return ::Process32First(handle, t) == TRUE;
123 static bool Next(HANDLE handle, Type* t) {
124 return ::Process32Next(handle, t) == TRUE;
128 class ProcessEnumerator : public ToolhelpEnumeratorBase<ToolhelpProcessTraits> {
131 : ToolhelpEnumeratorBase(
132 ToolhelpProcessTraits::CreateSnapshot(TH32CS_SNAPPROCESS, 0)) {
136 DISALLOW_EVIL_CONSTRUCTORS(ProcessEnumerator);
139 class ToolhelpModuleTraits : public ToolhelpTraits {
141 typedef MODULEENTRY32 Type;
143 static bool First(HANDLE handle, Type* t) {
144 return ::Module32First(handle, t) == TRUE;
147 static bool Next(HANDLE handle, Type* t) {
148 return ::Module32Next(handle, t) == TRUE;
152 class ModuleEnumerator : public ToolhelpEnumeratorBase<ToolhelpModuleTraits> {
154 explicit ModuleEnumerator(uint32 process_id)
155 : ToolhelpEnumeratorBase(
156 ToolhelpModuleTraits::CreateSnapshot(TH32CS_SNAPMODULE,
161 DISALLOW_EVIL_CONSTRUCTORS(ModuleEnumerator);
164 } // namespace talk_base
166 #endif // TALK_BASE_WIN32TOOLHELP_H_