1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/chromium/base/win/scoped_handle.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,205 @@ 1.4 +// Copyright (c) 2012 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#ifndef BASE_WIN_SCOPED_HANDLE_H_ 1.9 +#define BASE_WIN_SCOPED_HANDLE_H_ 1.10 + 1.11 +#include <windows.h> 1.12 + 1.13 +#include "base/base_export.h" 1.14 +#include "base/basictypes.h" 1.15 +#include "base/location.h" 1.16 +#include "base/logging.h" 1.17 +#include "base/move.h" 1.18 + 1.19 +namespace base { 1.20 +namespace win { 1.21 + 1.22 +// TODO(rvargas): remove this with the rest of the verifier. 1.23 +#if defined(COMPILER_MSVC) 1.24 +// MSDN says to #include <intrin.h>, but that breaks the VS2005 build. 1.25 +extern "C" { 1.26 + void* _ReturnAddress(); 1.27 +} 1.28 +#define BASE_WIN_GET_CALLER _ReturnAddress() 1.29 +#elif defined(COMPILER_GCC) 1.30 +#define BASE_WIN_GET_CALLER __builtin_extract_return_addr(\\ 1.31 + __builtin_return_address(0)) 1.32 +#endif 1.33 + 1.34 +// Generic wrapper for raw handles that takes care of closing handles 1.35 +// automatically. The class interface follows the style of 1.36 +// the ScopedStdioHandle class with a few additions: 1.37 +// - IsValid() method can tolerate multiple invalid handle values such as NULL 1.38 +// and INVALID_HANDLE_VALUE (-1) for Win32 handles. 1.39 +// - Receive() method allows to receive a handle value from a function that 1.40 +// takes a raw handle pointer only. 1.41 +template <class Traits, class Verifier> 1.42 +class GenericScopedHandle { 1.43 + MOVE_ONLY_TYPE_FOR_CPP_03(GenericScopedHandle, RValue) 1.44 + 1.45 + public: 1.46 + typedef typename Traits::Handle Handle; 1.47 + 1.48 + // Helper object to contain the effect of Receive() to the function that needs 1.49 + // a pointer, and allow proper tracking of the handle. 1.50 + class Receiver { 1.51 + public: 1.52 + explicit Receiver(GenericScopedHandle* owner) 1.53 + : handle_(Traits::NullHandle()), 1.54 + owner_(owner) {} 1.55 + ~Receiver() { owner_->Set(handle_); } 1.56 + 1.57 + operator Handle*() { return &handle_; } 1.58 + 1.59 + private: 1.60 + Handle handle_; 1.61 + GenericScopedHandle* owner_; 1.62 + }; 1.63 + 1.64 + GenericScopedHandle() : handle_(Traits::NullHandle()) {} 1.65 + 1.66 + explicit GenericScopedHandle(Handle handle) : handle_(Traits::NullHandle()) { 1.67 + Set(handle); 1.68 + } 1.69 + 1.70 + // Move constructor for C++03 move emulation of this type. 1.71 + GenericScopedHandle(RValue other) : handle_(Traits::NullHandle()) { 1.72 + Set(other.object->Take()); 1.73 + } 1.74 + 1.75 + ~GenericScopedHandle() { 1.76 + Close(); 1.77 + } 1.78 + 1.79 + bool IsValid() const { 1.80 + return Traits::IsHandleValid(handle_); 1.81 + } 1.82 + 1.83 + // Move operator= for C++03 move emulation of this type. 1.84 + GenericScopedHandle& operator=(RValue other) { 1.85 + if (this != other.object) { 1.86 + Set(other.object->Take()); 1.87 + } 1.88 + return *this; 1.89 + } 1.90 + 1.91 + void Set(Handle handle) { 1.92 + if (handle_ != handle) { 1.93 + Close(); 1.94 + 1.95 + if (Traits::IsHandleValid(handle)) { 1.96 + handle_ = handle; 1.97 + Verifier::StartTracking(handle, this, BASE_WIN_GET_CALLER, 1.98 + tracked_objects::GetProgramCounter()); 1.99 + } 1.100 + } 1.101 + } 1.102 + 1.103 + Handle Get() const { 1.104 + return handle_; 1.105 + } 1.106 + 1.107 + operator Handle() const { 1.108 + return handle_; 1.109 + } 1.110 + 1.111 + // This method is intended to be used with functions that require a pointer to 1.112 + // a destination handle, like so: 1.113 + // void CreateRequiredHandle(Handle* out_handle); 1.114 + // ScopedHandle a; 1.115 + // CreateRequiredHandle(a.Receive()); 1.116 + Receiver Receive() { 1.117 + DCHECK(!Traits::IsHandleValid(handle_)) << "Handle must be NULL"; 1.118 + return Receiver(this); 1.119 + } 1.120 + 1.121 + // Transfers ownership away from this object. 1.122 + Handle Take() { 1.123 + Handle temp = handle_; 1.124 + handle_ = Traits::NullHandle(); 1.125 + if (Traits::IsHandleValid(temp)) { 1.126 + Verifier::StopTracking(temp, this, BASE_WIN_GET_CALLER, 1.127 + tracked_objects::GetProgramCounter()); 1.128 + } 1.129 + return temp; 1.130 + } 1.131 + 1.132 + // Explicitly closes the owned handle. 1.133 + void Close() { 1.134 + if (Traits::IsHandleValid(handle_)) { 1.135 + Verifier::StopTracking(handle_, this, BASE_WIN_GET_CALLER, 1.136 + tracked_objects::GetProgramCounter()); 1.137 + 1.138 + if (!Traits::CloseHandle(handle_)) 1.139 + CHECK(false); 1.140 + 1.141 + handle_ = Traits::NullHandle(); 1.142 + } 1.143 + } 1.144 + 1.145 + private: 1.146 + Handle handle_; 1.147 +}; 1.148 + 1.149 +#undef BASE_WIN_GET_CALLER 1.150 + 1.151 +// The traits class for Win32 handles that can be closed via CloseHandle() API. 1.152 +class HandleTraits { 1.153 + public: 1.154 + typedef HANDLE Handle; 1.155 + 1.156 + // Closes the handle. 1.157 + static bool CloseHandle(HANDLE handle) { 1.158 + return ::CloseHandle(handle) != FALSE; 1.159 + } 1.160 + 1.161 + // Returns true if the handle value is valid. 1.162 + static bool IsHandleValid(HANDLE handle) { 1.163 + return handle != NULL && handle != INVALID_HANDLE_VALUE; 1.164 + } 1.165 + 1.166 + // Returns NULL handle value. 1.167 + static HANDLE NullHandle() { 1.168 + return NULL; 1.169 + } 1.170 + 1.171 + private: 1.172 + DISALLOW_IMPLICIT_CONSTRUCTORS(HandleTraits); 1.173 +}; 1.174 + 1.175 +// Do-nothing verifier. 1.176 +class DummyVerifierTraits { 1.177 + public: 1.178 + typedef HANDLE Handle; 1.179 + 1.180 + static void StartTracking(HANDLE handle, const void* owner, 1.181 + const void* pc1, const void* pc2) {} 1.182 + static void StopTracking(HANDLE handle, const void* owner, 1.183 + const void* pc1, const void* pc2) {} 1.184 + 1.185 + private: 1.186 + DISALLOW_IMPLICIT_CONSTRUCTORS(DummyVerifierTraits); 1.187 +}; 1.188 + 1.189 +// Performs actual run-time tracking. 1.190 +class BASE_EXPORT VerifierTraits { 1.191 + public: 1.192 + typedef HANDLE Handle; 1.193 + 1.194 + static void StartTracking(HANDLE handle, const void* owner, 1.195 + const void* pc1, const void* pc2); 1.196 + static void StopTracking(HANDLE handle, const void* owner, 1.197 + const void* pc1, const void* pc2); 1.198 + 1.199 + private: 1.200 + DISALLOW_IMPLICIT_CONSTRUCTORS(VerifierTraits); 1.201 +}; 1.202 + 1.203 +typedef GenericScopedHandle<HandleTraits, VerifierTraits> ScopedHandle; 1.204 + 1.205 +} // namespace win 1.206 +} // namespace base 1.207 + 1.208 +#endif // BASE_SCOPED_HANDLE_WIN_H_