1d0626817SAndrew Rist /**************************************************************
2*48fbb544Smseidel  *
3d0626817SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4d0626817SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5d0626817SAndrew Rist  * distributed with this work for additional information
6d0626817SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7d0626817SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8d0626817SAndrew Rist  * "License"); you may not use this file except in compliance
9d0626817SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*48fbb544Smseidel  *
11d0626817SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*48fbb544Smseidel  *
13d0626817SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14d0626817SAndrew Rist  * software distributed under the License is distributed on an
15d0626817SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16d0626817SAndrew Rist  * KIND, either express or implied.  See the License for the
17d0626817SAndrew Rist  * specific language governing permissions and limitations
18d0626817SAndrew Rist  * under the License.
19*48fbb544Smseidel  *
20d0626817SAndrew Rist  *************************************************************/
21d0626817SAndrew Rist 
22d0626817SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_shell.hxx"
26cdf0e10cSrcweir #include "internal/global.hxx"
27cdf0e10cSrcweir #include "internal/PropertyHdl.hxx"
28cdf0e10cSrcweir #include "internal/fileextensions.hxx"
29cdf0e10cSrcweir #include "internal/metainforeader.hxx"
30cdf0e10cSrcweir #include "internal/utilities.hxx"
31cdf0e10cSrcweir #include "internal/config.hxx"
32cdf0e10cSrcweir 
33cdf0e10cSrcweir #include <propkey.h>
34cdf0e10cSrcweir #include <propvarutil.h>
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #include <malloc.h>
37cdf0e10cSrcweir #include <strsafe.h>
38cdf0e10cSrcweir 
39cdf0e10cSrcweir #include "internal/stream_helper.hxx"
40cdf0e10cSrcweir 
41cdf0e10cSrcweir //---------------------------
42cdf0e10cSrcweir // Module global
43cdf0e10cSrcweir //---------------------------
44cdf0e10cSrcweir long g_DllRefCnt = 0;
45cdf0e10cSrcweir HINSTANCE g_hModule = NULL;
46*48fbb544Smseidel 
47cdf0e10cSrcweir //
48cdf0e10cSrcweir // Map of property keys to the locations of their value(s) in the .??? XML schema
49cdf0e10cSrcweir //
50cdf0e10cSrcweir struct PROPERTYMAP
51cdf0e10cSrcweir {
52*48fbb544Smseidel 	PROPERTYKEY key;
53*48fbb544Smseidel 	PCWSTR pszXPathParent;
54*48fbb544Smseidel 	PCWSTR pszValueNodeName;
55cdf0e10cSrcweir };
56cdf0e10cSrcweir 
57cdf0e10cSrcweir PROPERTYMAP g_rgPROPERTYMAP[] =
58cdf0e10cSrcweir {
59*48fbb544Smseidel 	{ PKEY_Title,		L"OpenOffice",	L"Title" },
60*48fbb544Smseidel 	{ PKEY_Author,		L"OpenOffice",	L"Author" },
61*48fbb544Smseidel 	{ PKEY_Subject,		L"OpenOffice",	L"Subject" },
62*48fbb544Smseidel 	{ PKEY_Keywords,	L"OpenOffice",	L"Keyword" },
63*48fbb544Smseidel 	{ PKEY_Comment,		L"OpenOffice",	L"Comments" },
64cdf0e10cSrcweir };
65cdf0e10cSrcweir 
66cdf0e10cSrcweir size_t gPropertyMapTableSize = sizeof(g_rgPROPERTYMAP)/sizeof(g_rgPROPERTYMAP[0]);
67cdf0e10cSrcweir 
68cdf0e10cSrcweir //----------------------------
69cdf0e10cSrcweir //
70cdf0e10cSrcweir //----------------------------
71cdf0e10cSrcweir 
CPropertyHdl(long nRefCnt)72cdf0e10cSrcweir CPropertyHdl::CPropertyHdl( long nRefCnt ) :
73*48fbb544Smseidel 	m_RefCnt( nRefCnt ),
74*48fbb544Smseidel 	m_pCache( NULL )
75cdf0e10cSrcweir {
76*48fbb544Smseidel 	OutputDebugStringFormat( "CPropertyHdl: CTOR\n" );
77*48fbb544Smseidel 	InterlockedIncrement( &g_DllRefCnt );
78cdf0e10cSrcweir }
79cdf0e10cSrcweir 
80cdf0e10cSrcweir //----------------------------
81cdf0e10cSrcweir //
82cdf0e10cSrcweir //----------------------------
83cdf0e10cSrcweir 
~CPropertyHdl()84cdf0e10cSrcweir CPropertyHdl::~CPropertyHdl()
85cdf0e10cSrcweir {
86*48fbb544Smseidel 	if ( m_pCache )
87*48fbb544Smseidel 	{
88*48fbb544Smseidel 		m_pCache->Release();
89*48fbb544Smseidel 		m_pCache = NULL;
90*48fbb544Smseidel 	}
91*48fbb544Smseidel 	InterlockedDecrement( &g_DllRefCnt );
92cdf0e10cSrcweir }
93cdf0e10cSrcweir 
94cdf0e10cSrcweir //-----------------------------
95cdf0e10cSrcweir // IUnknown methods
96cdf0e10cSrcweir //-----------------------------
QueryInterface(REFIID riid,void __RPC_FAR * __RPC_FAR * ppvObject)97cdf0e10cSrcweir HRESULT STDMETHODCALLTYPE CPropertyHdl::QueryInterface(REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject)
98cdf0e10cSrcweir {
99*48fbb544Smseidel 	*ppvObject = 0;
100*48fbb544Smseidel 
101*48fbb544Smseidel 	if (IID_IUnknown == riid || IID_IPropertyStore == riid)
102*48fbb544Smseidel 	{
103*48fbb544Smseidel 		OutputDebugStringFormat( "CPropertyHdl: QueryInterface (IID_IPropertyStore)\n" );
104*48fbb544Smseidel 		IUnknown* pUnk = static_cast<IPropertyStore*>(this);
105*48fbb544Smseidel 		pUnk->AddRef();
106*48fbb544Smseidel 		*ppvObject = pUnk;
107*48fbb544Smseidel 		return S_OK;
108*48fbb544Smseidel 	}
109*48fbb544Smseidel 	else if (IID_IPropertyStoreCapabilities == riid)
110*48fbb544Smseidel 	{
111*48fbb544Smseidel 		OutputDebugStringFormat( "CPropertyHdl: QueryInterface (IID_IPropertyStoreCapabilities)\n" );
112*48fbb544Smseidel 		IUnknown* pUnk = static_cast<IPropertyStore*>(this);
113*48fbb544Smseidel 		pUnk->AddRef();
114*48fbb544Smseidel 		*ppvObject = pUnk;
115*48fbb544Smseidel 		return S_OK;
116*48fbb544Smseidel 	}
117*48fbb544Smseidel 	else if (IID_IInitializeWithStream == riid)
118*48fbb544Smseidel 	{
119*48fbb544Smseidel 		OutputDebugStringFormat( "CPropertyHdl: QueryInterface (IID_IInitializeWithStream)\n" );
120*48fbb544Smseidel 		IUnknown* pUnk = static_cast<IInitializeWithStream*>(this);
121*48fbb544Smseidel 		pUnk->AddRef();
122*48fbb544Smseidel 		*ppvObject = pUnk;
123*48fbb544Smseidel 		return S_OK;
124*48fbb544Smseidel 	}
125*48fbb544Smseidel 	OutputDebugStringFormat( "CPropertyHdl: QueryInterface (something different)\n" );
126*48fbb544Smseidel 
127*48fbb544Smseidel 	return E_NOINTERFACE;
128cdf0e10cSrcweir }
129cdf0e10cSrcweir 
130cdf0e10cSrcweir //----------------------------
AddRef(void)131cdf0e10cSrcweir ULONG STDMETHODCALLTYPE CPropertyHdl::AddRef( void )
132cdf0e10cSrcweir {
133cdf0e10cSrcweir 	return InterlockedIncrement( &m_RefCnt );
134cdf0e10cSrcweir }
135cdf0e10cSrcweir 
136cdf0e10cSrcweir //----------------------------
Release(void)137cdf0e10cSrcweir ULONG STDMETHODCALLTYPE CPropertyHdl::Release( void )
138cdf0e10cSrcweir {
139cdf0e10cSrcweir 	long refcnt = InterlockedDecrement( &m_RefCnt );
140cdf0e10cSrcweir 
141cdf0e10cSrcweir 	if ( 0 == m_RefCnt )
142cdf0e10cSrcweir 		delete this;
143cdf0e10cSrcweir 
144cdf0e10cSrcweir 	return refcnt;
145cdf0e10cSrcweir }
146cdf0e10cSrcweir 
147cdf0e10cSrcweir //-----------------------------
148cdf0e10cSrcweir // IPropertyStore
149cdf0e10cSrcweir //-----------------------------
GetCount(DWORD * pcProps)150cdf0e10cSrcweir HRESULT STDMETHODCALLTYPE CPropertyHdl::GetCount( DWORD *pcProps )
151cdf0e10cSrcweir {
152*48fbb544Smseidel 	HRESULT hr = E_UNEXPECTED;
153*48fbb544Smseidel 	if ( m_pCache && pcProps )
154*48fbb544Smseidel 	{
155*48fbb544Smseidel 		hr = m_pCache->GetCount( pcProps );
156*48fbb544Smseidel 	}
157cdf0e10cSrcweir 
158*48fbb544Smseidel 	return hr;
159cdf0e10cSrcweir }
160cdf0e10cSrcweir 
161cdf0e10cSrcweir //-----------------------------
GetAt(DWORD iProp,PROPERTYKEY * pKey)162cdf0e10cSrcweir HRESULT STDMETHODCALLTYPE CPropertyHdl::GetAt( DWORD iProp, PROPERTYKEY *pKey )
163cdf0e10cSrcweir {
164*48fbb544Smseidel 	HRESULT hr = E_UNEXPECTED;
165*48fbb544Smseidel 	if ( m_pCache )
166*48fbb544Smseidel 	{
167*48fbb544Smseidel 		hr = m_pCache->GetAt( iProp, pKey );
168*48fbb544Smseidel 	}
169cdf0e10cSrcweir 
170*48fbb544Smseidel 	return hr;
171cdf0e10cSrcweir }
172cdf0e10cSrcweir 
173cdf0e10cSrcweir //-----------------------------
GetValue(REFPROPERTYKEY key,PROPVARIANT * pPropVar)174cdf0e10cSrcweir HRESULT STDMETHODCALLTYPE CPropertyHdl::GetValue( REFPROPERTYKEY key, PROPVARIANT *pPropVar )
175cdf0e10cSrcweir {
176*48fbb544Smseidel 	HRESULT hr = E_UNEXPECTED;
177*48fbb544Smseidel 	if ( m_pCache )
178*48fbb544Smseidel 	{
179*48fbb544Smseidel 		hr = m_pCache->GetValue( key, pPropVar );
180*48fbb544Smseidel 	}
181cdf0e10cSrcweir 
182*48fbb544Smseidel 	return hr;
183cdf0e10cSrcweir }
184cdf0e10cSrcweir 
185cdf0e10cSrcweir //-----------------------------
SetValue(REFPROPERTYKEY key,REFPROPVARIANT propVar)186cdf0e10cSrcweir HRESULT STDMETHODCALLTYPE CPropertyHdl::SetValue( REFPROPERTYKEY key, REFPROPVARIANT propVar )
187cdf0e10cSrcweir {
188*48fbb544Smseidel 	HRESULT hr = E_UNEXPECTED;
189*48fbb544Smseidel 	if ( m_pCache )
190*48fbb544Smseidel 	{
191*48fbb544Smseidel 		hr = STG_E_ACCESSDENIED;
192*48fbb544Smseidel 	}
193*48fbb544Smseidel 	return hr;
194cdf0e10cSrcweir }
195cdf0e10cSrcweir 
196cdf0e10cSrcweir //-----------------------------
Commit()197cdf0e10cSrcweir HRESULT STDMETHODCALLTYPE CPropertyHdl::Commit()
198cdf0e10cSrcweir {
199*48fbb544Smseidel 	return S_OK;
200cdf0e10cSrcweir }
201cdf0e10cSrcweir 
202cdf0e10cSrcweir //-----------------------------
203cdf0e10cSrcweir // IPropertyStore
204cdf0e10cSrcweir //-----------------------------
IsPropertyWritable(REFPROPERTYKEY key)205cdf0e10cSrcweir HRESULT STDMETHODCALLTYPE CPropertyHdl::IsPropertyWritable( REFPROPERTYKEY key )
206cdf0e10cSrcweir {
207*48fbb544Smseidel 	// We start with read only properties only
208*48fbb544Smseidel 	return S_FALSE;
209cdf0e10cSrcweir }
210cdf0e10cSrcweir 
211cdf0e10cSrcweir //-----------------------------
212cdf0e10cSrcweir // IInitializeWithStream
213cdf0e10cSrcweir //-----------------------------
Initialize(IStream * pStream,DWORD grfMode)214cdf0e10cSrcweir HRESULT STDMETHODCALLTYPE CPropertyHdl::Initialize( IStream *pStream, DWORD grfMode )
215cdf0e10cSrcweir {
216*48fbb544Smseidel 	if ( grfMode & STGM_READWRITE )
217*48fbb544Smseidel 		return STG_E_ACCESSDENIED;
218cdf0e10cSrcweir 
219*48fbb544Smseidel 	if ( !m_pCache )
220*48fbb544Smseidel 	{
221cdf0e10cSrcweir #ifdef __MINGW32__
222*48fbb544Smseidel 		if ( FAILED( PSCreateMemoryPropertyStore( IID_IPropertyStoreCache, reinterpret_cast<void**>(&m_pCache) ) ) )
223cdf0e10cSrcweir #else
224*48fbb544Smseidel 		if ( FAILED( PSCreateMemoryPropertyStore( IID_PPV_ARGS( &m_pCache ) ) ) )
225cdf0e10cSrcweir #endif
226*48fbb544Smseidel 			OutputDebugStringFormat( "CPropertyHdl::Initialize: PSCreateMemoryPropertyStore failed" );
227*48fbb544Smseidel 
228*48fbb544Smseidel 		zlib_filefunc_def z_filefunc;
229*48fbb544Smseidel 		pStream = PrepareIStream( pStream, z_filefunc );
230*48fbb544Smseidel 
231*48fbb544Smseidel 		CMetaInfoReader *pMetaInfoReader = NULL;
232*48fbb544Smseidel 
233*48fbb544Smseidel 		try
234*48fbb544Smseidel 		{
235*48fbb544Smseidel 			pMetaInfoReader = new CMetaInfoReader( (void*)pStream, &z_filefunc );
236*48fbb544Smseidel 			LoadProperties( pMetaInfoReader );
237*48fbb544Smseidel 			delete pMetaInfoReader;
238*48fbb544Smseidel 		}
239*48fbb544Smseidel 		catch (const std::exception& e)
240*48fbb544Smseidel 		{
241*48fbb544Smseidel 			OutputDebugStringFormat( "CPropertyHdl::Initialize: Caught exception [%s]", e.what() );
242*48fbb544Smseidel 			return E_FAIL;
243*48fbb544Smseidel 		}
244cdf0e10cSrcweir /*
245*48fbb544Smseidel 	// load extended properties and search content
246*48fbb544Smseidel 	_LoadExtendedProperties();
247*48fbb544Smseidel 	_LoadSearchContent();
248cdf0e10cSrcweir */
249*48fbb544Smseidel 	}
250cdf0e10cSrcweir 
251*48fbb544Smseidel 	return S_OK;
252cdf0e10cSrcweir }
253cdf0e10cSrcweir 
254cdf0e10cSrcweir //-----------------------------
LoadProperties(CMetaInfoReader * pMetaInfoReader)255cdf0e10cSrcweir void CPropertyHdl::LoadProperties( CMetaInfoReader *pMetaInfoReader )
256cdf0e10cSrcweir {
257*48fbb544Smseidel 	OutputDebugStringFormat( "CPropertyHdl: LoadProperties\n" );
258*48fbb544Smseidel 	PROPVARIANT propvarValues;
259*48fbb544Smseidel 
260*48fbb544Smseidel 	for ( UINT i = 0; i < (UINT)gPropertyMapTableSize; ++i )
261*48fbb544Smseidel 	{
262*48fbb544Smseidel 		PropVariantClear( &propvarValues );
263*48fbb544Smseidel 		HRESULT hr = GetItemData( pMetaInfoReader, i, &propvarValues);
264*48fbb544Smseidel 		if (hr == S_OK)
265*48fbb544Smseidel 		{
266*48fbb544Smseidel 			// coerce the value(s) to the appropriate type for the property key
267*48fbb544Smseidel 			hr = PSCoerceToCanonicalValue( g_rgPROPERTYMAP[i].key, &propvarValues );
268*48fbb544Smseidel 			if (SUCCEEDED(hr))
269*48fbb544Smseidel 			{
270*48fbb544Smseidel 				// cache the value(s) loaded
271*48fbb544Smseidel 				hr = m_pCache->SetValueAndState( g_rgPROPERTYMAP[i].key, &propvarValues, PSC_NORMAL );
272*48fbb544Smseidel 			}
273*48fbb544Smseidel 		}
274*48fbb544Smseidel 	}
275cdf0e10cSrcweir }
276cdf0e10cSrcweir 
277cdf0e10cSrcweir //-----------------------------
GetItemData(CMetaInfoReader * pMetaInfoReader,UINT nIndex,PROPVARIANT * pVarData)278cdf0e10cSrcweir HRESULT CPropertyHdl::GetItemData( CMetaInfoReader *pMetaInfoReader, UINT nIndex, PROPVARIANT *pVarData )
279cdf0e10cSrcweir {
280*48fbb544Smseidel 	switch (nIndex) {
281*48fbb544Smseidel 	case 0: {
282*48fbb544Smseidel 			pVarData->vt = VT_BSTR;
283*48fbb544Smseidel 			pVarData->bstrVal = SysAllocString( pMetaInfoReader->getTagData( META_INFO_TITLE ).c_str() );
284*48fbb544Smseidel 			OutputDebugStringFormat( "CPropertyHdl::GetItemData: Title=%S.\n", pMetaInfoReader->getTagData( META_INFO_TITLE ).c_str() );
285*48fbb544Smseidel 			return S_OK;
286*48fbb544Smseidel 	}
287*48fbb544Smseidel 	case 1: {
288*48fbb544Smseidel 			pVarData->vt = VT_BSTR;
289cdf0e10cSrcweir 			pVarData->bstrVal = SysAllocString( pMetaInfoReader->getTagData( META_INFO_AUTHOR ).c_str() );
290*48fbb544Smseidel 			OutputDebugStringFormat( "CPropertyHdl::GetItemData: Author=%S.\n", pMetaInfoReader->getTagData( META_INFO_AUTHOR ).c_str() );
291cdf0e10cSrcweir 			return S_OK;
292cdf0e10cSrcweir 	}
293*48fbb544Smseidel 	case 2: {
294*48fbb544Smseidel 			pVarData->vt = VT_BSTR;
295cdf0e10cSrcweir 			pVarData->bstrVal = SysAllocString( pMetaInfoReader->getTagData( META_INFO_SUBJECT ).c_str() );
296*48fbb544Smseidel 			OutputDebugStringFormat( "CPropertyHdl::GetItemData: Subject=%S.\n", pMetaInfoReader->getTagData( META_INFO_SUBJECT ).c_str() );
297cdf0e10cSrcweir 			return S_OK;
298cdf0e10cSrcweir 	}
299*48fbb544Smseidel 	case 3: {
300*48fbb544Smseidel 			pVarData->vt = VT_BSTR;
301*48fbb544Smseidel 			pVarData->bstrVal = SysAllocString( pMetaInfoReader->getTagData( META_INFO_KEYWORDS ).c_str() );
302*48fbb544Smseidel 			OutputDebugStringFormat( "CPropertyHdl::GetItemData: Keywords=%S.\n", pMetaInfoReader->getTagData( META_INFO_KEYWORDS ).c_str() );
303*48fbb544Smseidel 			return S_OK;
304*48fbb544Smseidel 	}
305*48fbb544Smseidel 	case 4: {
306*48fbb544Smseidel 			pVarData->vt = VT_BSTR;
307*48fbb544Smseidel 			pVarData->bstrVal = SysAllocString( pMetaInfoReader->getTagData( META_INFO_DESCRIPTION ).c_str() );
308*48fbb544Smseidel 			OutputDebugStringFormat( "CPropertyHdl::GetItemData: Description=%S.\n", pMetaInfoReader->getTagData( META_INFO_DESCRIPTION ).c_str() );
309*48fbb544Smseidel 			return S_OK;
310*48fbb544Smseidel 	}
311*48fbb544Smseidel 	case 5: {
312*48fbb544Smseidel 			pVarData->vt = VT_BSTR;
313*48fbb544Smseidel 			pVarData->bstrVal = SysAllocString( pMetaInfoReader->getTagAttribute( META_INFO_DOCUMENT_STATISTIC, META_INFO_PAGES ).c_str() );
314*48fbb544Smseidel 			OutputDebugStringFormat( "CPropertyHdl::GetItemData: Pages=%S.\n", pMetaInfoReader->getTagAttribute( META_INFO_DOCUMENT_STATISTIC, META_INFO_PAGES ).c_str() );
315*48fbb544Smseidel 			return S_OK;
316*48fbb544Smseidel 	}
317*48fbb544Smseidel 	}
318cdf0e10cSrcweir 
319cdf0e10cSrcweir 	return S_FALSE;
320cdf0e10cSrcweir }
321cdf0e10cSrcweir 
322cdf0e10cSrcweir //-----------------------------------------------------------------------------
323*48fbb544Smseidel // CClassFactory
324cdf0e10cSrcweir //-----------------------------------------------------------------------------
325cdf0e10cSrcweir 
326cdf0e10cSrcweir long CClassFactory::s_ServerLocks = 0;
327cdf0e10cSrcweir 
328cdf0e10cSrcweir //-----------------------------------------------------------------------------
CClassFactory(const CLSID & clsid)329cdf0e10cSrcweir CClassFactory::CClassFactory( const CLSID& clsid ) :
330*48fbb544Smseidel 	m_RefCnt(1),
331*48fbb544Smseidel 	m_Clsid(clsid)
332cdf0e10cSrcweir {
333*48fbb544Smseidel 	InterlockedIncrement( &g_DllRefCnt );
334cdf0e10cSrcweir }
335cdf0e10cSrcweir 
336cdf0e10cSrcweir //-----------------------------------------------------------------------------
~CClassFactory()337cdf0e10cSrcweir CClassFactory::~CClassFactory()
338cdf0e10cSrcweir {
339*48fbb544Smseidel 	InterlockedDecrement( &g_DllRefCnt );
340cdf0e10cSrcweir }
341cdf0e10cSrcweir 
342cdf0e10cSrcweir //-----------------------------------------------------------------------------
343*48fbb544Smseidel // IUnknown methods
344cdf0e10cSrcweir //-----------------------------------------------------------------------------
QueryInterface(REFIID riid,void __RPC_FAR * __RPC_FAR * ppvObject)345cdf0e10cSrcweir HRESULT STDMETHODCALLTYPE CClassFactory::QueryInterface( REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject )
346cdf0e10cSrcweir {
347*48fbb544Smseidel 	*ppvObject = 0;
348*48fbb544Smseidel 
349*48fbb544Smseidel 	if ( IID_IUnknown == riid || IID_IClassFactory == riid )
350*48fbb544Smseidel 	{
351*48fbb544Smseidel 		IUnknown* pUnk = this;
352*48fbb544Smseidel 		pUnk->AddRef();
353*48fbb544Smseidel 		*ppvObject = pUnk;
354*48fbb544Smseidel 		return S_OK;
355*48fbb544Smseidel 	}
356cdf0e10cSrcweir 
357*48fbb544Smseidel 	return E_NOINTERFACE;
358cdf0e10cSrcweir }
359cdf0e10cSrcweir 
360cdf0e10cSrcweir //-----------------------------------------------------------------------------
AddRef(void)361cdf0e10cSrcweir ULONG STDMETHODCALLTYPE CClassFactory::AddRef( void )
362cdf0e10cSrcweir {
363*48fbb544Smseidel 	return InterlockedIncrement( &m_RefCnt );
364cdf0e10cSrcweir }
365cdf0e10cSrcweir 
366cdf0e10cSrcweir //-----------------------------------------------------------------------------
Release(void)367cdf0e10cSrcweir ULONG STDMETHODCALLTYPE CClassFactory::Release( void )
368cdf0e10cSrcweir {
369*48fbb544Smseidel 	long refcnt = InterlockedDecrement( &m_RefCnt );
370cdf0e10cSrcweir 
371*48fbb544Smseidel 	if (0 == refcnt)
372*48fbb544Smseidel 		delete this;
373cdf0e10cSrcweir 
374*48fbb544Smseidel 	return refcnt;
375cdf0e10cSrcweir }
376cdf0e10cSrcweir 
377cdf0e10cSrcweir //-----------------------------------------------------------------------------
378*48fbb544Smseidel // IClassFactory methods
379cdf0e10cSrcweir //-----------------------------------------------------------------------------
CreateInstance(IUnknown __RPC_FAR * pUnkOuter,REFIID riid,void __RPC_FAR * __RPC_FAR * ppvObject)380cdf0e10cSrcweir HRESULT STDMETHODCALLTYPE CClassFactory::CreateInstance(
381*48fbb544Smseidel 			IUnknown __RPC_FAR *pUnkOuter,
382*48fbb544Smseidel 			REFIID riid,
383*48fbb544Smseidel 			void __RPC_FAR *__RPC_FAR *ppvObject)
384cdf0e10cSrcweir {
385*48fbb544Smseidel 	if ( pUnkOuter != NULL )
386*48fbb544Smseidel 		return CLASS_E_NOAGGREGATION;
387cdf0e10cSrcweir 
388*48fbb544Smseidel 	IUnknown* pUnk = 0;
389cdf0e10cSrcweir 
390*48fbb544Smseidel 	if ( CLSID_PROPERTY_HANDLER == m_Clsid )
391*48fbb544Smseidel 		pUnk = static_cast<IPropertyStore*>( new CPropertyHdl() );
392cdf0e10cSrcweir 
393*48fbb544Smseidel 	POST_CONDITION(pUnk != 0, "Could not create COM object");
394cdf0e10cSrcweir 
395*48fbb544Smseidel 	if (0 == pUnk)
396*48fbb544Smseidel 		return E_OUTOFMEMORY;
397cdf0e10cSrcweir 
398*48fbb544Smseidel 	HRESULT hr = pUnk->QueryInterface( riid, ppvObject );
399cdf0e10cSrcweir 
400*48fbb544Smseidel 	// if QueryInterface failed the component will destroy itself
401*48fbb544Smseidel 	pUnk->Release();
402cdf0e10cSrcweir 
403*48fbb544Smseidel 	return hr;
404cdf0e10cSrcweir }
405cdf0e10cSrcweir 
406cdf0e10cSrcweir //-----------------------------------------------------------------------------
LockServer(BOOL fLock)407cdf0e10cSrcweir HRESULT STDMETHODCALLTYPE CClassFactory::LockServer( BOOL fLock )
408cdf0e10cSrcweir {
409*48fbb544Smseidel 	if ( fLock )
410*48fbb544Smseidel 		InterlockedIncrement( &s_ServerLocks );
411*48fbb544Smseidel 	else
412*48fbb544Smseidel 		InterlockedDecrement( &s_ServerLocks );
413cdf0e10cSrcweir 
414*48fbb544Smseidel 	return S_OK;
415cdf0e10cSrcweir }
416cdf0e10cSrcweir 
417cdf0e10cSrcweir //-----------------------------------------------------------------------------
IsLocked()418cdf0e10cSrcweir bool CClassFactory::IsLocked()
419cdf0e10cSrcweir {
420*48fbb544Smseidel 	return ( s_ServerLocks > 0 );
421cdf0e10cSrcweir }
422cdf0e10cSrcweir 
423cdf0e10cSrcweir //-----------------------------------------------------------------------------
DllGetClassObject(REFCLSID rclsid,REFIID riid,void ** ppv)424cdf0e10cSrcweir extern "C" STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void** ppv)
425cdf0e10cSrcweir {
426*48fbb544Smseidel 	OutputDebugStringFormat( "DllGetClassObject.\n" );
427*48fbb544Smseidel 	*ppv = 0;
428cdf0e10cSrcweir 
429*48fbb544Smseidel 	if ( rclsid != CLSID_PROPERTY_HANDLER )
430*48fbb544Smseidel 		return CLASS_E_CLASSNOTAVAILABLE;
431cdf0e10cSrcweir 
432*48fbb544Smseidel 	if ( (riid != IID_IUnknown) && (riid != IID_IClassFactory) )
433*48fbb544Smseidel 		return E_NOINTERFACE;
434cdf0e10cSrcweir 
435cdf0e10cSrcweir 	IUnknown* pUnk = new CClassFactory( rclsid );
436cdf0e10cSrcweir 	if ( 0 == pUnk )
437cdf0e10cSrcweir 		return E_OUTOFMEMORY;
438cdf0e10cSrcweir 
439cdf0e10cSrcweir 	*ppv = pUnk;
440cdf0e10cSrcweir 	return S_OK;
441cdf0e10cSrcweir }
442cdf0e10cSrcweir 
443cdf0e10cSrcweir //-----------------------------------------------------------------------------
DllCanUnloadNow(void)444cdf0e10cSrcweir extern "C" STDAPI DllCanUnloadNow( void )
445cdf0e10cSrcweir {
446*48fbb544Smseidel 	OutputDebugStringFormat( "DllCanUnloadNow.\n" );
447*48fbb544Smseidel 	if (CClassFactory::IsLocked() || g_DllRefCnt > 0)
448*48fbb544Smseidel 		return S_FALSE;
449cdf0e10cSrcweir 
450*48fbb544Smseidel 	return S_OK;
451cdf0e10cSrcweir }
452cdf0e10cSrcweir 
453cdf0e10cSrcweir //-----------------------------------------------------------------------------
DllMain(HINSTANCE hInst,ULONG,LPVOID)454cdf0e10cSrcweir BOOL WINAPI DllMain( HINSTANCE hInst, ULONG /*ul_reason_for_call*/, LPVOID /*lpReserved*/ )
455cdf0e10cSrcweir {
456*48fbb544Smseidel 	OutputDebugStringFormat( "DllMain.\n" );
457*48fbb544Smseidel 	g_hModule = hInst;
458*48fbb544Smseidel 	return TRUE;
459cdf0e10cSrcweir }
460*48fbb544Smseidel 
461*48fbb544Smseidel /* vim: set noet sw=4 ts=4: */
462