#include "StdAfx.h"
#include "COM.h"

// Constructor - set reference count to zero
CDaveClassFactory::CDaveClassFactory() {m_lRefCount=0;};

// IUnknown Interface
//
// QueryInterface

STDMETHODIMP CDaveClassFactory::QueryInterface(REFIID riid, void** ppv) {
    // Get the correct interface pointer
    if (riid == IID_IUnknown) *ppv = static_cast<IUnknown*>(this);
    else if (riid == IID_IClassFactory) *ppv = static_cast<IClassFactory*>(this);
    else {
        *ppv = NULL;
        return E_NOINTERFACE;
    }
    // Successfully got interface pointer, so increase reference count
    static_cast<IUnknown*>(*ppv)->AddRef(); // Why not just this.addref()?
    return S_OK;
};

// AddRef & Release
STDMETHODIMP_(ULONG) CDaveClassFactory::AddRef() {return InterlockedIncrement(&m_lRefCount);};
STDMETHODIMP_(ULONG) CDaveClassFactory::Release() {return InterlockedDecrement(&m_lRefCount);};

// IClassFactory
//
// CreateInstance
STDMETHODIMP CDaveClassFactory::CreateInstance(IUnknown* punkOuter, REFIID riid, void**ppvObject) {
    HRESULT hr;
    CDaveComponent *pObject;

    *ppvObject = NULL;

    // "We don't support no stinking aggregation..."
    if (punkOuter) return CLASS_E_NOAGGREGATION;

    // Create a new DJB object
    pObject = new CDaveComponent;
    if (!pObject) return E_OUTOFMEMORY;

    // Get a point to IUnknown for the new object
    hr = pObject->QueryInterface(riid, ppvObject);
    if (FAILED(hr)) delete pObject;
    return hr;
}

// LockServer
STDMETHODIMP CDaveClassFactory::LockServer(BOOL fLock) {
    CommonCount(fLock);
    return S_OK;
}