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 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 60 CClassFactory::~CClassFactory() 61 { 62 InterlockedDecrement(&g_DllRefCnt); 63 } 64 65 //----------------------------- 66 // IUnknown methods 67 //----------------------------- 68 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 88 ULONG STDMETHODCALLTYPE CClassFactory::AddRef(void) 89 { 90 return InterlockedIncrement(&m_RefCnt); 91 } 92 93 //----------------------------- 94 // 95 //----------------------------- 96 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 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 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 164 bool CClassFactory::IsLocked() 165 { 166 return (s_ServerLocks > 0); 167 } 168