/*++ 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 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(::GlobalLock(StgMedium.hGlobal)); if (NULL == pData) { ASSERT(FALSE); hr = E_UNEXPECTED; } else { ::memcpy(pBuffer, pData, cbBuffer); ::GlobalUnlock(StgMedium.hGlobal); } } ::GlobalFree(StgMedium.hGlobal); } return hr; }