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.
311 lines
9.9 KiB
311 lines
9.9 KiB
// DataObj.cpp : Implementation of data object classes
|
|
|
|
#include "stdafx.h"
|
|
#include "stdutils.h" // GetObjectType() utility routines
|
|
|
|
#include "macros.h"
|
|
USE_HANDLE_MACROS("MYCOMPUT(dataobj.cpp)")
|
|
|
|
#include "dataobj.h"
|
|
#include "compdata.h"
|
|
#include "resource.h" // IDS_SCOPE_MYCOMPUTER
|
|
|
|
#include <comstrm.h>
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
#include "stddtobj.cpp"
|
|
|
|
#ifdef __DAN_MORIN_HARDCODED_CONTEXT_MENU_EXTENSION__
|
|
// Additional clipboard formats for the Service context menu extension
|
|
CLIPFORMAT g_cfServiceName = (CLIPFORMAT)::RegisterClipboardFormat(L"FILEMGMT_SNAPIN_SERVICE_NAME");
|
|
CLIPFORMAT g_cfServiceDisplayName = (CLIPFORMAT)::RegisterClipboardFormat(L"FILEMGMT_SNAPIN_SERVICE_DISPLAYNAME");
|
|
#endif // __DAN_MORIN_HARDCODED_CONTEXT_MENU_EXTENSION__
|
|
|
|
// Additional clipboard formats for the Send Console Message snapin
|
|
//CLIPFORMAT CMyComputerDataObject::m_cfSendConsoleMessageText = (CLIPFORMAT)::RegisterClipboardFormat(_T("mmc.sendcmsg.MessageText"));
|
|
CLIPFORMAT CMyComputerDataObject::m_cfSendConsoleMessageRecipients = (CLIPFORMAT)::RegisterClipboardFormat(_T("mmc.sendcmsg.MessageRecipients"));
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CMyComputerDataObject::IDataObject::GetDataHere()
|
|
HRESULT CMyComputerDataObject::GetDataHere(
|
|
FORMATETC __RPC_FAR *pFormatEtcIn,
|
|
STGMEDIUM __RPC_FAR *pMedium)
|
|
{
|
|
MFC_TRY;
|
|
|
|
// ISSUE-2002/02/27-JonN test for NULL pointers
|
|
|
|
const CLIPFORMAT cf=pFormatEtcIn->cfFormat;
|
|
if (cf == m_CFNodeType)
|
|
{
|
|
const GUID* pguid = GetObjectTypeGUID( m_pcookie->m_objecttype );
|
|
stream_ptr s(pMedium);
|
|
return s.Write(pguid, sizeof(GUID));
|
|
}
|
|
else if (cf == m_CFSnapInCLSID)
|
|
{
|
|
const GUID* pguid = &CLSID_MyComputer;
|
|
stream_ptr s(pMedium);
|
|
return s.Write(pguid, sizeof(GUID));
|
|
}
|
|
else if (cf == m_CFNodeTypeString)
|
|
{
|
|
const BSTR strGUID = GetObjectTypeString( m_pcookie->m_objecttype );
|
|
stream_ptr s(pMedium);
|
|
return s.Write(strGUID);
|
|
}
|
|
else if (cf == m_CFDisplayName)
|
|
{
|
|
return PutDisplayName(pMedium);
|
|
}
|
|
else if (cf == m_CFDataObjectType)
|
|
{
|
|
stream_ptr s(pMedium);
|
|
return s.Write(&m_dataobjecttype, sizeof(m_dataobjecttype));
|
|
}
|
|
else if (cf == m_CFMachineName)
|
|
{
|
|
stream_ptr s(pMedium);
|
|
LPCWSTR pszMachineName = m_pcookie->QueryNonNULLMachineName();
|
|
if (IsBadStringPtr(pszMachineName,(UINT_PTR)-1)) // JonN 2/6/02 Security Push
|
|
{
|
|
ASSERT(FALSE);
|
|
return E_FAIL;
|
|
}
|
|
|
|
if ( !wcsncmp (pszMachineName, L"\\\\", 2) )
|
|
pszMachineName += 2; // skip whackwhack
|
|
return s.Write(pszMachineName);
|
|
}
|
|
else if (cf == m_CFRawCookie)
|
|
{
|
|
stream_ptr s(pMedium);
|
|
// CODEWORK This cast ensures that the data format is
|
|
// always a CCookie*, even for derived subclasses
|
|
CCookie* pcookie = (CCookie*)m_pcookie;
|
|
return s.Write(reinterpret_cast<PBYTE>(&pcookie), sizeof(m_pcookie));
|
|
}
|
|
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.
|
|
return s.Write (reinterpret_cast<PBYTE>(&m_fAllowOverrideMachineName), sizeof (BOOL));
|
|
}
|
|
|
|
return DV_E_FORMATETC;
|
|
|
|
MFC_CATCH;
|
|
} // CMyComputerDataObject::GetDataHere()
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// CMyComputerDataObject::IDataObject::GetData()
|
|
//
|
|
// Write data into the storage medium.
|
|
// The data will be retrieved by the Send Console Message snapin.
|
|
//
|
|
// HISTORY
|
|
// 12-Aug-97 t-danm Creation.
|
|
//
|
|
HRESULT
|
|
CMyComputerDataObject::GetData(
|
|
FORMATETC __RPC_FAR * pFormatEtcIn,
|
|
STGMEDIUM __RPC_FAR * pMedium)
|
|
{
|
|
// ISSUE-2002-02-27-JonN Should use MFC_TRY/MFC_CATCH
|
|
|
|
// JonN 2/20/02 Security Push
|
|
if (NULL == pFormatEtcIn || NULL == pMedium)
|
|
{
|
|
ASSERT(FALSE);
|
|
return E_POINTER;
|
|
}
|
|
|
|
HRESULT hr = S_OK;
|
|
const CLIPFORMAT cf = pFormatEtcIn->cfFormat;
|
|
if (cf == m_cfSendConsoleMessageRecipients)
|
|
{
|
|
//
|
|
// Write the list of recipients to the storage medium.
|
|
// - The list of recipients is a group of UNICODE strings
|
|
// terminated by TWO null characters.c
|
|
// - Allocated memory must include BOTH null characters.
|
|
//
|
|
ASSERT (m_pcookie);
|
|
if ( m_pcookie )
|
|
{
|
|
CString computerName = m_pcookie->QueryNonNULLMachineName ();
|
|
if ( computerName.IsEmpty () )
|
|
{
|
|
DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1 ;
|
|
VERIFY (::GetComputerName (
|
|
computerName.GetBufferSetLength (dwSize),
|
|
&dwSize));
|
|
computerName.ReleaseBuffer ();
|
|
}
|
|
size_t cch = computerName.GetLength () + 2;
|
|
HGLOBAL hGlobal = ::GlobalAlloc (GMEM_FIXED | GMEM_ZEROINIT,
|
|
cch * sizeof (WCHAR));
|
|
if ( hGlobal )
|
|
{
|
|
// JonN 2/6/02 Security Push: memcpy -> StringCchCopy
|
|
// this should leave two NULLS
|
|
StringCchCopyW ((LPWSTR)hGlobal, cch, (LPCWSTR)computerName);
|
|
pMedium->hGlobal = hGlobal;
|
|
return S_OK;
|
|
}
|
|
else
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
else
|
|
return E_UNEXPECTED;
|
|
} else if (cf == m_CFNodeID2)
|
|
{
|
|
const LPCTSTR strGUID = GetObjectTypeString( m_pcookie->m_objecttype );
|
|
|
|
// JonN 12/11/01 502856
|
|
int cbString = (lstrlen(strGUID) + 1) * sizeof(TCHAR);
|
|
|
|
pMedium->tymed = TYMED_HGLOBAL;
|
|
pMedium->hGlobal = ::GlobalAlloc(GMEM_SHARE|GMEM_MOVEABLE,
|
|
sizeof(SNodeID2) + cbString);
|
|
if (!(pMedium->hGlobal))
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
} else
|
|
{
|
|
SNodeID2 *pNodeID = (SNodeID2 *)GlobalLock(pMedium->hGlobal);
|
|
if (!pNodeID)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
GlobalFree(pMedium->hGlobal);
|
|
pMedium->hGlobal = NULL;
|
|
} else
|
|
{
|
|
pNodeID->dwFlags = 0;
|
|
pNodeID->cBytes = cbString;
|
|
// JonN 2/6/02 Security Push: function usage approved
|
|
CopyMemory(pNodeID->id, strGUID, cbString );
|
|
GlobalUnlock(pMedium->hGlobal);
|
|
}
|
|
}
|
|
} else
|
|
{
|
|
hr = DV_E_FORMATETC;
|
|
}
|
|
|
|
return hr;
|
|
} // CMyComputerDataObject::GetData()
|
|
|
|
//#endif // __DAN_MORIN_HARDCODED_CONTEXT_MENU_EXTENSION__
|
|
|
|
|
|
HRESULT CMyComputerDataObject::Initialize(
|
|
CMyComputerCookie* pcookie,
|
|
DATA_OBJECT_TYPES type,
|
|
BOOL fAllowOverrideMachineName)
|
|
{
|
|
// ISSUE-2002-/02/27-JonN check "type" parameter
|
|
if (NULL == pcookie || NULL != m_pcookie)
|
|
{
|
|
ASSERT(FALSE);
|
|
return E_UNEXPECTED;
|
|
}
|
|
m_dataobjecttype = type;
|
|
m_pcookie = pcookie;
|
|
m_fAllowOverrideMachineName = fAllowOverrideMachineName;
|
|
((CRefcountedObject*)m_pcookie)->AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
CMyComputerDataObject::~CMyComputerDataObject()
|
|
{
|
|
if (NULL != m_pcookie)
|
|
{
|
|
((CRefcountedObject*)m_pcookie)->Release();
|
|
}
|
|
else
|
|
{
|
|
ASSERT(FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
HRESULT CMyComputerDataObject::PutDisplayName(STGMEDIUM* pMedium)
|
|
// Writes the "friendly name" to the provided storage medium
|
|
// Returns the result of the write operation
|
|
{
|
|
// JonN 2/20/02 Security Push
|
|
if (NULL == pMedium)
|
|
{
|
|
ASSERT(FALSE);
|
|
return E_POINTER;
|
|
}
|
|
|
|
CString strDisplayName = m_pcookie->QueryTargetServer();
|
|
CString formattedName = FormatDisplayName (strDisplayName);
|
|
|
|
|
|
stream_ptr s(pMedium);
|
|
return s.Write(formattedName);
|
|
}
|
|
|
|
// Register the clipboard formats
|
|
CLIPFORMAT CMyComputerDataObject::m_CFDisplayName =
|
|
(CLIPFORMAT)RegisterClipboardFormat(CCF_DISPLAY_NAME);
|
|
CLIPFORMAT CMyComputerDataObject::m_CFNodeID2 =
|
|
(CLIPFORMAT)RegisterClipboardFormat(CCF_NODEID2);
|
|
CLIPFORMAT CMyComputerDataObject::m_CFMachineName =
|
|
(CLIPFORMAT)RegisterClipboardFormat(L"MMC_SNAPIN_MACHINE_NAME");
|
|
CLIPFORMAT CDataObject::m_CFRawCookie =
|
|
(CLIPFORMAT)RegisterClipboardFormat(L"MYCOMPUT_SNAPIN_RAW_COOKIE");
|
|
|
|
|
|
STDMETHODIMP CMyComputerComponentData::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject)
|
|
{
|
|
MFC_TRY;
|
|
|
|
// ISSUE-2002/02/27-JonN This would be more efficient if an instance of
|
|
// CMyComputerDataObject were permanently attached to CMyComputerCookie,
|
|
// or better yet, if they were the same object. QueryDataObject gets
|
|
// called a lot...
|
|
|
|
CMyComputerCookie* pUseThisCookie = (CMyComputerCookie*)ActiveBaseCookie(reinterpret_cast<CCookie*>(cookie));
|
|
// JonN 2/20/02 Security Push
|
|
if (NULL == pUseThisCookie)
|
|
{
|
|
ASSERT(FALSE);
|
|
return E_POINTER;
|
|
}
|
|
|
|
CComObject<CMyComputerDataObject>* pDataObject = NULL;
|
|
HRESULT hRes = CComObject<CMyComputerDataObject>::CreateInstance(&pDataObject);
|
|
if ( FAILED(hRes) )
|
|
return hRes;
|
|
|
|
HRESULT hr = pDataObject->Initialize( pUseThisCookie, type, m_fAllowOverrideMachineName);
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
hr = pDataObject->QueryInterface(IID_IDataObject,
|
|
reinterpret_cast<void**>(ppDataObject));
|
|
}
|
|
if ( FAILED(hr) )
|
|
{
|
|
delete pDataObject;
|
|
return hr;
|
|
}
|
|
|
|
return hr;
|
|
|
|
MFC_CATCH;
|
|
}
|