814 lines
21 KiB
C++
814 lines
21 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1997-2001.
|
|
//
|
|
// File: DataObj.cpp
|
|
//
|
|
// Contents: Implementation of data object classes
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "stdafx.h"
|
|
|
|
USE_HANDLE_MACROS("CERTMGR(dataobj.cpp)")
|
|
|
|
#include <gpedit.h>
|
|
#include "compdata.h"
|
|
#include "dataobj.h"
|
|
|
|
#pragma warning(push,3)
|
|
#include <sceattch.h>
|
|
#pragma warning(pop)
|
|
#include "uuids.h"
|
|
|
|
#ifdef _DEBUG
|
|
#ifndef ALPHA
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
#include "stddtobj.cpp"
|
|
|
|
|
|
// IDataObject interface implementation
|
|
|
|
CCertMgrDataObject::CCertMgrDataObject()
|
|
: m_pCookie (0),
|
|
m_objecttype (CERTMGR_SNAPIN),
|
|
m_dataobjecttype (CCT_UNINITIALIZED),
|
|
m_dwLocation (0),
|
|
m_pGPEInformation (0),
|
|
m_pRSOPInformation (0),
|
|
m_pbMultiSelData(NULL),
|
|
m_cbMultiSelData(0),
|
|
m_bMultiSelDobj(false),
|
|
m_iCurr(0)
|
|
{
|
|
}
|
|
|
|
HRESULT CCertMgrDataObject::GetDataHere(
|
|
FORMATETC __RPC_FAR *pFormatEtcIn,
|
|
STGMEDIUM __RPC_FAR *pMedium)
|
|
{
|
|
HRESULT hr = DV_E_FORMATETC;
|
|
|
|
const CLIPFORMAT cf=pFormatEtcIn->cfFormat;
|
|
if (cf == m_CFNodeType)
|
|
{
|
|
if ( IsValidObjectType (m_pCookie->m_objecttype) )
|
|
{
|
|
const GUID* pguid = GetObjectTypeGUID( m_pCookie->m_objecttype );
|
|
stream_ptr s(pMedium);
|
|
hr = s.Write(pguid, sizeof(GUID));
|
|
}
|
|
else
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
else if (cf == m_CFSnapInCLSID)
|
|
{
|
|
stream_ptr s(pMedium);
|
|
hr = s.Write(&m_SnapInCLSID, sizeof(GUID));
|
|
}
|
|
else if (cf == m_CFNodeTypeString)
|
|
{
|
|
if ( IsValidObjectType (m_pCookie->m_objecttype) )
|
|
{
|
|
const BSTR strGUID = GetObjectTypeString( m_pCookie->m_objecttype );
|
|
stream_ptr s(pMedium);
|
|
hr = s.Write(strGUID);
|
|
}
|
|
else
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
else if (cf == m_CFDisplayName)
|
|
{
|
|
hr = PutDisplayName(pMedium);
|
|
}
|
|
else if (cf == m_CFDataObjectType)
|
|
{
|
|
stream_ptr s(pMedium);
|
|
hr = s.Write(&m_dataobjecttype, sizeof(m_dataobjecttype));
|
|
}
|
|
else if (cf == m_CFMachineName)
|
|
{
|
|
if ( IsValidObjectType (m_pCookie->m_objecttype) )
|
|
{
|
|
stream_ptr s(pMedium);
|
|
hr = s.Write(m_pCookie->QueryNonNULLMachineName());
|
|
}
|
|
else
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
else if (cf == m_CFRawCookie)
|
|
{
|
|
stream_ptr s(pMedium);
|
|
|
|
|
|
if ( m_pCookie )
|
|
{
|
|
// CODEWORK This cast ensures that the data format is
|
|
// always a CCookie*, even for derived subclasses
|
|
if ( ((CCertMgrCookie*) MMC_MULTI_SELECT_COOKIE) == m_pCookie ||
|
|
IsValidObjectType (m_pCookie->m_objecttype) )
|
|
{
|
|
CCookie* pcookie = (CCookie*) m_pCookie;
|
|
hr = s.Write(reinterpret_cast<PBYTE>(&pcookie), sizeof(m_pCookie));
|
|
}
|
|
else
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
}
|
|
else if ( cf == m_CFSCE_GPTUnknown )
|
|
{
|
|
hr = CreateGPTUnknown (pMedium);
|
|
}
|
|
else if ( cf == m_CFSCE_RSOPUnknown )
|
|
{
|
|
hr = CreateRSOPUnknown (pMedium);
|
|
}
|
|
else if ( cf == m_CFMultiSel )
|
|
{
|
|
hr = CreateMultiSelectObject (pMedium);
|
|
}
|
|
else if (cf == m_CFSnapinPreloads)
|
|
{
|
|
stream_ptr s(pMedium);
|
|
// If this is TRUE, then the next time this snapin is loaded, it will
|
|
// be preloaded to give us the opportunity to change the root node
|
|
// name before the user sees it.
|
|
hr = s.Write (reinterpret_cast<PBYTE>(&m_fAllowOverrideMachineName), sizeof (BOOL));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CCertMgrDataObject::Initialize(
|
|
CCertMgrCookie* pcookie,
|
|
DATA_OBJECT_TYPES type,
|
|
BOOL fAllowOverrideMachineName,
|
|
DWORD dwLocation,
|
|
CString szManagedUser,
|
|
CString szManagedComputer,
|
|
CString szManagedService,
|
|
CCertMgrComponentData& refComponentData)
|
|
{
|
|
if ( !pcookie || m_pCookie )
|
|
{
|
|
ASSERT(FALSE);
|
|
return S_OK; // Initialize must not fail
|
|
}
|
|
|
|
m_dataobjecttype = type;
|
|
m_pCookie = pcookie;
|
|
m_fAllowOverrideMachineName = fAllowOverrideMachineName;
|
|
m_dwLocation = dwLocation;
|
|
m_szManagedUser = szManagedUser;
|
|
m_szManagedComputer = szManagedComputer;
|
|
m_szManagedService = szManagedService;
|
|
|
|
if ( ((CCertMgrCookie*) MMC_MULTI_SELECT_COOKIE) != m_pCookie )
|
|
((CRefcountedObject*)m_pCookie)->AddRef();
|
|
VERIFY( SUCCEEDED(refComponentData.GetClassID(&m_SnapInCLSID)) );
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
CCertMgrDataObject::~CCertMgrDataObject()
|
|
{
|
|
if ( m_pGPEInformation )
|
|
{
|
|
m_pGPEInformation->Release ();
|
|
m_pGPEInformation = 0;
|
|
}
|
|
|
|
if ( m_pRSOPInformation )
|
|
{
|
|
m_pRSOPInformation->Release ();
|
|
m_pRSOPInformation = 0;
|
|
}
|
|
|
|
if ( ((CCertMgrCookie*) MMC_MULTI_SELECT_COOKIE) != m_pCookie &&
|
|
m_pCookie && IsValidObjectType (m_pCookie->m_objecttype) )
|
|
{
|
|
((CRefcountedObject*)m_pCookie)->Release();
|
|
}
|
|
if (m_pbMultiSelData)
|
|
delete m_pbMultiSelData;
|
|
|
|
for (int i=0; i < m_rgCookies.GetSize(); ++i)
|
|
{
|
|
m_rgCookies[i]->Release();
|
|
}
|
|
}
|
|
|
|
void CCertMgrDataObject::AddCookie(CCertMgrCookie* pCookie)
|
|
{
|
|
m_rgCookies.Add(pCookie);
|
|
pCookie->AddRef();
|
|
}
|
|
|
|
HRESULT CCertMgrDataObject::PutDisplayName(STGMEDIUM* pMedium)
|
|
// Writes the "friendly name" to the provided storage medium
|
|
// Returns the result of the write operation
|
|
{
|
|
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
|
CString strDisplayName = m_pCookie->QueryTargetServer();
|
|
CString formattedName;
|
|
|
|
switch (m_dwLocation)
|
|
{
|
|
case CERT_SYSTEM_STORE_CURRENT_USER:
|
|
VERIFY (formattedName.LoadString (IDS_SCOPE_SNAPIN_TITLE_USER));
|
|
break;
|
|
|
|
case CERT_SYSTEM_STORE_LOCAL_MACHINE:
|
|
if (strDisplayName.IsEmpty())
|
|
{
|
|
VERIFY (formattedName.LoadString (IDS_SCOPE_SNAPIN_TITLE_LOCAL_MACHINE));
|
|
}
|
|
else
|
|
formattedName.FormatMessage (IDS_SCOPE_SNAPIN_TITLE_MACHINE, strDisplayName);
|
|
break;
|
|
|
|
case CERT_SYSTEM_STORE_CURRENT_SERVICE:
|
|
case CERT_SYSTEM_STORE_SERVICES:
|
|
if (strDisplayName.IsEmpty())
|
|
{
|
|
// Get this machine name and add it to the string.
|
|
formattedName.FormatMessage (IDS_SCOPE_SNAPIN_TITLE_SERVICE_LOCAL_MACHINE,
|
|
m_szManagedService);
|
|
}
|
|
else
|
|
{
|
|
formattedName.FormatMessage (IDS_SCOPE_SNAPIN_TITLE_SERVICE,
|
|
m_szManagedService, strDisplayName);
|
|
}
|
|
break;
|
|
|
|
// These next two titles can only be set from the debugger. They are used
|
|
// to create custom .MSC files.
|
|
case -1:
|
|
formattedName.FormatMessage (IDS_SCOPE_SNAPIN_TITLE_CERT_MGR_CURRENT_USER);
|
|
break;
|
|
|
|
case 0:
|
|
formattedName.FormatMessage (IDS_SCOPE_SNAPIN_TITLE_FILE);
|
|
break;
|
|
|
|
default:
|
|
ASSERT (0);
|
|
break;
|
|
}
|
|
|
|
stream_ptr s (pMedium);
|
|
return s.Write (formattedName);
|
|
}
|
|
|
|
// Register the clipboard formats
|
|
CLIPFORMAT CCertMgrDataObject::m_CFDisplayName =
|
|
(CLIPFORMAT)RegisterClipboardFormat(CCF_DISPLAY_NAME);
|
|
CLIPFORMAT CCertMgrDataObject::m_CFMachineName =
|
|
(CLIPFORMAT)RegisterClipboardFormat(L"MMC_SNAPIN_MACHINE_NAME");
|
|
CLIPFORMAT CDataObject::m_CFRawCookie =
|
|
(CLIPFORMAT)RegisterClipboardFormat(L"CERTMGR_SNAPIN_RAW_COOKIE");
|
|
CLIPFORMAT CCertMgrDataObject::m_CFMultiSel =
|
|
(CLIPFORMAT)RegisterClipboardFormat(CCF_OBJECT_TYPES_IN_MULTI_SELECT);
|
|
CLIPFORMAT CCertMgrDataObject::m_CFMultiSelDobj =
|
|
(CLIPFORMAT)RegisterClipboardFormat(CCF_MMC_MULTISELECT_DATAOBJECT);
|
|
CLIPFORMAT CCertMgrDataObject::m_CFSCEModeType =
|
|
(CLIPFORMAT)RegisterClipboardFormat(CCF_SCE_MODE_TYPE);
|
|
CLIPFORMAT CCertMgrDataObject::m_CFSCE_GPTUnknown =
|
|
(CLIPFORMAT)RegisterClipboardFormat(CCF_SCE_GPT_UNKNOWN);
|
|
CLIPFORMAT CCertMgrDataObject::m_CFSCE_RSOPUnknown =
|
|
(CLIPFORMAT)RegisterClipboardFormat(CCF_SCE_RSOP_UNKNOWN);
|
|
CLIPFORMAT CCertMgrDataObject::m_CFMultiSelDataObjs =
|
|
(CLIPFORMAT)RegisterClipboardFormat(CCF_MULTI_SELECT_SNAPINS);
|
|
|
|
|
|
void CCertMgrDataObject::SetMultiSelData(BYTE* pbMultiSelData, UINT cbMultiSelData)
|
|
{
|
|
m_pbMultiSelData = pbMultiSelData;
|
|
m_cbMultiSelData = cbMultiSelData;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CCertMgrComponentData::QueryDataObject (
|
|
MMC_COOKIE cookie,
|
|
DATA_OBJECT_TYPES type,
|
|
LPDATAOBJECT* ppDataObject)
|
|
{
|
|
if ( MMC_MULTI_SELECT_COOKIE == cookie )
|
|
{
|
|
return QueryMultiSelectDataObject (cookie, type, ppDataObject);
|
|
}
|
|
CCertMgrCookie* pUseThisCookie =
|
|
(CCertMgrCookie*) ActiveBaseCookie (
|
|
reinterpret_cast<CCookie*> (cookie));
|
|
|
|
CComObject<CCertMgrDataObject>* pDataObject = 0;
|
|
HRESULT hRes = CComObject<CCertMgrDataObject>::CreateInstance(&pDataObject);
|
|
if ( FAILED(hRes) )
|
|
return hRes;
|
|
|
|
if ( m_szManagedUser.IsEmpty () )
|
|
m_szManagedUser = m_szLoggedInUser;
|
|
|
|
m_szManagedComputer = pUseThisCookie->QueryTargetServer();
|
|
if ( m_szManagedComputer.IsEmpty () && m_strMachineNamePersist.CompareNoCase (m_szThisComputer) ) // !=
|
|
{
|
|
m_szManagedComputer = m_strMachineNamePersist;
|
|
}
|
|
if ( m_szManagedComputer.IsEmpty () )
|
|
m_szManagedComputer = pUseThisCookie->QueryNonNULLMachineName ();
|
|
if ( m_szManagedComputer.IsEmpty () )
|
|
m_szManagedComputer = m_szThisComputer;
|
|
|
|
// Raid bug 278491 US: Cert search for a remote computer application
|
|
// fails to search certs on a remote computer, instead running a search
|
|
// on Local machine
|
|
if ( m_szManagedComputer.CompareNoCase (m_szThisComputer) )
|
|
pUseThisCookie->SetMachineName (m_szManagedComputer);
|
|
|
|
// Truncate leading "\\"
|
|
if ( !wcsncmp (m_szManagedComputer, L"\\\\", 2) )
|
|
m_szManagedComputer = m_szManagedComputer.Mid (2);
|
|
|
|
HRESULT hr = pDataObject->Initialize (
|
|
pUseThisCookie,
|
|
type,
|
|
m_fAllowOverrideMachineName,
|
|
m_dwLocationPersist,
|
|
m_szManagedUser,
|
|
m_szManagedComputer,
|
|
m_szManagedServiceDisplayName,
|
|
*this);
|
|
if ( FAILED(hr) )
|
|
{
|
|
delete pDataObject;
|
|
return hr;
|
|
}
|
|
|
|
if ( m_pGPEInformation )
|
|
pDataObject->SetGPTInformation (m_pGPEInformation);
|
|
if ( m_bIsRSOP )
|
|
{
|
|
IRSOPInformation* pRSOPInformation = 0;
|
|
|
|
switch (pUseThisCookie->m_objecttype)
|
|
{
|
|
case CERTMGR_CERT_POLICIES_COMPUTER:
|
|
case CERTMGR_PKP_AUTOENROLLMENT_COMPUTER_SETTINGS:
|
|
case CERTMGR_SAFER_COMPUTER_ROOT:
|
|
case CERTMGR_SAFER_COMPUTER_LEVELS:
|
|
case CERTMGR_SAFER_COMPUTER_ENTRIES:
|
|
case CERTMGR_SAFER_COMPUTER_LEVEL:
|
|
case CERTMGR_SAFER_COMPUTER_ENTRY:
|
|
case CERTMGR_SAFER_COMPUTER_TRUSTED_PUBLISHERS:
|
|
case CERTMGR_SAFER_COMPUTER_DEFINED_FILE_TYPES:
|
|
pRSOPInformation = m_pRSOPInformationComputer;
|
|
break;
|
|
|
|
case CERTMGR_CERT_POLICIES_USER:
|
|
case CERTMGR_PKP_AUTOENROLLMENT_USER_SETTINGS:
|
|
case CERTMGR_SAFER_USER_ROOT:
|
|
case CERTMGR_SAFER_USER_LEVELS:
|
|
case CERTMGR_SAFER_USER_ENTRIES:
|
|
case CERTMGR_SAFER_USER_LEVEL:
|
|
case CERTMGR_SAFER_USER_ENTRY:
|
|
case CERTMGR_SAFER_USER_TRUSTED_PUBLISHERS:
|
|
case CERTMGR_SAFER_USER_DEFINED_FILE_TYPES:
|
|
case CERTMGR_SAFER_COMPUTER_ENFORCEMENT:
|
|
case CERTMGR_SAFER_USER_ENFORCEMENT:
|
|
pRSOPInformation = m_pRSOPInformationUser;
|
|
break;
|
|
|
|
case CERTMGR_CERTIFICATE:
|
|
case CERTMGR_LOG_STORE:
|
|
case CERTMGR_PHYS_STORE:
|
|
case CERTMGR_USAGE:
|
|
case CERTMGR_CRL_CONTAINER:
|
|
case CERTMGR_CTL_CONTAINER:
|
|
case CERTMGR_CERT_CONTAINER:
|
|
case CERTMGR_CRL:
|
|
case CERTMGR_CTL:
|
|
case CERTMGR_AUTO_CERT_REQUEST:
|
|
case CERTMGR_LOG_STORE_GPE:
|
|
case CERTMGR_LOG_STORE_RSOP:
|
|
default:
|
|
pRSOPInformation = m_pRSOPInformationComputer;
|
|
break;
|
|
}
|
|
pDataObject->SetRSOPInformation (pRSOPInformation);
|
|
}
|
|
pDataObject->AddRef();
|
|
*ppDataObject = pDataObject;
|
|
return hr;
|
|
}
|
|
|
|
typedef CArray<GUID, const GUID&> CGUIDArray;
|
|
|
|
void GuidArray_Add(CGUIDArray& rgGuids, const GUID& guid)
|
|
{
|
|
for (INT_PTR i=rgGuids.GetUpperBound(); i >= 0; --i)
|
|
{
|
|
if (rgGuids[i] == guid)
|
|
break;
|
|
}
|
|
|
|
if (i < 0)
|
|
rgGuids.Add(guid);
|
|
}
|
|
|
|
HRESULT CCertMgrComponentData::QueryMultiSelectDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type,
|
|
LPDATAOBJECT* ppDataObject)
|
|
{
|
|
ASSERT(ppDataObject != NULL);
|
|
if (ppDataObject == NULL)
|
|
return E_POINTER;
|
|
|
|
HRESULT hr = S_OK;
|
|
CGUIDArray rgGuids;
|
|
|
|
// Determine the items selected
|
|
ASSERT(m_pResultData != NULL);
|
|
RESULTDATAITEM rdi;
|
|
ZeroMemory(&rdi, sizeof(rdi));
|
|
rdi.mask = RDI_STATE;
|
|
rdi.nIndex = -1;
|
|
rdi.nState = TVIS_SELECTED;
|
|
|
|
CCookiePtrArray rgCookiesSelected;
|
|
while (m_pResultData->GetNextItem (&rdi) == S_OK)
|
|
{
|
|
const GUID* pguid;
|
|
CCertMgrCookie* pCookie = reinterpret_cast <CCertMgrCookie*> (rdi.lParam);
|
|
if ( pCookie )
|
|
{
|
|
rgCookiesSelected.Add (pCookie);
|
|
switch (pCookie->m_objecttype)
|
|
{
|
|
case CERTMGR_CERTIFICATE:
|
|
pguid = &NODEID_CertMgr_CERTIFICATE;
|
|
break;
|
|
|
|
case CERTMGR_CTL:
|
|
pguid = &NODEID_CertMgr_CTL;
|
|
break;
|
|
|
|
case CERTMGR_CRL:
|
|
pguid = &NODEID_CertMgr_CRL;
|
|
break;
|
|
|
|
case CERTMGR_AUTO_CERT_REQUEST:
|
|
pguid = &NODEID_CertMgr_AUTOCERT;
|
|
break;
|
|
|
|
case CERTMGR_SAFER_COMPUTER_ENTRY:
|
|
pguid = &NODEID_Safer_COMPUTER_ENTRY;
|
|
break;
|
|
|
|
case CERTMGR_SAFER_USER_ENTRY:
|
|
pguid = &NODEID_Safer_USER_ENTRY;
|
|
break;
|
|
|
|
default:
|
|
ASSERT (0);
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_INVALIDARG;
|
|
break;
|
|
}
|
|
|
|
GuidArray_Add(rgGuids, *pguid);
|
|
}
|
|
|
|
CComObject<CCertMgrDataObject>* pObject;
|
|
CComObject<CCertMgrDataObject>::CreateInstance(&pObject);
|
|
ASSERT(pObject != NULL);
|
|
|
|
// Save cookie and type for delayed rendering
|
|
pObject->Initialize ((CCertMgrCookie*) cookie,
|
|
type,
|
|
m_fAllowOverrideMachineName,
|
|
m_dwLocationPersist,
|
|
m_szManagedUser,
|
|
m_szManagedComputer,
|
|
m_szManagedServiceDisplayName,
|
|
*this);
|
|
pObject->SetMultiSelDobj();
|
|
|
|
|
|
|
|
// Store the coclass with the data object
|
|
UINT cb = (UINT)(rgGuids.GetSize() * sizeof(GUID));
|
|
GUID* pGuid = new GUID[(UINT)rgGuids.GetSize()];
|
|
if ( pGuid )
|
|
{
|
|
CopyMemory(pGuid, rgGuids.GetData(), cb);
|
|
pObject->SetMultiSelData((BYTE*)pGuid, cb);
|
|
for (int i=0; i < rgCookiesSelected.GetSize(); ++i)
|
|
{
|
|
pObject->AddCookie(rgCookiesSelected[i]);
|
|
}
|
|
|
|
return pObject->QueryInterface(
|
|
IID_PPV_ARG (IDataObject, ppDataObject));
|
|
}
|
|
else
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
|
|
HRESULT CCertMgrDataObject::SetGPTInformation(IGPEInformation * pGPTInformation)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( pGPTInformation )
|
|
{
|
|
m_pGPEInformation = pGPTInformation;
|
|
m_pGPEInformation->AddRef ();
|
|
}
|
|
else
|
|
hr = E_POINTER;
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CCertMgrDataObject::SetRSOPInformation(IRSOPInformation * pRSOPInformation)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( pRSOPInformation )
|
|
{
|
|
m_pRSOPInformation = pRSOPInformation;
|
|
m_pRSOPInformation->AddRef ();
|
|
}
|
|
else
|
|
hr = E_POINTER;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Member: CDataObject::CreateGPTUnknown
|
|
//
|
|
// Synopsis: Fill the hGlobal in [lpMedium] with a pointer to GPT's
|
|
// IUnknown interface. The object requesting this will be
|
|
// responsible for Releasing the interface
|
|
//
|
|
// History:
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
HRESULT CCertMgrDataObject::CreateGPTUnknown(LPSTGMEDIUM lpMedium)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
LPUNKNOWN pUnk = 0;
|
|
|
|
if ( !m_pGPEInformation )
|
|
{
|
|
//
|
|
// If we don't have a pointer to a GPT interface then we must not
|
|
// be in a mode where we're extending GPT and we can't provide a
|
|
// pointer to its IUnknown
|
|
//
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
hr = m_pGPEInformation->QueryInterface (
|
|
IID_PPV_ARG (IUnknown, &pUnk));
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
return Create (&pUnk, sizeof(pUnk), lpMedium);
|
|
}
|
|
else
|
|
{
|
|
return hr;
|
|
}
|
|
}
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Member: CDataObject::CreateRSOPUnknown
|
|
//
|
|
// Synopsis: Fill the hGlobal in [lpMedium] with a pointer to RSOP's
|
|
// IUnknown interface. The object requesting this will be
|
|
// responsible for Releasing the interface
|
|
//
|
|
// History:
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
HRESULT CCertMgrDataObject::CreateRSOPUnknown(LPSTGMEDIUM lpMedium)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
LPUNKNOWN pUnk = 0;
|
|
|
|
if ( !m_pRSOPInformation )
|
|
{
|
|
//
|
|
// If we don't have a pointer to a GPT interface then we must not
|
|
// be in a mode where we're extending GPT and we can't provide a
|
|
// pointer to its IUnknown
|
|
//
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
hr = m_pRSOPInformation->QueryInterface (
|
|
IID_PPV_ARG (IUnknown, &pUnk));
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
return Create (&pUnk, sizeof(pUnk), lpMedium);
|
|
}
|
|
else
|
|
{
|
|
return hr;
|
|
}
|
|
}
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Member: CDataObject::Create
|
|
//
|
|
// Synopsis: Fill the hGlobal in [lpmedium] with the data in pBuffer
|
|
//
|
|
// Arguments: [pBuffer] - [in] the data to be written
|
|
// [len] - [in] the length of that data
|
|
// [lpMedium] - [in,out] where to store the data
|
|
// History:
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
HRESULT CCertMgrDataObject::Create (const void* pBuffer, int len, LPSTGMEDIUM lpMedium)
|
|
{
|
|
HRESULT hr = DV_E_TYMED;
|
|
|
|
//
|
|
// Do some simple validation
|
|
//
|
|
if (pBuffer == NULL || lpMedium == NULL)
|
|
return E_POINTER;
|
|
|
|
//
|
|
// Make sure the type medium is HGLOBAL
|
|
//
|
|
if (lpMedium->tymed == TYMED_HGLOBAL) {
|
|
//
|
|
// Create the stream on the hGlobal passed in
|
|
//
|
|
LPSTREAM lpStream = 0;
|
|
hr = CreateStreamOnHGlobal(lpMedium->hGlobal, FALSE, &lpStream);
|
|
|
|
ASSERT (SUCCEEDED (hr));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//
|
|
// Write to the stream the number of bytes
|
|
//
|
|
ULONG written = 0;
|
|
hr = lpStream->Write(pBuffer, len, &written);
|
|
ASSERT (SUCCEEDED (hr));
|
|
|
|
//
|
|
// Because we told CreateStreamOnHGlobal with 'FALSE',
|
|
// only the stream is released here.
|
|
// Note - the caller (i.e. snap-in, object) will free the HGLOBAL
|
|
// at the correct time. This is according to the IDataObject specification.
|
|
//
|
|
lpStream->Release();
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Method: CCertMgrDataObject::CreateMultiSelectObject
|
|
//
|
|
// Synopsis: this is to create the list of types selected
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
HRESULT CCertMgrDataObject::CreateMultiSelectObject(LPSTGMEDIUM lpMedium)
|
|
{
|
|
ASSERT(m_pbMultiSelData != 0);
|
|
ASSERT(m_cbMultiSelData != 0);
|
|
|
|
lpMedium->tymed = TYMED_HGLOBAL;
|
|
lpMedium->hGlobal = ::GlobalAlloc(GMEM_SHARE|GMEM_MOVEABLE,
|
|
(m_cbMultiSelData + sizeof(DWORD)));
|
|
if (lpMedium->hGlobal == NULL)
|
|
return STG_E_MEDIUMFULL;
|
|
|
|
BYTE* pb = reinterpret_cast<BYTE*>(::GlobalLock(lpMedium->hGlobal));
|
|
*((DWORD*)pb) = m_cbMultiSelData / sizeof(GUID);
|
|
pb += sizeof(DWORD);
|
|
CopyMemory(pb, m_pbMultiSelData, m_cbMultiSelData);
|
|
|
|
::GlobalUnlock(lpMedium->hGlobal);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
LPDATAOBJECT ExtractMultiSelect (LPDATAOBJECT lpDataObject)
|
|
{
|
|
if (lpDataObject == NULL)
|
|
return NULL;
|
|
|
|
SMMCDataObjects * pDO = NULL;
|
|
|
|
STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
|
|
FORMATETC formatetc = { CCertMgrDataObject::m_CFMultiSelDataObjs, NULL,
|
|
DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
|
|
|
if ( FAILED (lpDataObject->GetData (&formatetc, &stgmedium)) )
|
|
{
|
|
return NULL;
|
|
}
|
|
else
|
|
{
|
|
pDO = reinterpret_cast<SMMCDataObjects*>(stgmedium.hGlobal);
|
|
return pDO->lpDataObject[0]; //assume that ours is the 1st
|
|
}
|
|
}
|
|
|
|
STDMETHODIMP CCertMgrDataObject::GetData(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
|
|
HRESULT hr = DV_E_CLIPFORMAT;
|
|
|
|
if (lpFormatetc->cfFormat == m_CFMultiSel)
|
|
{
|
|
ASSERT(((CCertMgrCookie*) MMC_MULTI_SELECT_COOKIE) == m_pCookie);
|
|
if ( ((CCertMgrCookie*) MMC_MULTI_SELECT_COOKIE) == m_pCookie )
|
|
{
|
|
hr = CreateMultiSelectObject (lpMedium);
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CCertMgrDataObject::Next(ULONG celt, MMC_COOKIE* rgelt, ULONG *pceltFetched)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if ((rgelt == NULL) ||
|
|
((celt > 1) && (pceltFetched == NULL)))
|
|
{
|
|
hr = E_INVALIDARG;
|
|
CHECK_HRESULT(hr);
|
|
return hr;
|
|
}
|
|
|
|
ULONG celtTemp = (ULONG)(m_rgCookies.GetSize() - m_iCurr);
|
|
celtTemp = (celt < celtTemp) ? celt : celtTemp;
|
|
|
|
if (pceltFetched)
|
|
*pceltFetched = celtTemp;
|
|
|
|
if (celtTemp == 0)
|
|
return S_FALSE;
|
|
|
|
for (ULONG i=0; i < celtTemp; ++i)
|
|
{
|
|
rgelt[i] = reinterpret_cast<MMC_COOKIE>(m_rgCookies[m_iCurr++]);
|
|
}
|
|
|
|
return (celtTemp < celt) ? S_FALSE : S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CCertMgrDataObject::Skip(ULONG celt)
|
|
{
|
|
ULONG celtTemp = (ULONG)(m_rgCookies.GetSize() - m_iCurr);
|
|
celtTemp = (celt < celtTemp) ? celt : celtTemp;
|
|
|
|
m_iCurr += celtTemp;
|
|
|
|
return (celtTemp < celt) ? S_FALSE : S_OK;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CCertMgrDataObject::Reset(void)
|
|
{
|
|
m_iCurr = 0;
|
|
return S_OK;
|
|
}
|
|
|