|
|
// 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; }
|