VBoxDnDDataObject.cpp revision a29027bb2378172c7c88610ad5311548b66f96f6
/* $Id$ */
/** @file
* VBoxDnDDataObject.cpp - IDataObject implementation.
*/
/*
* Copyright (C) 2013-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#include <windows.h>
#include <new> /* For bad_alloc. */
#include <shlobj.h>
#include <iprt/semaphore.h>
#ifdef LOG_GROUP
#endif
#define LOG_GROUP LOG_GROUP_GUEST_DND
#include "VBoxTray.h"
#include "VBoxHelpers.h"
#include "VBoxDnD.h"
#ifdef DEBUG
/* Enable the following line to get much more debug output about
* (un)known clipboard formats. */
//#define VBOX_DND_DEBUG_FORMATS
#endif
/** @todo Implement IDataObjectAsyncCapability interface? */
: mStatus(Uninitialized),
mRefCount(1),
mcFormats(0),
mcbData(0)
{
/* Make sure that there's enough room for our fixed formats. */
try
{
if ( pFormatEtc
&& pStgMed)
{
{
LogFlowFunc(("Format %RU32: cfFormat=%RI16, tyMed=%RU32, dwAspect=%RU32\n",
mpFormatEtc[i] = pFormatEtc[i];
mpStgMedium[i] = pStgMed[i];
}
}
}
{
hr = E_OUTOFMEMORY;
}
{
/* Most commonly used format. */
#if 0
/* IStream. */
TYMED_ISTREAM, 0 /* lIndex */);
/* Required for e.g. Windows Media Player. */
#endif
}
}
VBoxDnDDataObject::~VBoxDnDDataObject(void)
{
if (mpFormatEtc)
delete[] mpFormatEtc;
if (mpStgMedium)
delete[] mpStgMedium;
if (mpvData)
}
/* static */
{
int rc;
try
{
rc = VINF_SUCCESS;
}
{
rc = VERR_NO_MEMORY;
}
return rc;
}
/*
* IUnknown methods.
*/
{
return InterlockedIncrement(&mRefCount);
}
{
if (lCount == 0)
{
delete this;
return 0;
}
return lCount;
}
{
if ( iid == IID_IDataObject
|| iid == IID_IUnknown)
{
AddRef();
*ppvObject = this;
return S_OK;
}
*ppvObject = 0;
return E_NOINTERFACE;
}
/**
* Retrieves the data stored in this object and store the result in
* pMedium.
*
* @return IPRT status code.
* @return HRESULT
* @param pFormatEtc
* @param pMedium
*/
{
return DV_E_FORMATETC;
return DV_E_FORMATETC;
{
LogFlowFunc(("Waiting for event ...\n"));
}
{
LogFlowFunc(("cfFormat=%RI16, sFormat=%s, tyMed=%RU32, dwAspect=%RU32\n",
LogFlowFunc(("Got strFormat=%s, pvData=%p, cbData=%RU32\n",
{
{
/* Extract path from URI. */
if ( pszPath
{
pszPath++; /** @todo Skip first '/' (part of URI). Correct? */
}
}
#ifdef DEBUG
#endif
#if 0
{
}
{
}
{
}
else
#endif
{
{
/** @todo Not working yet -- needs URI to plain ASCII conversion. */
}
}
{
int rc = VINF_SUCCESS;
{
}
if (pBuf)
{
{
if (RT_SUCCESS(rc))
{
}
else
break;
/* Terminate current file name. */
*pCurFile = L'\0';
}
if (RT_SUCCESS(rc))
{
| GMEM_DDESHARE, cbBuf);
{
if (pMem)
{
}
}
}
}
else
rc = VERR_NO_MEMORY;
if (RT_FAILURE(rc))
hr = DV_E_FORMATETC;
}
}
}
{
LogFlowFunc(("Copying medium ...\n"));
switch (pThisMedium->tymed)
{
case TYMED_HGLOBAL:
break;
default:
break;
}
}
return hr;
}
/**
* Only required for IStream / IStorage interfaces.
*
* @return IPRT status code.
* @return HRESULT
* @param pFormatEtc
* @param pMedium
*/
{
LogFlowFunc(("\n"));
return DATA_E_FORMATETC;
}
/**
* Query if this objects supports a specific format.
*
* @return IPRT status code.
* @return HRESULT
* @param pFormatEtc
*/
{
LogFlowFunc(("\n"));
}
STDMETHODIMP VBoxDnDDataObject::GetCanonicalFormatEtc(FORMATETC *pFormatEct, FORMATETC *pFormatEtcOut)
{
LogFlowFunc(("\n"));
/* Set this to NULL in any case. */
return E_NOTIMPL;
}
{
return E_NOTIMPL;
}
{
LogFlowFunc(("dwDirection=%RI32, mcFormats=%RI32, mpFormatEtc=%p\n",
if (dwDirection == DATADIR_GET)
{
}
else
return hr;
}
STDMETHODIMP VBoxDnDDataObject::DAdvise(FORMATETC *pFormatEtc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
{
return OLE_E_ADVISENOTSUPPORTED;
}
{
return OLE_E_ADVISENOTSUPPORTED;
}
{
return OLE_E_ADVISENOTSUPPORTED;
}
/*
* Own stuff.
*/
int VBoxDnDDataObject::Abort(void)
{
LogFlowFunc(("Aborting ...\n"));
return RTSemEventSignal(mSemEvent);
}
/* static */
{
#ifdef VBOX_DND_DEBUG_FORMATS
char szFormat[128];
#endif
switch (fmt)
{
case 1:
return "CF_TEXT";
case 2:
return "CF_BITMAP";
case 3:
return "CF_METAFILEPICT";
case 4:
return "CF_SYLK";
case 5:
return "CF_DIF";
case 6:
return "CF_TIFF";
case 7:
return "CF_OEMTEXT";
case 8:
return "CF_DIB";
case 9:
return "CF_PALETTE";
case 10:
return "CF_PENDATA";
case 11:
return "CF_RIFF";
case 12:
return "CF_WAVE";
case 13:
return "CF_UNICODETEXT";
case 14:
return "CF_ENHMETAFILE";
case 15:
return "CF_HDROP";
case 16:
return "CF_LOCALE";
case 17:
return "CF_DIBV5";
case 18:
return "CF_MAX";
case 49158:
return "FileName";
case 49159:
return "FileNameW";
case 49161:
return "DATAOBJECT";
case 49171:
return "Ole Private Data";
case 49314:
return "Shell Object Offsets";
case 49316:
return "File Contents";
case 49317:
return "File Group Descriptor";
case 49323:
return "Preferred Drop Effect";
case 49380:
return "Shell Object Offsets";
case 49382:
return "FileContents";
case 49383:
return "FileGroupDescriptor";
case 49389:
return "Preferred DropEffect";
case 49268:
return "Shell IDList Array";
case 49619:
return "RenPrivateFileAttachments";
default:
break;
}
return "unknown";
}
{
AssertReturn(pFormatEtc, false);
/* puIndex is optional. */
{
{
LogFlowFunc(("Format found: tyMed=%RI32, cfFormat=%RI16, sFormats=%s, dwAspect=%RI32, ulIndex=%RU32\n",
pFormatEtc->tymed, pFormatEtc->cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mpFormatEtc[i].cfFormat),
pFormatEtc->dwAspect, i));
if (puIndex)
*puIndex = i;
return true;
}
}
#ifdef VBOX_DND_DEBUG_FORMATS
LogFlowFunc(("Format NOT found: tyMed=%RI32, cfFormat=%RI16, sFormats=%s, dwAspect=%RI32\n",
pFormatEtc->tymed, pFormatEtc->cfFormat, VBoxDnDDataObject::ClipboardFormatToString(pFormatEtc->cfFormat),
pFormatEtc->dwAspect));
#endif
return false;
}
/* static */
{
if (pvSource)
{
if (pvDest)
return pvDest;
}
return NULL;
}
{
LogFlowFunc(("Registered format=%ld, sFormat=%s\n",
}
{
}
{
LogFlowFunc(("Signalling ...\n"));
int rc;
if (cbData)
{
if (mpvData)
{
rc = VINF_SUCCESS;
}
else
rc = VERR_NO_MEMORY;
}
else
rc = VINF_SUCCESS;
if (RT_FAILURE(rc))
/* Signal in any case. */
if (RT_SUCCESS(rc))
return rc;
}