1/*
2 * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "WebKitDLL.h"
28#include "WebKitClassFactory.h"
29
30#include "CFDictionaryPropertyBag.h"
31#include "ForEachCoClass.h"
32#include "WebArchive.h"
33#include "WebCache.h"
34#include "WebCookieManager.h"
35#include "WebCoreStatistics.h"
36#include "WebDatabaseManager.h"
37#include "WebDownload.h"
38#include "WebError.h"
39#include "WebFrame.h"
40#include "WebGeolocationPosition.h"
41#include "WebHistory.h"
42#include "WebHistoryItem.h"
43#include "WebIconDatabase.h"
44#include "WebJavaScriptCollector.h"
45#include "WebKit.h"
46#include "WebKitStatistics.h"
47#include "WebMutableURLRequest.h"
48#include "WebNotificationCenter.h"
49#include "WebPreferences.h"
50#include "WebScriptWorld.h"
51#include "WebScrollBar.h"
52#include "WebSerializedJSValue.h"
53#include "WebTextRenderer.h"
54#include "WebURLCredential.h"
55#include "WebURLProtectionSpace.h"
56#include "WebURLResponse.h"
57#include "WebUserContentURLPattern.h"
58#include "WebView.h"
59#include "WebWorkersPrivate.h"
60#include <JavaScriptCore/InitializeThreading.h>
61#include <WebCore/SoftLinking.h>
62#include <wtf/Threading.h>
63
64// WebKitClassFactory ---------------------------------------------------------
65#if USE(SAFARI_THEME)
66#ifdef DEBUG_ALL
67SOFT_LINK_DEBUG_LIBRARY(SafariTheme)
68#else
69SOFT_LINK_LIBRARY(SafariTheme)
70#endif
71
72SOFT_LINK(SafariTheme, STInitialize, void, APIENTRY, (), ())
73#endif
74
75WebKitClassFactory::WebKitClassFactory(CLSID targetClass)
76: m_targetClass(targetClass)
77, m_refCount(0)
78{
79#if USE(SAFARI_THEME)
80    static bool didInitializeSafariTheme;
81    if (!didInitializeSafariTheme) {
82        if (SafariThemeLibrary())
83            STInitialize();
84        didInitializeSafariTheme = true;
85    }
86#endif
87
88    JSC::initializeThreading();
89    WTF::initializeMainThread();
90
91    gClassCount++;
92    gClassNameCount.add("WebKitClassFactory");
93}
94
95WebKitClassFactory::~WebKitClassFactory()
96{
97    gClassCount--;
98    gClassNameCount.remove("WebKitClassFactory");
99}
100
101// IUnknown -------------------------------------------------------------------
102
103HRESULT STDMETHODCALLTYPE WebKitClassFactory::QueryInterface(REFIID riid, void** ppvObject)
104{
105    *ppvObject = 0;
106    if (IsEqualGUID(riid, IID_IUnknown))
107        *ppvObject = static_cast<IUnknown*>(this);
108    else if (IsEqualGUID(riid, IID_IClassFactory))
109        *ppvObject = static_cast<IClassFactory*>(this);
110    else
111        return E_NOINTERFACE;
112
113    AddRef();
114    return S_OK;
115}
116
117ULONG STDMETHODCALLTYPE WebKitClassFactory::AddRef(void)
118{
119    return ++m_refCount;
120}
121
122ULONG STDMETHODCALLTYPE WebKitClassFactory::Release(void)
123{
124    ULONG newRef = --m_refCount;
125    if (!newRef && !gLockCount)
126        delete(this);
127
128    return newRef;
129}
130
131// FIXME: Remove these functions once all createInstance() functions return COMPtr.
132template <typename T>
133static T* releaseRefFromCreateInstance(T* object)
134{
135    return object;
136}
137
138template <typename T>
139static T* releaseRefFromCreateInstance(COMPtr<T> object)
140{
141    return object.releaseRef();
142}
143
144// IClassFactory --------------------------------------------------------------
145
146HRESULT STDMETHODCALLTYPE WebKitClassFactory::CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppvObject)
147{
148    IUnknown* unknown = 0;
149    *ppvObject = 0;
150
151    if (pUnkOuter)
152        return CLASS_E_NOAGGREGATION;
153
154#define INITIALIZE_IF_CLASS(cls) \
155    if (IsEqualGUID(m_targetClass, CLSID_##cls)) \
156        unknown = static_cast<I##cls*>(releaseRefFromCreateInstance(cls::createInstance())); \
157    else \
158    // end of macro
159
160    // These #defines are needed to appease the INITIALIZE_IF_CLASS macro.
161    // There is no ICFDictionaryPropertyBag, we use IPropertyBag instead.
162#define ICFDictionaryPropertyBag IPropertyBag
163    // There is no IWebScrollBar, we only have IWebScrollBarPrivate.
164#define IWebScrollBar IWebScrollBarPrivate
165    // There is no class called WebURLRequest -- WebMutableURLRequest implements it for us.
166#define WebURLRequest WebMutableURLRequest
167
168    FOR_EACH_COCLASS(INITIALIZE_IF_CLASS)
169        // This is the final else case
170        return CLASS_E_CLASSNOTAVAILABLE;
171
172#undef ICFDictionaryPropertyBag
173#undef IWebScrollBar
174#undef WebURLRequest
175#undef INITIALIZE_IF_CLASS
176
177    if (!unknown)
178        return E_OUTOFMEMORY;
179
180    HRESULT hr = unknown->QueryInterface(riid, ppvObject);
181    if (FAILED(hr))
182        delete unknown;
183    else
184        unknown->Release(); // both createInstance() and QueryInterface() added refs
185
186    return hr;
187}
188
189HRESULT STDMETHODCALLTYPE WebKitClassFactory::LockServer(BOOL fLock)
190{
191    if (fLock)
192        gLockCount++;
193    else
194        gLockCount--;
195
196    return S_OK;
197}
198