// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef SANDBOX_SRC_HANDLE_TABLE_H_ #define SANDBOX_SRC_HANDLE_TABLE_H_ #include #include #include "base/basictypes.h" #include "base/string16.h" #include "sandbox/win/src/nt_internals.h" namespace sandbox { // HandleTable retrieves the global handle table and provides helper classes // for iterating through the table and retrieving handle info. class HandleTable { public: static const char16* HandleTable::kTypeProcess; static const char16* HandleTable::kTypeThread; static const char16* HandleTable::kTypeFile; static const char16* HandleTable::kTypeDirectory; static const char16* HandleTable::kTypeKey; static const char16* HandleTable::kTypeWindowStation; static const char16* HandleTable::kTypeDesktop; static const char16* HandleTable::kTypeService; static const char16* HandleTable::kTypeMutex; static const char16* HandleTable::kTypeSemaphore; static const char16* HandleTable::kTypeEvent; static const char16* HandleTable::kTypeTimer; static const char16* HandleTable::kTypeNamedPipe; static const char16* HandleTable::kTypeJobObject; static const char16* HandleTable::kTypeFileMap; static const char16* HandleTable::kTypeAlpcPort; class Iterator; // Used by the iterator to provide simple caching accessors to handle data. class HandleEntry { public: bool operator==(const HandleEntry& rhs) const { return handle_entry_ == rhs.handle_entry_; } bool operator!=(const HandleEntry& rhs) const { return handle_entry_ != rhs.handle_entry_; } const SYSTEM_HANDLE_INFORMATION* handle_entry() const { return handle_entry_; } const OBJECT_TYPE_INFORMATION* TypeInfo(); const string16& Name(); const string16& Type(); bool IsType(const string16& type_string); private: friend class Iterator; friend class HandleTable; enum UpdateType { UPDATE_INFO_ONLY, UPDATE_INFO_AND_NAME, UPDATE_INFO_AND_TYPE_NAME, }; explicit HandleEntry(const SYSTEM_HANDLE_INFORMATION* handle_info_entry); bool needs_info_update() { return handle_entry_ != last_entry_; } void UpdateInfo(UpdateType flag); OBJECT_TYPE_INFORMATION* type_info_internal() { return reinterpret_cast( &(type_info_buffer_[0])); } const SYSTEM_HANDLE_INFORMATION* handle_entry_; const SYSTEM_HANDLE_INFORMATION* last_entry_; std::vector type_info_buffer_; string16 handle_name_; string16 type_name_; DISALLOW_COPY_AND_ASSIGN(HandleEntry); }; class Iterator { public: Iterator(const HandleTable& table, const SYSTEM_HANDLE_INFORMATION* start, const SYSTEM_HANDLE_INFORMATION* stop); Iterator(const Iterator& it); Iterator& operator++() { if (++(current_.handle_entry_) == end_) current_.handle_entry_ = table_.end(); return *this; } bool operator==(const Iterator& rhs) const { return current_ == rhs.current_; } bool operator!=(const Iterator& rhs) const { return current_ != rhs.current_; } HandleEntry& operator*() { return current_; } operator const SYSTEM_HANDLE_INFORMATION*() { return current_.handle_entry_; } HandleEntry* operator->() { return ¤t_; } private: const HandleTable& table_; HandleEntry current_; const SYSTEM_HANDLE_INFORMATION* end_; }; HandleTable(); Iterator begin() const { return Iterator(*this, handle_info()->Information, &handle_info()->Information[handle_info()->NumberOfHandles]); } const SYSTEM_HANDLE_INFORMATION_EX* handle_info() const { return reinterpret_cast( &(handle_info_buffer_[0])); } // Returns an iterator to the handles for only the supplied process ID. Iterator HandlesForProcess(ULONG process_id) const; const SYSTEM_HANDLE_INFORMATION* end() const { return &handle_info()->Information[handle_info()->NumberOfHandles]; } private: SYSTEM_HANDLE_INFORMATION_EX* handle_info_internal() { return reinterpret_cast( &(handle_info_buffer_[0])); } std::vector handle_info_buffer_; DISALLOW_COPY_AND_ASSIGN(HandleTable); }; } // namespace sandbox #endif // SANDBOX_SRC_HANDLE_TABLE_H_