blob: 64a191a1c20a196d07d81f18913955da67b7be2d [file] [log] [blame]
henrike@webrtc.org0e118e72013-07-10 00:45:36 +00001// Copyright 2010 Google Inc. All Rights Reserved.
2
3
4#ifndef TALK_BASE_WIN32TOOLHELP_H_
5#define TALK_BASE_WIN32TOOLHELP_H_
6
7#ifndef WIN32
8#error WIN32 Only
9#endif
10
11#include "talk/base/win32.h"
12
13// Should be included first, but that causes redefinitions.
14#include <tlhelp32.h>
15
16#include "talk/base/constructormagic.h"
17
18namespace talk_base {
19
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.
23//
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
27//
28// - implement bool First(HANDLE, T*) normally calls a
29// Xxxx32First method in the toolhelp API. Ex Process32First(...)
30//
31// - implement bool Next(HANDLE, T*) normally calls a
32// Xxxx32Next method in the toolhelp API. Ex Process32Next(...)
33//
34// - implement bool CloseHandle(HANDLE)
35//
36template<typename Traits>
37class ToolhelpEnumeratorBase {
38 public:
39 ToolhelpEnumeratorBase(HANDLE snapshot)
40 : snapshot_(snapshot), broken_(false), first_(true) {
41
42 // Clear out the Traits::Type structure instance.
43 Zero(&current_);
44 }
45
46 virtual ~ToolhelpEnumeratorBase() {
47 Close();
48 }
49
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.
54 bool Next() {
55 if (!Valid()) {
56 return false;
57 }
58
59 // Move the iteration forward.
60 current_.dwSize = sizeof(typename Traits::Type);
61 bool incr_ok = false;
62 if (first_) {
63 incr_ok = Traits::First(snapshot_, &current_);
64 first_ = false;
65 } else {
66 incr_ok = Traits::Next(snapshot_, &current_);
67 }
68
69 if (!incr_ok) {
70 Zero(&current_);
71 broken_ = true;
72 }
73
74 return incr_ok;
75 }
76
77 const typename Traits::Type& current() const {
78 return current_;
79 }
80
81 void Close() {
82 if (snapshot_ != INVALID_HANDLE_VALUE) {
83 Traits::CloseHandle(snapshot_);
84 snapshot_ = INVALID_HANDLE_VALUE;
85 }
86 }
87
88 private:
89 // Checks the state of the snapshot handle.
90 bool Valid() {
91 return snapshot_ != INVALID_HANDLE_VALUE && !broken_;
92 }
93
94 static void Zero(typename Traits::Type* buff) {
95 ZeroMemory(buff, sizeof(typename Traits::Type));
96 }
97
98 HANDLE snapshot_;
99 typename Traits::Type current_;
100 bool broken_;
101 bool first_;
102};
103
104class ToolhelpTraits {
105 public:
106 static HANDLE CreateSnapshot(uint32 flags, uint32 process_id) {
107 return CreateToolhelp32Snapshot(flags, process_id);
108 }
109
110 static bool CloseHandle(HANDLE handle) {
111 return ::CloseHandle(handle) == TRUE;
112 }
113};
114
115class ToolhelpProcessTraits : public ToolhelpTraits {
116 public:
117 typedef PROCESSENTRY32 Type;
118
119 static bool First(HANDLE handle, Type* t) {
120 return ::Process32First(handle, t) == TRUE;
121 }
122
123 static bool Next(HANDLE handle, Type* t) {
124 return ::Process32Next(handle, t) == TRUE;
125 }
126};
127
128class ProcessEnumerator : public ToolhelpEnumeratorBase<ToolhelpProcessTraits> {
129 public:
130 ProcessEnumerator()
131 : ToolhelpEnumeratorBase(
132 ToolhelpProcessTraits::CreateSnapshot(TH32CS_SNAPPROCESS, 0)) {
133 }
134
135 private:
136 DISALLOW_EVIL_CONSTRUCTORS(ProcessEnumerator);
137};
138
139class ToolhelpModuleTraits : public ToolhelpTraits {
140 public:
141 typedef MODULEENTRY32 Type;
142
143 static bool First(HANDLE handle, Type* t) {
144 return ::Module32First(handle, t) == TRUE;
145 }
146
147 static bool Next(HANDLE handle, Type* t) {
148 return ::Module32Next(handle, t) == TRUE;
149 }
150};
151
152class ModuleEnumerator : public ToolhelpEnumeratorBase<ToolhelpModuleTraits> {
153 public:
154 explicit ModuleEnumerator(uint32 process_id)
155 : ToolhelpEnumeratorBase(
156 ToolhelpModuleTraits::CreateSnapshot(TH32CS_SNAPMODULE,
157 process_id)) {
158 }
159
160 private:
161 DISALLOW_EVIL_CONSTRUCTORS(ModuleEnumerator);
162};
163
164} // namespace talk_base
165
166#endif // TALK_BASE_WIN32TOOLHELP_H_