windows-nt/Source/XPSP1/NT/ds/security/gina/snapins/fde/scope.cpp

921 lines
26 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//+--------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1994 - 1998.
//
// File: scope.cpp
//
// Contents: implementation of the scope pane
//
// Classes: CScopePane
//
// History: 03-14-1998 stevebl Created
// 07-16-1998 rahulth Added calls to IGPEInformation::PolicyChanged
//
//---------------------------------------------------------------------------
#include "precomp.hxx"
#include <shlobj.h>
#include <winnetwk.h>
// Comment this line to stop trying to set the main snapin icon in the
// scope pane.
#define SET_SCOPE_ICONS 1
// Un-comment the next line to persist snap-in related data. (This really
// shouldn't be necessary since I get all my info from my parent anyway.)
// #define PERSIST_DATA 1
///////////////////////////////////////////////////////////////////////////////
// IComponentData implementation
DEBUG_DECLARE_INSTANCE_COUNTER(CScopePane);
CScopePane::CScopePane()
{
HKEY hKey;
DWORD dwDisp;
DEBUG_INCREMENT_INSTANCE_COUNTER(CScopePane);
m_bIsDirty = FALSE;
m_fRSOP = FALSE;
m_pScope = NULL;
m_pConsole = NULL;
m_pIPropertySheetProvider = NULL;
m_fLoaded = FALSE;
m_fExtension = FALSE;
m_pIGPEInformation = NULL;
m_pIRSOPInformation = NULL;
}
CScopePane::~CScopePane()
{
DEBUG_DECREMENT_INSTANCE_COUNTER(CScopePane);
ASSERT(m_pScope == NULL);
ASSERT(CResultPane::lDataObjectRefCount == 0);
}
#include <msi.h>
//+--------------------------------------------------------------------------
//
// Member: CScopePane::CreateNestedDirectory
//
// Synopsis: Ensures the existance of a path. If any directory along the
// path doesn't exist, this routine will create it.
//
// Arguments: [lpDirectory] - path to the leaf directory
// [lpSecurityAttributes] - security attributes
//
// Returns: 1 on success
// 0 on failure
//
// History: 3-17-1998 stevebl Copied from ADE
//
// Notes: Originally written by EricFlo
//
//---------------------------------------------------------------------------
UINT CScopePane::CreateNestedDirectory (LPTSTR lpDirectory, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
{
TCHAR szDirectory[MAX_PATH];
LPTSTR lpEnd;
//
// Check for NULL pointer
//
if (!lpDirectory || !(*lpDirectory)) {
SetLastError(ERROR_INVALID_DATA);
return 0;
}
//
// First, see if we can create the directory without having
// to build parent directories.
//
if (CreateDirectory (lpDirectory, lpSecurityAttributes)) {
return 1;
}
//
// If this directory exists already, this is OK too.
//
if (GetLastError() == ERROR_ALREADY_EXISTS) {
return ERROR_ALREADY_EXISTS;
}
//
// No luck, copy the string to a buffer we can munge
//
lstrcpy (szDirectory, lpDirectory);
//
// Find the first subdirectory name
//
lpEnd = szDirectory;
if (szDirectory[1] == TEXT(':')) {
lpEnd += 3;
} else if (szDirectory[1] == TEXT('\\')) {
//
// Skip the first two slashes
//
lpEnd += 2;
//
// Find the slash between the server name and
// the share name.
//
while (*lpEnd && *lpEnd != TEXT('\\')) {
lpEnd++;
}
if (!(*lpEnd)) {
return 0;
}
//
// Skip the slash, and find the slash between
// the share name and the directory name.
//
lpEnd++;
while (*lpEnd && *lpEnd != TEXT('\\')) {
lpEnd++;
}
if (!(*lpEnd)) {
return 0;
}
//
// Leave pointer at the beginning of the directory.
//
lpEnd++;
} else if (szDirectory[0] == TEXT('\\')) {
lpEnd++;
}
while (*lpEnd) {
while (*lpEnd && *lpEnd != TEXT('\\')) {
lpEnd++;
}
if (*lpEnd == TEXT('\\')) {
*lpEnd = TEXT('\0');
if (!CreateDirectory (szDirectory, NULL)) {
if (GetLastError() != ERROR_ALREADY_EXISTS) {
return 0;
}
}
*lpEnd = TEXT('\\');
lpEnd++;
}
}
//
// Create the final directory
//
if (CreateDirectory (szDirectory, lpSecurityAttributes)) {
return 1;
}
if (GetLastError() == ERROR_ALREADY_EXISTS) {
return ERROR_ALREADY_EXISTS;
}
//
// Failed
//
return 0;
}
STDMETHODIMP CScopePane::Initialize(LPUNKNOWN pUnknown)
{
ASSERT(pUnknown != NULL);
HRESULT hr;
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// MMC should only call ::Initialize once!
ASSERT(m_pScope == NULL);
pUnknown->QueryInterface(IID_IConsoleNameSpace,
reinterpret_cast<void**>(&m_pScope));
ASSERT(hr == S_OK);
hr = pUnknown->QueryInterface(IID_IPropertySheetProvider,
(void **)&m_pIPropertySheetProvider);
hr = pUnknown->QueryInterface(IID_IConsole, reinterpret_cast<void**>(&m_pConsole));
ASSERT(hr == S_OK);
hr = m_pConsole->QueryInterface (IID_IDisplayHelp, reinterpret_cast<void**>(&m_pDisplayHelp));
ASSERT(hr == S_OK);
#ifdef SET_SCOPE_ICONS
LPIMAGELIST lpScopeImage;
hr = m_pConsole->QueryScopeImageList(&lpScopeImage);
ASSERT(hr == S_OK);
// Load the bitmaps from the dll
CBitmap bmp16x16;
CBitmap bmp32x32;
bmp16x16.LoadBitmap(IDB_16x16);
bmp32x32.LoadBitmap(IDB_32x32);
// Set the images
lpScopeImage->ImageListSetStrip(reinterpret_cast<LONG_PTR *>(static_cast<HBITMAP>(bmp16x16)),
reinterpret_cast<LONG_PTR *>(static_cast<HBITMAP>(bmp32x32)),
0, RGB(255,0,255));
lpScopeImage->Release();
#endif
return S_OK;
}
STDMETHODIMP CScopePane::CreateComponent(LPCOMPONENT* ppComponent)
{
ASSERT(ppComponent != NULL);
CComObject<CResultPane>* pObject;
CComObject<CResultPane>::CreateInstance(&pObject);
ASSERT(pObject != NULL);
m_pResultPane = pObject;
// Store IComponentData
pObject->SetIComponentData(this);
return pObject->QueryInterface(IID_IComponent,
reinterpret_cast<void**>(ppComponent));
}
STDMETHODIMP CScopePane::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
{
ASSERT(m_pScope != NULL);
HRESULT hr = S_OK;
UINT i;
// Since it's my folder it has an internal format.
// Design Note: for extension. I can use the fact, that the data object doesn't have
// my internal format and I should look at the node type and see how to extend it.
if (event == MMCN_PROPERTY_CHANGE)
{
// perform any action needed as a result of result property changes
hr = OnProperties(param);
}
else
{
INTERNAL* pInternal = ExtractInternalFormat(lpDataObject);
MMC_COOKIE cookie = 0;
if (pInternal != NULL)
{
cookie = pInternal->m_cookie;
FREE_INTERNAL(pInternal);
}
else
{
// only way we could not be able to extract our own format is if we're operating as an extension
m_fExtension = TRUE;
}
if (m_fRSOP)
{
WCHAR szBuffer[MAX_DS_PATH];
if (m_pIRSOPInformation == NULL)
{
IRSOPInformation * pIRSOPInformation;
hr = lpDataObject->QueryInterface(IID_IRSOPInformation,
reinterpret_cast<void**>(&pIRSOPInformation));
if (SUCCEEDED(hr))
{
m_pIRSOPInformation = pIRSOPInformation;
m_pIRSOPInformation->AddRef();
/* extract the namespace here */
hr = m_pIRSOPInformation->GetNamespace(GPO_SECTION_USER, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]));
if (SUCCEEDED(hr))
{
m_szRSOPNamespace = szBuffer;
}
pIRSOPInformation->Release();
}
}
}
else
{
if (m_pIGPEInformation == NULL)
{
IGPEInformation * pIGPEInformation;
hr = lpDataObject->QueryInterface(IID_IGPEInformation,
reinterpret_cast<void**>(&pIGPEInformation));
if (SUCCEEDED(hr))
{
GROUP_POLICY_OBJECT_TYPE gpoType;
hr = pIGPEInformation->GetType(&gpoType);
if (SUCCEEDED(hr))
{
if (gpoType == GPOTypeDS)
{
WCHAR szBuffer[MAX_PATH];
do
{
AFX_MANAGE_STATE (AfxGetStaticModuleState());
hr = pIGPEInformation->GetFileSysPath(GPO_SECTION_USER, szBuffer, MAX_PATH);
if (FAILED(hr))
break;
m_pIGPEInformation = pIGPEInformation;
m_pIGPEInformation->AddRef();
m_szFileRoot = szBuffer;
m_szFileRoot += L"\\Documents & Settings";
CreateNestedDirectory (((LPOLESTR)(LPCOLESTR)(m_szFileRoot)), NULL);
//initialize the folder data.
for (i = IDS_DIRS_START; i < IDS_DIRS_END; i++)
{
m_FolderData[GETINDEX(i)].Initialize (i,
(LPCTSTR) m_szFileRoot);
}
ConvertOldStyleSection (m_szFileRoot);
} while (0);
}
else
{
// force this to fail
hr = E_FAIL;
}
}
pIGPEInformation->Release();
}
}
}
if (SUCCEEDED(hr))
{
switch(event)
{
case MMCN_EXPAND:
{
hr = OnExpand(cookie, arg, param);
}
break;
case MMCN_SELECT:
hr = OnSelect(cookie, arg, param);
break;
case MMCN_CONTEXTMENU:
hr = OnContextMenu(cookie, arg, param);
break;
default:
//perform the default action
hr = S_FALSE;
break;
}
}
}
return hr;
}
STDMETHODIMP CScopePane::Destroy()
{
SAFE_RELEASE(m_pScope);
SAFE_RELEASE(m_pDisplayHelp);
SAFE_RELEASE(m_pConsole);
SAFE_RELEASE(m_pIPropertySheetProvider);
SAFE_RELEASE(m_pIGPEInformation);
SAFE_RELEASE(m_pIRSOPInformation);
return S_OK;
}
STDMETHODIMP CScopePane::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject)
{
ASSERT(ppDataObject != NULL);
CComObject<CDataObject>* pObject = NULL;
CComObject<CDataObject>::CreateInstance(&pObject);
ASSERT(pObject != NULL);
if (!pObject)
return E_UNEXPECTED;
// Save cookie and type for delayed rendering
pObject->SetID (m_FolderData[GETINDEX(cookie)].m_scopeID);
pObject->SetType(type);
pObject->SetCookie(cookie);
return pObject->QueryInterface(IID_IDataObject,
reinterpret_cast<void**>(ppDataObject));
}
///////////////////////////////////////////////////////////////////////////////
//// IPersistStreamInit interface members
STDMETHODIMP CScopePane::GetClassID(CLSID *pClassID)
{
ASSERT(pClassID != NULL);
// Copy the CLSID for this snapin
*pClassID = CLSID_Snapin;
return S_OK;
}
STDMETHODIMP CScopePane::IsDirty()
{
return ThisIsDirty() ? S_OK : S_FALSE;
}
STDMETHODIMP CScopePane::Load(IStream *pStm)
{
#ifdef PERSIST_DATA
ASSERT(pStm);
// UNDONE - Read data from the stream here.
return SUCCEEDED(hr) ? S_OK : E_FAIL;
#else
return S_OK;
#endif
}
STDMETHODIMP CScopePane::Save(IStream *pStm, BOOL fClearDirty)
{
#ifdef PERSIST_DATA
ASSERT(pStm);
// UNDONE - Write data to the stream here.
// on error, return STG_E_CANTSAVE;
#endif
if (fClearDirty)
ClearDirty();
return S_OK;
}
STDMETHODIMP CScopePane::GetSizeMax(ULARGE_INTEGER *pcbSize)
{
ASSERT(pcbSize);
// UNDONE - set the size of the string to be saved
ULONG cb = 0;
// Set the size of the string to be saved
ULISet32(*pcbSize, cb);
return S_OK;
}
STDMETHODIMP CScopePane::InitNew(void)
{
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
//// Notify handlers for IComponentData
HRESULT CScopePane::OnAdd(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
{
return E_UNEXPECTED;
}
HRESULT CScopePane::OnExpand(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
{
if (arg == TRUE) //MMC never sends arg = FALSE (for collapse)
{
// Did Initialize get called?
ASSERT(m_pScope != NULL);
EnumerateScopePane(cookie,
param);
}
return S_OK;
}
HRESULT CScopePane::OnSelect(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
{
return E_UNEXPECTED;
}
HRESULT CScopePane::OnContextMenu(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
{
return S_OK;
}
HRESULT CScopePane::OnProperties(LPARAM param)
{
if (param == NULL)
{
return S_OK;
}
ASSERT(param != NULL);
return S_OK;
}
void CScopePane::EnumerateScopePane(MMC_COOKIE cookie, HSCOPEITEM pParent)
{
AFX_MANAGE_STATE (AfxGetStaticModuleState());
CString szFullPathname;
CString szParent;
SCOPEDATAITEM scopeItem;
FILETIME ftCurr;
LONG i;
int cChildren = 0;
DWORD myDocsFlags = REDIR_DONT_CARE;
DWORD myPicsFlags = REDIR_DONT_CARE;
memset(&scopeItem, 0, sizeof(SCOPEDATAITEM));
CHourglass hourglass; //this may take some time, so put up an hourglass
GetSystemTimeAsFileTime (&ftCurr);
//set the common members for the scope pane items
scopeItem.mask = SDI_STR | SDI_PARAM | SDI_CHILDREN;
#ifdef SET_SCOPE_ICONS
scopeItem.mask |= SDI_IMAGE | SDI_OPENIMAGE;
scopeItem.nImage = IMG_CLOSEDBOX;
scopeItem.nOpenImage = IMG_OPENBOX;
#endif
scopeItem.relativeID = pParent;
scopeItem.displayname = MMC_CALLBACK;
if (m_fExtension)
{
switch(cookie)
{
case NULL: //getting the folder
// if we're an extension then add a root folder to hang everything off of
if (m_fRSOP)
{
// make sure that nodes don't get enumerated if they contain no data
if (FAILED(m_pResultPane->TestForRSOPData(cookie)))
{
return;
}
}
scopeItem.lParam = IDS_FOLDER_TITLE; //use resource id's as cookies
scopeItem.cChildren = 1;
m_pScope->InsertItem(&scopeItem);
break;
case IDS_FOLDER_TITLE:
for (i = IDS_LEVEL1_DIRS_START; i < IDS_LEVEL1_DIRS_END; i++)
{
BOOL fInsert = TRUE;
if (m_fRSOP)
{
if (FAILED(m_pResultPane->TestForRSOPData(i)))
{
fInsert = FALSE;
}
}
if (fInsert)
{
scopeItem.lParam = i;
m_FolderData[GETINDEX(i)].Initialize(i,
(LPCTSTR) m_szFileRoot
);
if (i == IDS_MYDOCS && !m_fRSOP)
{
//
// Show the My Pictures folder only if it does not follow MyDocs.
// and only if there is no registry setting overriding the hiding behavior
// for My Pics
//
if (AlwaysShowMyPicsNode())
{
cChildren = 1;
m_FolderData[GETINDEX(i)].m_bHideChildren = FALSE;
}
else
{
m_FolderData[GETINDEX(IDS_MYPICS)].Initialize(IDS_MYPICS,
(LPCTSTR) m_szFileRoot
);
m_FolderData[GETINDEX(i)].LoadSection();
m_FolderData[GETINDEX(IDS_MYPICS)].LoadSection();
myDocsFlags = m_FolderData[GETINDEX(i)].m_dwFlags;
myPicsFlags = m_FolderData[GETINDEX(IDS_MYPICS)].m_dwFlags;
if (((REDIR_DONT_CARE & myDocsFlags) && (REDIR_DONT_CARE & myPicsFlags)) ||
((REDIR_FOLLOW_PARENT & myPicsFlags) && (!(REDIR_DONT_CARE & myDocsFlags)))
)
{
cChildren = 0;
m_FolderData[GETINDEX(i)].m_bHideChildren = TRUE;
}
else
{
cChildren = 1;
m_FolderData[GETINDEX(i)].m_bHideChildren = FALSE;
}
}
}
scopeItem.cChildren = cChildren; //only My Docs will possibly have children
m_pScope->InsertItem(&scopeItem);
m_FolderData[GETINDEX(i)].SetScopeItemID(scopeItem.ID);
}
if (IDS_MYDOCS == i && m_fRSOP && SUCCEEDED(m_pResultPane->TestForRSOPData(IDS_MYPICS)))
{
// In RSOP mode we put My Pictures after My Documents
// instead of under it. Otherwise the results pane
// for My Documents would contain a folder along with
// the data and it would look very odd.
scopeItem.lParam = IDS_MYPICS;
scopeItem.cChildren = 0;
m_pScope->InsertItem(&scopeItem);
m_FolderData[GETINDEX(IDS_MYPICS)].Initialize (IDS_MYPICS,
(LPCTSTR) m_szFileRoot
);
m_FolderData[GETINDEX(IDS_MYPICS)].SetScopeItemID(scopeItem.ID);
}
}
break;
case IDS_MYDOCS: //of all levels 1 folder, only MyDocs has children
if (!m_fRSOP && !(m_FolderData[GETINDEX(IDS_MYDOCS)].m_bHideChildren))
{
scopeItem.lParam = IDS_MYPICS;
scopeItem.cChildren = 0;
m_pScope->InsertItem(&scopeItem);
m_FolderData[GETINDEX(IDS_MYPICS)].Initialize (IDS_MYPICS,
(LPCTSTR) m_szFileRoot
);
m_FolderData[GETINDEX(IDS_MYPICS)].SetScopeItemID(scopeItem.ID);
}
break;
}
}
}
STDMETHODIMP CScopePane::GetSnapinDescription(LPOLESTR * lpDescription)
{
// UNDONE
OLESAFE_COPYSTRING(*lpDescription, L"description");
return S_OK;
}
STDMETHODIMP CScopePane::GetProvider(LPOLESTR * lpName)
{
// UNDONE
OLESAFE_COPYSTRING(*lpName, L"provider");
return S_OK;
}
STDMETHODIMP CScopePane::GetSnapinVersion(LPOLESTR * lpVersion)
{
// UNDONE
OLESAFE_COPYSTRING(*lpVersion, L"version");
return S_OK;
}
STDMETHODIMP CScopePane::GetSnapinImage(HICON * hAppIcon)
{
// UNDONE
return E_NOTIMPL;
}
STDMETHODIMP CScopePane::GetStaticFolderImage(HBITMAP * hSmallImage,
HBITMAP * hSmallImageOpen,
HBITMAP * hLargeImage,
COLORREF * cMask)
{
// UNDONE
return E_NOTIMPL;
}
STDMETHODIMP CScopePane::GetHelpTopic(LPOLESTR *lpCompiledHelpFile)
{
LPOLESTR lpHelpFile;
lpHelpFile = (LPOLESTR) CoTaskMemAlloc (MAX_PATH * sizeof(WCHAR));
if (!lpHelpFile)
{
DbgMsg((TEXT("CScopePane::GetHelpTopic: Failed to allocate memory.")));
return E_OUTOFMEMORY;
}
ExpandEnvironmentStringsW (L"%SystemRoot%\\Help\\gpedit.chm",
lpHelpFile, MAX_PATH);
*lpCompiledHelpFile = lpHelpFile;
return S_OK;
}
STDMETHODIMP CScopePane::GetDisplayInfo(SCOPEDATAITEM* pScopeDataItem)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
LONG i;
ASSERT(pScopeDataItem != NULL);
if (pScopeDataItem == NULL)
return E_POINTER;
if (IDS_FOLDER_TITLE == pScopeDataItem->lParam)
{
m_szFolderTitle.LoadString(IDS_FOLDER_TITLE);
pScopeDataItem->displayname = (unsigned short *)((LPCOLESTR)m_szFolderTitle);
}
else
{
pScopeDataItem->displayname = L"???";
if (-1 != (i = GETINDEX(pScopeDataItem->lParam)))
pScopeDataItem->displayname = (unsigned short*)((LPCOLESTR)(m_FolderData[i].m_szDisplayname));
}
ASSERT(pScopeDataItem->displayname != NULL);
return S_OK;
}
STDMETHODIMP CScopePane::CompareObjects(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
{
if (lpDataObjectA == NULL || lpDataObjectB == NULL)
return E_POINTER;
// Make sure both data object are mine
INTERNAL* pA;
INTERNAL* pB;
HRESULT hr = S_FALSE;
pA = ExtractInternalFormat(lpDataObjectA);
pB = ExtractInternalFormat(lpDataObjectB);
if (pA != NULL && pB != NULL)
hr = ((pA->m_type == pB->m_type) && (pA->m_cookie == pB->m_cookie)) ? S_OK : S_FALSE;
FREE_INTERNAL(pA);
FREE_INTERNAL(pB);
return hr;
}
// Scope item property pages:
STDMETHODIMP CScopePane::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider,
LONG_PTR handle,
LPDATAOBJECT lpIDataObject)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = S_FALSE;
INTERNAL* pInternal = ExtractInternalFormat(lpIDataObject);
if (! pInternal)
return S_FALSE;
DWORD cookie = pInternal->m_cookie;
LONG i;
BOOL fShowPage = FALSE;
AFX_OLDPROPSHEETPAGE * pPsp;
AFX_OLDPROPSHEETPAGE * pPspSettings;
CFileInfo* pFileInfo;
//it is one of the folders
i = GETINDEX (cookie);
pFileInfo = &(m_FolderData[i]);
if (!pFileInfo->m_pRedirPage) //make sure that the property page is not already up.
{
pFileInfo->m_pRedirPage = new CRedirect(cookie);
pFileInfo->m_pRedirPage->m_ppThis = &(pFileInfo->m_pRedirPage);
pFileInfo->m_pRedirPage->m_pScope = this;
pFileInfo->m_pRedirPage->m_pFileInfo = pFileInfo;
fShowPage = TRUE;
pPsp = (AFX_OLDPROPSHEETPAGE *)&(pFileInfo->m_pRedirPage->m_psp);
//create the settings page;
pFileInfo->m_pSettingsPage = new CRedirPref();
pFileInfo->m_pSettingsPage->m_ppThis = &(pFileInfo->m_pSettingsPage);
pFileInfo->m_pSettingsPage->m_pFileInfo = pFileInfo;
pPspSettings = (AFX_OLDPROPSHEETPAGE *)&(pFileInfo->m_pSettingsPage->m_psp);
}
if (fShowPage) //show page if it is not already up.
{
hr = SetPropPageToDeleteOnClose (pPsp);
if (SUCCEEDED (hr))
hr = SetPropPageToDeleteOnClose (pPspSettings);
if (SUCCEEDED(hr))
{
HPROPSHEETPAGE hProp = CreateThemedPropertySheetPage(pPsp);
HPROPSHEETPAGE hPropSettings = CreateThemedPropertySheetPage(pPspSettings);
if (NULL == hProp || NULL == hPropSettings )
hr = E_UNEXPECTED;
else
{
lpProvider->AddPage(hProp);
lpProvider->AddPage (hPropSettings);
hr = S_OK;
}
}
}
FREE_INTERNAL(pInternal);
return hr;
}
// Scope item property pages:
STDMETHODIMP CScopePane::QueryPagesFor(LPDATAOBJECT lpDataObject)
{
// scope panes don't have property pages in RSOP mode
if (m_fRSOP)
{
return S_FALSE;
}
//the only property sheets we are presenting right now are those
//for built-in folder redirection
INTERNAL* pInternal = ExtractInternalFormat(lpDataObject);
if (! pInternal)
return S_FALSE;
MMC_COOKIE cookie = pInternal->m_cookie;
HRESULT hr = S_FALSE;
CError error;
if (CCT_SCOPE == pInternal->m_type)
{
if (SUCCEEDED(m_FolderData[GETINDEX(cookie)].LoadSection()))
hr = S_OK;
else
{
error.ShowConsoleMessage (m_pConsole, IDS_SECTIONLOAD_ERROR,
m_FolderData[GETINDEX(cookie)].m_szDisplayname);
hr = S_FALSE;
}
}
FREE_INTERNAL(pInternal);
return hr;
}
BOOL CScopePane::IsScopePaneNode(LPDATAOBJECT lpDataObject)
{
BOOL bResult = FALSE;
INTERNAL* pInternal = ExtractInternalFormat(lpDataObject);
if (! pInternal)
return bResult;
if (pInternal->m_type == CCT_SCOPE)
bResult = TRUE;
FREE_INTERNAL(pInternal);
return bResult;
}
///////////////////////////////////////////////////////////////////////////////
// IExtendContextMenu implementation
//
STDMETHODIMP CScopePane::AddMenuItems(LPDATAOBJECT pDataObject,
LPCONTEXTMENUCALLBACK pContextMenuCallback,
LONG * pInsertionAllowed)
{
//we do not have any commands on the menu.
return S_OK;
}
STDMETHODIMP CScopePane::Command(long nCommandID, LPDATAOBJECT pDataObject)
{
//we do not have any commands on the menu
return S_OK;
}