Leaked source code of windows server 2003
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.
 
 
 
 
 
 

1018 lines
28 KiB

// This is a part of the Microsoft Management Console.
// Copyright (C) Microsoft Corporation, 1995 - 1999
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Management Console and related
// electronic documentation provided with the interfaces.
#include "stdafx.h"
#include <sceattch.h>
#include "genpage.h"
#include <atlimpl.cpp>
#define __dwFILE__ __dwFILE_CAPESNPN_COMPDATA_CPP__
// Array of menu item commands to be inserted into the contest menu.
// Note - the first item is the menu text, // CCM_SPECIAL_DEFAULT_ITEM
// the second item is the status string
///////////////////////////////////////////////////////////////////////////////
// IComponentData implementation
DEBUG_DECLARE_INSTANCE_COUNTER(CComponentDataImpl);
CComponentDataImpl::CComponentDataImpl()
: m_bIsDirty(TRUE), m_pScope(NULL), m_pConsole(NULL),
#if DBG
m_bInitializedCD(false), m_bDestroyedCD(false),
#endif
m_fAdvancedServer(false), m_hrCreateFolder(S_OK)
{
DEBUG_INCREMENT_INSTANCE_COUNTER(CComponentDataImpl);
#ifdef _DEBUG
m_cDataObjects = 0;
#endif
}
CComponentDataImpl::~CComponentDataImpl()
{
DEBUG_DECREMENT_INSTANCE_COUNTER(CComponentDataImpl);
ASSERT(m_pScope == NULL);
ASSERT(!m_bInitializedCD || m_bDestroyedCD);
// Some snap-in is hanging on to data objects.
// If they access, it will crash!!!
ASSERT(m_cDataObjects <= 1);
}
STDMETHODIMP CComponentDataImpl::Initialize(LPUNKNOWN pUnknown)
{
DBX_PRINT(_T(" ---------- CComponentDataImpl::Initialize<0x08x>\n"), this);
#if DBG
m_bInitializedCD = true;
#endif
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));
// add the images for the scope tree
::CBitmap bmp16x16;
LPIMAGELIST lpScopeImage;
hr = pUnknown->QueryInterface(IID_IConsole2, reinterpret_cast<void**>(&m_pConsole));
ASSERT(hr == S_OK);
hr = m_pConsole->QueryScopeImageList(&lpScopeImage);
ASSERT(hr == S_OK);
// Load the bitmaps from the dll
bmp16x16.LoadBitmap(IDB_16x16);
// Set the images
lpScopeImage->ImageListSetStrip(reinterpret_cast<LONG_PTR *>(static_cast<HBITMAP>(bmp16x16)),
reinterpret_cast<LONG_PTR *>(static_cast<HBITMAP>(bmp16x16)),
0, RGB(255, 0, 255));
lpScopeImage->Release();
// Add any init code here NOT based on info from .MSC file
return S_OK;
}
STDMETHODIMP CComponentDataImpl::CreateComponent(LPCOMPONENT* ppComponent)
{
ASSERT(ppComponent != NULL);
CComObject<CSnapin>* pObject;
CComObject<CSnapin>::CreateInstance(&pObject);
ASSERT(pObject != NULL);
// Store IComponentData
pObject->SetIComponentData(this);
return pObject->QueryInterface(IID_IComponent,
reinterpret_cast<void**>(ppComponent));
}
STDMETHODIMP CComponentDataImpl::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
{
ASSERT(m_pScope != NULL);
HRESULT hr = S_OK;
HWND hwndConsole;
AFX_MANAGE_STATE(AfxGetStaticModuleState());
INTERNAL* pInternal;
MMC_COOKIE cookie;
// 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.
// switch on events where we don't care about pInternal->m_cookie
switch(event)
{
case MMCN_PROPERTY_CHANGE:
hr = OnProperties(param);
goto Ret;
case MMCN_EXPAND:
hr = OnExpand(lpDataObject, arg, param);
goto Ret;
default:
break;
}
// handle cases where we do care about pInternal->m_cookie
pInternal = ExtractInternalFormat(lpDataObject);
if (pInternal == NULL)
return S_OK;
cookie = pInternal->m_cookie;
::GlobalFree(reinterpret_cast<HANDLE>(pInternal));
switch(event)
{
case MMCN_PASTE:
break;
case MMCN_DELETE:
hr = OnDelete(cookie);
break;
case MMCN_REMOVE_CHILDREN:
hr = OnRemoveChildren(arg);
break;
case MMCN_RENAME:
hr = OnRename(cookie, arg, param);
break;
default:
break;
}
Ret:
return hr;
}
STDMETHODIMP CComponentDataImpl::Destroy()
{
DBX_PRINT(_T(" ---------- CComponentDataImpl::Destroy<0x08x>\n"), this);
ASSERT(m_bInitializedCD);
#if DBG
m_bDestroyedCD = true;
#endif
// Delete enumerated scope items
DeleteList();
SAFE_RELEASE(m_pScope);
SAFE_RELEASE(m_pConsole);
return S_OK;
}
STDMETHODIMP CComponentDataImpl::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject)
{
#ifdef _DEBUG
if (cookie == 0)
{
ASSERT(type != CCT_RESULT);
}
else
{
ASSERT(type == CCT_SCOPE);
DWORD dwItemType = GetItemType(cookie);
ASSERT(dwItemType == SCOPE_LEVEL_ITEM);
//ASSERT((dwItemType == SCOPE_LEVEL_ITEM) || (dwItemType == CA_LEVEL_ITEM));
}
#endif
return _QueryDataObject(cookie, type, this, ppDataObject);
}
///////////////////////////////////////////////////////////////////////////////
//// ISnapinHelp interface
STDMETHODIMP CComponentDataImpl::GetHelpTopic(LPOLESTR* lpCompiledHelpFile)
{
if (lpCompiledHelpFile == NULL)
return E_POINTER;
UINT cbWindows = 0;
WCHAR szWindows[MAX_PATH+1];
cbWindows = GetSystemWindowsDirectory(szWindows, MAX_PATH);
if (cbWindows == 0)
return S_FALSE;
cbWindows += wcslen(HTMLHELP_COLLECTION_FILENAME);
cbWindows++; // include null term
cbWindows *= sizeof(WCHAR); // make this bytes, not chars
*lpCompiledHelpFile = (LPOLESTR) CoTaskMemAlloc(cbWindows);
if (*lpCompiledHelpFile == NULL)
return E_OUTOFMEMORY;
myRegisterMemFree(*lpCompiledHelpFile, CSM_COTASKALLOC); // this is freed by mmc, not our tracking
USES_CONVERSION;
wcscpy(*lpCompiledHelpFile, T2OLE(szWindows));
wcscat(*lpCompiledHelpFile, T2OLE(HTMLHELP_COLLECTION_FILENAME));
return S_OK;
}
// tells of other topics my chm links to
STDMETHODIMP CComponentDataImpl::GetLinkedTopics(LPOLESTR* lpCompiledHelpFiles)
{
if (lpCompiledHelpFiles == NULL)
return E_POINTER;
UINT cbWindows = 0;
WCHAR szWindows[MAX_PATH+1];
cbWindows = GetSystemWindowsDirectory(szWindows, MAX_PATH);
if (cbWindows == 0)
return S_FALSE;
cbWindows += wcslen(HTMLHELP_COLLECTIONLINK_FILENAME);
cbWindows++; // include null term
cbWindows *= sizeof(WCHAR); // make this bytes, not chars
*lpCompiledHelpFiles = (LPOLESTR) CoTaskMemAlloc(cbWindows);
if (*lpCompiledHelpFiles == NULL)
return E_OUTOFMEMORY;
myRegisterMemFree(*lpCompiledHelpFiles, CSM_COTASKALLOC); // this is freed by mmc, not our tracking
USES_CONVERSION;
wcscpy(*lpCompiledHelpFiles, T2OLE(szWindows));
wcscat(*lpCompiledHelpFiles, T2OLE(HTMLHELP_COLLECTIONLINK_FILENAME));
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
//// IPersistStream interface members
/*
STDMETHODIMP CComponentDataImpl::GetClassID(CLSID *pClassID)
{
ASSERT(pClassID != NULL);
// Copy the CLSID for this snapin
*pClassID = CLSID_CAPolicyExtensionSnapIn;
return E_NOTIMPL;
}
*/
STDMETHODIMP CComponentDataImpl::IsDirty()
{
// Always save / Always dirty.
return ThisIsDirty() ? S_OK : S_FALSE;
}
STDMETHODIMP CComponentDataImpl::Load(IStream *pStm)
{
DBX_PRINT(_T(" ---------- CComponentDataImpl::Load<0x08x>\n"), this);
ASSERT(pStm);
ASSERT(m_bInitializedCD);
// Read the string
DWORD dwVer;
ULONG nBytesRead;
HRESULT hr = pStm->Read(&dwVer, sizeof(DWORD), &nBytesRead);
// Verify that the read succeeded
ASSERT(SUCCEEDED(hr) && nBytesRead == sizeof(DWORD));
// check to see if this is the correct version
if (dwVer != 0x1)
{
return STG_E_OLDFORMAT;
}
ClearDirty();
return SUCCEEDED(hr) ? S_OK : E_FAIL;
}
STDMETHODIMP CComponentDataImpl::Save(IStream *pStm, BOOL fClearDirty)
{
DBX_PRINT(_T(" ---------- CComponentDataImpl::Save<0x08x>\n"), this);
ASSERT(pStm);
ASSERT(m_bInitializedCD);
// Write the string
ULONG nBytesWritten;
DWORD dwVer = 0x1;
HRESULT hr = pStm->Write(&dwVer, sizeof(DWORD), &nBytesWritten);
// Verify that the write operation succeeded
ASSERT(SUCCEEDED(hr) && nBytesWritten == sizeof(DWORD));
if (FAILED(hr))
return STG_E_CANTSAVE;
if (fClearDirty)
ClearDirty();
return S_OK;
}
STDMETHODIMP CComponentDataImpl::GetSizeMax(ULARGE_INTEGER *pcbSize)
{
ASSERT(pcbSize);
DWORD cbSize;
cbSize = sizeof(DWORD); // version
// Set the size of the string to be saved
ULISet32(*pcbSize, cbSize);
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
//// Notify handlers for IComponentData
HRESULT CComponentDataImpl::OnDelete(MMC_COOKIE cookie)
{
return S_OK;
}
HRESULT CComponentDataImpl::OnRemoveChildren(LPARAM arg)
{
return S_OK;
}
HRESULT CComponentDataImpl::OnRename(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
{
if (arg == 0)
return S_OK;
LPOLESTR pszNewName = reinterpret_cast<LPOLESTR>(param);
if (pszNewName == NULL)
return E_INVALIDARG;
CFolder* pFolder = reinterpret_cast<CFolder*>(cookie);
ASSERT(pFolder != NULL);
if (pFolder == NULL)
return E_INVALIDARG;
pFolder->SetName(pszNewName);
return S_OK;
}
HRESULT CComponentDataImpl::OnExpand(LPDATAOBJECT lpDataObject, LPARAM arg, LPARAM param)
{
HRESULT hr = S_OK;
GUID* pNodeGUID = NULL;
CFolder* pFolder=NULL;
bool fInsertFolder = false;
STGMEDIUM stgmediumNodeType = { TYMED_HGLOBAL, NULL };
STGMEDIUM stgmediumCAType = { TYMED_HGLOBAL, NULL };
STGMEDIUM stgmediumCAName = { TYMED_HGLOBAL, NULL };
STGMEDIUM stgmediumCARoles = { TYMED_HGLOBAL, NULL };
LPWSTR pszDSName = NULL;
if (arg == TRUE)
{
// Did Initialize get called?
ASSERT(m_pScope != NULL);
//
// get the guid of the current node
//
UINT s_cfNodeType;
s_cfNodeType = RegisterClipboardFormat(W2T(CCF_NODETYPE));
FORMATETC formatetcNodeType = { (CLIPFORMAT)s_cfNodeType, NULL,
DVASPECT_CONTENT, -1, TYMED_HGLOBAL
};
hr = lpDataObject->GetDataHere(&formatetcNodeType, &stgmediumNodeType);
_JumpIfError(hr, Ret, "GetDataHere NodeType");
pNodeGUID = (GUID*) GlobalLock(stgmediumNodeType.hGlobal);
if (pNodeGUID == NULL)
{
hr = E_UNEXPECTED;
_JumpError(hr, Ret, "GlobalLock failed");
}
//
// if this is the parents node then add our node undeneath it
//
// CA Manager parent
if (memcmp(pNodeGUID, (void *)&cCAManagerParentNodeID, sizeof(GUID)) == 0)
{
fInsertFolder = true;
CString szFolderName;
// Only add node under ENT ROOT, ENT SUB
UINT cfCAType = RegisterClipboardFormat(W2T((LPWSTR)SNAPIN_CA_INSTALL_TYPE));
FORMATETC formatetcCAType = { (CLIPFORMAT)cfCAType, NULL,
DVASPECT_CONTENT, -1, TYMED_HGLOBAL
};
hr = lpDataObject->GetDataHere(&formatetcCAType, &stgmediumCAType);
_JumpIfError(hr, Ret, "GetDataHere CAType");
PDWORD rgdw = (DWORD*)GlobalLock(stgmediumCAType.hGlobal);
ENUM_CATYPES caType = (ENUM_CATYPES)rgdw[0];
DBGPRINT((DBG_SS_CERTMMC, "CA Type: %d\n", caType));
// return immediately if we're not an ENT {ROOT | SUB}
if ((caType != ENUM_ENTERPRISE_SUBCA) &&
(caType != ENUM_ENTERPRISE_ROOTCA))
{
hr = S_OK;
goto Ret;
}
m_fAdvancedServer = (rgdw[1]!=0)?true:false;
DBGPRINT((DBG_SS_CERTMMC, "Advanced Server: %hs\n",
m_fAdvancedServer?"yes":"no"));
VERIFY(szFolderName.LoadString(IDS_POLICYSETTINGS));
pFolder = new CFolder();
if(pFolder == NULL)
{
hr = E_OUTOFMEMORY;
goto Ret;
}
pFolder->Create(
(LPWSTR)((LPCTSTR)szFolderName),
IMGINDEX_FOLDER,
IMGINDEX_FOLDER_OPEN,
SCOPE_LEVEL_ITEM,
POLICYSETTINGS,
FALSE);
m_scopeItemList.AddTail(pFolder);
pFolder->m_pScopeItem->relativeID = param;
// Set the folder as the cookie
pFolder->m_pScopeItem->mask |= SDI_PARAM;
pFolder->m_pScopeItem->lParam = reinterpret_cast<LPARAM>(pFolder);
pFolder->SetCookie(reinterpret_cast<LONG_PTR>(pFolder));
// get the name of the CA that we are administering
LPWSTR pCAName = NULL;
// nab CA Name
UINT cfCAName = RegisterClipboardFormat(W2T((LPWSTR)CA_SANITIZED_NAME));
FORMATETC formatetcCAName = { (CLIPFORMAT)cfCAName, NULL,
DVASPECT_CONTENT, -1, TYMED_HGLOBAL
};
hr = lpDataObject->GetDataHere(&formatetcCAName, &stgmediumCAName);
_JumpIfError(hr, Ret, "GetDataHere CAName");
pCAName = (LPWSTR)GlobalLock(stgmediumCAName.hGlobal);
if (pCAName == NULL)
{
hr = E_UNEXPECTED;
_JumpError(hr, Ret, "GlobalLock");
}
pFolder->m_szCAName = pCAName;
hr = mySanitizedNameToDSName(pCAName, &pszDSName);
_JumpIfError(hr, Ret, "mySanitizedNameToDSName");
// Get current user's roles
DWORD* pdwRoles;
UINT cfCARoles = RegisterClipboardFormat(W2T((LPWSTR)CA_ROLES));
FORMATETC formatetcCARoles = { (CLIPFORMAT)cfCARoles, NULL,
DVASPECT_CONTENT, -1, TYMED_HGLOBAL
};
hr = lpDataObject->GetDataHere(&formatetcCARoles, &stgmediumCARoles);
_JumpIfError(hr, Ret, "GetDataHere CAName");
pdwRoles = (DWORD*)GlobalLock(stgmediumCARoles.hGlobal);
if (pdwRoles == NULL)
{
hr = E_UNEXPECTED;
_JumpError(hr, Ret, "GlobalLock");
}
pFolder->m_dwRoles = *pdwRoles;
DBGPRINT((DBG_SS_CERTMMC, "Roles: 0x%08x\n", *pdwRoles));
//
// get a handle to the CA based on the name
//
hr = CAFindByName(
pszDSName,
NULL,
CA_FIND_INCLUDE_UNTRUSTED,
&pFolder->m_hCAInfo);
_JumpIfErrorStr(hr, Ret, "CAFindByName", pszDSName);
// if we made it here then everything is initialized, so add the folder
}
}
// Note - On return, the ID member of 'm_pScopeItem'
// contains the handle to the newly inserted item!
ASSERT(pFolder->m_pScopeItem->ID != NULL);
Ret:
// undo fix to add folder under all circumstances -- we were
// inserting a NULL ptr!
if(fInsertFolder && (NULL != pFolder))
{
m_hrCreateFolder = hr;
m_pScope->InsertItem(pFolder->m_pScopeItem);
}
if (stgmediumNodeType.hGlobal)
{
GlobalUnlock(stgmediumNodeType.hGlobal);
ReleaseStgMedium(&stgmediumNodeType);
}
if (stgmediumCAType.hGlobal)
{
GlobalUnlock(stgmediumCAType.hGlobal);
ReleaseStgMedium(&stgmediumCAType);
}
if (stgmediumCAName.hGlobal)
{
GlobalUnlock(stgmediumCAName.hGlobal);
ReleaseStgMedium(&stgmediumCAName);
}
if (stgmediumCARoles.hGlobal)
{
GlobalUnlock(stgmediumCARoles.hGlobal);
ReleaseStgMedium(&stgmediumCARoles);
}
if (pszDSName)
LocalFree(pszDSName);
return hr;
}
HRESULT CComponentDataImpl::OnSelect(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
{
return E_UNEXPECTED;
}
HRESULT CComponentDataImpl::OnProperties(LPARAM param)
{
HRESULT hr = S_OK;
CFolder* pItem = NULL;
CFolder* pFolder = NULL;
POSITION pos = 0;
if (param == NULL)
{
goto error;
}
ASSERT(param != NULL);
pFolder = new CFolder();
if(pFolder == NULL)
{
hr = E_OUTOFMEMORY;
goto error;
}
// Create a new folder object
pFolder->Create( reinterpret_cast<LPOLESTR>(param), 0, 0, SCOPE_LEVEL_ITEM, STATIC, FALSE);
// The static folder in the last item in the list
pos = m_scopeItemList.GetTailPosition();
ASSERT(pos);
// Add it to the internal list
if (pos)
{
pItem = m_scopeItemList.GetAt(pos);
if(pItem == NULL)
{
hr = E_OUTOFMEMORY;
goto error;
}
m_scopeItemList.AddTail(pFolder);
if((pFolder->m_pScopeItem == NULL) || (pItem->m_pScopeItem == NULL))
{
hr = E_POINTER;
goto error;
}
pFolder->m_pScopeItem->relativeID = pItem->m_pScopeItem->relativeID;
// Set the folder as the cookie
pFolder->m_pScopeItem->mask |= SDI_PARAM;
pFolder->m_pScopeItem->lParam = reinterpret_cast<LPARAM>(pFolder);
pFolder->SetCookie(reinterpret_cast<LONG_PTR>(pFolder));
m_pScope->InsertItem(pFolder->m_pScopeItem);
pFolder = NULL;
}
::GlobalFree(reinterpret_cast<void*>(param));
error:
if(pFolder)
{
delete pFolder;
}
return hr;
}
void CComponentDataImpl::DeleteList()
{
POSITION pos = m_scopeItemList.GetHeadPosition();
while (pos)
delete m_scopeItemList.GetNext(pos);
m_scopeItemList.RemoveAll();
}
CFolder* CComponentDataImpl::FindObject(MMC_COOKIE cookie)
{
CFolder* pFolder = NULL;
POSITION pos = m_scopeItemList.GetHeadPosition();
while(pos)
{
pFolder = m_scopeItemList.GetNext(pos);
if (*pFolder == cookie)
return pFolder;
}
return NULL;
}
STDMETHODIMP CComponentDataImpl::GetDisplayInfo(SCOPEDATAITEM* pScopeDataItem)
{
ASSERT(pScopeDataItem != NULL);
if (pScopeDataItem == NULL)
return E_POINTER;
CFolder* pFolder = reinterpret_cast<CFolder*>(pScopeDataItem->lParam);
if (pScopeDataItem->mask & SDI_STR)
{
//
// if this is certtype folder, and it is for the second column, then add usages string
//
if (FALSE)//(pFolder->m_hCertType != NULL) && (pScopeDataItem-> == ))
{
}
else
{
pScopeDataItem->displayname = pFolder->m_pszName;
}
}
if (pScopeDataItem->mask & SDI_IMAGE)
pScopeDataItem->nImage = pFolder->m_pScopeItem->nImage;
if (pScopeDataItem->mask & SDI_OPENIMAGE)
pScopeDataItem->nOpenImage = pFolder->m_pScopeItem->nOpenImage;
return S_OK;
}
STDMETHODIMP CComponentDataImpl::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(lpDataObjectA);
if (pA != NULL && pB != NULL)
hr = (*pA == *pB) ? S_OK : S_FALSE;
if(pA != NULL)
{
::GlobalFree(reinterpret_cast<HANDLE>(pA));
}
if(pB != NULL)
{
::GlobalFree(reinterpret_cast<HANDLE>(pB));
}
return hr;
}
/////////////////////////////////////////////////////////////////////////////
// IExtendPropertySheet Implementation
STDMETHODIMP CComponentDataImpl::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider,
LONG_PTR handle,
LPDATAOBJECT lpIDataObject)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// Look at the data object and determine if this an extension or a primary
ASSERT(lpIDataObject != NULL);
#if DBG
CLSID* pCoClassID = ExtractClassID(lpIDataObject);
if(pCoClassID == NULL)
{
ASSERT(FALSE);
return E_UNEXPECTED;
}
// Which page is needed? (determined by which node is active)
ASSERT(IsEqualCLSID(*pCoClassID, GetCoClassID()));
FREE_DATA(pCoClassID);
#endif
PropertyPage* pBasePage;
INTERNAL* pInternal = ExtractInternalFormat(lpIDataObject);
if (pInternal == NULL)
{
return S_OK;
}
ASSERT(pInternal->m_type == CCT_SCOPE);
ASSERT(pInternal->m_cookie);
CFolder* pFolder = reinterpret_cast<CFolder*>(pInternal->m_cookie);
ASSERT(pFolder != NULL);
if (pFolder == NULL)
return E_INVALIDARG;
// switch (pFolder->m_type)
return S_OK;
}
STDMETHODIMP CComponentDataImpl::QueryPagesFor(LPDATAOBJECT lpDataObject)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// Get the node type and see if it's one of mine
BOOL bResult = FALSE;
INTERNAL* pInternal = ExtractInternalFormat(lpDataObject);
if (pInternal == NULL)
{
return S_OK;
}
ASSERT(pInternal);
ASSERT(pInternal->m_cookie);
CFolder* pFolder = reinterpret_cast<CFolder*>(pInternal->m_cookie);
switch(pFolder->m_type)
{
case POLICYSETTINGS:
case SCE_EXTENSION:
bResult = TRUE;
break;
default:
bResult = FALSE;
break;
}
FREE_DATA(pInternal);
return (bResult) ? S_OK : S_FALSE;
}
///////////////////////////////////////////////////////////////////////////////
// IExtendContextMenu implementation
//
STDMETHODIMP CComponentDataImpl::AddMenuItems(LPDATAOBJECT pDataObject,
LPCONTEXTMENUCALLBACK pContextMenuCallback,
long *pInsertionAllowed)
{
HRESULT hr = S_OK;
CONTEXTMENUITEM menuItem;
CString szMenu;
CString szHint;
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// Note - snap-ins need to look at the data object and determine
// in what context, menu items need to be added. They must also
// observe the insertion allowed flags to see what items can be
// added.
if (IsMMCMultiSelectDataObject(pDataObject) == TRUE)
return S_FALSE;
INTERNAL* pInternal = ExtractInternalFormat(pDataObject);
if (pInternal == NULL)
{
return S_OK;
}
CFolder* pFolder = reinterpret_cast<CFolder*>(pInternal->m_cookie);
if (*pInsertionAllowed & CCM_INSERTIONALLOWED_NEW)
{
::ZeroMemory (&menuItem, sizeof (menuItem));
menuItem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_NEW;
menuItem.fFlags = 0;
menuItem.fSpecialFlags = 0;
switch(pFolder->m_type)
{
case POLICYSETTINGS:
VERIFY (szMenu.LoadString (IDS_CERTIFICATE_TYPE));
menuItem.strName = (LPTSTR)(LPCTSTR) szMenu;
VERIFY (szHint.LoadString (IDS_CERTIFICATE_TYPE_HINT));
menuItem.strStatusBarText = (LPTSTR)(LPCTSTR) szHint;
menuItem.lCommandID = IDM_NEW_CERTTYPE;
// only CA admins or user with DS write access
// can modify CA template list
if(!(CA_ACCESS_ADMIN & pFolder->GetRoles()) &&
!g_fCurrentUserHasDSWriteAccess)
menuItem.fFlags = MFS_GRAYED;
// bug 462320: for SUB CA, right after installing the CA cert, CA info is unavailable,
// so there is no way to enable new certs.
if(!pFolder->m_hCAInfo)
menuItem.fFlags = MFS_GRAYED;
hr = pContextMenuCallback->AddItem (&menuItem);
ASSERT (SUCCEEDED (hr));
break;
default:
break;
}
}
if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
{
::ZeroMemory (&menuItem, sizeof (menuItem));
menuItem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TOP;
menuItem.fFlags = 0;
menuItem.fSpecialFlags = 0;
switch(pFolder->m_type)
{
case POLICYSETTINGS:
VERIFY (szMenu.LoadString (IDS_MANAGETASK));
menuItem.strName = (LPTSTR)(LPCTSTR) szMenu;
VERIFY (szHint.LoadString (IDS_MANAGETASK_HINT));
menuItem.strStatusBarText = (LPTSTR)(LPCTSTR) szHint;
menuItem.lCommandID = IDM_MANAGE;
hr = pContextMenuCallback->AddItem (&menuItem);
ASSERT (SUCCEEDED (hr));
break;
}
}
return hr;
}
STDMETHODIMP CComponentDataImpl::Command(long nCommandID, LPDATAOBJECT pDataObject)
{
// Note - snap-ins need to look at the data object and determine
// in what context the command is being called.
DWORD dwErr;
HCERTTYPE hNewCertType;
HWND hwndConsole;
AFX_MANAGE_STATE(AfxGetStaticModuleState());
INTERNAL* pi = ExtractInternalFormat(pDataObject);
if(pi == NULL)
{
return E_POINTER;
}
ASSERT(pi);
ASSERT(pi->m_type == CCT_SCOPE);
CFolder* pFolder = reinterpret_cast<CFolder*>(pi->m_cookie);
// Handle each of the commands.
switch (nCommandID)
{
case IDM_NEW_CERTTYPE:
{
if (pFolder)
{
switch(pFolder->m_type)
{
case POLICYSETTINGS:
{
// NOMFC
CCertTemplateSelectDialog TemplateSelectDialog;
TemplateSelectDialog.SetCA(pFolder->m_hCAInfo, m_fAdvancedServer);
// if fails, NULL will work
HWND hWnd = NULL;
m_pConsole->GetMainWindow(&hWnd);
DialogBoxParam(
g_hInstance,
MAKEINTRESOURCE(IDD_SELECT_CERTIFICATE_TEMPLATE),
hWnd,
SelectCertTemplateDialogProc,
(LPARAM)&TemplateSelectDialog);
break;
}
default:
break;
}
}
m_pConsole->UpdateAllViews(pDataObject, 0, 0);
break;
}
case IDM_MANAGE:
if (pFolder && pFolder->m_type == POLICYSETTINGS)
{
StartCertificateTemplatesSnapin();
}
break;
default:
ASSERT(FALSE); // Unknown command!
break;
}
return S_OK;
}
HRESULT CComponentDataImpl::StartCertificateTemplatesSnapin()
{
HRESULT hr = S_OK;
SHELLEXECUTEINFO shi;
HWND hwnd = NULL;
m_pConsole->GetMainWindow(&hwnd);
ZeroMemory(&shi, sizeof(shi));
shi.cbSize = sizeof(shi);
shi.hwnd = hwnd;
shi.lpVerb = SZ_VERB_OPEN;
shi.lpFile = SZ_CERTTMPL_MSC;
shi.fMask = SEE_MASK_FLAG_NO_UI;
if(!ShellExecuteEx(&shi))
{
hr = myHLastError();
_JumpError(hr, error, "ShellExecuteEx");
}
error:
return hr;
}