You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
229 lines
5.7 KiB
229 lines
5.7 KiB
|
|
#include <windows.h>
|
|
#include <olectl.h>
|
|
#include <advpub.h> // REGINSTALL
|
|
|
|
#include "volclean.h"
|
|
|
|
/*
|
|
**------------------------------------------------------------------------------
|
|
** Global variables
|
|
**------------------------------------------------------------------------------
|
|
*/
|
|
extern "C" {
|
|
LONG g_cRefCount = 0;
|
|
}
|
|
|
|
typedef HRESULT (WINAPI *PFNCREATEINSTANCE)(REFIID, void **);
|
|
|
|
/*
|
|
**------------------------------------------------------------------------------
|
|
** DllCanUnloadNow
|
|
**
|
|
** Purpose: Answers if the DLL can be free, that is, if there are no
|
|
** references to anything this DLL provides.
|
|
** Return: TRUE, if OK to unload (i.e. nobody is using us or has us locked)
|
|
** FALSE, otherwise
|
|
** Notes;
|
|
**------------------------------------------------------------------------------
|
|
*/
|
|
STDAPI DllCanUnloadNow(void)
|
|
{
|
|
//
|
|
// Are there any outstanding references?
|
|
//
|
|
return (g_cRefCount == 0 ? S_OK : S_FALSE);
|
|
}
|
|
|
|
|
|
STDAPI_(void) DllAddRef(void)
|
|
{
|
|
InterlockedIncrement(&g_cRefCount);
|
|
}
|
|
|
|
|
|
STDAPI_(void) DllRelease(void)
|
|
{
|
|
InterlockedDecrement(&g_cRefCount);
|
|
}
|
|
|
|
|
|
class CWebDavCleanerClassFactory : IClassFactory
|
|
{
|
|
LONG m_cRef;
|
|
PFNCREATEINSTANCE m_pfnCreateInstance;
|
|
|
|
public:
|
|
CWebDavCleanerClassFactory(PFNCREATEINSTANCE pfnCreate)
|
|
: m_cRef(1),
|
|
m_pfnCreateInstance(pfnCreate)
|
|
{
|
|
Trace(L"CWebDavCleanerClassFactory::CWebDavCleanerClassFactory");
|
|
DllAddRef();
|
|
}
|
|
|
|
~CWebDavCleanerClassFactory()
|
|
{
|
|
Trace(L"CWebDavCleanerClassFactory::~CWebDavCleanerClassFactory");
|
|
DllRelease();
|
|
}
|
|
|
|
// IUnknown methods
|
|
STDMETHODIMP QueryInterface(REFIID, LPVOID FAR *);
|
|
STDMETHODIMP_(ULONG) AddRef();
|
|
STDMETHODIMP_(ULONG) Release();
|
|
|
|
// IClassFactory methods
|
|
STDMETHODIMP CreateInstance(LPUNKNOWN, REFIID, LPVOID FAR *);
|
|
STDMETHODIMP LockServer(BOOL);
|
|
};
|
|
|
|
|
|
/*
|
|
**------------------------------------------------------------------------------
|
|
** DllGetClassObject
|
|
**
|
|
** Purpose: Provides an IClassFactory for a given CLSID that this DLL is
|
|
** registered to support. This DLL is placed under the CLSID
|
|
** in the registration database as the InProcServer.
|
|
** Parameters:
|
|
** clsID - REFCLSID that identifies the class factory desired.
|
|
** Since this parameter is passed this DLL can handle
|
|
** any number of objects simply by returning different
|
|
** different class factories here for different CLSIDs.
|
|
** riid - REFIID specifying the interface the caller wants
|
|
** on the class object, usually IID_ClassFactory.
|
|
** ppvOut - pointer in which to return the interface pointer.
|
|
** Return: NOERROR on success, otherwise an error code
|
|
** Notes;
|
|
**------------------------------------------------------------------------------
|
|
*/
|
|
STDAPI DllGetClassObject(
|
|
IN REFCLSID rclsid,
|
|
IN REFIID riid,
|
|
OUT void **ppv
|
|
)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
PFNCREATEINSTANCE pfnCreateInstance = NULL;
|
|
Trace(L"DllGetClassObject");
|
|
|
|
*ppv = NULL;
|
|
|
|
//
|
|
// Is the request for our cleaner object?
|
|
//
|
|
if (IsEqualCLSID(rclsid, CLSID_WebDavVolumeCleaner)) {
|
|
pfnCreateInstance = CWebDavCleaner::CreateInstance;
|
|
}
|
|
else {
|
|
//
|
|
// Error - we don't know about this object
|
|
//
|
|
return CLASS_E_CLASSNOTAVAILABLE;
|
|
}
|
|
|
|
//
|
|
// Get our IClassFactory for making CWebDavCleaner objects
|
|
//
|
|
CWebDavCleanerClassFactory *pClassFactory = new CWebDavCleanerClassFactory(pfnCreateInstance);
|
|
if (pClassFactory) {
|
|
//
|
|
// Make sure the new class factory likes the requested interface
|
|
//
|
|
hr = pClassFactory->QueryInterface(riid, ppv);
|
|
if (FAILED(hr)) {
|
|
//
|
|
// Error - interface rejected
|
|
//
|
|
delete pClassFactory;
|
|
}
|
|
else {
|
|
//
|
|
// Release initial ref
|
|
//
|
|
pClassFactory->Release();
|
|
}
|
|
}
|
|
else {
|
|
//
|
|
// Error - couldn't make factory object
|
|
//
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
STDMETHODIMP
|
|
CWebDavCleanerClassFactory::QueryInterface(REFIID riid, void **ppv)
|
|
{
|
|
Trace(L"CWebDavCleanerClassFactory::QueryInterface");
|
|
if (!ppv) {
|
|
return E_POINTER;
|
|
}
|
|
|
|
if (riid == IID_IClassFactory) {
|
|
*ppv = static_cast<IClassFactory*>(this);
|
|
}
|
|
else {
|
|
*ppv = NULL;
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
STDMETHODIMP_(ULONG)
|
|
CWebDavCleanerClassFactory::AddRef()
|
|
{
|
|
Trace(L"CWebDavCleanerClassFactory::AddRef");
|
|
return InterlockedIncrement(&m_cRef);
|
|
}
|
|
|
|
|
|
STDMETHODIMP_(ULONG)
|
|
CWebDavCleanerClassFactory::Release()
|
|
{
|
|
Trace(L"CWebDavCleanerClassFactory::Release");
|
|
if (InterlockedDecrement(&m_cRef))
|
|
return m_cRef;
|
|
|
|
delete this;
|
|
return 0;
|
|
}
|
|
|
|
|
|
STDMETHODIMP
|
|
CWebDavCleanerClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv)
|
|
{
|
|
HRESULT hr = E_UNEXPECTED;
|
|
Trace(L"CWebDavCleanerClassFactory::CreateInstance");
|
|
|
|
*ppv = NULL;
|
|
|
|
if (pUnkOuter)
|
|
return CLASS_E_NOAGGREGATION;
|
|
|
|
if (m_pfnCreateInstance)
|
|
hr = m_pfnCreateInstance(riid, ppv);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
STDMETHODIMP
|
|
CWebDavCleanerClassFactory::LockServer(BOOL fLock)
|
|
{
|
|
Trace(L"CWebDavCleanerClassFactory::LockServer");
|
|
if (fLock)
|
|
DllAddRef();
|
|
else
|
|
DllRelease();
|
|
return S_OK;
|
|
}
|
|
|