Home | History | Annotate | Download | only in src
      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 
     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 
     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     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 
    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