1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/win/scoped_comptr.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <shlobj.h> 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/gtest/include/gtest/gtest.h" 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 12731df977c0511bca2206b5f333555b1205ff1f43Iain Merricknamespace base { 13731df977c0511bca2206b5f333555b1205ff1f43Iain Merricknamespace win { 14731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace { 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct Dummy { 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Dummy() : adds(0), releases(0) { } 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void AddRef() { ++adds; } 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Release() { ++releases; } 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int adds; 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int releases; 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottextern const IID dummy_iid; 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst IID dummy_iid = { 0x12345678u, 0x1234u, 0x5678u, 01, 23, 45, 67, 89, 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 01, 23, 45 }; 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ScopedComPtrTest, ScopedComPtr) { 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(memcmp(&ScopedComPtr<IUnknown>::iid(), &IID_IUnknown, 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sizeof(IID)) == 0); 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(SUCCEEDED(::CoInitialize(NULL))); 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ScopedComPtr<IUnknown> unk; 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(SUCCEEDED(unk.CreateInstance(CLSID_ShellLink))); 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ScopedComPtr<IUnknown> unk2; 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unk2.Attach(unk.Detach()); 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(unk == NULL); 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(unk2 != NULL); 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ScopedComPtr<IMalloc> mem_alloc; 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(SUCCEEDED(CoGetMalloc(1, mem_alloc.Receive()))); 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ScopedComPtr<IUnknown> qi_test; 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_HRESULT_SUCCEEDED(mem_alloc.QueryInterface(IID_IUnknown, 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott reinterpret_cast<void**>(qi_test.Receive()))); 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(qi_test.get() != NULL); 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott qi_test.Release(); 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // test ScopedComPtr& constructor 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ScopedComPtr<IMalloc> copy1(mem_alloc); 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(copy1.IsSameObject(mem_alloc)); 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(copy1.IsSameObject(unk2)); // unk2 is valid but different 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(copy1.IsSameObject(unk)); // unk is NULL 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott IMalloc* naked_copy = copy1.Detach(); 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott copy1 = naked_copy; // Test the =(T*) operator. 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott naked_copy->Release(); 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott copy1.Release(); 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(copy1.IsSameObject(unk2)); // unk2 is valid, copy1 is not 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // test Interface* constructor 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ScopedComPtr<IMalloc> copy2(static_cast<IMalloc*>(mem_alloc)); 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(copy2.IsSameObject(mem_alloc)); 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(SUCCEEDED(unk.QueryFrom(mem_alloc))); 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(unk != NULL); 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unk.Release(); 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(unk == NULL); 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(unk.IsSameObject(copy1)); // both are NULL 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ::CoUninitialize(); 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ScopedComPtrTest, ScopedComPtrVector) { 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Verify we don't get error C2558. 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef ScopedComPtr<Dummy, &dummy_iid> Ptr; 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::vector<Ptr> bleh; 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<Dummy> p(new Dummy); 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Ptr p2(p.get()); 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(p->adds, 1); 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(p->releases, 0); 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Ptr p3 = p2; 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(p->adds, 2); 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(p->releases, 0); 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott p3 = p2; 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(p->adds, 3); 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(p->releases, 1); 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // To avoid hitting a reallocation. 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bleh.reserve(1); 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bleh.push_back(p2); 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(p->adds, 4); 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(p->releases, 1); 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(bleh[0], p.get()); 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bleh.pop_back(); 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(p->adds, 4); 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(p->releases, 2); 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(p->adds, 4); 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(p->releases, 4); 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 111731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 112731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} // namespace win 113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} // namespace base 114