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 ¤t_; } 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