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