1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_shell.hxx"
26 #include "internal/global.hxx"
27 #include "classfactory.hxx"
28 #include "internal/infotips.hxx"
29 #include "internal/propsheets.hxx"
30 #include "internal/columninfo.hxx"
31 #ifdef __MINGW32__
32 #include <algorithm>
33 using ::std::max;
34 using ::std::min;
35 #endif
36 #include "internal/thumbviewer.hxx"
37 #include "internal/shlxthdl.hxx"
38 
39 //-----------------------------
40 //
41 //-----------------------------
42 
43 long CClassFactory::s_ServerLocks = 0;
44 
45 //-----------------------------
46 //
47 //-----------------------------
48 
CClassFactory(const CLSID & clsid)49 CClassFactory::CClassFactory(const CLSID& clsid) :
50 	m_RefCnt(1),
51 	m_Clsid(clsid)
52 {
53 	InterlockedIncrement(&g_DllRefCnt);
54 }
55 
56 //-----------------------------
57 //
58 //-----------------------------
59 
~CClassFactory()60 CClassFactory::~CClassFactory()
61 {
62 	InterlockedDecrement(&g_DllRefCnt);
63 }
64 
65 //-----------------------------
66 // IUnknown methods
67 //-----------------------------
68 
QueryInterface(REFIID riid,void __RPC_FAR * __RPC_FAR * ppvObject)69 HRESULT STDMETHODCALLTYPE CClassFactory::QueryInterface(REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject)
70 {
71 	*ppvObject = 0;
72 
73 	if (IID_IUnknown == riid || IID_IClassFactory == riid)
74 	{
75 		IUnknown* pUnk = this;
76 		pUnk->AddRef();
77 		*ppvObject = pUnk;
78 		return S_OK;
79 	}
80 
81 	return E_NOINTERFACE;
82 }
83 
84 //-----------------------------
85 //
86 //-----------------------------
87 
AddRef(void)88 ULONG STDMETHODCALLTYPE CClassFactory::AddRef(void)
89 {
90 	return InterlockedIncrement(&m_RefCnt);
91 }
92 
93 //-----------------------------
94 //
95 //-----------------------------
96 
Release(void)97 ULONG STDMETHODCALLTYPE CClassFactory::Release(void)
98 {
99 	long refcnt = InterlockedDecrement(&m_RefCnt);
100 
101 	if (0 == refcnt)
102 		delete this;
103 
104 	return refcnt;
105 }
106 
107 //-----------------------------
108 // IClassFactory methods
109 //-----------------------------
110 
CreateInstance(IUnknown __RPC_FAR * pUnkOuter,REFIID riid,void __RPC_FAR * __RPC_FAR * ppvObject)111 HRESULT STDMETHODCALLTYPE CClassFactory::CreateInstance(
112             IUnknown __RPC_FAR *pUnkOuter,
113             REFIID riid,
114             void __RPC_FAR *__RPC_FAR *ppvObject)
115 {
116 	if ((pUnkOuter != NULL))
117 		return CLASS_E_NOAGGREGATION;
118 
119 	IUnknown* pUnk = 0;
120 
121 	if (CLSID_PROPERTYSHEET_HANDLER == m_Clsid)
122 		pUnk = static_cast<IShellExtInit*>(new CPropertySheet());
123 
124 	else if (CLSID_INFOTIP_HANDLER == m_Clsid)
125 		pUnk = static_cast<IQueryInfo*>(new CInfoTip());
126 
127 	else if (CLSID_COLUMN_HANDLER == m_Clsid)
128 		pUnk = static_cast<IColumnProvider*>(new CColumnInfo());
129 
130     else if (CLSID_THUMBVIEWER_HANDLER == m_Clsid)
131         pUnk = static_cast<IExtractImage*>(new CThumbviewer());
132 
133 	POST_CONDITION(pUnk != 0, "Could not create COM object");
134 
135 	if (0 == pUnk)
136 		return E_OUTOFMEMORY;
137 
138 	HRESULT hr = pUnk->QueryInterface(riid, ppvObject);
139 
140 	// if QueryInterface failed the component will destroy itself
141 	pUnk->Release();
142 
143 	return hr;
144 }
145 
146 //-----------------------------
147 //
148 //-----------------------------
149 
LockServer(BOOL fLock)150 HRESULT STDMETHODCALLTYPE CClassFactory::LockServer(BOOL fLock)
151 {
152 	if (fLock)
153 		InterlockedIncrement(&s_ServerLocks);
154 	else
155 		InterlockedDecrement(&s_ServerLocks);
156 
157 	return S_OK;
158 }
159 
160 //-----------------------------
161 //
162 //-----------------------------
163 
IsLocked()164 bool CClassFactory::IsLocked()
165 {
166 	return (s_ServerLocks > 0);
167 }
168