/////////////////////////////////////////////////////////////////////////////// /* 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(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(&m_pResult)); if (FAILED(hr)) return hr; // // Get IHeaderCtrl interface to header control. // hr = m_pConsole->QueryInterface(IID_IHeaderCtrl, reinterpret_cast(&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(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(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(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(""), // 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(this); } else if (IID_IExtendContextMenu == riid) { *ppvOut = static_cast(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(&m_pConsole)); if (FAILED(hr)) { DBGERROR((TEXT("CSnapInCompData failed QI for IID_IConsole"))); return hr; } hr = pUnk->QueryInterface(IID_IConsoleNameSpace, reinterpret_cast(&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(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(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(&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(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(&pDataA)))) return S_FALSE; if (FAILED(pdoB->QueryInterface(IID_IDiskQuotaSnapInData, reinterpret_cast(&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(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(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(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 psei; HRESULT hr = CoInitialize(NULL); if (SUCCEEDED(hr)) { hr = CoCreateInstance(CLSID_DiskQuotaUI, NULL, CLSCTX_INPROC_SERVER, IID_IShellExtInit, reinterpret_cast(psei.getaddr())); if (SUCCEEDED(hr)) { com_autoptr pspse; hr = psei->QueryInterface(IID_ISnapInPropSheetExt, reinterpret_cast(pspse.getaddr())); if (SUCCEEDED(hr)) { com_autoptr pdqp; hr = pspse->QueryInterface(IID_IDiskQuotaPolicy, reinterpret_cast(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(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