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.
1728 lines
47 KiB
1728 lines
47 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 <userenv.h>
|
|
#include "genpage.h"
|
|
#include <winldap.h>
|
|
#include "csldap.h"
|
|
|
|
#define __dwFILE__ __dwFILE_CAPESNPN_CSNAPIN_CPP__
|
|
|
|
bool g_fCurrentUserHasDSWriteAccess = false;
|
|
bool g_fCurrentUserHasDSWriteAccessTested = false;
|
|
|
|
|
|
static MMCBUTTON SvrMgrToolbar1Buttons[] =
|
|
{
|
|
{ 0, IDC_STARTSERVER, TBSTATE_ENABLED, TBSTYLE_BUTTON, L"Start", L"Start this service" },
|
|
{ 1, IDC_STOPSERVER, TBSTATE_ENABLED, TBSTYLE_BUTTON, L"Stop", L"Stop this service" },
|
|
};
|
|
|
|
static int n_count = 0;
|
|
|
|
//
|
|
// Extracts the coclass guid format from the data object
|
|
//
|
|
template <class TYPE>
|
|
TYPE* Extract(LPDATAOBJECT lpDataObject, unsigned int cf)
|
|
{
|
|
ASSERT(lpDataObject != NULL);
|
|
|
|
TYPE* p = NULL;
|
|
|
|
STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
|
|
FORMATETC formatetc = { (CLIPFORMAT)cf, NULL,
|
|
DVASPECT_CONTENT, -1, TYMED_HGLOBAL
|
|
};
|
|
|
|
// Allocate memory for the stream
|
|
int len = (int)((cf == CDataObject::m_cfWorkstation) ?
|
|
((MAX_COMPUTERNAME_LENGTH+1) * sizeof(TYPE)) : sizeof(TYPE));
|
|
|
|
stgmedium.hGlobal = GlobalAlloc(GMEM_SHARE, len);
|
|
|
|
// Get the workstation name from the data object
|
|
do
|
|
{
|
|
if (stgmedium.hGlobal == NULL)
|
|
break;
|
|
|
|
if (FAILED(lpDataObject->GetDataHere(&formatetc, &stgmedium)))
|
|
{
|
|
GlobalFree(stgmedium.hGlobal);
|
|
break;
|
|
}
|
|
|
|
p = reinterpret_cast<TYPE*>(stgmedium.hGlobal);
|
|
|
|
if (p == NULL)
|
|
break;
|
|
|
|
|
|
} while (FALSE);
|
|
|
|
return p;
|
|
}
|
|
|
|
BOOL IsMMCMultiSelectDataObject(LPDATAOBJECT pDataObject)
|
|
{
|
|
if (pDataObject == NULL)
|
|
return FALSE;
|
|
|
|
FORMATETC fmt = {(CLIPFORMAT)CDataObject::m_cfIsMultiSel, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
|
|
|
return (pDataObject->QueryGetData(&fmt) == S_OK);
|
|
}
|
|
|
|
// Data object extraction helpers
|
|
CLSID* ExtractClassID(LPDATAOBJECT lpDataObject)
|
|
{
|
|
return Extract<CLSID>(lpDataObject, CDataObject::m_cfCoClass);
|
|
}
|
|
|
|
GUID* ExtractNodeType(LPDATAOBJECT lpDataObject)
|
|
{
|
|
return Extract<GUID>(lpDataObject, CDataObject::m_cfNodeType);
|
|
}
|
|
|
|
wchar_t* ExtractWorkstation(LPDATAOBJECT lpDataObject)
|
|
{
|
|
return Extract<wchar_t>(lpDataObject, CDataObject::m_cfWorkstation);
|
|
}
|
|
|
|
INTERNAL* ExtractInternalFormat(LPDATAOBJECT lpDataObject)
|
|
{
|
|
return Extract<INTERNAL>(lpDataObject, CDataObject::m_cfInternal);
|
|
}
|
|
|
|
|
|
HRESULT _QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type,
|
|
CComponentDataImpl* pImpl, LPDATAOBJECT* ppDataObject)
|
|
{
|
|
ASSERT(ppDataObject != NULL);
|
|
ASSERT(pImpl != NULL);
|
|
|
|
CComObject<CDataObject>* pObject;
|
|
|
|
CComObject<CDataObject>::CreateInstance(&pObject);
|
|
ASSERT(pObject != NULL);
|
|
|
|
if(pObject == NULL)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
// Save cookie and type for delayed rendering
|
|
pObject->SetType(type);
|
|
pObject->SetCookie(cookie);
|
|
|
|
// Store the coclass with the data object
|
|
pObject->SetClsid(pImpl->GetCoClassID());
|
|
|
|
return pObject->QueryInterface(IID_IDataObject,
|
|
reinterpret_cast<void**>(ppDataObject));
|
|
|
|
}
|
|
|
|
DWORD GetItemType(MMC_COOKIE cookie)
|
|
{
|
|
// folder = CFoder* is cookie
|
|
// result = RESULT_DATA* is the cookie
|
|
|
|
return (*reinterpret_cast<DWORD*>(cookie));
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CSnapin's IComponent implementation
|
|
|
|
STDMETHODIMP CSnapin::GetResultViewType(MMC_COOKIE cookie, LPOLESTR* ppViewType, long* pViewOptions)
|
|
{
|
|
if (m_CustomViewID == VIEW_ERROR_OCX)
|
|
{
|
|
StringFromCLSID (CLSID_MessageView, ppViewType);
|
|
return S_FALSE;
|
|
}
|
|
else
|
|
{
|
|
*pViewOptions = MMC_VIEW_OPTIONS_MULTISELECT;
|
|
|
|
// if list view
|
|
if (m_CustomViewID == VIEW_DEFAULT_LV)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
}
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
STDMETHODIMP CSnapin::Initialize(LPCONSOLE lpConsole)
|
|
{
|
|
DBX_PRINT(_T(" ---------- CSnapin::Initialize<0x08x>\n"), this);
|
|
ASSERT(lpConsole != NULL);
|
|
m_bInitializedC = true;
|
|
HRESULT hr;
|
|
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
|
|
// Save the IConsole pointer
|
|
if (lpConsole == NULL)
|
|
return E_POINTER;
|
|
|
|
hr = lpConsole->QueryInterface(IID_IConsole2,
|
|
reinterpret_cast<void**>(&m_pConsole));
|
|
_JumpIfError(hr, Ret, "QI IID_IConsole2");
|
|
|
|
// Load resource strings
|
|
LoadResources();
|
|
|
|
// QI for a IHeaderCtrl
|
|
hr = m_pConsole->QueryInterface(IID_IHeaderCtrl,
|
|
reinterpret_cast<void**>(&m_pHeader));
|
|
_JumpIfError(hr, Ret, "QI IID_IHeaderCtrl");
|
|
|
|
// Give the console the header control interface pointer
|
|
if (SUCCEEDED(hr))
|
|
m_pConsole->SetHeader(m_pHeader);
|
|
|
|
hr = m_pConsole->QueryInterface(IID_IResultData,
|
|
reinterpret_cast<void**>(&m_pResult));
|
|
_JumpIfError(hr, Ret, "QI IID_IResultData");
|
|
|
|
hr = m_pConsole->QueryResultImageList(&m_pImageResult);
|
|
_JumpIfError(hr, Ret, "ImageResult");
|
|
|
|
hr = m_pConsole->QueryConsoleVerb(&m_pConsoleVerb);
|
|
_JumpIfError(hr, Ret, "m_pConsoleVerb");
|
|
|
|
Ret:
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CSnapin::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
if (IS_SPECIAL_DATAOBJECT(lpDataObject))
|
|
{
|
|
if (event == MMCN_BTN_CLICK)
|
|
{
|
|
if (m_CustomViewID != VIEW_DEFAULT_LV)
|
|
{
|
|
switch (param)
|
|
{
|
|
case MMC_VERB_REFRESH:
|
|
::AfxMessageBox(_T("MMCN_BTN_CLICK::MMC_VERB_REFRESH"));
|
|
_OnRefresh(lpDataObject);
|
|
break;
|
|
|
|
case MMC_VERB_PROPERTIES:
|
|
::AfxMessageBox(_T("MMCN_BTN_CLICK::MMC_VERB_PROPERTIES"));
|
|
break;
|
|
|
|
default:
|
|
::AfxMessageBox(_T("MMCN_BTN_CLICK::param unknown"));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (event)
|
|
{
|
|
case MMCN_REFRESH:
|
|
::AfxMessageBox(_T("MMCN_BTN_CLICK::MMCN_REFRESH"));
|
|
_OnRefresh(lpDataObject);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT hr = S_OK;
|
|
MMC_COOKIE cookie = NULL;
|
|
|
|
switch(event)
|
|
{
|
|
case MMCN_COLUMNS_CHANGED:
|
|
hr = S_OK;
|
|
break;
|
|
case MMCN_PROPERTY_CHANGE:
|
|
hr = OnPropertyChange(lpDataObject);
|
|
break;
|
|
case MMCN_VIEW_CHANGE:
|
|
hr = OnUpdateView(lpDataObject);
|
|
break;
|
|
case MMCN_DESELECT_ALL:
|
|
DBX_PRINT(_T("CSnapin::Notify -> MMCN_DESELECT_ALL \n"));
|
|
break;
|
|
case MMCN_COLUMN_CLICK:
|
|
DBX_PRINT(_T("CSnapin::Notify -> MMCN_COLUMN_CLICK \n"));
|
|
break;
|
|
case MMCN_SNAPINHELP:
|
|
AfxMessageBox(_T("CSnapin::Notify ->MMCN_SNAPINHELP"));
|
|
break;
|
|
default:
|
|
{
|
|
INTERNAL* pInternal = NULL;
|
|
|
|
if (IsMMCMultiSelectDataObject(lpDataObject) == FALSE)
|
|
{
|
|
pInternal = ExtractInternalFormat(lpDataObject);
|
|
|
|
if (pInternal == NULL)
|
|
{
|
|
//ASSERT(FALSE);
|
|
return S_OK;
|
|
}
|
|
cookie = pInternal->m_cookie;
|
|
}
|
|
|
|
switch(event)
|
|
{
|
|
case MMCN_ACTIVATE:
|
|
break;
|
|
|
|
case MMCN_CLICK:
|
|
if (NULL == pInternal)
|
|
{
|
|
hr = S_FALSE;
|
|
break;
|
|
}
|
|
|
|
hr = OnResultItemClk(pInternal->m_type, cookie);
|
|
break;
|
|
|
|
case MMCN_DBLCLICK:
|
|
hr = S_FALSE; // do the default verb
|
|
break;
|
|
|
|
case MMCN_ADD_IMAGES:
|
|
OnAddImages(cookie, arg, param);
|
|
break;
|
|
|
|
case MMCN_SHOW:
|
|
hr = OnShow(cookie, arg, param);
|
|
break;
|
|
|
|
case MMCN_MINIMIZED:
|
|
hr = OnMinimize(cookie, arg, param);
|
|
break;
|
|
|
|
case MMCN_DESELECT_ALL:
|
|
case MMCN_SELECT:
|
|
HandleStandardVerbs((event == MMCN_DESELECT_ALL),
|
|
arg, lpDataObject);
|
|
break;
|
|
|
|
case MMCN_PASTE:
|
|
AfxMessageBox(_T("CSnapin::MMCN_PASTE"));
|
|
break;
|
|
|
|
case MMCN_DELETE:
|
|
hr = OnDelete(lpDataObject, arg, param);
|
|
// fall through to refresh -- break;
|
|
|
|
case MMCN_REFRESH:
|
|
{
|
|
_OnRefresh(lpDataObject);
|
|
}
|
|
break;
|
|
|
|
case MMCN_CONTEXTHELP:
|
|
hr = OnContextHelp(lpDataObject);
|
|
break;
|
|
|
|
case MMCN_RENAME:
|
|
OutputDebugString(_T("\n\n\t\tCSnapin::MMCN_RENAME\n\n"));
|
|
break;
|
|
|
|
// Note - Future expansion of notify types possible
|
|
default:
|
|
hr = E_UNEXPECTED;
|
|
break;
|
|
}
|
|
|
|
if (pInternal != NULL)
|
|
FREE_DATA(pInternal);
|
|
|
|
break;
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CSnapin::OnUpdateView(LPDATAOBJECT pDataObject)
|
|
{
|
|
_OnRefresh(pDataObject);
|
|
return S_OK;
|
|
}
|
|
|
|
void CSnapin::_OnRefresh(LPDATAOBJECT pDataObject)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
INTERNAL* pInternal = ExtractInternalFormat(pDataObject);
|
|
if (pInternal == NULL)
|
|
return;
|
|
|
|
if (pInternal->m_type == CCT_SCOPE)
|
|
{
|
|
CComponentDataImpl* pData = dynamic_cast<CComponentDataImpl*>(m_pComponentData);
|
|
CFolder* pFolder = pData->FindObject(pInternal->m_cookie);
|
|
|
|
// only do if this is the currently selected folder!!
|
|
if (m_pCurrentlySelectedScopeFolder == pFolder)
|
|
{
|
|
// HIDE, remove all items, remove header, SHOW
|
|
OnShow(pInternal->m_cookie, FALSE, 0); // emulate HIDE
|
|
m_pResult->DeleteAllRsltItems(); // delete items from m_pResult
|
|
while(S_OK == m_pHeader->DeleteColumn(0)) {}; // remove all cols from header
|
|
OnShow(pInternal->m_cookie, TRUE, 0); // emulate SHOW
|
|
}
|
|
}
|
|
else
|
|
{
|
|
RESULT_DATA* pData = reinterpret_cast<RESULT_DATA*>(pInternal->m_cookie);
|
|
}
|
|
|
|
FREE_DATA(pInternal);
|
|
}
|
|
|
|
|
|
HRESULT CSnapin::OnContextHelp(LPDATAOBJECT pdtobj)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
CString cstrHelpFile;
|
|
IDisplayHelp* pDisplayHelp = NULL;
|
|
WCHAR szWindows[MAX_PATH];
|
|
szWindows[0] = L'\0';
|
|
|
|
hr = m_pConsole->QueryInterface (IID_IDisplayHelp, (void**)&pDisplayHelp);
|
|
_JumpIfError(hr, Ret, "QI IDisplayHelp");
|
|
|
|
if (0 == GetSystemWindowsDirectory(szWindows, MAX_PATH))
|
|
{
|
|
hr = myHLastError();
|
|
_JumpError(hr, Ret, "GetSystemWindowsDirectory");
|
|
}
|
|
|
|
cstrHelpFile = szWindows;
|
|
cstrHelpFile += HTMLHELP_COLLECTIONLINK_FILENAME;
|
|
cstrHelpFile += L"::/sag_cs_topnode.htm";
|
|
|
|
hr = pDisplayHelp->ShowTopic (T2OLE ((LPWSTR)(LPCWSTR)cstrHelpFile));
|
|
_JumpIfError(hr, Ret, "ShowTopic");
|
|
|
|
Ret:
|
|
if (pDisplayHelp)
|
|
pDisplayHelp->Release();
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CSnapin::Destroy(MMC_COOKIE cookie)
|
|
{
|
|
DBX_PRINT(_T(" ---------- CSnapin::Destroy<0x08x>\n"), this);
|
|
ASSERT(m_bInitializedC);
|
|
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
m_bDestroyedC = true;
|
|
|
|
// Release the interfaces that we QI'ed
|
|
if (m_pConsole != NULL)
|
|
{
|
|
// Tell the console to release the header control interface
|
|
m_pConsole->SetHeader(NULL);
|
|
SAFE_RELEASE(m_pHeader);
|
|
|
|
SAFE_RELEASE(m_pResult);
|
|
SAFE_RELEASE(m_pImageResult);
|
|
|
|
// Release the IConsole interface last
|
|
SAFE_RELEASE(m_pConsole);
|
|
SAFE_RELEASE(m_pComponentData); // QI'ed in IComponentDataImpl::CreateComponent
|
|
|
|
SAFE_RELEASE(m_pConsoleVerb);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT CSnapin::QueryMultiSelectDataObject(MMC_COOKIE cookie,
|
|
DATA_OBJECT_TYPES type,
|
|
LPDATAOBJECT* ppDataObject)
|
|
{
|
|
|
|
CComponentDataImpl* pImpl = dynamic_cast<CComponentDataImpl*>(m_pComponentData);
|
|
CComObject<CDataObject>* pObject = NULL;
|
|
HRESULT hr = S_OK;
|
|
LPRESULTDATA pResultData = NULL;
|
|
RESULTDATAITEM rdi;
|
|
|
|
ASSERT(ppDataObject != NULL);
|
|
|
|
if (ppDataObject == NULL)
|
|
{
|
|
hr = E_POINTER;
|
|
goto error;
|
|
}
|
|
|
|
|
|
hr = m_pConsole->QueryInterface(IID_IResultData,
|
|
reinterpret_cast<void**>(&pResultData));
|
|
if(hr != S_OK)
|
|
{
|
|
goto error;
|
|
}
|
|
ASSERT(pResultData != NULL);
|
|
|
|
|
|
CComObject<CDataObject>::CreateInstance(&pObject);
|
|
ASSERT(pObject != NULL);
|
|
|
|
// Save cookie and type for delayed rendering
|
|
pObject->SetType(type);
|
|
pObject->SetCookie(cookie);
|
|
|
|
// tell dataobj who we are
|
|
// pObject->SetComponentData(pImpl);
|
|
|
|
|
|
// Determine the items selected
|
|
|
|
ZeroMemory(&rdi, sizeof(rdi));
|
|
rdi.mask = RDI_STATE;
|
|
rdi.nIndex = -1;
|
|
rdi.nState = TVIS_SELECTED;
|
|
|
|
while (pResultData->GetNextItem (&rdi) == S_OK)
|
|
{
|
|
CFolder* pFolder = reinterpret_cast <CFolder *> (rdi.lParam);
|
|
|
|
if ( pFolder )
|
|
{
|
|
if(pFolder->GetType() == CA_CERT_TYPE)
|
|
{
|
|
pObject->AddCookie((MMC_COOKIE)pFolder);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_INVALIDARG;
|
|
goto error;
|
|
}
|
|
}
|
|
// We're always adding things from policy settings these days.
|
|
|
|
pObject->SetMultiSelDobj();
|
|
pObject->SetClsid(pImpl->GetCoClassID());
|
|
|
|
SMMCObjectTypes sObjGuids; // one is fine for now
|
|
sObjGuids.count = 1;
|
|
CopyMemory(&sObjGuids.guid[0], &cNodeTypePolicySettings, sizeof(GUID));
|
|
|
|
// Store the coclass with the data object
|
|
pObject->SetMultiSelData(&sObjGuids, sizeof(SMMCObjectTypes));
|
|
|
|
hr = pObject->QueryInterface(IID_IDataObject,
|
|
reinterpret_cast<void**>(ppDataObject));
|
|
pObject = NULL;
|
|
|
|
error:
|
|
if(pObject)
|
|
{
|
|
pObject->Release();
|
|
}
|
|
if (pResultData)
|
|
{
|
|
pResultData->Release();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CSnapin::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type,
|
|
LPDATAOBJECT* ppDataObject)
|
|
{
|
|
if (cookie == MMC_MULTI_SELECT_COOKIE)
|
|
{
|
|
return QueryMultiSelectDataObject(cookie, type, ppDataObject);
|
|
}
|
|
|
|
ASSERT(type == CCT_RESULT);
|
|
|
|
// Delegate it to the IComponentData
|
|
ASSERT(m_pComponentData != NULL);
|
|
CComponentDataImpl* pImpl = dynamic_cast<CComponentDataImpl*>(m_pComponentData);
|
|
ASSERT(pImpl != NULL);
|
|
return _QueryDataObject(cookie, type, pImpl, ppDataObject);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CSnapin's implementation specific members
|
|
|
|
DEBUG_DECLARE_INSTANCE_COUNTER(CSnapin);
|
|
|
|
CSnapin::CSnapin()
|
|
: m_bIsDirty(TRUE), m_bInitializedC(false), m_bDestroyedC(false)
|
|
{
|
|
DEBUG_INCREMENT_INSTANCE_COUNTER(CSnapin);
|
|
Construct();
|
|
}
|
|
|
|
CSnapin::~CSnapin()
|
|
{
|
|
#if DBG==1
|
|
ASSERT(dbg_cRef == 0);
|
|
#endif
|
|
|
|
DEBUG_DECREMENT_INSTANCE_COUNTER(CSnapin);
|
|
|
|
if (m_pSvrMgrToolbar1)
|
|
SAFE_RELEASE(m_pSvrMgrToolbar1);
|
|
|
|
#ifdef INSERT_DEBUG_FOLDERS
|
|
SAFE_RELEASE(m_pMenuButton1);
|
|
#endif // INSERT_DEBUG_FOLDERS
|
|
|
|
if (m_pControlbar)
|
|
SAFE_RELEASE(m_pControlbar);
|
|
|
|
// Make sure the interfaces have been released
|
|
ASSERT(m_pConsole == NULL);
|
|
ASSERT(m_pHeader == NULL);
|
|
ASSERT(m_pSvrMgrToolbar1 == NULL);
|
|
|
|
delete m_pbmpSvrMgrToolbar1;
|
|
|
|
ASSERT(!m_bInitializedC || m_bDestroyedC);
|
|
|
|
Construct();
|
|
}
|
|
|
|
void CSnapin::Construct()
|
|
{
|
|
#if DBG==1
|
|
dbg_cRef = 0;
|
|
#endif
|
|
|
|
m_pConsole = NULL;
|
|
m_pHeader = NULL;
|
|
|
|
m_pResult = NULL;
|
|
m_pImageResult = NULL;
|
|
m_pComponentData = NULL;
|
|
|
|
m_pControlbar = NULL;
|
|
|
|
#ifdef INSERT_DEBUG_FOLDERS
|
|
m_pMenuButton1 = NULL;
|
|
#endif // INSERT_DEBUG_FOLDERS
|
|
|
|
m_pSvrMgrToolbar1 = NULL;
|
|
m_pbmpSvrMgrToolbar1 = NULL;
|
|
|
|
m_pConsoleVerb = NULL;
|
|
|
|
m_CustomViewID = VIEW_DEFAULT_LV;
|
|
m_bVirtualView = FALSE;
|
|
}
|
|
|
|
CString g_ColumnHead_Name;
|
|
CString g_ColumnHead_Size;
|
|
CString g_ColumnHead_Type;
|
|
CString g_ColumnHead_IntendedPurpose;
|
|
|
|
void CSnapin::LoadResources()
|
|
{
|
|
// Load strings from resources
|
|
g_ColumnHead_Name.LoadString(IDS_COLUMN_NAME);
|
|
g_ColumnHead_Size.LoadString(IDS_COLUMN_SIZE);
|
|
g_ColumnHead_Type.LoadString(IDS_COLUMN_TYPE);
|
|
g_ColumnHead_IntendedPurpose.LoadString(IDS_COLUMN_INTENDED_PURPOSE);
|
|
}
|
|
|
|
HRESULT CSnapin::InitializeHeaders(MMC_COOKIE cookie)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
ASSERT(m_pHeader);
|
|
|
|
HRESULT hr = S_OK;
|
|
BOOL fInsertedHeaders=FALSE;
|
|
|
|
USES_CONVERSION;
|
|
|
|
CFolder* pFolder = reinterpret_cast<CFolder*>(cookie);
|
|
|
|
switch (pFolder->m_type)
|
|
{
|
|
case POLICYSETTINGS:
|
|
case SCE_EXTENSION:
|
|
|
|
m_pHeader->InsertColumn(0, W2COLE(g_ColumnHead_Name), LVCFMT_LEFT, 230); // Name
|
|
m_pHeader->InsertColumn(1, W2COLE(g_ColumnHead_IntendedPurpose), LVCFMT_LEFT, 230); // Intended Purpose
|
|
fInsertedHeaders = TRUE;
|
|
break;
|
|
|
|
default:
|
|
// other scopes
|
|
m_pHeader->InsertColumn(0, W2COLE(g_ColumnHead_Name), LVCFMT_LEFT, 180); // Name
|
|
m_pHeader->InsertColumn(1, W2COLE(g_ColumnHead_Size), LVCFMT_LEFT, 90); // Size
|
|
m_pHeader->InsertColumn(2, W2COLE(g_ColumnHead_Type), LVCFMT_LEFT, 160); // Type
|
|
fInsertedHeaders = TRUE;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CSnapin::GetDisplayInfo(LPRESULTDATAITEM pResult)
|
|
{
|
|
static WCHAR* s_szSize = L"200";
|
|
static WCHAR* s_szUnnamedItems = L"Unnamed subitem";
|
|
ASSERT(pResult != NULL);
|
|
|
|
CFolder* pFolder = reinterpret_cast<CFolder*>(pResult->lParam);
|
|
ASSERT(pFolder);
|
|
|
|
if (pResult)
|
|
{
|
|
// a folder or a result?
|
|
if (pResult->bScopeItem == TRUE)
|
|
{
|
|
if (pResult->mask & RDI_STR)
|
|
{
|
|
switch (pFolder->m_type)
|
|
{
|
|
case POLICYSETTINGS:
|
|
case SCE_EXTENSION:
|
|
// just a single column here
|
|
pResult->str = pFolder->m_pszName;
|
|
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
ASSERT(pResult->str != NULL);
|
|
|
|
if (pResult->str == NULL)
|
|
pResult->str = (LPOLESTR)L"";
|
|
}
|
|
|
|
if (pResult->mask & RDI_IMAGE)
|
|
{
|
|
if (pResult->nState & TVIS_EXPANDED)
|
|
pResult->nImage = pFolder->m_pScopeItem->nOpenImage;
|
|
else
|
|
pResult->nImage = pFolder->m_pScopeItem->nImage;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
RESULT_DATA* pData;
|
|
|
|
// lParam is the item pointer
|
|
pData= reinterpret_cast<RESULT_DATA*>(pResult->lParam);
|
|
|
|
if (pResult->mask & RDI_STR)
|
|
{
|
|
ASSERT(pFolder->m_hCertType != NULL);
|
|
|
|
if (pResult->nCol == 0)
|
|
pResult->str = pFolder->m_pszName;
|
|
else if (pResult->nCol == 1)
|
|
pResult->str = (LPWSTR)((LPCWSTR) pFolder->m_szIntendedUsages);
|
|
|
|
|
|
ASSERT(pResult->str != NULL);
|
|
|
|
if (pResult->str == NULL)
|
|
pResult->str = (LPOLESTR)L"";
|
|
}
|
|
|
|
// MMC can request image and indent for virtual data
|
|
if (pResult->mask & RDI_IMAGE)
|
|
{
|
|
// UNDONE: what to do here?
|
|
ASSERT(0);
|
|
pResult->nImage = IMGINDEX_CERTTYPE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// IExtendContextMenu Implementation
|
|
STDMETHODIMP CSnapin::AddMenuItems(LPDATAOBJECT pDataObject,
|
|
LPCONTEXTMENUCALLBACK pContextMenuCallback,
|
|
LONG *pInsertionAllowed)
|
|
{
|
|
|
|
return dynamic_cast<CComponentDataImpl*>(m_pComponentData)->
|
|
AddMenuItems(pDataObject, pContextMenuCallback, pInsertionAllowed);
|
|
}
|
|
|
|
|
|
STDMETHODIMP CSnapin::Command(long nCommandID, LPDATAOBJECT pDataObject)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
INTERNAL* pInternal = ExtractInternalFormat(pDataObject);
|
|
HRESULT hr;
|
|
HWND hwndConsole;
|
|
|
|
if (pInternal == NULL)
|
|
return E_FAIL;
|
|
|
|
CFolder* pFolder = reinterpret_cast<CFolder*>(pInternal->m_cookie);
|
|
|
|
if (pInternal->m_type == CCT_SCOPE)
|
|
{
|
|
// Handle view specific commands here
|
|
switch (nCommandID)
|
|
{
|
|
case MMCC_STANDARD_VIEW_SELECT:
|
|
m_CustomViewID = VIEW_DEFAULT_LV;
|
|
break;
|
|
|
|
default:
|
|
// Pass non-view specific commands to ComponentData
|
|
return dynamic_cast<CComponentDataImpl*>(m_pComponentData)->
|
|
Command(nCommandID, pDataObject);
|
|
}
|
|
}
|
|
else if (pInternal->m_type == CCT_RESULT)
|
|
{
|
|
// snag the selected items
|
|
|
|
// only support single selection for now
|
|
m_pResult->ModifyViewStyle(MMC_SINGLESEL, (MMC_RESULT_VIEW_STYLE)0);
|
|
|
|
RESULTDATAITEM rdi;
|
|
ZeroMemory(&rdi, sizeof(rdi));
|
|
|
|
rdi.mask = RDI_STATE;
|
|
rdi.nState = LVIS_SELECTED;
|
|
rdi.nIndex = -1;
|
|
m_pResult->GetNextItem(&rdi);
|
|
|
|
int iSel = rdi.nIndex;
|
|
|
|
RESULT_DATA* pData;
|
|
|
|
ZeroMemory(&rdi, sizeof(rdi));
|
|
rdi.mask = RDI_PARAM;
|
|
rdi.nIndex = iSel;
|
|
hr = m_pResult->GetItem(&rdi);
|
|
ASSERT(SUCCEEDED(hr));
|
|
ASSERT(rdi.lParam != 0);
|
|
|
|
pData = reinterpret_cast<RESULT_DATA*>(rdi.lParam);
|
|
|
|
|
|
// No current commands :(
|
|
}
|
|
else
|
|
{
|
|
ASSERT(0);
|
|
}
|
|
|
|
FREE_DATA(pInternal);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CSnapin::GetClassID(CLSID *pClassID)
|
|
{
|
|
ASSERT(pClassID != NULL);
|
|
|
|
ASSERT(0);
|
|
|
|
// Copy the CLSID for this snapin
|
|
// reid fix - what is up with this?
|
|
*pClassID = CLSID_CAPolicyExtensionSnapIn;
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP CSnapin::IsDirty()
|
|
{
|
|
// Always save / Always dirty.
|
|
return ThisIsDirty() ? S_OK : S_FALSE;
|
|
}
|
|
|
|
STDMETHODIMP CSnapin::Load(IStream *pStm)
|
|
{
|
|
DBX_PRINT(_T(" ---------- CSnapin::Load<0x08x>\n"), this);
|
|
ASSERT(m_bInitializedC);
|
|
|
|
ASSERT(pStm);
|
|
// Read the string
|
|
DWORD dwVer;
|
|
ULONG nBytesRead;
|
|
HRESULT hr = pStm->Read(&dwVer, sizeof(DWORD), &nBytesRead);
|
|
ASSERT(SUCCEEDED(hr) && nBytesRead == sizeof(DWORD));
|
|
|
|
if (dwVer != 0x1)
|
|
{
|
|
return (STG_E_OLDFORMAT);
|
|
}
|
|
|
|
ClearDirty();
|
|
|
|
return SUCCEEDED(hr) ? S_OK : E_FAIL;
|
|
}
|
|
|
|
STDMETHODIMP CSnapin::Save(IStream *pStm, BOOL fClearDirty)
|
|
{
|
|
DBX_PRINT(_T(" ---------- CSnapin::Save<0x08x>\n"), this);
|
|
ASSERT(m_bInitializedC);
|
|
|
|
ASSERT(pStm);
|
|
|
|
// Write the string
|
|
ULONG nBytesWritten;
|
|
DWORD dwVersion = 0x1;
|
|
HRESULT hr = pStm->Write(&dwVersion, 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 CSnapin::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;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// IExtendControlbar implementation
|
|
//
|
|
|
|
|
|
STDMETHODIMP CSnapin::SetControlbar(LPCONTROLBAR pControlbar)
|
|
{
|
|
/* TRACE(_T("CSnapin::SetControlbar(%ld)\n"),pControlbar);
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
if (m_pControlbar)
|
|
SAFE_RELEASE(m_pControlbar);
|
|
|
|
if (pControlbar != NULL)
|
|
{
|
|
// Hold on to the controlbar interface.
|
|
m_pControlbar = pControlbar;
|
|
m_pControlbar->AddRef();
|
|
|
|
HRESULT hr=S_FALSE;
|
|
|
|
#ifdef INSERT_DEBUG_FOLDERS
|
|
if (!m_pMenuButton1)
|
|
{
|
|
hr = m_pControlbar->Create(MENUBUTTON, this,
|
|
reinterpret_cast<LPUNKNOWN*>(&m_pMenuButton1));
|
|
ASSERT(SUCCEEDED(hr));
|
|
}
|
|
|
|
if (m_pMenuButton1)
|
|
{
|
|
// Unlike toolbar buttons, menu buttons need to be added every time.
|
|
hr = m_pMenuButton1->AddButton(FOLDEREX_MENU, L"FolderEx", L"Extended Folder Menu");
|
|
ASSERT(SUCCEEDED(hr));
|
|
hr = m_pMenuButton1->AddButton(FILEEX_MENU, L"FileEx", L"Extended File Menu");
|
|
ASSERT(SUCCEEDED(hr));
|
|
}
|
|
#endif // INSERT_DEBUG_FOLDERS
|
|
|
|
|
|
// SvrMgrToolbar1
|
|
if (!m_pSvrMgrToolbar1)
|
|
{
|
|
hr = m_pControlbar->Create(TOOLBAR, this, reinterpret_cast<LPUNKNOWN*>(&m_pSvrMgrToolbar1));
|
|
ASSERT(SUCCEEDED(hr));
|
|
|
|
// Add the bitmap
|
|
m_pbmpSvrMgrToolbar1 = new ::CBitmap;
|
|
m_pbmpSvrMgrToolbar1->LoadBitmap(IDB_TOOLBAR_SVRMGR1);
|
|
hr = m_pSvrMgrToolbar1->AddBitmap(36, *m_pbmpSvrMgrToolbar1, 16, 16, RGB(192,192,192));
|
|
ASSERT(SUCCEEDED(hr));
|
|
|
|
// Add the buttons to the toolbar
|
|
hr = m_pSvrMgrToolbar1->AddButtons(ARRAYLEN(SvrMgrToolbar1Buttons), SvrMgrToolbar1Buttons);
|
|
ASSERT(SUCCEEDED(hr));
|
|
}
|
|
|
|
}
|
|
*/
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
void CSnapin::OnButtonClick(LPDATAOBJECT pdtobj, int idBtn)
|
|
{
|
|
WCHAR name[128];
|
|
DWORD cName = sizeof(name)/sizeof(WCHAR);
|
|
GetItemName(pdtobj, name, &cName);
|
|
|
|
switch(idBtn)
|
|
{
|
|
case IDC_STOPSERVER:
|
|
case IDC_STARTSERVER:
|
|
// bubble this to our other handler
|
|
dynamic_cast<CComponentDataImpl*>(m_pComponentData)->
|
|
Command(idBtn, pdtobj);
|
|
break;
|
|
default:
|
|
{
|
|
#ifdef _DEBUG
|
|
TCHAR buf[150];
|
|
wsprintf(buf, L"Toolbar button<%d> was clicked.\nThe currently selected result item is <%ws>", idBtn, name);
|
|
OutputDebugString(buf);
|
|
#endif // _DEBUG
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
STDMETHODIMP CSnapin::ControlbarNotify(MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
|
|
{
|
|
/* HRESULT hr=S_FALSE;
|
|
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
switch (event)
|
|
{
|
|
case MMCN_BTN_CLICK:
|
|
//TCHAR szMessage[MAX_PATH];
|
|
//wsprintf(szMessage, _T("CommandID %ld"),param);
|
|
//AfxMessageBox(szMessage);
|
|
OnButtonClick(reinterpret_cast<LPDATAOBJECT>(arg), param);
|
|
break;
|
|
|
|
case MMCN_DESELECT_ALL:
|
|
case MMCN_SELECT:
|
|
HandleExtToolbars((event == MMCN_DESELECT_ALL), arg, param);
|
|
break;
|
|
|
|
case MMCN_MENU_BTNCLICK:
|
|
HandleExtMenus(arg, param);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
*/
|
|
return S_OK;
|
|
}
|
|
|
|
// This compares two data objects to see if they are the same object.
|
|
// return
|
|
// S_OK if equal otherwise S_FALSE
|
|
//
|
|
// Note: check to make sure both objects belong to the snap-in.
|
|
//
|
|
|
|
STDMETHODIMP CSnapin::CompareObjects(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
|
|
// This compare is used to sort the item's in the listview
|
|
//
|
|
// Parameters:
|
|
//
|
|
// lUserParam - user param passed in when IResultData::Sort() was called
|
|
// cookieA - first item to compare
|
|
// cookieB - second item to compare
|
|
// pnResult [in, out]- contains the col on entry,
|
|
// -1, 0, 1 based on comparison for return value.
|
|
//
|
|
// Note: Assum sort is ascending when comparing.
|
|
|
|
|
|
STDMETHODIMP CSnapin::Compare(LPARAM lUserParam, MMC_COOKIE cookieA, MMC_COOKIE cookieB, int* pnResult)
|
|
{
|
|
if (pnResult == NULL)
|
|
{
|
|
ASSERT(FALSE);
|
|
return E_POINTER;
|
|
}
|
|
|
|
// check col range
|
|
int nCol = *pnResult;
|
|
ASSERT(nCol >=0);
|
|
|
|
*pnResult = 0;
|
|
|
|
USES_CONVERSION;
|
|
|
|
LPWSTR szStringA;
|
|
LPWSTR szStringB;
|
|
|
|
CFolder* pDataA = reinterpret_cast<CFolder*>(cookieA);
|
|
CFolder* pDataB = reinterpret_cast<CFolder*>(cookieB);
|
|
|
|
|
|
ASSERT(pDataA != NULL && pDataB != NULL);
|
|
|
|
if (nCol == 0)
|
|
{
|
|
szStringA = OLE2W(pDataA->m_pszName);
|
|
szStringB = OLE2W(pDataB->m_pszName);
|
|
}
|
|
else if (nCol == 1)
|
|
{
|
|
szStringA = OLE2W((LPWSTR)((LPCWSTR) pDataA->m_szIntendedUsages));
|
|
szStringB = OLE2W((LPWSTR)((LPCWSTR) pDataB->m_szIntendedUsages));
|
|
}
|
|
else
|
|
return S_OK;
|
|
|
|
if ((szStringA == NULL) || (szStringB == NULL))
|
|
return E_POINTER;
|
|
|
|
*pnResult = wcscmp(szStringA, szStringB);
|
|
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
// independent of scope/result type, will return parent folder
|
|
CFolder* GetParentFolder(INTERNAL* pInternal)
|
|
{
|
|
if (NULL == pInternal)
|
|
return NULL;
|
|
|
|
if (CCT_SCOPE == pInternal->m_type)
|
|
{
|
|
return reinterpret_cast<CFolder*>(pInternal->m_cookie);
|
|
}
|
|
else if (CCT_RESULT == pInternal->m_type)
|
|
{
|
|
RESULT_DATA* pData = reinterpret_cast<RESULT_DATA*>(pInternal->m_cookie);
|
|
CSASSERT(pData != NULL);
|
|
if (pData != NULL)
|
|
return pData->pParentFolder;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
CFolder* CSnapin::GetVirtualFolder()
|
|
{
|
|
CSASSERT(m_bVirtualView);
|
|
return m_pCurrentlySelectedScopeFolder;
|
|
}
|
|
|
|
CFolder* CSnapin::GetParentFolder(INTERNAL* pInternal)
|
|
{
|
|
CFolder* p;
|
|
|
|
if(m_bVirtualView)
|
|
p = GetVirtualFolder();
|
|
else
|
|
p = ::GetParentFolder(pInternal);
|
|
|
|
#if DBG
|
|
if (p != m_pCurrentlySelectedScopeFolder)
|
|
{
|
|
if (NULL == p)
|
|
DBGPRINT((DBG_SS_CERTMMC, "Parent derived NULL, current saved folder is <%ws>\n", m_pCurrentlySelectedScopeFolder->m_pszName));
|
|
else if (NULL == m_pCurrentlySelectedScopeFolder)
|
|
DBGPRINT((DBG_SS_CERTMMC, "Parent derived as <%ws>, current saved folder is NULL\n", p->m_pszName));
|
|
else
|
|
DBGPRINT((DBG_SS_CERTMMC, "Parent derived as <%ws>, current saved folder is <%ws>\n", p->m_pszName, m_pCurrentlySelectedScopeFolder->m_pszName));
|
|
}
|
|
#endif
|
|
|
|
return p;
|
|
}
|
|
|
|
|
|
void CSnapin::HandleStandardVerbs(bool bDeselectAll, LPARAM arg,
|
|
LPDATAOBJECT lpDataObject)
|
|
{
|
|
|
|
if(m_pConsoleVerb == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (m_CustomViewID != VIEW_DEFAULT_LV)
|
|
{
|
|
if(m_CustomViewID != VIEW_ERROR_OCX)
|
|
{
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_REFRESH, HIDDEN, FALSE);
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_REFRESH, ENABLED, TRUE);
|
|
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_PROPERTIES, HIDDEN, FALSE);
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_PROPERTIES, ENABLED, TRUE);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (!bDeselectAll && lpDataObject == NULL)
|
|
return;
|
|
|
|
// You should crack the data object and enable/disable/hide standard
|
|
// commands appropriately. The standard commands are reset everytime you get
|
|
// called. So you must reset them back.
|
|
|
|
WORD bScope = LOWORD(arg);
|
|
WORD bSelect = HIWORD(arg);
|
|
|
|
DBX_PRINT(_T(" %4d - CSnapin::OnSelect<%d, %d>\n"), ++n_count, bScope, bSelect);
|
|
|
|
DWORD dwCertTypeFlags;
|
|
HRESULT hr;
|
|
INTERNAL* pInternal = lpDataObject ? ExtractInternalFormat(lpDataObject) : NULL;
|
|
// if scope item, derive parent folder from pInternal.
|
|
// if result item, recall parent folder from saved state
|
|
|
|
CFolder *pFolder = NULL;
|
|
|
|
if (IsMMCMultiSelectDataObject(lpDataObject))
|
|
{
|
|
RESULTDATAITEM Item;
|
|
|
|
CDataObject *pDataObject = reinterpret_cast<CDataObject*>(lpDataObject);
|
|
|
|
MMC_COOKIE cookie;
|
|
|
|
hr = pDataObject->GetCookieAt(0, &cookie);
|
|
if(S_OK != hr)
|
|
{
|
|
_PrintIfError(hr, "GetCookieAt");
|
|
return;
|
|
}
|
|
|
|
pFolder = reinterpret_cast<CFolder*>(cookie);
|
|
|
|
}
|
|
else
|
|
{
|
|
pFolder = reinterpret_cast<CFolder*>(pInternal->m_cookie);
|
|
}
|
|
|
|
BOOL fRoleCanDelete = FALSE;
|
|
|
|
if(!g_fCurrentUserHasDSWriteAccessTested)
|
|
{
|
|
CurrentUserCanInstallCA(g_fCurrentUserHasDSWriteAccess);
|
|
g_fCurrentUserHasDSWriteAccessTested = true;
|
|
}
|
|
|
|
if(pFolder)
|
|
fRoleCanDelete =
|
|
((CA_ACCESS_ADMIN & pFolder->GetRoles())||
|
|
g_fCurrentUserHasDSWriteAccess)?TRUE:FALSE;
|
|
|
|
if (!bDeselectAll && IsMMCMultiSelectDataObject(lpDataObject) == TRUE)
|
|
{
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_DELETE, HIDDEN, FALSE);
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_DELETE, ENABLED, fRoleCanDelete);
|
|
return;
|
|
}
|
|
if (bDeselectAll || !bSelect)
|
|
{
|
|
// we have no items selected, so add the Refresh verb
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_REFRESH, HIDDEN, FALSE);
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_REFRESH, ENABLED, TRUE);
|
|
|
|
// bail
|
|
return;
|
|
}
|
|
|
|
// Standard funcitonality NOT support by all items
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_COPY, HIDDEN, TRUE);
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_COPY, ENABLED, FALSE);
|
|
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_PASTE, HIDDEN, TRUE);
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_PASTE, ENABLED, FALSE);
|
|
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_RENAME, ENABLED, FALSE);
|
|
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_OPEN, HIDDEN, TRUE);
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_OPEN, ENABLED, FALSE);
|
|
|
|
m_pConsoleVerb->SetDefaultVerb(MMC_VERB_NONE);
|
|
|
|
if (pInternal)
|
|
{
|
|
if (pInternal->m_type == CCT_SCOPE)
|
|
{
|
|
|
|
// Common verbs through all states
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_REFRESH, HIDDEN, FALSE);
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_REFRESH, ENABLED, TRUE);
|
|
|
|
|
|
// Scope items can't be deleted
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_DELETE, HIDDEN, TRUE);
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_DELETE, ENABLED, FALSE);
|
|
|
|
// No properties on the scope item
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_PROPERTIES, HIDDEN, TRUE);
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_PROPERTIES, ENABLED, FALSE);
|
|
|
|
// default folder verb is open
|
|
m_pConsoleVerb->SetDefaultVerb(MMC_VERB_OPEN);
|
|
}
|
|
else
|
|
{
|
|
// check to see if this is a default cert type and we are in GPT,
|
|
// if so then don't enable delete
|
|
if (pFolder != NULL)
|
|
{
|
|
// Common verbs through all states
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_REFRESH, HIDDEN, TRUE);
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_REFRESH, ENABLED, FALSE);
|
|
|
|
// They do have properties
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_PROPERTIES, HIDDEN, FALSE);
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_PROPERTIES, ENABLED, TRUE);
|
|
|
|
// They can be deleted
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_DELETE, HIDDEN, FALSE);
|
|
m_pConsoleVerb->SetVerbState(MMC_VERB_DELETE, ENABLED, fRoleCanDelete);
|
|
|
|
m_pConsoleVerb->SetDefaultVerb(MMC_VERB_PROPERTIES);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
FREE_DATA(pInternal);
|
|
}
|
|
|
|
void EnableToolbar(LPTOOLBAR pToolbar, MMCBUTTON rgSnapinButtons[], int nRgSize,
|
|
BOOL bEnable)
|
|
{
|
|
for (int i=0; i < nRgSize; ++i)
|
|
{
|
|
if (rgSnapinButtons[i].idCommand != 0)
|
|
pToolbar->SetButtonState(rgSnapinButtons[i].idCommand, ENABLED,
|
|
bEnable);
|
|
}
|
|
}
|
|
|
|
|
|
void EnableMenuBtns(LPMENUBUTTON pMenuBtn, MMCBUTTON rgSnapinButtons[], int nRgSize,
|
|
BOOL bEnable)
|
|
{
|
|
for (int i=0; i < nRgSize; ++i)
|
|
{
|
|
if (rgSnapinButtons[i].idCommand != 0)
|
|
pMenuBtn->SetButtonState(rgSnapinButtons[i].idCommand, ENABLED,
|
|
bEnable);
|
|
}
|
|
}
|
|
|
|
void CSnapin::HandleExtToolbars(bool bDeselectAll, LPARAM arg, LPARAM param)
|
|
{
|
|
INTERNAL* pInternal = NULL;
|
|
HRESULT hr;
|
|
|
|
BOOL bScope = (BOOL) LOWORD(arg);
|
|
BOOL bSelect = (BOOL) HIWORD(arg);
|
|
|
|
if (param)
|
|
{
|
|
LPDATAOBJECT pDataObject = reinterpret_cast<LPDATAOBJECT>(param);
|
|
pInternal = ExtractInternalFormat(pDataObject);
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
TCHAR buf[200];
|
|
wsprintf(buf, _T(" %4d - CExtendControlbar::OnSelect<%d, %d> = %d\n"),
|
|
++n_count, bScope, bSelect, pInternal ? pInternal->m_cookie : 0);
|
|
OutputDebugString(buf);
|
|
#endif //_DEBUG
|
|
|
|
// Deselection Notification?
|
|
if (bDeselectAll || bSelect == FALSE)
|
|
{
|
|
ASSERT(m_pSvrMgrToolbar1);
|
|
EnableToolbar(m_pSvrMgrToolbar1, SvrMgrToolbar1Buttons,
|
|
ARRAYLEN(SvrMgrToolbar1Buttons), FALSE);
|
|
|
|
#ifdef INSERT_DEBUG_FOLDERS
|
|
ASSERT(m_pMenuButton1 != NULL);
|
|
m_pMenuButton1->SetButtonState(FOLDEREX_MENU, ENABLED, FALSE);
|
|
m_pMenuButton1->SetButtonState(FILEEX_MENU, ENABLED, FALSE);
|
|
#endif // INSERT_DEBUG_FOLDERS
|
|
return;
|
|
}
|
|
|
|
ASSERT(bSelect == TRUE);
|
|
bool bFileExBtn = false;
|
|
if (bScope == TRUE)
|
|
{
|
|
// at SCOPE level?
|
|
LPDATAOBJECT pDataObject = reinterpret_cast<LPDATAOBJECT>(param);
|
|
|
|
pInternal = ExtractInternalFormat(pDataObject);
|
|
if (pInternal == NULL)
|
|
return;
|
|
|
|
CFolder* pFolder = reinterpret_cast<CFolder*>(pInternal->m_cookie);
|
|
|
|
if (pInternal->m_cookie == 0)
|
|
{
|
|
if (IsPrimaryImpl() == TRUE)
|
|
{
|
|
// Attach the SvrMgrToolbar1 to the window
|
|
hr = m_pControlbar->Attach(TOOLBAR, (LPUNKNOWN) m_pSvrMgrToolbar1);
|
|
ASSERT(SUCCEEDED(hr));
|
|
}
|
|
}
|
|
else if (IsPrimaryImpl() == TRUE /*&&
|
|
( pFolder->GetType() == SERVER_INSTANCE ||
|
|
pFolder->GetType() == SERVERFUNC_CRL_PUBLICATION ||
|
|
pFolder->GetType() == SERVERFUNC_ISSUED_CERTIFICATES ||
|
|
pFolder->GetType() == SERVERFUNC_PENDING_CERTIFICATES )*/)
|
|
{
|
|
// Attach the SvrMgrToolbar1 to the window
|
|
hr = m_pControlbar->Attach(TOOLBAR, (LPUNKNOWN) m_pSvrMgrToolbar1);
|
|
ASSERT(SUCCEEDED(hr));
|
|
}
|
|
else
|
|
{
|
|
// Detach the SvrMgrToolbar1 to the window
|
|
hr = m_pControlbar->Detach((LPUNKNOWN) m_pSvrMgrToolbar1);
|
|
ASSERT(SUCCEEDED(hr));
|
|
}
|
|
|
|
}
|
|
else // result item selected: result or subfolder
|
|
{
|
|
// at RESULTS level
|
|
LPDATAOBJECT pDataObject = reinterpret_cast<LPDATAOBJECT>(param);
|
|
|
|
if (pDataObject != NULL)
|
|
pInternal = ExtractInternalFormat(pDataObject);
|
|
|
|
if (pInternal == NULL)
|
|
return;
|
|
|
|
if (pInternal->m_type == CCT_RESULT)
|
|
{
|
|
bFileExBtn = true;
|
|
|
|
// UNDONE: what to do here with SvrMgrToolbar1Buttons1?
|
|
// For now, do nothing: allow them to remain in same state
|
|
|
|
}
|
|
else // sub folder slected
|
|
{
|
|
CFolder* pFolder = reinterpret_cast<CFolder*>(pInternal->m_cookie);
|
|
|
|
ASSERT(m_pControlbar);
|
|
|
|
if (pInternal->m_cookie == 0)
|
|
{
|
|
if (IsPrimaryImpl() == TRUE)
|
|
{
|
|
// Attach the SvrMgrToolbar1 to the window
|
|
hr = m_pControlbar->Attach(TOOLBAR, (LPUNKNOWN) m_pSvrMgrToolbar1);
|
|
ASSERT(SUCCEEDED(hr));
|
|
}
|
|
}
|
|
else if (IsPrimaryImpl() == TRUE /*&&
|
|
( pFolder->GetType() == SERVER_INSTANCE ||
|
|
pFolder->GetType() == SERVERFUNC_CRL_PUBLICATION ||
|
|
pFolder->GetType() == SERVERFUNC_ISSUED_CERTIFICATES ||
|
|
pFolder->GetType() == SERVERFUNC_PENDING_CERTIFICATES )*/)
|
|
{
|
|
// Attach the SvrMgrToolbar1 to the window
|
|
hr = m_pControlbar->Attach(TOOLBAR, (LPUNKNOWN) m_pSvrMgrToolbar1);
|
|
ASSERT(SUCCEEDED(hr));
|
|
}
|
|
else
|
|
{
|
|
// Detach the SvrMgrToolbar1 to the window
|
|
hr = m_pControlbar->Detach((LPUNKNOWN) m_pSvrMgrToolbar1);
|
|
ASSERT(SUCCEEDED(hr));
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef INSERT_DEBUG_FOLDERS
|
|
if (m_pMenuButton1)
|
|
{
|
|
// Always make sure the menuButton is attached
|
|
m_pControlbar->Attach(MENUBUTTON, m_pMenuButton1);
|
|
|
|
if (bFileExBtn)
|
|
{
|
|
m_pMenuButton1->SetButtonState(FILEEX_MENU, HIDDEN, FALSE);
|
|
m_pMenuButton1->SetButtonState(FOLDEREX_MENU, HIDDEN, TRUE);
|
|
m_pMenuButton1->SetButtonState(FILEEX_MENU, ENABLED, TRUE);
|
|
}
|
|
else
|
|
{
|
|
m_pMenuButton1->SetButtonState(FOLDEREX_MENU, HIDDEN, FALSE);
|
|
m_pMenuButton1->SetButtonState(FILEEX_MENU, HIDDEN, TRUE);
|
|
m_pMenuButton1->SetButtonState(FOLDEREX_MENU, ENABLED, TRUE);
|
|
}
|
|
}
|
|
#endif // INSERT_DEBUG_FOLDERS
|
|
FREE_DATA(pInternal);
|
|
}
|
|
|
|
// dropdown menu addition
|
|
void CSnapin::HandleExtMenus(LPARAM arg, LPARAM param)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
LPDATAOBJECT* ppDataObject = reinterpret_cast<LPDATAOBJECT*>(arg);
|
|
LPMENUBUTTONDATA pMenuData = reinterpret_cast<LPMENUBUTTONDATA>(param);
|
|
|
|
if (ppDataObject == NULL || pMenuData == NULL)
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
|
|
HMENU hMenu = NULL;
|
|
HMENU hSubMenu = NULL;
|
|
|
|
switch (pMenuData->idCommand)
|
|
{
|
|
case FOLDEREX_MENU:
|
|
hMenu = LoadMenu(g_hInstance, MAKEINTRESOURCE(FOLDEREX_MENU));
|
|
if (NULL == hMenu)
|
|
break;
|
|
hSubMenu = GetSubMenu(hMenu, 0);
|
|
break;
|
|
|
|
case FILEEX_MENU:
|
|
hMenu = LoadMenu(g_hInstance, MAKEINTRESOURCE(FILEEX_MENU));
|
|
if (NULL == hMenu)
|
|
break;
|
|
hSubMenu = GetSubMenu(hMenu, 0);
|
|
break;
|
|
|
|
default:
|
|
ASSERT(FALSE);
|
|
}
|
|
|
|
if (hSubMenu == NULL)
|
|
{
|
|
// might've already loaded hMenu -- free if we have
|
|
if (NULL != hMenu)
|
|
DestroyMenu(hMenu);
|
|
|
|
return;
|
|
}
|
|
|
|
//pMenu->TrackPopupMenu(TPM_RETURNCMD | TPM_NONOTIFY, pMenuData->x, pMenuData->y, AfxGetMainWnd());
|
|
HWND hwndMain = NULL;
|
|
m_pConsole->GetMainWindow(&hwndMain);
|
|
TrackPopupMenu(hSubMenu, TPM_RETURNCMD | TPM_NONOTIFY, pMenuData->x, pMenuData->y, 0, hwndMain, NULL);
|
|
|
|
// Destroy the menu.
|
|
if (NULL != hMenu)
|
|
DestroyMenu(hMenu);
|
|
}
|
|
|
|
|
|
void CSnapin::GetItemName(LPDATAOBJECT pdtobj, LPWSTR pszName, DWORD *pcName)
|
|
{
|
|
ASSERT(pszName != NULL);
|
|
pszName[0] = 0;
|
|
|
|
INTERNAL* pInternal = ExtractInternalFormat(pdtobj);
|
|
ASSERT(pInternal != NULL);
|
|
if (pInternal == NULL)
|
|
return;
|
|
|
|
ASSERT(pcName != NULL);
|
|
if (pcName == NULL)
|
|
return;
|
|
|
|
|
|
|
|
OLECHAR *pszTemp;
|
|
|
|
if (pInternal->m_type == CCT_RESULT)
|
|
{
|
|
RESULT_DATA* pData;
|
|
pData = reinterpret_cast<RESULT_DATA*>(pInternal->m_cookie);
|
|
|
|
ASSERT(pData != NULL);
|
|
pszTemp = pData->szStringArray[RESULTDATA_ARRAYENTRY_NAME]; // szName
|
|
}
|
|
else
|
|
{
|
|
CFolder* pFolder = reinterpret_cast<CFolder*>(pInternal->m_cookie);
|
|
if (pFolder == 0)
|
|
pszTemp = L"Static folder";
|
|
else
|
|
pszTemp = OLE2W(pFolder->m_pszName);
|
|
}
|
|
|
|
USES_CONVERSION;
|
|
|
|
|
|
lstrcpyn(pszName, OLE2W(pszTemp), *pcName);
|
|
if(*pcName > wcslen(pszName))
|
|
{
|
|
*pcName = wcslen(pszName) + 1;
|
|
}
|
|
|
|
FREE_DATA(pInternal);
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// IExtendPropertySheet Implementation
|
|
|
|
STDMETHODIMP CSnapin::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);
|
|
|
|
PropertyPage* pBasePage;
|
|
|
|
INTERNAL* pInternal = ExtractInternalFormat(lpIDataObject);
|
|
|
|
if(pInternal == NULL)
|
|
{
|
|
return E_POINTER;
|
|
}
|
|
|
|
switch (pInternal->m_type)
|
|
{
|
|
case CCT_RESULT:
|
|
{
|
|
if (0 == pInternal->m_cookie)
|
|
{
|
|
// base scope
|
|
// no properties exist here
|
|
/*
|
|
// Create the primary property page
|
|
CGeneralPage* pPage = new CGeneralPage();
|
|
if(pPage == NULL)
|
|
{
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
pPage->m_hConsoleHandle = handle;
|
|
pBasePage = pPage;
|
|
*/
|
|
return S_OK;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// switch on folder type
|
|
CFolder* pFolder = reinterpret_cast<CFolder*>(pInternal->m_cookie);
|
|
ASSERT(pFolder != NULL);
|
|
if (pFolder == NULL)
|
|
return E_INVALIDARG;
|
|
|
|
//1
|
|
CCertTemplateGeneralPage* pControlPage = new CCertTemplateGeneralPage(pFolder->m_hCertType);
|
|
if(pControlPage == NULL)
|
|
{
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
{
|
|
pControlPage->m_hConsoleHandle = handle; // only do this on primary
|
|
pBasePage = pControlPage;
|
|
HPROPSHEETPAGE hPage = CreatePropertySheetPage(&pBasePage->m_psp);
|
|
if (hPage == NULL)
|
|
{
|
|
delete (pControlPage);
|
|
return E_UNEXPECTED;
|
|
}
|
|
lpProvider->AddPage(hPage);
|
|
}
|
|
|
|
|
|
|
|
return S_OK;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
// Object gets deleted when the page is destroyed
|
|
ASSERT(lpProvider != NULL);
|
|
|
|
|
|
HPROPSHEETPAGE hPage = CreatePropertySheetPage(&pBasePage->m_psp);
|
|
if (hPage == NULL)
|
|
return E_UNEXPECTED;
|
|
|
|
lpProvider->AddPage(hPage);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CSnapin::QueryPagesFor(LPDATAOBJECT lpDataObject)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
INTERNAL* pInternal = ExtractInternalFormat(lpDataObject);
|
|
|
|
if(pInternal == NULL)
|
|
{
|
|
return E_POINTER;
|
|
}
|
|
ASSERT(pInternal);
|
|
ASSERT(pInternal->m_type == CCT_RESULT);
|
|
|
|
CFolder* pFolder = reinterpret_cast<CFolder*>(pInternal->m_cookie);
|
|
|
|
FREE_DATA(pInternal);
|
|
|
|
return S_OK;
|
|
}
|