int wf_cliprdr_server_file_contents_request(CliprdrClientContext* context, CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest) { UINT32 uSize = 0; BYTE* pData = NULL; HRESULT hRet = S_OK; FORMATETC vFormatEtc; LPDATAOBJECT pDataObj = NULL; STGMEDIUM vStgMedium; LPSTREAM pStream = NULL; BOOL bIsStreamFile = TRUE; static LPSTREAM pStreamStc = NULL; static UINT32 uStreamIdStc = 0; wfClipboard* clipboard = (wfClipboard*) context->custom; if (fileContentsRequest->dwFlags == FILECONTENTS_SIZE) fileContentsRequest->cbRequested = sizeof(UINT64); pData = (BYTE*) calloc(1, fileContentsRequest->cbRequested); if (!pData) goto error; hRet = OleGetClipboard(&pDataObj); if (FAILED(hRet)) { WLog_ERR(TAG, "filecontents: get ole clipboard failed."); goto error; } ZeroMemory(&vFormatEtc, sizeof(FORMATETC)); ZeroMemory(&vStgMedium, sizeof(STGMEDIUM)); vFormatEtc.cfFormat = clipboard->ID_FILECONTENTS; vFormatEtc.tymed = TYMED_ISTREAM; vFormatEtc.dwAspect = 1; vFormatEtc.lindex = fileContentsRequest->listIndex; vFormatEtc.ptd = NULL; if ((uStreamIdStc != fileContentsRequest->streamId) || !pStreamStc) { LPENUMFORMATETC pEnumFormatEtc; ULONG CeltFetched; FORMATETC vFormatEtc2; if (pStreamStc) { IStream_Release(pStreamStc); pStreamStc = NULL; } bIsStreamFile = FALSE; hRet = IDataObject_EnumFormatEtc(pDataObj, DATADIR_GET, &pEnumFormatEtc); if (hRet == S_OK) { do { hRet = IEnumFORMATETC_Next(pEnumFormatEtc, 1, &vFormatEtc2, &CeltFetched); if (hRet == S_OK) { if (vFormatEtc2.cfFormat == clipboard->ID_FILECONTENTS) { hRet = IDataObject_GetData(pDataObj, &vFormatEtc, &vStgMedium); if (hRet == S_OK) { pStreamStc = vStgMedium.pstm; uStreamIdStc = fileContentsRequest->streamId; bIsStreamFile = TRUE; } break; } } } while (hRet == S_OK); } } if (bIsStreamFile == TRUE) { if (fileContentsRequest->dwFlags == FILECONTENTS_SIZE) { STATSTG vStatStg; ZeroMemory(&vStatStg, sizeof(STATSTG)); hRet = IStream_Stat(pStreamStc, &vStatStg, STATFLAG_NONAME); if (hRet == S_OK) { *((UINT32*) &pData[0]) = vStatStg.cbSize.LowPart; *((UINT32*) &pData[4]) = vStatStg.cbSize.HighPart; uSize = fileContentsRequest->cbRequested; } } else if (fileContentsRequest->dwFlags == FILECONTENTS_RANGE) { LARGE_INTEGER dlibMove; ULARGE_INTEGER dlibNewPosition; dlibMove.HighPart = fileContentsRequest->nPositionHigh; dlibMove.LowPart = fileContentsRequest->nPositionLow; hRet = IStream_Seek(pStreamStc, dlibMove, STREAM_SEEK_SET, &dlibNewPosition); if (SUCCEEDED(hRet)) { hRet = IStream_Read(pStreamStc, pData, fileContentsRequest->cbRequested, (PULONG) &uSize); } } } else { if (fileContentsRequest->dwFlags == FILECONTENTS_SIZE) { *((UINT32*) &pData[0]) = clipboard->fileDescriptor[fileContentsRequest->listIndex]->nFileSizeLow; *((UINT32*) &pData[4]) = clipboard->fileDescriptor[fileContentsRequest->listIndex]->nFileSizeHigh; uSize = fileContentsRequest->cbRequested; } else if (fileContentsRequest->dwFlags == FILECONTENTS_RANGE) { BOOL bRet; bRet = wf_cliprdr_get_file_contents(clipboard->file_names[fileContentsRequest->listIndex], pData, fileContentsRequest->nPositionLow, fileContentsRequest->nPositionHigh, fileContentsRequest->cbRequested, &uSize); if (bRet == FALSE) { WLog_ERR(TAG, "get file contents failed."); uSize = 0; goto error; } } } IDataObject_Release(pDataObj); if (uSize == 0) { free(pData); pData = NULL; } cliprdr_send_response_filecontents(clipboard, fileContentsRequest->streamId, uSize, pData); free(pData); return 1; error: if (pData) { free(pData); pData = NULL; } if (pDataObj) { IDataObject_Release(pDataObj); pDataObj = NULL; } WLog_ERR(TAG, "filecontents: send failed response."); cliprdr_send_response_filecontents(clipboard, fileContentsRequest->streamId, 0, NULL); return -1; }
static void wf_cliprdr_process_cb_filecontents_request_event(wfContext *wfc, RDP_CB_FILECONTENTS_REQUEST_EVENT *event) { cliprdrContext *cliprdr = (cliprdrContext *)wfc->cliprdr_context; UINT32 uSize = 0; BYTE *pData = NULL; HRESULT hRet = S_OK; FORMATETC vFormatEtc; LPDATAOBJECT pDataObj = NULL; STGMEDIUM vStgMedium; LPSTREAM pStream = NULL; BOOL bIsStreamFile = TRUE; static LPSTREAM pStreamStc = NULL; static UINT32 uStreamIdStc = 0; pData = (BYTE *)calloc(1, event->cbRequested); if (!pData) goto error; hRet = OleGetClipboard(&pDataObj); if (!SUCCEEDED(hRet)) { fprintf(stderr, "filecontents: get ole clipboard failed.\n"); goto error; } ZeroMemory(&vFormatEtc, sizeof(FORMATETC)); ZeroMemory(&vStgMedium, sizeof(STGMEDIUM)); vFormatEtc.cfFormat = cliprdr->ID_FILECONTENTS; vFormatEtc.tymed = TYMED_ISTREAM; vFormatEtc.dwAspect = 1; vFormatEtc.lindex = event->lindex; vFormatEtc.ptd = NULL; if (uStreamIdStc != event->streamId || pStreamStc == NULL) { LPENUMFORMATETC pEnumFormatEtc; ULONG CeltFetched; FORMATETC vFormatEtc2; if (pStreamStc != NULL) { IStream_Release(pStreamStc); pStreamStc = NULL; } bIsStreamFile = FALSE; hRet = IDataObject_EnumFormatEtc(pDataObj, DATADIR_GET, &pEnumFormatEtc); if (hRet == S_OK) { do { hRet = IEnumFORMATETC_Next(pEnumFormatEtc, 1, &vFormatEtc2, &CeltFetched); if (hRet == S_OK) { if (vFormatEtc2.cfFormat == cliprdr->ID_FILECONTENTS) { hRet = IDataObject_GetData(pDataObj, &vFormatEtc, &vStgMedium); if (hRet == S_OK) { pStreamStc = vStgMedium.pstm; uStreamIdStc = event->streamId; bIsStreamFile = TRUE; } break; } } } while (hRet == S_OK); } } if (bIsStreamFile == TRUE) { if (event->dwFlags == 0x00000001) /* FILECONTENTS_SIZE */ { STATSTG vStatStg; ZeroMemory(&vStatStg, sizeof(STATSTG)); hRet = IStream_Stat(pStreamStc, &vStatStg, STATFLAG_NONAME); if (hRet == S_OK) { Write_UINT32(pData, vStatStg.cbSize.LowPart); Write_UINT32(pData + 4, vStatStg.cbSize.HighPart); uSize = event->cbRequested; } } else if (event->dwFlags == 0x00000002) /* FILECONTENTS_RANGE */ { LARGE_INTEGER dlibMove; ULARGE_INTEGER dlibNewPosition; dlibMove.HighPart = event->nPositionHigh; dlibMove.LowPart = event->nPositionLow; hRet = IStream_Seek(pStreamStc, dlibMove, STREAM_SEEK_SET, &dlibNewPosition); if (SUCCEEDED(hRet)) { hRet = IStream_Read(pStreamStc, pData, event->cbRequested, (PULONG)&uSize); } } } else // is local file { if (event->dwFlags == 0x00000001) /* FILECONTENTS_SIZE */ { Write_UINT32(pData, cliprdr->fileDescriptor[event->lindex]->nFileSizeLow); Write_UINT32(pData + 4, cliprdr->fileDescriptor[event->lindex]->nFileSizeHigh); uSize = event->cbRequested; } else if (event->dwFlags == 0x00000002) /* FILECONTENTS_RANGE */ { BOOL bRet; bRet = wf_cliprdr_get_file_contents(cliprdr->file_names[event->lindex], pData, event->nPositionLow, event->nPositionHigh, event->cbRequested, &uSize); if (bRet == FALSE) { fprintf(stderr, "get file contents failed.\n"); uSize = 0; goto error; } } } IDataObject_Release(pDataObj); if (uSize == 0) { free(pData); pData = NULL; } cliprdr_send_response_filecontents(cliprdr, event->streamId, uSize, pData); return; error: if (pData) { free(pData); pData = NULL; } if (pDataObj) { IDataObject_Release(pDataObj); pDataObj = NULL; } fprintf(stderr, "filecontents: send failed response.\n"); cliprdr_send_response_filecontents(cliprdr, event->streamId, 0, NULL); return; }