Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(320)

Side by Side Diff: chrome_frame/vtable_patch_manager.cc

Issue 218019: Initial import of the Chrome Frame codebase. Integration in chrome.gyp coming... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome_frame/vtable_patch_manager.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome_frame/vtable_patch_manager.h"
6
7 #include "base/logging.h"
8
9 #include "chrome_frame/function_stub.h"
10
11 namespace vtable_patch {
12
13 // Convenient definition of a VTABLE
14 typedef PROC* Vtable;
15
16 // Returns a pointer to the VTable of a COM interface.
17 // @param unknown [in] The pointer of the COM interface.
18 inline Vtable GetIFVTable(void* unknown) {
19 return reinterpret_cast<Vtable>(*reinterpret_cast<void**>(unknown));
20 }
21
22 HRESULT PatchInterfaceMethods(void* unknown, MethodPatchInfo* patches) {
23 // Do some sanity checking of the input arguments.
24 if (NULL == unknown || NULL == patches) {
25 NOTREACHED();
26 return E_INVALIDARG;
27 }
28
29 Vtable vtable = GetIFVTable(unknown);
30 DCHECK(vtable);
31
32 for (MethodPatchInfo* it = patches; it->index_ != -1; ++it) {
33 PROC original_fn = vtable[it->index_];
34 FunctionStub* stub = FunctionStub::FromCode(original_fn);
35 if (stub != NULL) {
36 DLOG(ERROR) << "attempt to patch a function that's already patched";
37 DCHECK(stub->absolute_target() ==
38 reinterpret_cast<uintptr_t>(it->method_)) <<
39 "patching the same method multiple times with different hooks?";
40 continue;
41 }
42
43 stub = FunctionStub::Create(reinterpret_cast<uintptr_t>(original_fn),
44 it->method_);
45 if (!stub) {
46 NOTREACHED();
47 return E_OUTOFMEMORY;
48 } else {
49 DWORD protect = 0;
50 if (::VirtualProtect(&vtable[it->index_], sizeof(PROC),
51 PAGE_EXECUTE_READWRITE, &protect)) {
52 it->stub_ = stub; // save the stub
53 vtable[it->index_] = stub->code();
54 ::VirtualProtect(&vtable[it->index_], sizeof(PROC), protect,
55 &protect);
56 } else {
57 NOTREACHED();
58 }
59 }
60 }
61
62 return S_OK;
63 }
64
65 HRESULT UnpatchInterfaceMethods(MethodPatchInfo* patches) {
66 for (MethodPatchInfo* it = patches; it->index_ != -1; ++it) {
67 if (it->stub_) {
68 DCHECK(it->stub_->absolute_target() ==
69 reinterpret_cast<uintptr_t>(it->method_));
70 // Modify the stub to just jump directly to the original function.
71 it->stub_->BypassStub(reinterpret_cast<void*>(it->stub_->argument()));
72 it->stub_ = NULL;
73 // Leave the stub in memory so that we won't break any possible chains.
74 } else {
75 DLOG(WARNING) << "attempt to unpatch a function that wasn't patched";
76 }
77 }
78
79 return S_OK;
80 }
81
82 } // namespace vtable_patch
OLDNEW
« no previous file with comments | « chrome_frame/vtable_patch_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698