- add third_party src.
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / base / win32toolhelp.h
1 // 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
18 namespace 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 //
36 template<typename Traits>
37 class 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
104 class 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
115 class 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
128 class 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
139 class 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
152 class 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_