Windows2000/private/windows/shell/shole/sccls.c
2020-09-30 17:12:32 +02:00

121 lines
2.4 KiB
C

#include "shole.h"
#include "ids.h"
#include "scguid.h"
UINT g_cRefThisDll = 0; // per-instance
class CMyClassFactory : public IClassFactory
{
public:
CMyClassFactory(REFCLSID rclsid);
~CMyClassFactory() { g_cRefThisDll--; }
// IUnKnown
virtual HRESULT __stdcall QueryInterface(REFIID,void **);
virtual ULONG __stdcall AddRef(void);
virtual ULONG __stdcall Release(void);
// IClassFactory
virtual HRESULT __stdcall CreateInstance(
IUnknown *pUnkOuter, REFIID riid, void **ppvObject);
virtual HRESULT __stdcall LockServer(BOOL fLock);
protected:
UINT _cRef;
CLSID _clsid;
};
CMyClassFactory::CMyClassFactory(REFCLSID rclsid) : _cRef(1), _clsid(rclsid)
{
g_cRefThisDll++;
}
HRESULT CMyClassFactory::QueryInterface(REFIID riid, void **ppvObject)
{
HRESULT hres;
if (IsEqualGUID(riid, IID_IClassFactory) || IsEqualGUID(riid, IID_IUnknown)) {
_cRef++;
*ppvObject = (LPCLASSFACTORY)this;
hres = NOERROR;
}
else
{
*ppvObject = NULL;
hres = ResultFromScode(E_NOINTERFACE);
}
return hres;
}
ULONG CMyClassFactory::AddRef(void)
{
return ++_cRef;
}
ULONG CMyClassFactory::Release(void)
{
if (--_cRef>0) {
return _cRef;
}
delete this;
return 0;
}
HRESULT CMyClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject)
{
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;
LPUNKNOWN punk;
HRESULT hres;
if (IsEqualGUID(_clsid, CLSID_CScrapData))
{
hres = CScrapData_CreateInstance(&punk);
}
else
{
return E_UNEXPECTED;
}
if (SUCCEEDED(hres))
{
hres = punk->QueryInterface(riid, ppvObject);
punk->Release();
}
return hres;
}
HRESULT CMyClassFactory::LockServer(BOOL fLock)
{
return S_OK;
}
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID * ppvOut)
{
if (IsEqualGUID(rclsid,CLSID_CScrapData))
{
CMyClassFactory *pmycls = new CMyClassFactory(rclsid);
if (pmycls)
{
HRESULT hres = pmycls->QueryInterface(riid, ppvOut);
pmycls->Release();
return hres;
}
return E_OUTOFMEMORY;
}
return CLASS_E_CLASSNOTAVAILABLE;
}
STDAPI DllCanUnloadNow(void)
{
if (g_cRefThisDll)
{
return S_FALSE;
}
DebugMsg(DM_TRACE, TEXT("sc TR - DllCanUnloadNow returning S_OK (bye, bye...)"));
return S_OK;
}