www.pudn.com > clamwin-0.85.1-src.zip > ShellExt.cpp


//----------------------------------------------------------------------------- 
// Name:        ShellExt.cpp 
// Product:     ClamWin Antivirus 
// 
// Author:      alch [alch at users dot sourceforge dot net] 
// 
// Created:     2004/19/03 
// Copyright:   Copyright alch (c) 2004 
// Licence:      
//   This program is free software; you can redistribute it and/or modify 
//   it under the terms of the GNU General Public License as published by 
//   the Free Software Foundation; either version 2 of the License, or 
//   (at your option) any later version. 
//  
//   This program is distributed in the hope that it will be useful, 
//   but WITHOUT ANY WARRANTY; without even the implied warranty of 
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
//   GNU General Public License for more details. 
//  
//   You should have received a copy of the GNU General Public License 
//   along with this program; if not, write to the Free Software 
//   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 
//----------------------------------------------------------------------------- 
  
// 
// Initialize GUIDs (should be done only and at-least once per DLL/EXE) 
// 
#include  
#include  
#define INITGUID 
#include  
#include  
#include "ShellExt.h" 
 
 
// 
// Global variables 
// 
UINT      g_cRefThisDll = 0;    // Reference count of this DLL. 
HINSTANCE g_hmodThisDll = NULL; // Handle to this DLL itself. 
 
extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) 
{ 
	if (dwReason == DLL_PROCESS_ATTACH) 
		g_hmodThisDll = hInstance; 
	 
	return 1;   // ok 
} 
 
//--------------------------------------------------------------------------- 
// DllCanUnloadNow 
//--------------------------------------------------------------------------- 
STDAPI  DllCanUnloadNow(void) 
{ 
	return (g_cRefThisDll == 0 ? S_OK : S_FALSE); 
} 
 
//--------------------------------------------------------------------------- 
// DllGetClassObject 
//--------------------------------------------------------------------------- 
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvOut) 
{ 
	*ppvOut = NULL; 
	 
	if (IsEqualIID(rclsid, CLSID_ShellExtension)) 
	{ 
		CShellExtClassFactory *pcf = new CShellExtClassFactory; 
		 
		return pcf->QueryInterface(riid, ppvOut); 
	} 
	 
	return CLASS_E_CLASSNOTAVAILABLE; 
} 
 
//--------------------------------------------------------------------------- 
// CShellExtClassFactory::CShellExtClassFactory 
//--------------------------------------------------------------------------- 
 
CShellExtClassFactory::CShellExtClassFactory() 
{ 
	m_cRef = 0L; 
	 
	g_cRefThisDll++;     
} 
 
//--------------------------------------------------------------------------- 
// CShellExtClassFactory::~CShellExtClassFactory 
//--------------------------------------------------------------------------- 
 
CShellExtClassFactory::~CShellExtClassFactory()                          
{ 
	g_cRefThisDll--; 
} 
 
//--------------------------------------------------------------------------- 
// CShellExtClassFactory::QueryInterface 
//--------------------------------------------------------------------------- 
 
STDMETHODIMP CShellExtClassFactory::QueryInterface(REFIID riid, 
                                                   LPVOID FAR *ppv) 
{ 
	*ppv = NULL; 
	 
	// Any interface on this object is the object pointer 
	 
	if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory)) 
	{ 
		*ppv = (LPCLASSFACTORY)this; 
		 
		AddRef(); 
		 
		return NOERROR; 
	} 
	 
	return E_NOINTERFACE; 
}        
 
//--------------------------------------------------------------------------- 
// CShellExtClassFactory::AddRef 
//--------------------------------------------------------------------------- 
 
STDMETHODIMP_(ULONG) CShellExtClassFactory::AddRef() 
{ 
	return ++m_cRef; 
} 
 
//--------------------------------------------------------------------------- 
// CShellExtClassFactory::Release 
//--------------------------------------------------------------------------- 
 
STDMETHODIMP_(ULONG) CShellExtClassFactory::Release() 
{ 
	if (--m_cRef) 
		return m_cRef; 
	 
	delete this; 
	 
	return 0L; 
} 
 
//--------------------------------------------------------------------------- 
// CShellExtClassFactory::CreateInstance 
//--------------------------------------------------------------------------- 
 
STDMETHODIMP CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, 
																	REFIID riid, 
																	LPVOID *ppvObj) 
{ 
	*ppvObj = NULL; 
	 
	// Shell extensions typically don't support aggregation (inheritance) 
	 
	if (pUnkOuter) 
		return CLASS_E_NOAGGREGATION; 
	 
	// Create the main shell extension object.  The shell will then call 
	// QueryInterface with IID_IShellExtInit--this is how shell extensions are 
	// initialized. 
	 
	LPCSHELLEXT pShellExt = new CShellExt();  //Create the CShellExt object 
	 
	if (NULL == pShellExt) 
		return E_OUTOFMEMORY; 
	 
	return pShellExt->QueryInterface(riid, ppvObj); 
} 
 
//--------------------------------------------------------------------------- 
// CShellExtClassFactory::LockServer 
//--------------------------------------------------------------------------- 
 
STDMETHODIMP CShellExtClassFactory::LockServer(BOOL fLock) 
{ 
	return NOERROR; 
} 
 
// *********************** CShellExt ************************* 
 
//--------------------------------------------------------------------------- 
// CShellExt::CShellExt 
//--------------------------------------------------------------------------- 
 
CShellExt::CShellExt() 
{ 
	m_cRef = 0L; 
	m_pDataObj = NULL; 
	m_szPath = NULL; 
	 
	g_cRefThisDll++; 
} 
 
//--------------------------------------------------------------------------- 
// CShellExt::~CShellExt 
//--------------------------------------------------------------------------- 
 
CShellExt::~CShellExt() 
{ 
    if (m_szPath) 
        delete [] m_szPath; 
	if (m_pDataObj) 
		m_pDataObj->Release(); 
	 
	g_cRefThisDll--; 
} 
 
//--------------------------------------------------------------------------- 
// CShellExt::QueryInterface 
//--------------------------------------------------------------------------- 
 
STDMETHODIMP CShellExt::QueryInterface(REFIID riid, LPVOID FAR *ppv) 
{ 
	*ppv = NULL; 
	 
	if (IsEqualIID(riid, IID_IShellExtInit) || IsEqualIID(riid, IID_IUnknown)) 
		*ppv = (LPSHELLEXTINIT)this; 
	else if (IsEqualIID(riid, IID_IContextMenu)) 
		*ppv = (LPCONTEXTMENU)this; 
	if (*ppv) 
	{ 
		AddRef(); 
		return NOERROR; 
	} 
	return E_NOINTERFACE; 
} 
 
//--------------------------------------------------------------------------- 
// CShellExt::AddRef 
//--------------------------------------------------------------------------- 
 
STDMETHODIMP_(ULONG) CShellExt::AddRef() 
{ 
	return ++m_cRef; 
} 
 
//--------------------------------------------------------------------------- 
// CShellExt::Release 
//--------------------------------------------------------------------------- 
 
STDMETHODIMP_(ULONG) CShellExt::Release() 
{ 
	if (--m_cRef) 
		return m_cRef; 
	 
	delete this; 
	 
	return 0L; 
}