windows-nt/Source/XPSP1/NT/shell/osshell/dskquota/ui/snapin.cpp
2020-09-26 16:20:57 +08:00

1368 lines
33 KiB
C++

///////////////////////////////////////////////////////////////////////////////
/* File: snapin.cpp
Description: Implements the MMC snapin for disk quota policy.
Revision History:
Date Description Programmer
-------- --------------------------------------------------- ----------
02/14/98 Initial creation. BrianAu
06/25/98 Disabled snapin code with #ifdef POLICY_MMC_SNAPIN. BrianAu
Switching to ADM-file approach to entering policy
data. Keeping snapin code available in case
we decide to switch back at a later time.
*/
///////////////////////////////////////////////////////////////////////////////
#include "pch.h"
#pragma hdrstop
#ifdef POLICY_MMC_SNAPIN
#include "snapin.h"
#include "resource.h"
#include "guidsp.h"
#include "policy.h"
//-----------------------------------------------------------------------------
// CSnapInItem
//-----------------------------------------------------------------------------
//
// General rendering function usable by this class and any
// derived classes to render data onto a medium. Only accepts
// TYMED_HGLOBAL.
//
HRESULT
CSnapInItem::RenderData( // [ static ]
LPVOID pvData,
int cbData,
LPSTGMEDIUM pMedium
)
{
DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CSnapInItem::RenderData [ general ]")));
HRESULT hr = DV_E_TYMED;
if (NULL == pvData || NULL == pMedium)
return E_INVALIDARG;
//
// Make sure the type medium is HGLOBAL
//
if (TYMED_HGLOBAL == pMedium->tymed)
{
//
// Create the stream on the hGlobal passed in
//
LPSTREAM pStream;
hr = CreateStreamOnHGlobal(pMedium->hGlobal, FALSE, &pStream);
if (SUCCEEDED(hr))
{
//
// Write to the stream the number of bytes
//
unsigned long written;
hr = pStream->Write(pvData, cbData, &written);
//
// Because we told CreateStreamOnHGlobal with 'FALSE',
// only the stream is released here.
// Note - the caller (i.e. snap-in, object) will free the HGLOBAL
// at the correct time. This is according to the IDataObject specification.
//
pStream->Release();
}
}
return hr;
}
//
// Format a GUID as a string.
//
void
CSnapInItem::GUIDToString( // [ static ]
const GUID& guid,
CString *pstr
)
{
StringFromGUID2(guid, pstr->GetBuffer(50), 50);
pstr->ReleaseBuffer();
}
//-----------------------------------------------------------------------------
// CScopeItem
//-----------------------------------------------------------------------------
UINT CScopeItem::m_cfNodeType = RegisterClipboardFormat(CCF_NODETYPE);
UINT CScopeItem::m_cfNodeTypeString = RegisterClipboardFormat(CCF_SZNODETYPE);
UINT CScopeItem::m_cfDisplayName = RegisterClipboardFormat(CCF_DISPLAY_NAME);
UINT CScopeItem::m_cfCoClass = RegisterClipboardFormat(CCF_SNAPIN_CLASSID);
//
// Returns: S_OK = Data successfully rendered.
// DV_E_CLIPFORMAT = Clipboard format not supported.
// DV_E_TYMED = Medium is not HGLOBAL.
// Other = Rendering error.
HRESULT
CScopeItem::RenderData(
UINT cf,
LPSTGMEDIUM pMedium
) const
{
DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CScopeItem::RenderData")));
HRESULT hr = DV_E_CLIPFORMAT;
if (cf == m_cfNodeType)
{
DBGPRINT((DM_SNAPIN, DL_LOW, TEXT("Rendering CCF_NODETYPE")));
hr = CSnapInItem::RenderData((LPVOID)&m_idType, sizeof(m_idType), pMedium);
}
else if (cf == m_cfNodeTypeString)
{
DBGPRINT((DM_SNAPIN, DL_LOW, TEXT("Rendering CCF_SZNODETYPE")));
CString s;
GUIDToString(m_idType, &s);
hr = CSnapInItem::RenderData((LPVOID)s.Cstr(), (s.Length() + 1) * sizeof(TCHAR), pMedium);
}
else if (cf == m_cfDisplayName)
{
DBGPRINT((DM_SNAPIN, DL_LOW, TEXT("Rendering CCF_DISPLAY_NAME")));
const CString& s = m_cd.DisplayName();
hr = CSnapInItem::RenderData((LPVOID)s.Cstr(), (s.Length() + 1) * sizeof(TCHAR), pMedium);
}
else if (cf == m_cfCoClass)
{
DBGPRINT((DM_SNAPIN, DL_LOW, TEXT("Rendering CCF_SNAPIN_CLASSID")));
hr = CSnapInItem::RenderData((LPVOID)&m_cd.ClassId(), sizeof(GUID), pMedium);
}
return hr;
}
CScopeItem::~CScopeItem(
void
)
{
DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CScopeItem::~CScopeItem")));
while(0 < m_rgpChildren.Count())
{
delete m_rgpChildren[0];
m_rgpChildren.Delete(0);
}
while(0 < m_rgpResultItems.Count())
{
delete m_rgpResultItems[0];
m_rgpResultItems.Delete(0);
}
}
//-----------------------------------------------------------------------------
// CSnapInComp
//-----------------------------------------------------------------------------
CSnapInComp::CSnapInComp(
HINSTANCE hInstance,
CSnapInCompData& cd
) : m_cRef(0),
m_hInstance(hInstance),
m_cd(cd),
m_pConsole(NULL),
m_pResult(NULL),
m_pHeader(NULL),
m_pImageResult(NULL),
m_strColumn(hInstance, IDS_SNAPIN_COLUMN),
m_cxColumn(200),
m_lViewMode(LVS_ICON)
{
DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CSnapInComp::CSnapInComp")));
}
CSnapInComp::~CSnapInComp(
void
)
{
DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CSnapInComp::~CSnapInComp")));
if (NULL != m_pImageResult)
{
m_pImageResult->Release();
m_pImageResult = NULL;
}
if (NULL != m_pResult)
{
m_pResult->Release();
m_pResult = NULL;
}
if (NULL != m_pHeader)
{
m_pHeader->Release();
m_pHeader = NULL;
}
if (NULL != m_pConsole)
{
m_pConsole->Release();
m_pConsole = NULL;
}
}
HRESULT
CSnapInComp::QueryInterface(
REFIID riid,
LPVOID *ppvOut
)
{
DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CSnapInComp::QueryInterface")));
DBGPRINTIID(DM_SNAPIN, DL_MID, riid);
HRESULT hr = E_NOINTERFACE;
if (NULL == ppvOut)
return E_INVALIDARG;
*ppvOut = NULL;
if (IID_IUnknown == riid || IID_IComponent == riid)
{
*ppvOut = this;
}
else if (IID_IExtendContextMenu == riid)
{
*ppvOut = static_cast<IExtendContextMenu *>(this);
}
if (NULL != *ppvOut)
{
((LPUNKNOWN)*ppvOut)->AddRef();
hr = NOERROR;
}
return hr;
}
ULONG
CSnapInComp::AddRef(
void
)
{
DBGTRACE((DM_SNAPIN, DL_LOW, TEXT("CSnapInComp::AddRef")));
ULONG ulReturn = m_cRef + 1;
InterlockedIncrement(&m_cRef);
return ulReturn;
}
ULONG
CSnapInComp::Release(
void
)
{
DBGTRACE((DM_SNAPIN, DL_LOW, TEXT("CSnapInComp::Release")));
ULONG ulReturn = m_cRef - 1;
if (InterlockedDecrement(&m_cRef) == 0)
{
delete this;
ulReturn = 0;
}
return ulReturn;
}
HRESULT
CSnapInComp::Initialize(
LPCONSOLE lpConsole
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInComp::Initialize")));
HRESULT hr = NOERROR;
m_pConsole = lpConsole;
m_pConsole->AddRef();
//
// Get IResultData interface to result pane.
//
hr = m_pConsole->QueryInterface(IID_IResultData,
reinterpret_cast<void **>(&m_pResult));
if (FAILED(hr))
return hr;
//
// Get IHeaderCtrl interface to header control.
//
hr = m_pConsole->QueryInterface(IID_IHeaderCtrl,
reinterpret_cast<void **>(&m_pHeader));
if (FAILED(hr))
return hr;
// m_pConsole->SetHeader(m_pHeader); // Needed?
hr = m_pConsole->QueryResultImageList(&m_pImageResult);
return hr;
}
HRESULT
CSnapInComp::Notify(
LPDATAOBJECT lpDataObject,
MMC_NOTIFY_TYPE event,
long arg,
long param
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInComp::Notify")));
DBGPRINT((DM_SNAPIN, DL_LOW, TEXT("\tpObj = 0x%08X, event = %d, arg = %d, param = 0x%08X"), lpDataObject, event, arg, param));
HRESULT hr = S_OK;
switch(event)
{
case MMCN_ADD_IMAGES:
DBGPRINT((DM_SNAPIN, DL_LOW, TEXT("MMCN_ADD_IMAGES")));
{
//
// Result pane image list has only one icon.
//
HICON hIcon = LoadIcon(m_hInstance, MAKEINTRESOURCE(IDI_QUOTA));
m_pImageResult->ImageListSetIcon(reinterpret_cast<long *>(hIcon), 0);
}
break;
case MMCN_SHOW:
DBGPRINT((DM_SNAPIN, DL_LOW, TEXT("MMCN_SHOW, arg = %d"), arg));
if (arg)
{
//
// Showing view. Set view information.
//
m_pHeader->InsertColumn(0, m_strColumn, LVCFMT_LEFT, m_cxColumn);
m_pResult->SetViewMode(m_lViewMode);
CScopeItem *psi;
hr = GetScopeItem((HSCOPEITEM)param, &psi);
if (FAILED(hr))
{
DBGERROR((TEXT("Failed getting item for MMCN_SHOW")));
return hr;
}
RESULTDATAITEM rdi;
rdi.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
int cResultItems = psi->NumResultItems();
for (int i = 0; i < cResultItems; i++)
{
CResultItem *pri = psi->ResultItem(i);
DBGASSERT((NULL != pri));
rdi.str = MMC_CALLBACK;
rdi.nImage = pri->ImageIndex();
rdi.lParam = (LPARAM)pri;
m_pResult->InsertItem(&rdi);
}
}
else
{
//
// Hiding view. Gather view information.
//
m_pHeader->GetColumnWidth(0, &m_cxColumn);
m_pResult->GetViewMode(&m_lViewMode);
}
break;
case MMCN_CLICK:
case MMCN_DBLCLICK:
DBGPRINT((DM_SNAPIN, DL_LOW, TEXT("MMCN_CLICK or MMCN_DBLCLICK")));
m_cd.OpenVolumeQuotaProperties();
break;
default:
break;
}
return hr;
}
HRESULT
CSnapInComp::Destroy(
LONG cookie
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInComp::Destroy")));
if (NULL != m_pImageResult)
{
m_pImageResult->Release();
m_pImageResult = NULL;
}
if (NULL != m_pResult)
{
m_pResult->Release();
m_pResult = NULL;
}
if (NULL != m_pHeader)
{
m_pHeader->Release();
m_pHeader = NULL;
}
if (NULL != m_pConsole)
{
m_pConsole->Release();
m_pConsole = NULL;
}
return NOERROR;
}
HRESULT
CSnapInComp::QueryDataObject(
long cookie,
DATA_OBJECT_TYPES type,
LPDATAOBJECT *ppDataObject
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInComp::QueryDataObject")));
//
// Forward the data object query to the component data object.
//
return m_cd.QueryDataObject(cookie, type, ppDataObject);
}
HRESULT
CSnapInComp::GetResultViewType(
long cookie,
LPOLESTR *ppViewType,
long *pViewOptions
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInComp::GetResultViewType")));
//
// Tell snapin mgr to use default listview.
//
return S_FALSE;
}
HRESULT
CSnapInComp::GetDisplayInfo(
RESULTDATAITEM *prdi
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInComp::GetDisplayInfo")));
CSnapInItem *psi = reinterpret_cast<CSnapInItem *>(prdi->lParam);
if (RDI_STR & prdi->mask)
{
prdi->str = (LPOLESTR)psi->DisplayName().Cstr();
}
if (RDI_IMAGE & prdi->mask)
{
prdi->nImage = psi->ImageIndex();
}
if (RDI_STATE & prdi->mask)
{
prdi->nState = 0;
}
if (RDI_INDEX & prdi->mask)
{
prdi->nIndex = 0;
}
if (RDI_INDENT & prdi->mask)
{
prdi->iIndent = 0;
}
return S_OK;
}
HRESULT
CSnapInComp::CompareObjects(
LPDATAOBJECT pdoA,
LPDATAOBJECT pdoB
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInComp::CompareObjects")));
return m_cd.CompareObjects(pdoA, pdoB);
}
HRESULT
CSnapInComp::AddMenuItems(
LPDATAOBJECT pDataObject,
LPCONTEXTMENUCALLBACK piCallback,
long *pInsertionAllowed
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInComp::AddMenuItems")));
return m_cd.AddMenuItems(pDataObject, piCallback, pInsertionAllowed);
}
HRESULT
CSnapInComp::Command(
long lCommandID,
LPDATAOBJECT pDataObject
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInComp::Command")));
return m_cd.Command(lCommandID, pDataObject);
}
HRESULT
CSnapInComp::GetScopeItem(
HSCOPEITEM hItem,
CScopeItem **ppsi
) const
{
HRESULT hr;
SCOPEDATAITEM item;
item.mask = SDI_PARAM;
item.ID = hItem;
hr = m_cd.m_pScope->GetItem(&item);
if (SUCCEEDED(hr))
{
*ppsi = reinterpret_cast<CScopeItem *>(item.lParam);
}
return hr;
}
//-----------------------------------------------------------------------------
// CSnapInCompData
//-----------------------------------------------------------------------------
CSnapInCompData::CSnapInCompData(
HINSTANCE hInstance,
LPCTSTR pszDisplayName,
const GUID& idClass
) : m_cRef(0),
m_hInstance(hInstance),
m_strDisplayName(pszDisplayName),
m_idClass(idClass),
m_pConsole(NULL),
m_pScope(NULL),
m_pRootScopeItem(NULL),
m_hRoot(NULL),
m_pGPEInformation(NULL)
{
DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CSnapInCompData::CSnapInCompData")));
InterlockedIncrement(&g_cRefThisDll);
//
// Root node.
//
m_pRootScopeItem = new CScopeItem(NODEID_DiskQuotaRoot, // Node ID
*this, // Snapin comp data ref.
NULL, // Parent node ptr.
TEXT("<root>"), // Node name str.
-1, // Image index.
-1); // Image index "open".
//
// Add "Disk Quota Settings" as a child of the root.
//
CString strName(hInstance, IDS_SNAPIN_SCOPENAME);
CScopeItem *psi = new CScopeItem(NODEID_DiskQuotaSettings,
*this,
m_pRootScopeItem,
strName,
iICON_QUOTA,
iICON_QUOTA_OPEN);
m_pRootScopeItem->AddChild(psi);
//
// Add single result item to "Disk Quota Settings".
//
strName.Format(hInstance, IDS_SNAPIN_RESULTNAME);
psi->AddResultItem(new CResultItem(strName, 0, *psi));
}
CSnapInCompData::~CSnapInCompData(
void
)
{
DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CSnapInCompData::~CSnapInCompData")));
delete m_pRootScopeItem;
if (NULL != m_pScope)
m_pScope->Release();
if (NULL != m_pConsole)
m_pConsole->Release();
if (NULL != m_pGPEInformation)
m_pGPEInformation->Release();
InterlockedDecrement(&g_cRefThisDll);
}
HRESULT
CSnapInCompData::QueryInterface(
REFIID riid,
LPVOID *ppvOut
)
{
DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CSnapInCompData::QueryInterface")));
DBGPRINTIID(DM_SNAPIN, DL_MID, riid);
HRESULT hr = E_NOINTERFACE;
if (NULL == ppvOut)
return E_INVALIDARG;
*ppvOut = NULL;
if (IID_IUnknown == riid || IID_IComponentData == riid)
{
*ppvOut = this;
}
else if (IID_IPersistStreamInit == riid)
{
*ppvOut = static_cast<IPersistStreamInit *>(this);
}
else if (IID_IExtendContextMenu == riid)
{
*ppvOut = static_cast<IExtendContextMenu *>(this);
}
if (NULL != *ppvOut)
{
((LPUNKNOWN)*ppvOut)->AddRef();
hr = NOERROR;
}
return hr;
}
ULONG
CSnapInCompData::AddRef(
void
)
{
DBGTRACE((DM_SNAPIN, DL_LOW, TEXT("CSnapInCompData::AddRef")));
ULONG ulReturn = m_cRef + 1;
InterlockedIncrement(&m_cRef);
return ulReturn;
}
ULONG
CSnapInCompData::Release(
void
)
{
DBGTRACE((DM_SNAPIN, DL_LOW, TEXT("CSnapInCompData::Release")));
ULONG ulReturn = m_cRef - 1;
if (InterlockedDecrement(&m_cRef) == 0)
{
delete this;
ulReturn = 0;
}
return ulReturn;
}
HRESULT
CSnapInCompData::Initialize(
LPUNKNOWN pUnk
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::Initialize")));
DBGASSERT((NULL != pUnk));
DBGASSERT((NULL == m_pConsole));
HRESULT hr = pUnk->QueryInterface(IID_IConsole,
reinterpret_cast<void **>(&m_pConsole));
if (FAILED(hr))
{
DBGERROR((TEXT("CSnapInCompData failed QI for IID_IConsole")));
return hr;
}
hr = pUnk->QueryInterface(IID_IConsoleNameSpace,
reinterpret_cast<void **>(&m_pScope));
if (FAILED(hr))
{
DBGERROR((TEXT("CSnapInCompData failed QI for IID_IConsoleNameSpace")));
return hr;
}
LPIMAGELIST pImageList = NULL;
hr = m_pConsole->QueryScopeImageList(&pImageList);
if (FAILED(hr))
{
DBGERROR((TEXT("CSnapInCompData failed to get scope image list")));
return hr;
}
//
// Set the scope pane's image list icons.
//
static const struct
{
int idIcon;
int iIconIndex;
} rgIcons[] = { { IDI_QUOTA, iICON_QUOTA },
{ IDI_QUOTA_OPEN, iICON_QUOTA_OPEN } };
for (int i = 0; i < ARRAYSIZE(rgIcons); i++)
{
HICON hIcon = LoadIcon(m_hInstance,
MAKEINTRESOURCE(rgIcons[i].idIcon));
pImageList->ImageListSetIcon(reinterpret_cast<long *>(hIcon),
rgIcons[i].iIconIndex);
}
pImageList->Release();
return hr;
}
HRESULT
CSnapInCompData::CreateComponent(
LPCOMPONENT *ppComp
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::CreateComponent")));
HRESULT hr = S_OK;
try
{
CSnapInComp *pComp = new CSnapInComp(m_hInstance, *this);
hr = pComp->QueryInterface(IID_IComponent, reinterpret_cast<void **>(ppComp));
}
catch(CAllocException& e)
{
DBGERROR((TEXT("Insufficient memory")));
hr = E_OUTOFMEMORY;
}
return hr;
}
HRESULT
CSnapInCompData::Destroy(
void
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::Destroy")));
if (NULL != m_pScope)
{
m_pScope->Release();
m_pScope = NULL;
}
if (NULL != m_pConsole)
{
m_pConsole->Release();
m_pConsole = NULL;
}
return S_OK;
}
HRESULT
CSnapInCompData::Notify(
LPDATAOBJECT pDataObject,
MMC_NOTIFY_TYPE event,
long arg,
long param
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::Notify")));
DBGPRINT((DM_SNAPIN, DL_LOW, TEXT("\tpDataObj = 0x%08X, event = 0x%08X, arg = %d, param = 0x%08X"),
pDataObject, event, arg, param));
HRESULT hr = S_OK;
try
{
switch(event)
{
case MMCN_EXPAND:
if (arg)
{
if (NULL == m_pGPEInformation)
{
hr = pDataObject->QueryInterface(IID_IGPEInformation,
reinterpret_cast<void **>(&m_pGPEInformation));
}
if (NULL != m_pGPEInformation)
{
hr = EnumerateScopePane((HSCOPEITEM)param);
}
}
break;
default:
break;
}
}
catch(CAllocException& e)
{
DBGERROR((TEXT("Insufficient memory")));
hr = E_OUTOFMEMORY;
}
return hr;
}
HRESULT
CSnapInCompData::GetDisplayInfo(
SCOPEDATAITEM *psdi
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::GetDispInfo")));
DBGPRINT((DM_SNAPIN, DL_LOW, TEXT("\tmask = 0x%08X"), psdi->mask));
HRESULT hr = S_OK;
CScopeItem *pItem = reinterpret_cast<CScopeItem *>(psdi->lParam);
if (psdi->mask & SDI_STR)
{
psdi->displayname = (LPOLESTR)((LPCTSTR)pItem->DisplayName());
}
if (psdi->mask & SDI_IMAGE)
{
psdi->nImage = pItem->ImageIndex();
}
if (psdi->mask & SDI_OPENIMAGE)
{
psdi->nOpenImage = pItem->OpenImageIndex();
}
if (psdi->mask & SDI_CHILDREN)
{
psdi->cChildren = pItem->NumChildren();
}
return hr;
}
HRESULT
CSnapInCompData::CompareObjects(
LPDATAOBJECT pdoA,
LPDATAOBJECT pdoB
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::GetDispInfo")));
LPQUOTADATAOBJECT pDataA, pDataB;
HRESULT hr = S_FALSE;
if (FAILED(pdoA->QueryInterface(IID_IDiskQuotaSnapInData, reinterpret_cast<void **>(&pDataA))))
return S_FALSE;
if (FAILED(pdoB->QueryInterface(IID_IDiskQuotaSnapInData, reinterpret_cast<void **>(&pDataB))))
{
pDataA->Release();
return FALSE;
}
CSnapInItem *psiA, *psiB;
pDataA->GetItem(&psiA);
pDataB->GetItem(&psiB);
if (psiA == psiB)
hr = S_OK;
pDataA->Release();
pDataB->Release();
return hr;
}
HRESULT
CSnapInCompData::QueryDataObject(
long cookie,
DATA_OBJECT_TYPES type,
LPDATAOBJECT *ppDataObject
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::QueryDataObject")));
HRESULT hr = E_NOINTERFACE;
CDataObject *pDataObject = NULL;
LPQUOTADATAOBJECT pQuotaData = NULL;
try
{
pDataObject = new CDataObject(*this);
pDataObject->SetType(type);
pDataObject->SetItem(reinterpret_cast<CSnapInItem *>(cookie));
hr = pDataObject->QueryInterface(IID_IDataObject, (LPVOID *)ppDataObject);
}
catch(CAllocException& e)
{
DBGERROR((TEXT("Insufficient memory")));
hr = E_OUTOFMEMORY;
}
return hr;
}
HRESULT
CSnapInCompData::EnumerateScopePane (
HSCOPEITEM hParent
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::EnumerateScopePane")));
HRESULT hr = S_OK;
CScopeItem *psi = m_pRootScopeItem; // Default to enumerating from root.
SCOPEDATAITEM item;
if (NULL == m_hRoot)
m_hRoot = hParent; // Remember the root node's handle.
if (m_hRoot != hParent)
{
item.mask = SDI_PARAM;
item.ID = hParent;
hr = m_pScope->GetItem (&item);
if (FAILED(hr))
{
DBGERROR((TEXT("Failed getting item")));
return hr;
}
psi = reinterpret_cast<CScopeItem *>(item.lParam);
}
item.mask = SDI_STR | SDI_STATE | SDI_IMAGE | SDI_OPENIMAGE | SDI_PARAM | SDI_CHILDREN;
item.nState = 0;
item.relativeID = hParent;
int cChildren = psi->NumChildren();
for (int iChild = 0; iChild < cChildren; iChild++)
{
CScopeItem *pChild = psi->Child(iChild);
item.displayname = MMC_CALLBACK;
item.nImage = pChild->ImageIndex();
item.nOpenImage = pChild->OpenImageIndex();
item.cChildren = pChild->NumChildren();
item.lParam = reinterpret_cast<LPARAM>(pChild);
m_pScope->InsertItem (&item);
}
return S_OK;
}
HRESULT
CSnapInCompData::InitNew(
void
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::InitNew")));
return S_OK;
}
HRESULT
CSnapInCompData::GetClassID(
CLSID *pClassID
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::GetClassID")));
if (!pClassID)
return E_FAIL;
*pClassID = ClassId();
return S_OK;
}
HRESULT
CSnapInCompData::IsDirty(
void
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::IsDirty")));
return S_FALSE;
}
HRESULT
CSnapInCompData::Load(
IStream *pStm
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::Load")));
return S_OK;
}
HRESULT
CSnapInCompData::Save(
IStream *pStm,
BOOL fClearDirty
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::Save")));
return S_OK;
}
HRESULT
CSnapInCompData::GetSizeMax(
ULARGE_INTEGER *pcbSize
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::GetSizeMax")));
DWORD dwSize = 0;
if (NULL == pcbSize)
return E_FAIL;
pcbSize->QuadPart = 0;
return S_OK;
}
HRESULT
CSnapInCompData::AddMenuItems(
LPDATAOBJECT pDataObject,
LPCONTEXTMENUCALLBACK piCallback,
long *pInsertionAllowed
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::AddMenuItems")));
HRESULT hr = S_OK;
if (CCM_INSERTIONALLOWED_TOP & *pInsertionAllowed)
{
CString strOpen(m_hInstance, IDS_VERB_OPEN);
CONTEXTMENUITEM ci;
ci.strName = strOpen;
ci.strStatusBarText = NULL;
ci.lCommandID = 0;
ci.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TOP;
ci.fFlags = 0;
ci.fSpecialFlags = CCM_SPECIAL_DEFAULT_ITEM;
hr = piCallback->AddItem(&ci);
if (FAILED(hr))
{
DBGERROR((TEXT("Error 0x%08X adding context menu item"), hr));
}
}
return hr;
}
HRESULT
CSnapInCompData::Command(
long lCommandID,
LPDATAOBJECT pDataObject
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::Command")));
DBGPRINT((DM_SNAPIN, DL_LOW, TEXT("Command ID = %d"), lCommandID));
if (0 == lCommandID)
OpenVolumeQuotaProperties();
else
DBGERROR((TEXT("Unrecognized command ID (%d)"), lCommandID));
return S_OK;
}
const int MAX_SNAPIN_PROP_PAGES = 1;
BOOL CALLBACK
CSnapInCompData::AddPropSheetPage(
HPROPSHEETPAGE hpage,
LPARAM lParam
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::AddPropSheetPage")));
PROPSHEETHEADER * ppsh = (PROPSHEETHEADER *)lParam;
if (ppsh->nPages < MAX_SNAPIN_PROP_PAGES)
{
ppsh->phpage[ppsh->nPages++] = hpage;
return TRUE;
}
return FALSE;
}
DWORD
CSnapInCompData::PropPageThreadProc(
LPVOID pvParam
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::PropPageThreadProc")));
MSG msg;
HWND hwndPropSheet = NULL;
CSnapInCompData *pThis = (CSnapInCompData *)pvParam;
com_autoptr<IShellExtInit> psei;
HRESULT hr = CoInitialize(NULL);
if (SUCCEEDED(hr))
{
hr = CoCreateInstance(CLSID_DiskQuotaUI,
NULL,
CLSCTX_INPROC_SERVER,
IID_IShellExtInit,
reinterpret_cast<void **>(psei.getaddr()));
if (SUCCEEDED(hr))
{
com_autoptr<IShellPropSheetExt> pspse;
hr = psei->QueryInterface(IID_ISnapInPropSheetExt,
reinterpret_cast<void **>(pspse.getaddr()));
if (SUCCEEDED(hr))
{
com_autoptr<IDiskQuotaPolicy> pdqp;
hr = pspse->QueryInterface(IID_IDiskQuotaPolicy,
reinterpret_cast<void **>(pdqp.getaddr()));
if (SUCCEEDED(hr))
{
pdqp->Initialize(pThis->m_pGPEInformation, NULL);
HPROPSHEETPAGE rghPages[1];
PROPSHEETHEADER psh;
ZeroMemory(&psh, sizeof(psh));
//
// Define sheet.
//
psh.dwSize = sizeof(PROPSHEETHEADER);
psh.dwFlags = PSH_MODELESS;
psh.hInstance = pThis->m_hInstance;
psh.pszIcon = NULL;
psh.pszCaption = NULL;
psh.nPages = 0;
psh.nStartPage = 0;
psh.phpage = rghPages;
pThis->m_pConsole->GetMainWindow(&psh.hwndParent);
hr = pspse->AddPages(AddPropSheetPage, (LPARAM)&psh);
if (SUCCEEDED(hr))
{
hwndPropSheet = (HWND)PropertySheet(&psh);
if (NULL != hwndPropSheet)
{
//
// Set the title on the property sheet.
//
CString strTitle(pThis->m_hInstance, IDS_SNAPIN_POLICYDLG_TITLE);
SetWindowText(hwndPropSheet, strTitle);
MSG msg;
while (0 != ::GetMessage(&msg, NULL, 0, 0))
{
if (!PropSheet_IsDialogMessage(hwndPropSheet, &msg))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
if (NULL == PropSheet_GetCurrentPageHwnd(hwndPropSheet))
{
DestroyWindow(hwndPropSheet);
PostQuitMessage(0);
}
}
}
else if (-1 == (int)hwndPropSheet)
{
DBGERROR((TEXT("PropertySheet failed with error %d"), GetLastError()));
}
}
else
{
DBGERROR((TEXT("AddPages failed")));
}
}
}
}
else
DBGERROR((TEXT("CoCreateInstance failed with result 0x%08X"), hr));
CoUninitialize();
}
else
DBGERROR((TEXT("CoInitialize failed with result 0x%08X"), hr));
return 0;
}
//
// Create a new thread and run the volume properties dialog (modified for
// policy snapin).
//
HRESULT
CSnapInCompData::OpenVolumeQuotaProperties(
void
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CSnapInCompData::OpenVolumeQuotaProperties")));
HRESULT hr = E_FAIL;
UINT idThread;
HANDLE hThread = CreateThread(NULL,
0, // Default stack size
(LPTHREAD_START_ROUTINE)PropPageThreadProc,
(LPVOID)this,
0,
(LPDWORD)&idThread);
if (INVALID_HANDLE_VALUE != hThread)
{
hr = NOERROR;
CloseHandle(hThread);
}
return hr;
}
//-----------------------------------------------------------------------------
// Snap-in data object implementation. CDataObject
//-----------------------------------------------------------------------------
CDataObject::CDataObject(
CSnapInCompData& cd
) : m_cRef(0),
m_cd(cd),
m_type(CCT_UNINITIALIZED),
m_pItem(NULL)
{
DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CDataObject::CDataObject")));
}
CDataObject::~CDataObject(
void
)
{
DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CDataObject::~CDataObject")));
}
HRESULT
CDataObject::QueryInterface(
REFIID riid,
LPVOID *ppvOut
)
{
DBGTRACE((DM_SNAPIN, DL_MID, TEXT("CDataObject::QueryInterface")));
DBGPRINTIID(DM_SNAPIN, DL_MID, riid);
HRESULT hr = E_NOINTERFACE;
if (NULL == ppvOut)
return E_INVALIDARG;
*ppvOut = NULL;
if (IID_IDiskQuotaSnapInData == riid)
{
*ppvOut = reinterpret_cast<IQuotaDataObject *>(this);
}
else if(IID_IUnknown == riid || IID_IDataObject == riid)
{
*ppvOut = this;
}
if (NULL != *ppvOut)
{
((LPUNKNOWN)*ppvOut)->AddRef();
hr = NOERROR;
}
return hr;
}
ULONG
CDataObject::AddRef(
void
)
{
DBGTRACE((DM_SNAPIN, DL_LOW, TEXT("CDataObject::AddRef")));
ULONG ulReturn = m_cRef + 1;
InterlockedIncrement(&m_cRef);
return ulReturn;
}
ULONG
CDataObject::Release(
void
)
{
DBGTRACE((DM_SNAPIN, DL_LOW, TEXT("CDataObject::Release")));
ULONG ulReturn = m_cRef - 1;
if (InterlockedDecrement(&m_cRef) == 0)
{
delete this;
ulReturn = 0;
}
return ulReturn;
}
HRESULT
CDataObject::GetDataHere(
LPFORMATETC lpFormatetc,
LPSTGMEDIUM lpMedium
)
{
DBGTRACE((DM_SNAPIN, DL_HIGH, TEXT("CDataObject::GetDataHere")));
HRESULT hr = S_OK;
try
{
//
// Forward the rendering request to the data object's item object.
//
hr = m_pItem->RenderData(lpFormatetc->cfFormat, lpMedium);
}
catch(CAllocException& e)
{
DBGERROR((TEXT("Insufficient memory")));
hr = E_OUTOFMEMORY;
}
return hr;
}
#endif // POLICY_MMC_SNAPIN