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
15namespace sandbox {
16
17// HandleTable retrieves the global handle table and provides helper classes
18// for iterating through the table and retrieving handle info.
19class HandleTable {
20 public:
21  static const base::char16* HandleTable::kTypeProcess;
22  static const base::char16* HandleTable::kTypeThread;
23  static const base::char16* HandleTable::kTypeFile;
24  static const base::char16* HandleTable::kTypeDirectory;
25  static const base::char16* HandleTable::kTypeKey;
26  static const base::char16* HandleTable::kTypeWindowStation;
27  static const base::char16* HandleTable::kTypeDesktop;
28  static const base::char16* HandleTable::kTypeService;
29  static const base::char16* HandleTable::kTypeMutex;
30  static const base::char16* HandleTable::kTypeSemaphore;
31  static const base::char16* HandleTable::kTypeEvent;
32  static const base::char16* HandleTable::kTypeTimer;
33  static const base::char16* HandleTable::kTypeNamedPipe;
34  static const base::char16* HandleTable::kTypeJobObject;
35  static const base::char16* HandleTable::kTypeFileMap;
36  static const base::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
51    const SYSTEM_HANDLE_INFORMATION* handle_entry() const {
52      return handle_entry_;
53    }
54
55    const OBJECT_TYPE_INFORMATION* TypeInfo();
56
57    const base::string16& Name();
58
59    const base::string16& Type();
60
61    bool IsType(const base::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
75    bool needs_info_update() { return handle_entry_ != last_entry_; }
76
77    void UpdateInfo(UpdateType flag);
78
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    base::string16 handle_name_;
88    base::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
130  Iterator begin() const {
131    return Iterator(*this, handle_info()->Information,
132        &handle_info()->Information[handle_info()->NumberOfHandles]);
133  }
134
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;
142  const SYSTEM_HANDLE_INFORMATION* end() const {
143    return &handle_info()->Information[handle_info()->NumberOfHandles];
144  }
145
146 private:
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