
#include "stdafx.h"
#include "ShellExt.h"

CShellExtClassFactory::CShellExtClassFactory()
{
	m_cRef = 0L;

    g_nRefThisDll++;	
}
																
CShellExtClassFactory::~CShellExtClassFactory()				
{
    g_nRefThisDll--;
}

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;
}	

STDMETHODIMP_(ULONG) CShellExtClassFactory::AddRef()
{
    return ++m_cRef;
}

STDMETHODIMP_(ULONG) CShellExtClassFactory::Release()
{
    if (--m_cRef)
        return m_cRef;

    delete this;

    return 0L;
}

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);
}


STDMETHODIMP CShellExtClassFactory::LockServer(BOOL fLock)
{
    return NOERROR;
}

// *********************** CShellExt *************************
CShellExt::CShellExt()
{
	ODSTR("CShellExt::CShellExt()\n");
    m_cRef = 0L;
    m_pDataObj = NULL;

    g_nRefThisDll++;
	m_nFileCount = 0;
	m_pFileNames = NULL;
}

CShellExt::~CShellExt()
{
	ODSTR("CShellExt::~CShellExt()\n");
    if (m_pDataObj)
        m_pDataObj->Release();

	g_nRefThisDll--;

	FreeVars();
}

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;
    }
    else if (IsEqualIID(riid, IID_IExtractIcon))
    {
        *ppv = (LPEXTRACTICON)this;
    }
    else if (IsEqualIID(riid, IID_IPersistFile))
    {
        *ppv = (LPPERSISTFILE)this;
    }
    else if (IsEqualIID(riid, IID_IShellPropSheetExt))
    {
        *ppv = (LPSHELLPROPSHEETEXT)this;
    }
    else if (IsEqualIID(riid, IID_IShellCopyHook))
    {
        *ppv = (LPCOPYHOOK)this;
    }

    if (*ppv)
    {
        AddRef();

        return NOERROR;
    }

	return E_NOINTERFACE;
}

STDMETHODIMP_(ULONG) CShellExt::AddRef()
{
    return ++m_cRef;
}

STDMETHODIMP_(ULONG) CShellExt::Release()
{
    if (--m_cRef)
        return m_cRef;

    delete this;

    return 0L;
}

BOOL CShellExt::CheckFileExt(LPCTSTR pStr,LPCTSTR lpExt)
{
	char* p=strrchr(pStr,'.');
	if(p)
	{
		p++;
		if(stricmp(p,lpExt)==0)
			return TRUE;
	}
	return FALSE;
}

void CShellExt::FreeVars()
{
	if(m_pFileNames)
	{
		for(int i=0;i<m_nFileCount;i++)
		{
			if(m_pFileNames[i])
			{
				delete[] m_pFileNames[i];
			}
		}	
		m_nFileCount = 0;
		delete[] m_pFileNames;
		m_pFileNames = NULL;
	}
}
