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

Unified Diff: chrome_frame/vtable_patch_manager_unittest.cc

Issue 126143005: Remove Chrome Frame code and resources. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: sync to r244038 Created 6 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome_frame/vtable_patch_manager.cc ('k') | tools/gritsettings/resource_ids » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome_frame/vtable_patch_manager_unittest.cc
diff --git a/chrome_frame/vtable_patch_manager_unittest.cc b/chrome_frame/vtable_patch_manager_unittest.cc
deleted file mode 100644
index 1135385f92707b4f3f63b9051fc4864ba50bba95..0000000000000000000000000000000000000000
--- a/chrome_frame/vtable_patch_manager_unittest.cc
+++ /dev/null
@@ -1,293 +0,0 @@
-// 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.
-
-#include "chrome_frame/vtable_patch_manager.h"
-
-#include <unknwn.h>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/message_loop/message_loop.h"
-#include "base/threading/thread.h"
-#include "base/win/scoped_handle.h"
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-
-namespace {
-// GMock names we use.
-using testing::_;
-using testing::Return;
-
-class MockClassFactory : public IClassFactory {
- public:
- MOCK_METHOD2_WITH_CALLTYPE(__stdcall, QueryInterface,
- HRESULT(REFIID riid, void **object));
- MOCK_METHOD0_WITH_CALLTYPE(__stdcall, AddRef, ULONG());
- MOCK_METHOD0_WITH_CALLTYPE(__stdcall, Release, ULONG());
- MOCK_METHOD3_WITH_CALLTYPE(__stdcall, CreateInstance,
- HRESULT (IUnknown *outer, REFIID riid, void **object));
- MOCK_METHOD1_WITH_CALLTYPE(__stdcall, LockServer, HRESULT(BOOL lock));
-};
-
-// Retrieve the vtable for an interface.
-void* GetVtable(IUnknown* unk) {
- return *reinterpret_cast<void**>(unk);
-}
-
-// Forward decl.
-extern vtable_patch::MethodPatchInfo IClassFactory_PatchInfo[];
-
-class VtablePatchManagerTest: public testing::Test {
- public:
- VtablePatchManagerTest() {
- EXPECT_TRUE(current_ == NULL);
- current_ = this;
- }
-
- ~VtablePatchManagerTest() {
- EXPECT_TRUE(current_ == this);
- current_ = NULL;
- }
-
- virtual void SetUp() {
- // Make a backup of the test vtable and it's page protection settings.
- void* vtable = GetVtable(&factory_);
- MEMORY_BASIC_INFORMATION info;
- ASSERT_TRUE(::VirtualQuery(vtable, &info, sizeof(info)));
- vtable_protection_ = info.Protect;
- memcpy(vtable_backup_, vtable, sizeof(vtable_backup_));
- }
-
- virtual void TearDown() {
- // Unpatch to make sure we've restored state for subsequent test.
- UnpatchInterfaceMethods(IClassFactory_PatchInfo);
-
- // Restore the test vtable and its page protection settings.
- void* vtable = GetVtable(&factory_);
- DWORD old_protect = 0;
- EXPECT_TRUE(::VirtualProtect(vtable, sizeof(vtable_backup_),
- PAGE_EXECUTE_WRITECOPY, &old_protect));
- memcpy(vtable, vtable_backup_, sizeof(vtable_backup_));
- EXPECT_TRUE(::VirtualProtect(vtable, sizeof(vtable_backup_),
- vtable_protection_, &old_protect));
- }
-
- typedef HRESULT (__stdcall* LockServerFun)(IClassFactory* self, BOOL lock);
- MOCK_METHOD3(LockServerPatch,
- HRESULT(LockServerFun old_fun, IClassFactory* self, BOOL lock));
-
- static HRESULT STDMETHODCALLTYPE LockServerPatchCallback(
- LockServerFun fun, IClassFactory* self, BOOL lock) {
- EXPECT_TRUE(current_ != NULL);
- if (current_ != NULL)
- return current_->LockServerPatch(fun, self, lock);
- else
- return E_UNEXPECTED;
- }
-
- protected:
- // Number of functions in the IClassFactory vtable.
- static const size_t kFunctionCount = 5;
-
- // Backup of the factory_ vtable as we found it at Setup.
- PROC vtable_backup_[kFunctionCount];
- // VirtualProtect flags on the factory_ vtable as we found it at Setup.
- DWORD vtable_protection_;
-
- // The mock factory class we patch.
- MockClassFactory factory_;
-
- // Current test running for routing the patch callback function.
- static VtablePatchManagerTest* current_;
-};
-
-VtablePatchManagerTest* VtablePatchManagerTest::current_ = NULL;
-
-BEGIN_VTABLE_PATCHES(IClassFactory)
- VTABLE_PATCH_ENTRY(4, &VtablePatchManagerTest::LockServerPatchCallback)
-END_VTABLE_PATCHES();
-
-} // namespace
-
-TEST_F(VtablePatchManagerTest, ReplacePointer) {
- void* const kFunctionOriginal = reinterpret_cast<void*>(0xCAFEBABE);
- void* const kFunctionFoo = reinterpret_cast<void*>(0xF0F0F0F0);
- void* const kFunctionBar = reinterpret_cast<void*>(0xBABABABA);
-
- using vtable_patch::internal::ReplaceFunctionPointer;
- // Replacing a non-writable location should fail, but not crash.
- EXPECT_FALSE(ReplaceFunctionPointer(NULL, kFunctionBar, kFunctionFoo));
-
- void* foo_entry = kFunctionOriginal;
- // Replacing with the wrong original function should
- // fail and not change the entry.
- EXPECT_FALSE(ReplaceFunctionPointer(&foo_entry, kFunctionBar, kFunctionFoo));
- EXPECT_EQ(foo_entry, kFunctionOriginal);
-
- // Replacing with the correct original should succeed.
- EXPECT_TRUE(ReplaceFunctionPointer(&foo_entry,
- kFunctionBar,
- kFunctionOriginal));
- EXPECT_EQ(foo_entry, kFunctionBar);
-}
-
-TEST_F(VtablePatchManagerTest, PatchInterfaceMethods) {
- // Unpatched.
- EXPECT_CALL(factory_, LockServer(TRUE))
- .WillOnce(Return(E_FAIL));
- EXPECT_EQ(E_FAIL, factory_.LockServer(TRUE));
-
- EXPECT_HRESULT_SUCCEEDED(
- PatchInterfaceMethods(&factory_, IClassFactory_PatchInfo));
-
- EXPECT_NE(0, memcmp(GetVtable(&factory_),
- vtable_backup_,
- sizeof(vtable_backup_)));
-
- // This should not be called while the patch is in effect.
- EXPECT_CALL(factory_, LockServer(_))
- .Times(0);
-
- EXPECT_CALL(*this, LockServerPatch(testing::_, &factory_, TRUE))
- .WillOnce(testing::Return(S_FALSE));
-
- EXPECT_EQ(S_FALSE, factory_.LockServer(TRUE));
-}
-
-TEST_F(VtablePatchManagerTest, UnpatchInterfaceMethods) {
- // Patch it.
- EXPECT_HRESULT_SUCCEEDED(
- PatchInterfaceMethods(&factory_, IClassFactory_PatchInfo));
-
- EXPECT_NE(0, memcmp(GetVtable(&factory_),
- vtable_backup_,
- sizeof(vtable_backup_)));
-
- // This should not be called while the patch is in effect.
- EXPECT_CALL(factory_, LockServer(testing::_))
- .Times(0);
-
- EXPECT_CALL(*this, LockServerPatch(testing::_, &factory_, TRUE))
- .WillOnce(testing::Return(S_FALSE));
-
- EXPECT_EQ(S_FALSE, factory_.LockServer(TRUE));
-
- // Now unpatch.
- EXPECT_HRESULT_SUCCEEDED(
- UnpatchInterfaceMethods(IClassFactory_PatchInfo));
-
- // And check that the call comes through correctly.
- EXPECT_CALL(factory_, LockServer(FALSE))
- .WillOnce(testing::Return(E_FAIL));
- EXPECT_EQ(E_FAIL, factory_.LockServer(FALSE));
-}
-
-TEST_F(VtablePatchManagerTest, DoublePatch) {
- // Patch it.
- EXPECT_HRESULT_SUCCEEDED(
- PatchInterfaceMethods(&factory_, IClassFactory_PatchInfo));
-
- // Capture the VTable after patching.
- PROC vtable[kFunctionCount];
- memcpy(vtable, GetVtable(&factory_), sizeof(vtable));
-
- // Patch it again, this should be idempotent.
- EXPECT_HRESULT_SUCCEEDED(
- PatchInterfaceMethods(&factory_, IClassFactory_PatchInfo));
-
- // Should not have changed the VTable on second call.
- EXPECT_EQ(0, memcmp(vtable, GetVtable(&factory_), sizeof(vtable)));
-}
-
-namespace vtable_patch {
-// Expose internal implementation detail, purely for testing.
-extern base::Lock patch_lock_;
-
-} // namespace vtable_patch
-
-TEST_F(VtablePatchManagerTest, ThreadSafePatching) {
- // It's difficult to test for threadsafe patching, but as a close proxy,
- // test for no patching happening from a background thread while the patch
- // lock is held.
- base::Thread background("Background Test Thread");
-
- EXPECT_TRUE(background.Start());
- base::win::ScopedHandle event(::CreateEvent(NULL, TRUE, FALSE, NULL));
-
- // Grab the patch lock.
- vtable_patch::patch_lock_.Acquire();
-
- // Instruct the background thread to patch factory_.
- background.message_loop()->PostTask(
- FROM_HERE,
- base::Bind(base::IgnoreResult(&vtable_patch::PatchInterfaceMethods),
- &factory_, &IClassFactory_PatchInfo[0]));
-
- // And subsequently to signal the event. Neither of these actions should
- // occur until we've released the patch lock.
- background.message_loop()->PostTask(
- FROM_HERE, base::Bind(base::IgnoreResult(::SetEvent), event.Get()));
-
- // Wait for a little while, to give the background thread time to process.
- // We expect this wait to time out, as the background thread should end up
- // blocking on the patch lock.
- EXPECT_EQ(WAIT_TIMEOUT, ::WaitForSingleObject(event.Get(), 50));
-
- // Verify that patching did not take place yet.
- EXPECT_CALL(factory_, LockServer(TRUE))
- .WillOnce(Return(S_FALSE));
- EXPECT_EQ(S_FALSE, factory_.LockServer(TRUE));
-
- // Release the lock and wait on the event again to ensure
- // the patching has taken place now.
- vtable_patch::patch_lock_.Release();
- EXPECT_EQ(WAIT_OBJECT_0, ::WaitForSingleObject(event.Get(), INFINITE));
-
- // We should not get called here anymore.
- EXPECT_CALL(factory_, LockServer(TRUE))
- .Times(0);
-
- // But should be diverted here.
- EXPECT_CALL(*this, LockServerPatch(_, &factory_, TRUE))
- .WillOnce(Return(S_FALSE));
- EXPECT_EQ(S_FALSE, factory_.LockServer(TRUE));
-
- // Same deal for unpatching.
- ::ResetEvent(event.Get());
-
- // Grab the patch lock.
- vtable_patch::patch_lock_.Acquire();
-
- // Instruct the background thread to unpatch.
- background.message_loop()->PostTask(
- FROM_HERE,
- base::Bind(base::IgnoreResult(&vtable_patch::UnpatchInterfaceMethods),
- &IClassFactory_PatchInfo[0]));
-
- // And subsequently to signal the event. Neither of these actions should
- // occur until we've released the patch lock.
- background.message_loop()->PostTask(
- FROM_HERE, base::Bind(base::IgnoreResult(::SetEvent), event.Get()));
-
- // Wait for a little while, to give the background thread time to process.
- // We expect this wait to time out, as the background thread should end up
- // blocking on the patch lock.
- EXPECT_EQ(WAIT_TIMEOUT, ::WaitForSingleObject(event.Get(), 50));
-
- // We should still be patched.
- EXPECT_CALL(factory_, LockServer(TRUE))
- .Times(0);
- EXPECT_CALL(*this, LockServerPatch(_, &factory_, TRUE))
- .WillOnce(Return(S_FALSE));
- EXPECT_EQ(S_FALSE, factory_.LockServer(TRUE));
-
- // Release the patch lock and wait on the event.
- vtable_patch::patch_lock_.Release();
- EXPECT_EQ(WAIT_OBJECT_0, ::WaitForSingleObject(event.Get(), INFINITE));
-
- // Verify that unpatching took place.
- EXPECT_CALL(factory_, LockServer(TRUE))
- .WillOnce(Return(S_FALSE));
- EXPECT_EQ(S_FALSE, factory_.LockServer(TRUE));
-}
« no previous file with comments | « chrome_frame/vtable_patch_manager.cc ('k') | tools/gritsettings/resource_ids » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698