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.
278 lines
8.7 KiB
278 lines
8.7 KiB
/*++
|
|
|
|
Copyright (C) Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
dataobj.cpp
|
|
|
|
Abstract:
|
|
|
|
header file defines CDataObject class
|
|
|
|
Author:
|
|
|
|
William Hsieh (williamh) created
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
#include "devmgr.h"
|
|
#include "DataObj.h"
|
|
|
|
|
|
unsigned int CDataObject::m_cfNodeType = RegisterClipboardFormat(CCF_NODETYPE);
|
|
unsigned int CDataObject::m_cfNodeTypeString = RegisterClipboardFormat(CCF_SZNODETYPE);
|
|
unsigned int CDataObject::m_cfDisplayName = RegisterClipboardFormat(CCF_DISPLAY_NAME);
|
|
unsigned int CDataObject::m_cfCoClass = RegisterClipboardFormat(CCF_SNAPIN_CLASSID);
|
|
unsigned int CDataObject::m_cfSnapinInternal = RegisterClipboardFormat(SNAPIN_INTERNAL);
|
|
unsigned int CDataObject::m_cfMachineName = RegisterClipboardFormat(MMC_SNAPIN_MACHINE_NAME);
|
|
unsigned int CDataObject::m_cfClassGuid = RegisterClipboardFormat(DEVMGR_SNAPIN_CLASS_GUID);
|
|
unsigned int CDataObject::m_cfDeviceID = RegisterClipboardFormat(DEVMGR_SNAPIN_DEVICE_ID);
|
|
|
|
//
|
|
// IUnknown interface implementation
|
|
//
|
|
|
|
ULONG
|
|
CDataObject::AddRef()
|
|
{
|
|
return ::InterlockedIncrement(&m_Ref);
|
|
}
|
|
|
|
ULONG
|
|
CDataObject::Release()
|
|
{
|
|
ASSERT( 0 != m_Ref );
|
|
ULONG cRef = ::InterlockedDecrement(&m_Ref);
|
|
if ( 0 == cRef )
|
|
{
|
|
delete this;
|
|
}
|
|
return cRef;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CDataObject::QueryInterface(
|
|
REFIID riid,
|
|
void** ppv
|
|
)
|
|
{
|
|
if (!ppv) {
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if (IsEqualIID(riid, IID_IUnknown)) {
|
|
|
|
*ppv = (IUnknown*)this;
|
|
|
|
} else if (IsEqualIID(riid, IID_IDataObject)) {
|
|
|
|
*ppv = this;
|
|
|
|
} else {
|
|
|
|
hr = E_NOINTERFACE;
|
|
}
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
AddRef();
|
|
} else {
|
|
*ppv = NULL;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
CDataObject::Initialize(
|
|
DATA_OBJECT_TYPES Type,
|
|
COOKIE_TYPE ct,
|
|
CCookie* pCookie,
|
|
String& strMachineName
|
|
)
|
|
{
|
|
try {
|
|
m_strMachineName = strMachineName;
|
|
m_pCookie = pCookie;
|
|
m_Type = Type;
|
|
m_ct = ct;
|
|
|
|
} catch (CMemoryException* e) {
|
|
e->Delete();
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
STDMETHODIMP
|
|
CDataObject::GetDataHere(
|
|
LPFORMATETC lpFormatetc,
|
|
LPSTGMEDIUM lpMedium
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
try {
|
|
const CLIPFORMAT cf = lpFormatetc->cfFormat;
|
|
hr = DV_E_FORMATETC;
|
|
SafeInterfacePtr<IStream> StreamPtr;
|
|
|
|
if (TYMED_HGLOBAL == lpMedium->tymed) {
|
|
ULONG ulWritten;
|
|
hr = CreateStreamOnHGlobal(lpMedium->hGlobal, FALSE, &StreamPtr);
|
|
|
|
if (S_OK == hr) {
|
|
const NODEINFO* pni = &NodeInfo[m_ct];
|
|
ASSERT(pni->ct == m_ct);
|
|
|
|
if (cf == m_cfNodeType) {
|
|
const GUID* pGuid = &pni->Guid;
|
|
hr = StreamPtr->Write(pGuid, sizeof(GUID), &ulWritten);
|
|
} else if (cf == m_cfNodeTypeString) {
|
|
const TCHAR *pszGuid = pni->GuidString;
|
|
hr = StreamPtr->Write(pszGuid,
|
|
(ULONG)(wcslen(pszGuid) + 1) * sizeof(TCHAR),
|
|
&ulWritten
|
|
);
|
|
} else if (cf == m_cfDisplayName) {
|
|
if (pni->idsFormat) {
|
|
String strDisplayName;
|
|
TCHAR Format[LINE_LEN];
|
|
TCHAR LocalMachine[LINE_LEN];
|
|
::LoadString(g_hInstance, pni->idsFormat, Format, ARRAYLEN(Format));
|
|
LPCTSTR MachineName = m_strMachineName;
|
|
|
|
if (m_strMachineName.IsEmpty()) {
|
|
::LoadString(g_hInstance, IDS_LOCAL_MACHINE, LocalMachine,
|
|
ARRAYLEN(LocalMachine));
|
|
MachineName = LocalMachine;
|
|
}
|
|
|
|
strDisplayName.Format(Format, MachineName);
|
|
hr = StreamPtr->Write(strDisplayName,
|
|
(strDisplayName.GetLength() + 1) * sizeof(TCHAR),
|
|
&ulWritten
|
|
);
|
|
}
|
|
} else if (cf == m_cfSnapinInternal) {
|
|
INTERNAL_DATA tID;
|
|
tID.ct = m_ct;
|
|
tID.dot = m_Type;
|
|
tID.cookie = (MMC_COOKIE)m_pCookie;
|
|
hr = StreamPtr->Write(&tID,
|
|
sizeof(INTERNAL_DATA),
|
|
&ulWritten
|
|
);
|
|
} else if (cf == m_cfCoClass) {
|
|
hr = StreamPtr->Write(&CLSID_DEVMGR,
|
|
sizeof(CLSID),
|
|
&ulWritten
|
|
);
|
|
} else if (cf == m_cfMachineName) {
|
|
if (!m_strMachineName.IsEmpty()) {
|
|
hr = StreamPtr->Write((LPCTSTR)m_strMachineName,
|
|
(m_strMachineName.GetLength()+1) * sizeof(TCHAR),
|
|
NULL);
|
|
} else {
|
|
TCHAR Nothing[1];
|
|
Nothing[0] = _T('\0');
|
|
hr = StreamPtr->Write(Nothing, sizeof(Nothing), NULL);
|
|
}
|
|
} else if (cf == m_cfClassGuid) {
|
|
if (COOKIE_TYPE_RESULTITEM_CLASS == m_pCookie->GetType()) {
|
|
CClass* pClass = (CClass*)m_pCookie->GetResultItem();
|
|
ASSERT(pClass);
|
|
LPGUID pClassGuid = *pClass;
|
|
hr = StreamPtr->Write(pClassGuid, sizeof(GUID), NULL);
|
|
}
|
|
} else if (cf == m_cfDeviceID) {
|
|
if (COOKIE_TYPE_RESULTITEM_DEVICE == m_pCookie->GetType()) {
|
|
CDevice* pDevice = (CDevice*)m_pCookie->GetResultItem();
|
|
ASSERT(pDevice);
|
|
LPCTSTR DeviceID = pDevice->GetDeviceID();
|
|
|
|
hr = StreamPtr->Write(DeviceID,
|
|
(ULONG)(wcslen(DeviceID) + 1) * sizeof(TCHAR),
|
|
NULL
|
|
);
|
|
}
|
|
} else {
|
|
hr = DV_E_FORMATETC;
|
|
}
|
|
}
|
|
}
|
|
} catch (CMemoryException* e) {
|
|
e->Delete();
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CDataObject::GetData(
|
|
LPFORMATETC lpFormatetc,
|
|
LPSTGMEDIUM lpMedium
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER(lpFormatetc);
|
|
UNREFERENCED_PARAMETER(lpMedium);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CDataObject::EnumFormatEtc(
|
|
DWORD dwDirection,
|
|
LPENUMFORMATETC* ppEnumFormatEtc
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER(dwDirection);
|
|
UNREFERENCED_PARAMETER(ppEnumFormatEtc);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT ExtractData(
|
|
IDataObject* pIDataObject,
|
|
unsigned int cfClipFormat,
|
|
BYTE* pBuffer,
|
|
DWORD cbBuffer
|
|
)
|
|
{
|
|
if ((NULL == pIDataObject) || (NULL == pBuffer)) {
|
|
return E_POINTER;
|
|
}
|
|
|
|
HRESULT hr = S_OK;
|
|
FORMATETC FormatEtc = {(CLIPFORMAT)cfClipFormat, NULL, DVASPECT_CONTENT, -1 , TYMED_HGLOBAL};
|
|
STGMEDIUM StgMedium = {TYMED_HGLOBAL, NULL};
|
|
|
|
StgMedium.hGlobal = ::GlobalAlloc(GMEM_SHARE, cbBuffer);
|
|
if (NULL == StgMedium.hGlobal) {
|
|
ASSERT(FALSE);
|
|
hr = E_OUTOFMEMORY;
|
|
} else {
|
|
hr = pIDataObject->GetDataHere(&FormatEtc, &StgMedium);
|
|
if (SUCCEEDED(hr)) {
|
|
BYTE* pData = reinterpret_cast<BYTE*>(::GlobalLock(StgMedium.hGlobal));
|
|
if (NULL == pData) {
|
|
ASSERT(FALSE);
|
|
hr = E_UNEXPECTED;
|
|
} else {
|
|
::memcpy(pBuffer, pData, cbBuffer);
|
|
::GlobalUnlock(StgMedium.hGlobal);
|
|
}
|
|
}
|
|
::GlobalFree(StgMedium.hGlobal);
|
|
}
|
|
|
|
return hr;
|
|
}
|