1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_shell.hxx"
30 #include "internal/global.hxx"
31 #include "classfactory.hxx"
32 #include "internal/infotips.hxx"
33 #include "internal/propsheets.hxx"
34 #include "internal/columninfo.hxx"
35 #ifdef __MINGW32__
36 #include <algorithm>
37 using ::std::max;
38 using ::std::min;
39 #endif
40 #include "internal/thumbviewer.hxx"
41 #include "internal/shlxthdl.hxx"
42 
43 //-----------------------------
44 //
45 //-----------------------------
46 
47 long CClassFactory::s_ServerLocks = 0;
48 
49 //-----------------------------
50 //
51 //-----------------------------
52 
53 CClassFactory::CClassFactory(const CLSID& clsid) :
54 	m_RefCnt(1),
55 	m_Clsid(clsid)
56 {
57 	InterlockedIncrement(&g_DllRefCnt);
58 }
59 
60 //-----------------------------
61 //
62 //-----------------------------
63 
64 CClassFactory::~CClassFactory()
65 {
66 	InterlockedDecrement(&g_DllRefCnt);
67 }
68 
69 //-----------------------------
70 // IUnknown methods
71 //-----------------------------
72 
73 HRESULT STDMETHODCALLTYPE CClassFactory::QueryInterface(REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject)
74 {
75 	*ppvObject = 0;
76 
77 	if (IID_IUnknown == riid || IID_IClassFactory == riid)
78 	{
79 		IUnknown* pUnk = this;
80 		pUnk->AddRef();
81 		*ppvObject = pUnk;
82 		return S_OK;
83 	}
84 
85 	return E_NOINTERFACE;
86 }
87 
88 //-----------------------------
89 //
90 //-----------------------------
91 
92 ULONG STDMETHODCALLTYPE CClassFactory::AddRef(void)
93 {
94 	return InterlockedIncrement(&m_RefCnt);
95 }
96 
97 //-----------------------------
98 //
99 //-----------------------------
100 
101 ULONG STDMETHODCALLTYPE CClassFactory::Release(void)
102 {
103 	long refcnt = InterlockedDecrement(&m_RefCnt);
104 
105 	if (0 == refcnt)
106 		delete this;
107 
108 	return refcnt;
109 }
110 
111 //-----------------------------
112 // IClassFactory methods
113 //-----------------------------
114 
115 HRESULT STDMETHODCALLTYPE CClassFactory::CreateInstance(
116             IUnknown __RPC_FAR *pUnkOuter,
117             REFIID riid,
118             void __RPC_FAR *__RPC_FAR *ppvObject)
119 {
120 	if ((pUnkOuter != NULL))
121 		return CLASS_E_NOAGGREGATION;
122 
123 	IUnknown* pUnk = 0;
124 
125 	if (CLSID_PROPERTYSHEET_HANDLER == m_Clsid)
126 		pUnk = static_cast<IShellExtInit*>(new CPropertySheet());
127 
128 	else if (CLSID_INFOTIP_HANDLER == m_Clsid)
129 		pUnk = static_cast<IQueryInfo*>(new CInfoTip());
130 
131 	else if (CLSID_COLUMN_HANDLER == m_Clsid)
132 		pUnk = static_cast<IColumnProvider*>(new CColumnInfo());
133 
134     else if (CLSID_THUMBVIEWER_HANDLER == m_Clsid)
135         pUnk = static_cast<IExtractImage*>(new CThumbviewer());
136 
137 	POST_CONDITION(pUnk != 0, "Could not create COM object");
138 
139 	if (0 == pUnk)
140 		return E_OUTOFMEMORY;
141 
142 	HRESULT hr = pUnk->QueryInterface(riid, ppvObject);
143 
144 	// if QueryInterface failed the component will destroy itself
145 	pUnk->Release();
146 
147 	return hr;
148 }
149 
150 //-----------------------------
151 //
152 //-----------------------------
153 
154 HRESULT STDMETHODCALLTYPE CClassFactory::LockServer(BOOL fLock)
155 {
156 	if (fLock)
157 		InterlockedIncrement(&s_ServerLocks);
158 	else
159 		InterlockedDecrement(&s_ServerLocks);
160 
161 	return S_OK;
162 }
163 
164 //-----------------------------
165 //
166 //-----------------------------
167 
168 bool CClassFactory::IsLocked()
169 {
170 	return (s_ServerLocks > 0);
171 }
172