Windows2000/private/windows/shell/dskquota/ui/factory.cpp
2020-09-30 17:12:32 +02:00

370 lines
9.1 KiB
C++

/* File: factory.cpp
Description: Contains the member function definitions for class
DiskQuotaUIClassFactory. The class factory object generates
new instances of DiskQuotaControl objects. The object implements
IClassFactory.
Revision History:
Date Description Programmer
-------- ----------- ----------
05/22/96 Initial creation. BrianAu
08/15/96 Added shell extension support. BrianAu
02/04/98 Added creation of IComponent. BrianAu
06/25/98 Disabled MMC snapin code. BrianAu
*/
#include "pch.h" // PCH
#pragma hdrstop
#include "factory.h"
#include "extinit.h"
#include "snapin.h"
#include "resource.h"
#include "guidsp.h"
// Verify that build is UNICODE.
#if !defined(UNICODE)
# error This module must be compiled UNICODE.
#endif
extern LONG g_cLockThisDll; // Supports LockServer().
/* Function: DiskQuotaUIClassFactory::QueryInterface
Description: Retrieves a pointer to the IUnknown or IClassFactory
interface. Recoginizes the IID_IUnknown and IID_IClassFactory
interface IDs.
Arguments:
riid - Reference to requested interface ID.
ppvOut - Address of interface pointer variable to accept interface ptr.
Returns:
NO_ERROR - Success.
E_NOINTERFACE - Requested interface not supported.
E_INVALIDARG - ppvOut argument was NULL.
Revision History:
Date Description Programmer
-------- ----------- ----------
05/22/96 Initial creation. BrianAu
08/15/96 Added IShellPropSheetExt BrianAu
*/
STDMETHODIMP
DiskQuotaUIClassFactory::QueryInterface(
REFIID riid,
LPVOID *ppvOut
)
{
DBGTRACE((DM_COM, DL_HIGH, TEXT("DiskQuotaUIClassFactory::QueryInterface")));
HRESULT hResult = E_NOINTERFACE;
if (NULL == ppvOut)
return E_INVALIDARG;
*ppvOut = NULL;
if (IID_IUnknown == riid || IID_IClassFactory == riid)
{
*ppvOut = this;
((LPUNKNOWN)*ppvOut)->AddRef();
hResult = NOERROR;
}
return hResult;
}
/* Function: DiskQuotaUIClassFactory::AddRef
Description: Increments object reference count.
Arguments: None.
Returns: New reference count value.
Revision History:
Date Description Programmer
-------- ----------- ----------
05/22/96 Initial creation. BrianAu
*/
STDMETHODIMP_(ULONG)
DiskQuotaUIClassFactory::AddRef(
VOID
)
{
ULONG ulReturn = m_cRef + 1;
DBGPRINT((DM_COM, DL_HIGH, TEXT("DiskQuotaUIClassFactory::AddRef, 0x%08X %d -> %d"),
this, ulReturn - 1, ulReturn));
InterlockedIncrement(&m_cRef);
return ulReturn;
}
/* Function: DiskQuotaUIClassFactory::Release
Description: Decrements object reference count. If count drops to 0,
object is deleted.
Arguments: None.
Returns: New reference count value.
Revision History:
Date Description Programmer
-------- ----------- ----------
05/22/96 Initial creation. BrianAu
*/
STDMETHODIMP_(ULONG)
DiskQuotaUIClassFactory::Release(
VOID
)
{
ULONG ulReturn = m_cRef - 1;
DBGPRINT((DM_COM, DL_HIGH, TEXT("DiskQuotaUIClassFactory::Release, 0x%08X %d -> %d"),
this, ulReturn + 1, ulReturn));
if (InterlockedDecrement(&m_cRef) == 0)
{
delete this;
ulReturn = 0;
}
return ulReturn;
}
/* Function: DiskQuotaUIClassFactory::CreateInstance
Description: Creates a new instance of a DiskQuotaControl object, returning
a pointer to its IDiskQuotaControl interface.
Arguments:
pUnkOuter - Pointer to outer object's IUnknown interface for IUnknown
delegation in support of aggregation. Aggregation is not supported
by IDiskQuotaControl.
riid - Reference to interface ID being requested.
ppvOut - Address of interface pointer variable to accept interface
pointer.
Returns:
NO_ERROR - Success.
CLASS_E_NOAGGREGATION - Aggregation was requested but is not supported.
E_OUTOFMEMORY - Insufficient memory to create new object.
E_NOINTERFACE - Requested interface not supported.
E_INVALIDARG - ppvOut arg was NULL.
Revision History:
Date Description Programmer
-------- ----------- ----------
05/22/96 Initial creation. BrianAu
08/15/96 Added shell extension support. BrianAu
*/
STDMETHODIMP
DiskQuotaUIClassFactory::CreateInstance(
LPUNKNOWN pUnkOuter,
REFIID riid,
LPVOID *ppvOut
)
{
DBGTRACE((DM_COM, DL_HIGH, TEXT("DiskQuotaUIClassFactory::CreateInstance")));
HRESULT hResult = NO_ERROR;
TCHAR szGUID[MAX_PATH];
StringFromGUID2(riid, szGUID, sizeof(szGUID));
DBGPRINT((DM_COM, DL_HIGH, TEXT("CreateInstance: %s"), szGUID));
if (NULL == ppvOut)
return E_INVALIDARG;
*ppvOut = NULL;
try
{
if (NULL != pUnkOuter && IID_IUnknown != riid)
{
hResult = CLASS_E_NOAGGREGATION;
}
else
{
InstanceProxy *pip = new InstanceProxy;
hResult = pip->QueryInterface(riid, ppvOut);
if (IID_IUnknown != riid || FAILED(hResult))
{
// Either caller requested something other than IUnknown
// or QI failed. We can delete the instance proxy.
// It's only necessary to keep around if the caller asked
// for IUnknown.
delete pip;
}
}
}
catch(CAllocException& e)
{
hResult = E_OUTOFMEMORY;
}
catch(...)
{
hResult = E_UNEXPECTED;
}
return hResult;
}
/* Function: DiskQuotaUIClassFactory::LockServer
Description: Places/removes a lock on the DLL server. See OLE 2
documentation of IClassFactory for details.
Arguments:
fLock - TRUE = Increment lock count, FALSE = Decrement lock count.
Returns:
S_OK - Success.
S_FALSE - Lock count is already 0. Can't be decremented.
Revision History:
Date Description Programmer
-------- ----------- ----------
05/22/96 Initial creation. BrianAu
*/
STDMETHODIMP
DiskQuotaUIClassFactory::LockServer(
BOOL fLock
)
{
DBGTRACE((DM_COM, DL_HIGH, TEXT("DiskQuotaUIClassFactory::LockServer")));
HRESULT hResult = S_OK;
if (fLock)
{
// Increment the lock count.
InterlockedIncrement(&g_cLockThisDll);
}
else
{
// Decrement only if lock count is > 0.
// Otherwise, it's an error.
LONG lLock = g_cLockThisDll - 1;
if (0 <= lLock)
{
InterlockedDecrement(&g_cLockThisDll);
CoFreeUnusedLibraries();
}
else
hResult = S_FALSE; // Lock count already at 0.
}
return hResult;
}
HRESULT
InstanceProxy::QueryInterface(
REFIID riid,
LPVOID *ppvOut
)
{
HRESULT hResult = E_NOINTERFACE;
DBGTRACE((DM_COM, DL_HIGH, TEXT("InstanceProxy::QueryInterface")));
if (NULL == ppvOut)
return E_INVALIDARG;
*ppvOut = NULL;
if (IID_IUnknown == riid)
{
DBGPRINT((DM_COM, DL_MID, TEXT("Requested IID_IUnknown")));
*ppvOut = this;
((LPUNKNOWN)*ppvOut)->AddRef();
hResult = NOERROR;
}
#ifdef POLICY_MMC_SNAPIN
else if (IID_IComponentData == riid)
{
DBGPRINT((DM_COM, DL_MID, TEXT("Requested IID_IComponentData")));
CSnapInCompData *psicd = new CSnapInCompData(g_hInstDll,
CString(g_hInstDll, IDS_SNAPIN_NAME),
CLSID_DiskQuotaUI);
hResult = psicd->QueryInterface(riid, ppvOut);
if (FAILED(hResult))
delete psicd;
}
#endif // POLICY_MMC_SNAPIN
else if (IID_IShellExtInit == riid)
{
DBGPRINT((DM_COM, DL_MID, TEXT("Requested IID_IShellExtInit")));
ShellExtInit *pExtInit = new ShellExtInit;
hResult = pExtInit->QueryInterface(IID_IShellExtInit, ppvOut);
if (FAILED(hResult))
delete pExtInit;
}
return hResult;
}
ULONG
InstanceProxy::AddRef(
VOID
)
{
DBGTRACE((DM_COM, DL_MID, TEXT("InstanceProxy::AddRef")));
ULONG ulReturn = m_cRef + 1;
InterlockedIncrement(&m_cRef);
return ulReturn;
}
ULONG
InstanceProxy::Release(
VOID
)
{
DBGTRACE((DM_COM, DL_MID, TEXT("InstanceProxy::Release")));
ULONG ulReturn = m_cRef - 1;
if (InterlockedDecrement(&m_cRef) == 0)
{
delete this;
ulReturn = 0;
}
return ulReturn;
}