Пример #1
0
/******************************************************************************
 *           CLIPFORMAT_UserSize [OLE32.@]
 *
 * Calculates the buffer size required to marshal a clip format.
 *
 * PARAMS
 *  pFlags       [I] Flags. See notes.
 *  StartingSize [I] Starting size of the buffer. This value is added on to
 *                   the buffer size required for the clip format.
 *  pCF          [I] Clip format to size.
 *
 * RETURNS
 *  The buffer size required to marshal a clip format plus the starting size.
 *
 * NOTES
 *  Even though the function is documented to take a pointer to an unsigned
 *  long in pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
 *  the first parameter is an unsigned long.
 *  This function is only intended to be called by the RPC runtime.
 */
unsigned long __RPC_USER CLIPFORMAT_UserSize(unsigned long *pFlags, unsigned long StartingSize, CLIPFORMAT *pCF)
{
    unsigned long size = StartingSize;

    TRACE("("); dump_user_flags(pFlags); TRACE(", %ld, %p\n", StartingSize, pCF);

    size += sizeof(userCLIPFORMAT);

    /* only need to marshal the name if it is not a pre-defined type and
     * we are going remote */
    if ((*pCF >= 0xc000) && (LOWORD(*pFlags) == MSHCTX_DIFFERENTMACHINE))
    {
        WCHAR format[255];
        INT ret;
        size += 3 * sizeof(INT);
        /* urg! this function is badly designed because it won't tell us how
         * much space is needed without doing a dummy run of storing the
         * name into a buffer */
        ret = GetClipboardFormatNameW(*pCF, format, sizeof(format)/sizeof(format[0])-1);
        if (!ret)
            RaiseException(DV_E_CLIPFORMAT, 0, 0, NULL);
        size += (ret + 1) * sizeof(WCHAR);
    }
    return size;
}
Пример #2
0
/* static */
void VBoxDnDDropTarget::DumpFormats(IDataObject *pDataObject)
{
    AssertPtrReturnVoid(pDataObject);

    /* Enumerate supported source formats. This shouldn't happen too often
     * on day to day use, but still keep it in here. */
    IEnumFORMATETC *pEnumFormats;
    HRESULT hr2 = pDataObject->EnumFormatEtc(DATADIR_GET, &pEnumFormats);
    if (SUCCEEDED(hr2))
    {
        LogRel(("DnD: The following formats were offered to us:\n"));

        FORMATETC curFormatEtc;
        while (pEnumFormats->Next(1, &curFormatEtc,
                                  NULL /* pceltFetched */) == S_OK)
        {
            WCHAR wszCfName[128]; /* 128 chars should be enough, rest will be truncated. */
            hr2 = GetClipboardFormatNameW(curFormatEtc.cfFormat, wszCfName,
                                          sizeof(wszCfName) / sizeof(WCHAR));
            LogRel(("\tcfFormat=%RI16 (%s), tyMed=%RI32, dwAspect=%RI32, strCustomName=%ls, hr=%Rhrc\n",
                    curFormatEtc.cfFormat,
                    VBoxDnDDataObject::ClipboardFormatToString(curFormatEtc.cfFormat),
                    curFormatEtc.tymed,
                    curFormatEtc.dwAspect,
                    wszCfName, hr2));
        }

        pEnumFormats->Release();
    }
}
Пример #3
0
Clipboard::Format::Format(UINT format, SIZE_T size)
    : format_(format), size_(size), data_(std::make_unique<char[]>(size)) {
  if (0xC000 <= format) {  // registered format
    name_.resize(256);
    auto length = GetClipboardFormatNameW(format, &name_[0],
                                          static_cast<int>(name_.size() + 1));
    name_.resize(length);
  }
}
Пример #4
0
/**************************************************************************
 *		GetClipboardFormatNameA (USER32.@)
 */
INT WINAPI GetClipboardFormatNameA(UINT wFormat, LPSTR retStr, INT maxlen)
{
    INT ret;
    LPWSTR p = HeapAlloc( GetProcessHeap(), 0, maxlen*sizeof(WCHAR) );
    if(p == NULL) return 0; /* FIXME: is this the correct failure value? */

    ret = GetClipboardFormatNameW( wFormat, p, maxlen );

    if (ret && maxlen > 0 && !WideCharToMultiByte( CP_ACP, 0, p, -1, retStr, maxlen, 0, 0))
        retStr[maxlen-1] = 0;
    HeapFree( GetProcessHeap(), 0, p );
    return ret;
}
Пример #5
0
/**
 * Get the clipboard name if there is one.
 * @param UINT format the format we want the name of.
 * @return wchar_t* the format name or NULL if there isn't one, (or not needed).
 */
wchar_t* ClipboardData::GetClipboardName(UINT format)
{
  // if it is a known type then we don't need/have the name
  if (format < CF_MAX)
  {
    return NULL;
  }

  //  get the text from the clipboard.
  static const unsigned l = 1024;  //  max len of the meta file
  wchar_t* dataName = new wchar_t[l + 1];
  memset(dataName, 0, l + 1);
  if (GetClipboardFormatNameW(format, dataName, l) == 0)
  {
    //  either it did not work
    // or the value we found is not good.
    delete[] dataName;
    return NULL;
  }

  // return the value we found.
  return dataName;
}
Пример #6
0
/******************************************************************************
 *           CLIPFORMAT_UserMarshal [OLE32.@]
 *
 * Marshals a clip format into a buffer.
 *
 * PARAMS
 *  pFlags  [I] Flags. See notes.
 *  pBuffer [I] Buffer to marshal the clip format into.
 *  pCF     [I] Clip format to marshal.
 *
 * RETURNS
 *  The end of the marshaled data in the buffer.
 *
 * NOTES
 *  Even though the function is documented to take a pointer to an unsigned
 *  long in pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
 *  the first parameter is an unsigned long.
 *  This function is only intended to be called by the RPC runtime.
 */
unsigned char * __RPC_USER CLIPFORMAT_UserMarshal(unsigned long *pFlags, unsigned char *pBuffer, CLIPFORMAT *pCF)
{
    wireCLIPFORMAT wirecf = (wireCLIPFORMAT)pBuffer;

    TRACE("("); dump_user_flags(pFlags); TRACE(", %p, &0x%04x\n", pBuffer, *pCF);

    wirecf->u.dwValue = *pCF;
    pBuffer += sizeof(*wirecf);

    /* only need to marshal the name if it is not a pre-defined type and
     * we are going remote */
    if ((*pCF >= 0xc000) && (LOWORD(*pFlags) == MSHCTX_DIFFERENTMACHINE))
    {
        WCHAR format[255];
        INT len;
        wirecf->fContext = WDT_REMOTE_CALL;
        len = GetClipboardFormatNameW(*pCF, format, sizeof(format)/sizeof(format[0])-1);
        if (!len)
            RaiseException(DV_E_CLIPFORMAT, 0, 0, NULL);
        len += 1;
        *(INT *)pBuffer = len;
        pBuffer += sizeof(INT);
        *(INT *)pBuffer = 0;
        pBuffer += sizeof(INT);
        *(INT *)pBuffer = len;
        pBuffer += sizeof(INT);
        TRACE("marshaling format name %s\n", debugstr_wn(format, len-1));
        lstrcpynW((LPWSTR)pBuffer, format, len);
        pBuffer += len * sizeof(WCHAR);
        *(WCHAR *)pBuffer = '\0';
        pBuffer += sizeof(WCHAR);
    }
    else
        wirecf->fContext = WDT_INPROC_CALL;

    return pBuffer;
}
Пример #7
0
static void cliprdr_send_format_list(cliprdrContext *cliprdr)
{
	RDP_CB_FORMAT_LIST_EVENT *cliprdr_event;
	BYTE *format_data;
	int format = 0;
	int data_size;
	int format_count;
	int len = 0;
	int namelen;

	if (!OpenClipboard(cliprdr->hwndClipboard))
	{
		DEBUG_CLIPRDR("OpenClipboard failed with 0x%x", GetLastError());
		return;
	}

	format_count = CountClipboardFormats();
	data_size = format_count * (4 + MAX_PATH * 2);

	format_data = (BYTE *)calloc(1, data_size);
	assert(format_data != NULL);

	while (format = EnumClipboardFormats(format))
	{
		Write_UINT32(format_data + len, format);
		len += 4;
		if ((cliprdr->capabilities & CAPS_USE_LONG_FORMAT_NAMES) != 0)
		{
			if (format >= CF_MAX)
			{
				namelen = GetClipboardFormatNameW(format, (LPWSTR)(format_data + len), MAX_PATH);
				len += namelen * sizeof(WCHAR);
			}
			len += 2;							/* end of Unicode string */
		}
		else
		{
			if (format >= CF_MAX)
			{
				static wchar_t wName[MAX_PATH] = {0};
				int wLen;

				ZeroMemory(wName, MAX_PATH*2);
				wLen = GetClipboardFormatNameW(format, wName, MAX_PATH);
				if (wLen < 16)
				{
					memcpy(format_data + len, wName, wLen * sizeof(WCHAR));
				}
				else
				{
					memcpy(format_data + len, wName, 32);	/* truncate the long name to 32 bytes */
				}
			}
			len += 32;
		}
	}

	CloseClipboard();

	cliprdr_event = (RDP_CB_FORMAT_LIST_EVENT *) freerdp_event_new(CliprdrChannel_Class,
			CliprdrChannel_FormatList, NULL, NULL);

	cliprdr_event->raw_format_data = (BYTE *)calloc(1, len);
	assert(cliprdr_event->raw_format_data != NULL);

	CopyMemory(cliprdr_event->raw_format_data, format_data, len);
	cliprdr_event->raw_format_data_size = len;

	free(format_data);

	freerdp_channels_send_event(cliprdr->channels, (wMessage *) cliprdr_event);
}
Пример #8
0
/* static */
const char* UIDnDDataObject::ClipboardFormatToString(CLIPFORMAT fmt)
{
    WCHAR wszFormat[128];
    if (GetClipboardFormatNameW(fmt, wszFormat, sizeof(wszFormat) / sizeof(WCHAR)))
        LogFlowFunc(("wFormat=%RI16, szName=%ls\n", fmt, wszFormat));

    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";
}
Пример #9
0
STDMETHODIMP VBoxDnDDropTarget::DragEnter(IDataObject *pDataObject, DWORD grfKeyState,
                                          POINTL pt, DWORD *pdwEffect)
{
    AssertPtrReturn(pDataObject, E_INVALIDARG);
    AssertPtrReturn(pdwEffect, E_INVALIDARG);

    LogFlowFunc(("pDataObject=0x%p, grfKeyState=0x%x, x=%ld, y=%ld, dwEffect=%RU32\n",
                 pDataObject, grfKeyState, pt.x, pt.y, *pdwEffect));

    reset();

    /** @todo At the moment we only support one DnD format at a time. */

    /* Try different formats. CF_HDROP is the most common one, so start
     * with this. */
    FORMATETC fmtEtc = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
    HRESULT hr = pDataObject->QueryGetData(&fmtEtc);
    if (hr == S_OK)
    {
        mFormats = "text/uri-list";
    }
    else
    {
        LogFlowFunc(("CF_HDROP not wanted, hr=%Rhrc\n", hr));

        /* So we couldn't retrieve the data in CF_HDROP format; try with
         * CF_UNICODETEXT + CF_TEXT formats now. Rest stays the same. */
        fmtEtc.cfFormat = CF_UNICODETEXT;
        hr = pDataObject->QueryGetData(&fmtEtc);
        if (hr == S_OK)
        {
            mFormats = "text/plain;charset=utf-8";
        }
        else
        {
            LogFlowFunc(("CF_UNICODETEXT not wanted, hr=%Rhrc\n", hr));

            fmtEtc.cfFormat = CF_TEXT;
            hr = pDataObject->QueryGetData(&fmtEtc);
            if (hr == S_OK)
            {
                mFormats = "text/plain;charset=utf-8";
            }
            else
            {
                LogFlowFunc(("CF_TEXT not wanted, hr=%Rhrc\n", hr));
                fmtEtc.cfFormat = 0; /* Mark it to not supported. */
            }
        }
    }

    /* Did we find a format that we support? */
    if (fmtEtc.cfFormat)
    {
        LogFlowFunc(("Found supported format %RI16 (%s)\n",
                     fmtEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(fmtEtc.cfFormat)));

        /* Make a copy of the FORMATETC structure so that we later can
         * use this for comparrison and stuff. */
        /** Note: The DVTARGETDEVICE member only is a shallow copy for now! */
        memcpy(&mFormatEtc, &fmtEtc, sizeof(FORMATETC));

        /* Which drop effect we're going to use? */
        /* Note: pt is not used since we don't need to differentiate within our
         *       proxy window. */
        *pdwEffect = VBoxDnDDropTarget::GetDropEffect(grfKeyState, *pdwEffect);
    }
    else
    {
        /* No or incompatible data -- so no drop effect required. */
        *pdwEffect = DROPEFFECT_NONE;

        switch (hr)
        {
            case ERROR_INVALID_FUNCTION:
            {
                LogRel(("DnD: Drag and drop format is not supported by VBoxTray\n"));

                /* Enumerate supported source formats. This shouldn't happen too often
                 * on day to day use, but still keep it in here. */
                IEnumFORMATETC *pEnumFormats;
                HRESULT hr2 = pDataObject->EnumFormatEtc(DATADIR_GET, &pEnumFormats);
                if (SUCCEEDED(hr2))
                {
                    LogRel(("DnD: The following formats were offered to us:\n"));

                    FORMATETC curFormatEtc;
                    while (pEnumFormats->Next(1, &curFormatEtc,
                                              NULL /* pceltFetched */) == S_OK)
                    {
                        WCHAR wszCfName[128]; /* 128 chars should be enough, rest will be truncated. */
                        hr2 = GetClipboardFormatNameW(curFormatEtc.cfFormat, wszCfName,
                                                      sizeof(wszCfName) / sizeof(WCHAR));
                        LogRel(("\tcfFormat=%RI16 (%s), tyMed=%RI32, dwAspect=%RI32, strCustomName=%ls, hr=%Rhrc\n",
                                curFormatEtc.cfFormat,
                                VBoxDnDDataObject::ClipboardFormatToString(curFormatEtc.cfFormat),
                                curFormatEtc.tymed,
                                curFormatEtc.dwAspect,
                                wszCfName, hr2));
                    }

                    pEnumFormats->Release();
                }

                break;
            }

            default:
                break;
        }
    }

    LogFlowFunc(("Returning cfFormat=%RI16, pdwEffect=%ld, hr=%Rhrc\n",
                 fmtEtc.cfFormat, *pdwEffect, hr));
    return hr;
}