• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 #ifndef SANDBOX_SRC_HANDLE_TABLE_H_
6 #define SANDBOX_SRC_HANDLE_TABLE_H_
7 
8 #include <windows.h>
9 #include <vector>
10 
11 #include "base/basictypes.h"
12 #include "base/strings/string16.h"
13 #include "sandbox/win/src/nt_internals.h"
14 
15 namespace sandbox {
16 
17 // HandleTable retrieves the global handle table and provides helper classes
18 // for iterating through the table and retrieving handle info.
19 class HandleTable {
20  public:
21   static const char16* HandleTable::kTypeProcess;
22   static const char16* HandleTable::kTypeThread;
23   static const char16* HandleTable::kTypeFile;
24   static const char16* HandleTable::kTypeDirectory;
25   static const char16* HandleTable::kTypeKey;
26   static const char16* HandleTable::kTypeWindowStation;
27   static const char16* HandleTable::kTypeDesktop;
28   static const char16* HandleTable::kTypeService;
29   static const char16* HandleTable::kTypeMutex;
30   static const char16* HandleTable::kTypeSemaphore;
31   static const char16* HandleTable::kTypeEvent;
32   static const char16* HandleTable::kTypeTimer;
33   static const char16* HandleTable::kTypeNamedPipe;
34   static const char16* HandleTable::kTypeJobObject;
35   static const char16* HandleTable::kTypeFileMap;
36   static const char16* HandleTable::kTypeAlpcPort;
37 
38   class Iterator;
39 
40   // Used by the iterator to provide simple caching accessors to handle data.
41   class HandleEntry {
42    public:
43     bool operator==(const HandleEntry& rhs) const {
44       return handle_entry_ == rhs.handle_entry_;
45     }
46 
47     bool operator!=(const HandleEntry& rhs) const {
48       return handle_entry_ != rhs.handle_entry_;
49     }
50 
handle_entry()51     const SYSTEM_HANDLE_INFORMATION* handle_entry() const {
52       return handle_entry_;
53     }
54 
55     const OBJECT_TYPE_INFORMATION* TypeInfo();
56 
57     const string16& Name();
58 
59     const string16& Type();
60 
61     bool IsType(const string16& type_string);
62 
63    private:
64     friend class Iterator;
65     friend class HandleTable;
66 
67     enum UpdateType {
68       UPDATE_INFO_ONLY,
69       UPDATE_INFO_AND_NAME,
70       UPDATE_INFO_AND_TYPE_NAME,
71     };
72 
73     explicit HandleEntry(const SYSTEM_HANDLE_INFORMATION* handle_info_entry);
74 
needs_info_update()75     bool needs_info_update() { return handle_entry_ != last_entry_; }
76 
77     void UpdateInfo(UpdateType flag);
78 
type_info_internal()79     OBJECT_TYPE_INFORMATION* type_info_internal() {
80       return reinterpret_cast<OBJECT_TYPE_INFORMATION*>(
81           &(type_info_buffer_[0]));
82     }
83 
84     const SYSTEM_HANDLE_INFORMATION* handle_entry_;
85     const SYSTEM_HANDLE_INFORMATION* last_entry_;
86     std::vector<BYTE> type_info_buffer_;
87     string16 handle_name_;
88     string16 type_name_;
89 
90     DISALLOW_COPY_AND_ASSIGN(HandleEntry);
91   };
92 
93   class Iterator {
94    public:
95     Iterator(const HandleTable& table, const SYSTEM_HANDLE_INFORMATION* start,
96              const SYSTEM_HANDLE_INFORMATION* stop);
97 
98     Iterator(const Iterator& it);
99 
100     Iterator& operator++() {
101       if (++(current_.handle_entry_) == end_)
102         current_.handle_entry_ = table_.end();
103       return *this;
104     }
105 
106     bool operator==(const Iterator& rhs) const {
107       return current_ == rhs.current_;
108     }
109 
110     bool operator!=(const Iterator& rhs) const {
111       return current_ != rhs.current_;
112     }
113 
114     HandleEntry& operator*() { return current_; }
115 
116     operator const SYSTEM_HANDLE_INFORMATION*() {
117       return current_.handle_entry_;
118     }
119 
120     HandleEntry* operator->() { return &current_; }
121 
122    private:
123     const HandleTable& table_;
124     HandleEntry current_;
125     const SYSTEM_HANDLE_INFORMATION* end_;
126   };
127 
128   HandleTable();
129 
begin()130   Iterator begin() const {
131     return Iterator(*this, handle_info()->Information,
132         &handle_info()->Information[handle_info()->NumberOfHandles]);
133   }
134 
handle_info()135   const SYSTEM_HANDLE_INFORMATION_EX* handle_info() const {
136     return reinterpret_cast<const SYSTEM_HANDLE_INFORMATION_EX*>(
137         &(handle_info_buffer_[0]));
138   }
139 
140   // Returns an iterator to the handles for only the supplied process ID.
141   Iterator HandlesForProcess(ULONG process_id) const;
end()142   const SYSTEM_HANDLE_INFORMATION* end() const {
143     return &handle_info()->Information[handle_info()->NumberOfHandles];
144   }
145 
146  private:
handle_info_internal()147   SYSTEM_HANDLE_INFORMATION_EX* handle_info_internal() {
148     return reinterpret_cast<SYSTEM_HANDLE_INFORMATION_EX*>(
149         &(handle_info_buffer_[0]));
150   }
151 
152   std::vector<BYTE> handle_info_buffer_;
153 
154   DISALLOW_COPY_AND_ASSIGN(HandleTable);
155 };
156 
157 }  // namespace sandbox
158 
159 #endif  // SANDBOX_SRC_HANDLE_TABLE_H_
160