OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome_frame/vtable_patch_manager.h" | 5 #include "chrome_frame/vtable_patch_manager.h" |
6 | 6 |
| 7 #include <algorithm> |
| 8 |
7 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/scoped_ptr.h" |
8 | 11 |
9 #include "chrome_frame/function_stub.h" | 12 #include "chrome_frame/function_stub.h" |
10 | 13 |
11 namespace vtable_patch { | 14 namespace vtable_patch { |
12 | 15 |
13 // Convenient definition of a VTABLE | 16 // Convenient definition of a VTABLE |
14 typedef PROC* Vtable; | 17 typedef PROC* Vtable; |
15 | 18 |
16 // Returns a pointer to the VTable of a COM interface. | 19 // Returns a pointer to the VTable of a COM interface. |
17 // @param unknown [in] The pointer of the COM interface. | 20 // @param unknown [in] The pointer of the COM interface. |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 it->stub_ = NULL; | 84 it->stub_ = NULL; |
82 // Leave the stub in memory so that we won't break any possible chains. | 85 // Leave the stub in memory so that we won't break any possible chains. |
83 } else { | 86 } else { |
84 DLOG(WARNING) << "attempt to unpatch a function that wasn't patched"; | 87 DLOG(WARNING) << "attempt to unpatch a function that wasn't patched"; |
85 } | 88 } |
86 } | 89 } |
87 | 90 |
88 return S_OK; | 91 return S_OK; |
89 } | 92 } |
90 | 93 |
| 94 // Disabled for now as we're not using it atm. |
| 95 #if 0 |
| 96 |
| 97 DynamicPatchManager::DynamicPatchManager(const MethodPatchInfo* patch_prototype) |
| 98 : patch_prototype_(patch_prototype) { |
| 99 DCHECK(patch_prototype_); |
| 100 DCHECK(patch_prototype_->stub_ == NULL); |
| 101 } |
| 102 |
| 103 DynamicPatchManager::~DynamicPatchManager() { |
| 104 UnpatchAll(); |
| 105 } |
| 106 |
| 107 HRESULT DynamicPatchManager::PatchObject(void* unknown) { |
| 108 int patched_methods = 0; |
| 109 for (; patch_prototype_[patched_methods].index_ != -1; patched_methods++) { |
| 110 // If you hit this, then you are likely using the prototype instance for |
| 111 // patching in _addition_ to this class. This is not a good idea :) |
| 112 DCHECK(patch_prototype_[patched_methods].stub_ == NULL); |
| 113 } |
| 114 |
| 115 // Prepare a new patch object using the patch info from the prototype. |
| 116 int mem_size = sizeof(PatchedObject) + |
| 117 sizeof(MethodPatchInfo) * patched_methods; |
| 118 PatchedObject* entry = reinterpret_cast<PatchedObject*>(new char[mem_size]); |
| 119 entry->vtable_ = GetIFVTable(unknown); |
| 120 memcpy(entry->patch_info_, patch_prototype_, |
| 121 sizeof(MethodPatchInfo) * (patched_methods + 1)); |
| 122 |
| 123 patch_list_lock_.Acquire(); |
| 124 |
| 125 // See if we've already patched this vtable before. |
| 126 // The search is done via the == operator of the PatchedObject class. |
| 127 PatchList::const_iterator it = std::find(patch_list_.begin(), |
| 128 patch_list_.end(), entry); |
| 129 HRESULT hr; |
| 130 if (it == patch_list_.end()) { |
| 131 hr = PatchInterfaceMethods(unknown, entry->patch_info_); |
| 132 if (SUCCEEDED(hr)) { |
| 133 patch_list_.push_back(entry); |
| 134 entry = NULL; // Ownership transferred to the array. |
| 135 } |
| 136 } else { |
| 137 hr = S_FALSE; |
| 138 } |
| 139 |
| 140 patch_list_lock_.Release(); |
| 141 |
| 142 delete entry; |
| 143 |
| 144 return hr; |
| 145 } |
| 146 |
| 147 bool DynamicPatchManager::UnpatchAll() { |
| 148 patch_list_lock_.Acquire(); |
| 149 PatchList::iterator it; |
| 150 for (it = patch_list_.begin(); it != patch_list_.end(); it++) { |
| 151 UnpatchInterfaceMethods((*it)->patch_info_); |
| 152 delete (*it); |
| 153 } |
| 154 patch_list_.clear(); |
| 155 patch_list_lock_.Release(); |
| 156 |
| 157 return true; |
| 158 } |
| 159 |
| 160 #endif // disabled DynamicPatchManager |
| 161 |
91 } // namespace vtable_patch | 162 } // namespace vtable_patch |
OLD | NEW |