Fixed clipboard file transfer.
authorArmin Novak <armin.novak@thincast.com>
Thu, 22 Oct 2015 07:31:47 +0000 (09:31 +0200)
committerArmin Novak <armin.novak@thincast.com>
Tue, 27 Oct 2015 09:44:32 +0000 (10:44 +0100)
client/Windows/wf_client.h
client/Windows/wf_cliprdr.c
client/Windows/wf_cliprdr.h

index 5ec8f82..8f65c44 100644 (file)
@@ -137,7 +137,7 @@ struct wf_context
        int yCurrentScroll;
        int yMaxScroll;
 
-       wfClipboard* clipboard;
+       void* clipboard;
        CliprdrClientContext* cliprdr;
 
        FloatBar* floatbar;
index dc1868f..85aa281 100644 (file)
 #include "config.h"
 #endif
 
+#define CINTERFACE
+#define COBJMACROS
+
+#include <Ole2.h>
+#include <ShlObj.h>
+#include <Windows.h>
+#include <WinUser.h>
+
 #include <assert.h>
 
 #include <winpr/crt.h>
 
 #define TAG CLIENT_TAG("windows")
 
+#ifdef WITH_DEBUG_CLIPRDR
+#define DEBUG_CLIPRDR(fmt, ...) WLog_DBG(TAG, fmt, ## __VA_ARGS__)
+#else
+#define DEBUG_CLIPRDR(fmt, ...) do { } while (0)
+#endif
+
+struct format_mapping
+{
+       UINT32 remote_format_id;
+       UINT32 local_format_id;
+       WCHAR* name;
+};
+typedef struct format_mapping formatMapping;
+
+struct _CliprdrEnumFORMATETC
+{
+       IEnumFORMATETC iEnumFORMATETC;
+
+       LONG m_lRefCount;
+       LONG m_nIndex;
+       LONG m_nNumFormats;
+       FORMATETC* m_pFormatEtc;
+};
+typedef struct _CliprdrEnumFORMATETC CliprdrEnumFORMATETC;
+
+struct _CliprdrStream
+{
+       IStream iStream;
+
+       LONG m_lRefCount;
+       LONG m_lIndex;
+       ULARGE_INTEGER m_lSize;
+       ULARGE_INTEGER m_lOffset;
+       void* m_pData;
+};
+typedef struct _CliprdrStream CliprdrStream;
+
+struct _CliprdrDataObject
+{
+       IDataObject iDataObject;
+
+       LONG m_lRefCount;
+       FORMATETC* m_pFormatEtc;
+       STGMEDIUM* m_pStgMedium;
+       LONG m_nNumFormats;
+       LONG m_nStreams;
+       IStream** m_pStream;
+       void* m_pData;
+};
+typedef struct _CliprdrDataObject CliprdrDataObject;
+
+struct wf_clipboard
+{
+       wfContext* wfc;
+       rdpChannels* channels;
+       CliprdrClientContext* context;
+
+       BOOL sync;
+       UINT32 capabilities;
+
+       size_t map_size;
+       size_t map_capacity;
+       formatMapping* format_mappings;
+
+       UINT32 requestedFormatId;
+
+       HWND hwnd;
+       HANDLE hmem;
+       HANDLE thread;
+       HANDLE response_data_event;
+
+       LPDATAOBJECT data_obj;
+       ULONG req_fsize;
+       char* req_fdata;
+       HANDLE req_fevent;
+
+       size_t nFiles;
+       size_t file_array_size;
+       WCHAR** file_names;
+       FILEDESCRIPTORW** fileDescriptor;
+};
+typedef struct wf_clipboard wfClipboard;
+
 extern BOOL WINAPI AddClipboardFormatListener(_In_ HWND hwnd);
 extern BOOL WINAPI RemoveClipboardFormatListener(_In_  HWND hwnd);
 
 #define WM_CLIPRDR_MESSAGE  (WM_USER + 156)
 #define OLE_SETCLIPBOARD    1
 
-BOOL wf_create_file_obj(wfClipboard* cliprdrrdr, IDataObject** ppDataObject);
-void wf_destroy_file_obj(IDataObject* instance);
+static BOOL wf_create_file_obj(wfClipboard* cliprdrrdr, IDataObject** ppDataObject);
+static void wf_destroy_file_obj(IDataObject* instance);
+static UINT32 get_remote_format_id(wfClipboard* clipboard, UINT32 local_format);
+static UINT cliprdr_send_data_request(wfClipboard* clipboard, UINT32 format);
+static UINT cliprdr_send_lock(wfClipboard* clipboard);
+static UINT cliprdr_send_unlock(wfClipboard* clipboard);
+static UINT cliprdr_send_request_filecontents(wfClipboard* clipboard, void* streamid,
+                                                                                         int index, int flag, DWORD positionhigh,
+                                                                                         DWORD positionlow, ULONG request);
+
+static void CliprdrDataObject_Delete(CliprdrDataObject* instance);
+
+static CliprdrEnumFORMATETC* CliprdrEnumFORMATETC_New(int nFormats, FORMATETC* pFormatEtc);
+static void CliprdrEnumFORMATETC_Delete(CliprdrEnumFORMATETC* instance);
+
+static void CliprdrStream_Delete(CliprdrStream* instance);
 
 /**
  * IStream
  */
 
-HRESULT STDMETHODCALLTYPE CliprdrStream_QueryInterface(IStream* This, REFIID riid, void** ppvObject)
+static HRESULT STDMETHODCALLTYPE CliprdrStream_QueryInterface(IStream* This,
+                                                                                                                         REFIID riid, void** ppvObject)
 {
-       CliprdrStream* instance = (CliprdrStream*) This;
-
        if (IsEqualIID(riid, &IID_IStream) || IsEqualIID(riid, &IID_IUnknown))
        {
                IStream_AddRef(This);
@@ -69,18 +173,24 @@ HRESULT STDMETHODCALLTYPE CliprdrStream_QueryInterface(IStream* This, REFIID rii
        }
 }
 
-ULONG STDMETHODCALLTYPE CliprdrStream_AddRef(IStream* This)
+static ULONG STDMETHODCALLTYPE CliprdrStream_AddRef(IStream* This)
 {
        CliprdrStream* instance = (CliprdrStream*) This;
 
+       if (!instance)
+               return 0;
+
        return InterlockedIncrement(&instance->m_lRefCount);
 }
 
-ULONG STDMETHODCALLTYPE CliprdrStream_Release(IStream* This)
+static ULONG STDMETHODCALLTYPE CliprdrStream_Release(IStream* This)
 {
        LONG count;
        CliprdrStream* instance = (CliprdrStream*) This;
 
+       if (!instance)
+               return 0;
+
        count = InterlockedDecrement(&instance->m_lRefCount);
 
        if (count == 0)
@@ -94,23 +204,25 @@ ULONG STDMETHODCALLTYPE CliprdrStream_Release(IStream* This)
        }
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrStream_Read(IStream* This, void *pv, ULONG cb, ULONG *pcbRead)
+static HRESULT STDMETHODCALLTYPE CliprdrStream_Read(IStream* This, void *pv,
+                                                                                                       ULONG cb, ULONG *pcbRead)
 {
        int ret;
        CliprdrStream* instance = (CliprdrStream*) This;
-       wfClipboard* clipboard = (wfClipboard*) instance->m_pData;
+       wfClipboard* clipboard;
 
-       if (!pv || !pcbRead)
+       if (!pv || !pcbRead || !instance)
                return E_INVALIDARG;
 
+       clipboard =  (wfClipboard*) instance->m_pData;
        *pcbRead = 0;
 
        if (instance->m_lOffset.QuadPart >= instance->m_lSize.QuadPart)
-               return E_FAIL;
+               return S_FALSE;
 
        ret = cliprdr_send_request_filecontents(clipboard, (void*) This,
-                       instance->m_lIndex, FILECONTENTS_RANGE,
-                       instance->m_lOffset.HighPart, instance->m_lOffset.LowPart, cb);
+                                                                                       instance->m_lIndex, FILECONTENTS_RANGE,
+                                                                                       instance->m_lOffset.HighPart, instance->m_lOffset.LowPart, cb);
 
        if (ret < 0)
                return E_FAIL;
@@ -125,38 +237,46 @@ HRESULT STDMETHODCALLTYPE CliprdrStream_Read(IStream* This, void *pv, ULONG cb,
        instance->m_lOffset.QuadPart += clipboard->req_fsize;
 
        if (clipboard->req_fsize < cb)
-               return E_FAIL;
+               return S_FALSE;
 
        return S_OK;
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrStream_Write(IStream* This, const void* pv, ULONG cb, ULONG *pcbWritten)
+static HRESULT STDMETHODCALLTYPE CliprdrStream_Write(IStream* This, const void* pv,
+                                                                                                        ULONG cb, ULONG *pcbWritten)
 {
-       CliprdrStream* instance = (CliprdrStream*) This;
+       (void)This;
+       (void)pv;
+       (void)cb;
+       (void)pcbWritten;
 
        return STG_E_ACCESSDENIED;
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrStream_Seek(IStream* This, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition)
+static HRESULT STDMETHODCALLTYPE CliprdrStream_Seek(IStream* This, LARGE_INTEGER dlibMove,
+                                                                                                       DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition)
 {
        ULONGLONG newoffset;
        CliprdrStream* instance = (CliprdrStream*) This;
 
+       if (!instance)
+               return E_INVALIDARG;
+
        newoffset = instance->m_lOffset.QuadPart;
 
        switch (dwOrigin)
        {
-               case STREAM_SEEK_SET:
-                       newoffset = dlibMove.QuadPart;
-                       break;
-               case STREAM_SEEK_CUR:
-                       newoffset += dlibMove.QuadPart;
-                       break;
-               case STREAM_SEEK_END:
-                       newoffset = instance->m_lSize.QuadPart + dlibMove.QuadPart;
-                       break;
-               default:
-                       return E_INVALIDARG;
+       case STREAM_SEEK_SET:
+               newoffset = dlibMove.QuadPart;
+               break;
+       case STREAM_SEEK_CUR:
+               newoffset += dlibMove.QuadPart;
+               break;
+       case STREAM_SEEK_END:
+               newoffset = instance->m_lSize.QuadPart + dlibMove.QuadPart;
+               break;
+       default:
+               return E_INVALIDARG;
        }
 
        if (newoffset < 0 || newoffset >= instance->m_lSize.QuadPart)
@@ -170,52 +290,72 @@ HRESULT STDMETHODCALLTYPE CliprdrStream_Seek(IStream* This, LARGE_INTEGER dlibMo
        return S_OK;
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrStream_SetSize(IStream* This, ULARGE_INTEGER libNewSize)
+static HRESULT STDMETHODCALLTYPE CliprdrStream_SetSize(IStream* This,
+                                                                                                          ULARGE_INTEGER libNewSize)
 {
-       CliprdrStream* instance = (CliprdrStream*) This;
+       (void)This;
+       (void)libNewSize;
 
-       return STG_E_INSUFFICIENTMEMORY;
+       return E_NOTIMPL;
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrStream_CopyTo(IStream* This, IStream* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, ULARGE_INTEGER *pcbWritten)
+static HRESULT STDMETHODCALLTYPE CliprdrStream_CopyTo(IStream* This, IStream* pstm,
+                                                                                                         ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead,
+                                                                                                         ULARGE_INTEGER *pcbWritten)
 {
-       CliprdrStream* instance = (CliprdrStream*) This;
+       (void)This;
+       (void)pstm;
+       (void)cb;
+       (void)pcbRead;
+       (void)pcbWritten;
 
-       return S_OK;
+       return E_NOTIMPL;
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrStream_Commit(IStream* This, DWORD grfCommitFlags)
+static HRESULT STDMETHODCALLTYPE CliprdrStream_Commit(IStream* This, DWORD grfCommitFlags)
 {
-       CliprdrStream* instance = (CliprdrStream*) This;
+       (void)This;
+       (void)grfCommitFlags;
 
-       return STG_E_MEDIUMFULL;
+       return E_NOTIMPL;
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrStream_Revert(IStream* This)
+static HRESULT STDMETHODCALLTYPE CliprdrStream_Revert(IStream* This)
 {
-       CliprdrStream* instance = (CliprdrStream*) This;
+       (void)This;
 
-       return STG_E_INSUFFICIENTMEMORY;
+       return E_NOTIMPL;
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrStream_LockRegion(IStream* This, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
+static HRESULT STDMETHODCALLTYPE CliprdrStream_LockRegion(IStream* This, ULARGE_INTEGER libOffset,
+                                                                                                                 ULARGE_INTEGER cb, DWORD dwLockType)
 {
-       CliprdrStream* instance = (CliprdrStream*) This;
+       (void)This;
+       (void)libOffset;
+       (void)cb;
+       (void)dwLockType;
 
-       return STG_E_INSUFFICIENTMEMORY;
+       return E_NOTIMPL;
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrStream_UnlockRegion(IStream* This, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
+static HRESULT STDMETHODCALLTYPE CliprdrStream_UnlockRegion(IStream* This, ULARGE_INTEGER libOffset,
+                                                                                                                       ULARGE_INTEGER cb, DWORD dwLockType)
 {
-       CliprdrStream* instance = (CliprdrStream*) This;
+       (void)This;
+       (void)libOffset;
+       (void)cb;
+       (void)dwLockType;
 
-       return STG_E_INSUFFICIENTMEMORY;
+       return E_NOTIMPL;
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrStream_Stat(IStream* This, STATSTG* pstatstg, DWORD grfStatFlag)
+static HRESULT STDMETHODCALLTYPE CliprdrStream_Stat(IStream* This, STATSTG* pstatstg, DWORD grfStatFlag)
 {
        CliprdrStream* instance = (CliprdrStream*) This;
 
+       if (!instance)
+               return E_INVALIDARG;
+
        if (pstatstg == NULL)
                return STG_E_INVALIDPOINTER;
 
@@ -223,37 +363,39 @@ HRESULT STDMETHODCALLTYPE CliprdrStream_Stat(IStream* This, STATSTG* pstatstg, D
 
        switch (grfStatFlag)
        {
-               case STATFLAG_DEFAULT:
-                       return STG_E_INSUFFICIENTMEMORY;
+       case STATFLAG_DEFAULT:
+               return STG_E_INSUFFICIENTMEMORY;
 
-               case STATFLAG_NONAME:
-                       pstatstg->cbSize.QuadPart = instance->m_lSize.QuadPart;
-                       pstatstg->grfLocksSupported = LOCK_EXCLUSIVE;
-                       pstatstg->grfMode = GENERIC_READ;
-                       pstatstg->grfStateBits = 0;
-                       pstatstg->type = STGTY_STREAM;
-                       break;
+       case STATFLAG_NONAME:
+               pstatstg->cbSize.QuadPart = instance->m_lSize.QuadPart;
+               pstatstg->grfLocksSupported = LOCK_EXCLUSIVE;
+               pstatstg->grfMode = GENERIC_READ;
+               pstatstg->grfStateBits = 0;
+               pstatstg->type = STGTY_STREAM;
+               break;
 
-               case STATFLAG_NOOPEN:
-                       return STG_E_INVALIDFLAG;
+       case STATFLAG_NOOPEN:
+               return STG_E_INVALIDFLAG;
 
-               default:
-                       return STG_E_INVALIDFLAG;
+       default:
+               return STG_E_INVALIDFLAG;
        }
 
        return S_OK;
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrStream_Clone(IStream* This, IStream** ppstm)
+static HRESULT STDMETHODCALLTYPE CliprdrStream_Clone(IStream* This, IStream** ppstm)
 {
-       CliprdrStream* instance = (CliprdrStream*) This;
+       (void)This;
+       (void)ppstm;
 
-       return STG_E_INSUFFICIENTMEMORY;
+       return E_NOTIMPL;
 }
 
-CliprdrStream* CliprdrStream_New(LONG index, void* pData)
+static CliprdrStream* CliprdrStream_New(LONG index, void* pData)
 {
        IStream* iStream;
+       BOOL success = FALSE;
        CliprdrStream* instance;
        wfClipboard* clipboard = (wfClipboard*) pData;
 
@@ -288,16 +430,22 @@ CliprdrStream* CliprdrStream_New(LONG index, void* pData)
                        instance->m_lOffset.QuadPart = 0;
 
                        /* get content size of this stream */
-                       cliprdr_send_request_filecontents(clipboard, (void*) instance,
-                               instance->m_lIndex, FILECONTENTS_SIZE, 0, 0, 8);
+                       if (cliprdr_send_request_filecontents(clipboard, (void*) instance,
+                                                                                                 instance->m_lIndex,
+                                                                                                 FILECONTENTS_SIZE, 0, 0, 8) == CHANNEL_RC_OK)
+                       {
+                               success = TRUE;
+                       }
+
                        instance->m_lSize.QuadPart = *((LONGLONG*) clipboard->req_fdata);
                        free(clipboard->req_fdata);
                }
-               else
-               {
-                       free(instance);
-                       instance = NULL;
-               }
+       }
+
+       if (!success)
+       {
+               CliprdrStream_Delete(instance);
+               instance = NULL;
        }
 
        return instance;
@@ -320,11 +468,14 @@ static int cliprdr_lookup_format(CliprdrDataObject* instance, FORMATETC* pFormat
 {
        int i;
 
+       if (!instance || !pFormatEtc)
+               return -1;
+
        for (i = 0; i < instance->m_nNumFormats; i++)
        {
                if ((pFormatEtc->tymed & instance->m_pFormatEtc[i].tymed) &&
-                       pFormatEtc->cfFormat == instance->m_pFormatEtc[i].cfFormat &&
-                       pFormatEtc->dwAspect == instance->m_pFormatEtc[i].dwAspect)
+                               pFormatEtc->cfFormat == instance->m_pFormatEtc[i].cfFormat &&
+                               pFormatEtc->dwAspect & instance->m_pFormatEtc[i].dwAspect)
                {
                        return i;
                }
@@ -333,9 +484,13 @@ static int cliprdr_lookup_format(CliprdrDataObject* instance, FORMATETC* pFormat
        return -1;
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrDataObject_QueryInterface(IDataObject* This, REFIID riid, void** ppvObject)
+static HRESULT STDMETHODCALLTYPE CliprdrDataObject_QueryInterface(
+               IDataObject* This, REFIID riid, void** ppvObject)
 {
-       CliprdrDataObject* instance = (CliprdrDataObject*) This;
+       (void)This;
+
+       if (!ppvObject)
+               return E_INVALIDARG;
 
        if (IsEqualIID(riid, &IID_IDataObject) || IsEqualIID(riid, &IID_IUnknown))
        {
@@ -350,18 +505,24 @@ HRESULT STDMETHODCALLTYPE CliprdrDataObject_QueryInterface(IDataObject* This, RE
        }
 }
 
-ULONG STDMETHODCALLTYPE CliprdrDataObject_AddRef(IDataObject* This)
+static ULONG STDMETHODCALLTYPE CliprdrDataObject_AddRef(IDataObject* This)
 {
        CliprdrDataObject* instance = (CliprdrDataObject*) This;
 
+       if (!instance)
+               return E_INVALIDARG;
+
        return InterlockedIncrement(&instance->m_lRefCount);
 }
 
-ULONG STDMETHODCALLTYPE CliprdrDataObject_Release(IDataObject* This)
+static ULONG STDMETHODCALLTYPE CliprdrDataObject_Release(IDataObject* This)
 {
        LONG count;
        CliprdrDataObject* instance = (CliprdrDataObject*) This;
 
+       if (!instance)
+               return E_INVALIDARG;
+
        count = InterlockedDecrement(&instance->m_lRefCount);
 
        if (count == 0)
@@ -370,33 +531,34 @@ ULONG STDMETHODCALLTYPE CliprdrDataObject_Release(IDataObject* This)
                return 0;
        }
        else
-       {
                return count;
-       }
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrDataObject_GetData(IDataObject* This, FORMATETC* pFormatEtc, STGMEDIUM* pMedium)
+static HRESULT STDMETHODCALLTYPE CliprdrDataObject_GetData(
+               IDataObject* This, FORMATETC* pFormatEtc, STGMEDIUM* pMedium)
 {
        int i, idx;
        CliprdrDataObject* instance = (CliprdrDataObject*) This;
-       wfClipboard* clipboard = (wfClipboard*) instance->m_pData;
+       wfClipboard* clipboard;
 
-       if (!pFormatEtc || !pMedium)
-       {
+       if (!pFormatEtc || !pMedium || !instance)
+               return E_INVALIDARG;
+
+       clipboard = clipboard = (wfClipboard*) instance->m_pData;
+
+       if (!clipboard)
                return E_INVALIDARG;
-       }
 
        if ((idx = cliprdr_lookup_format(instance, pFormatEtc)) == -1)
-       {
                return DV_E_FORMATETC;
-       }
 
        pMedium->tymed = instance->m_pFormatEtc[idx].tymed;
        pMedium->pUnkForRelease = 0;
 
-       if (instance->m_pFormatEtc[idx].cfFormat == clipboard->ID_FILEDESCRIPTORW)
+       if (instance->m_pFormatEtc[idx].cfFormat == RegisterClipboardFormat(CFSTR_FILEDESCRIPTORW))
        {
-               if (cliprdr_send_data_request(clipboard, instance->m_pFormatEtc[idx].cfFormat) != 0)
+               DWORD remote = get_remote_format_id(clipboard, instance->m_pFormatEtc[idx].cfFormat);
+               if (cliprdr_send_data_request(clipboard, remote) != 0)
                        return E_UNEXPECTED;
 
                pMedium->hGlobal = clipboard->hmem;   /* points to a FILEGROUPDESCRIPTOR structure */
@@ -404,7 +566,8 @@ HRESULT STDMETHODCALLTYPE CliprdrDataObject_GetData(IDataObject* This, FORMATETC
                /* GlobalLock returns a pointer to the first byte of the memory block,
                * in which is a FILEGROUPDESCRIPTOR structure, whose first UINT member
                * is the number of FILEDESCRIPTOR's */
-               instance->m_nStreams = *((PUINT) GlobalLock(clipboard->hmem));
+               FILEGROUPDESCRIPTOR *dsc = (FILEGROUPDESCRIPTOR*) GlobalLock(clipboard->hmem);
+               instance->m_nStreams = dsc->cItems;
                GlobalUnlock(clipboard->hmem);
 
                if (instance->m_nStreams > 0)
@@ -416,9 +579,7 @@ HRESULT STDMETHODCALLTYPE CliprdrDataObject_GetData(IDataObject* This, FORMATETC
                                if (instance->m_pStream)
                                {
                                        for (i = 0; i < instance->m_nStreams; i++)
-                                       {
                                                instance->m_pStream[i] = (IStream*) CliprdrStream_New(i, clipboard);
-                                       }
                                }
                        }
                }
@@ -436,7 +597,7 @@ HRESULT STDMETHODCALLTYPE CliprdrDataObject_GetData(IDataObject* This, FORMATETC
                        return E_OUTOFMEMORY;
                }
        }
-       else if (instance->m_pFormatEtc[idx].cfFormat == clipboard->ID_FILECONTENTS)
+       else if (instance->m_pFormatEtc[idx].cfFormat == RegisterClipboardFormat(CFSTR_FILECONTENTS))
        {
                if (pFormatEtc->lindex < instance->m_nStreams)
                {
@@ -444,45 +605,43 @@ HRESULT STDMETHODCALLTYPE CliprdrDataObject_GetData(IDataObject* This, FORMATETC
                        IDataObject_AddRef(instance->m_pStream[pFormatEtc->lindex]);
                }
                else
-               {
                        return E_INVALIDARG;
-               }
-       }
-       else if (instance->m_pFormatEtc[idx].cfFormat == clipboard->ID_PREFERREDDROPEFFECT)
-       {
-               if (cliprdr_send_data_request(clipboard, instance->m_pFormatEtc[idx].cfFormat) != 0)
-                       return E_UNEXPECTED;
-
-               pMedium->hGlobal = clipboard->hmem;
        }
        else
-       {
                return E_UNEXPECTED;
-       }
 
        return S_OK;
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrDataObject_GetDataHere(IDataObject* This, FORMATETC* pformatetc, STGMEDIUM* pmedium)
+static HRESULT STDMETHODCALLTYPE CliprdrDataObject_GetDataHere(
+               IDataObject* This, FORMATETC* pformatetc, STGMEDIUM* pmedium)
 {
-       CliprdrDataObject* instance = (CliprdrDataObject*) This;
+       (void)This;
+       (void)pformatetc;
+       (void)pmedium;
 
-       return DATA_E_FORMATETC;
+       return E_NOTIMPL;
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrDataObject_QueryGetData(IDataObject* This, FORMATETC* pformatetc)
+static HRESULT STDMETHODCALLTYPE CliprdrDataObject_QueryGetData(
+               IDataObject* This, FORMATETC* pformatetc)
 {
        CliprdrDataObject* instance = (CliprdrDataObject*) This;
 
        if (!pformatetc)
                return E_INVALIDARG;
 
-       return (cliprdr_lookup_format(instance, pformatetc) == -1) ? DV_E_FORMATETC : S_OK;
+       if (cliprdr_lookup_format(instance, pformatetc) == -1)
+               return DV_E_FORMATETC;
+
+       return S_OK;
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrDataObject_GetCanonicalFormatEtc(IDataObject* This, FORMATETC* pformatectIn, FORMATETC* pformatetcOut)
+static HRESULT STDMETHODCALLTYPE CliprdrDataObject_GetCanonicalFormatEtc(
+               IDataObject* This, FORMATETC* pformatectIn, FORMATETC* pformatetcOut)
 {
-       CliprdrDataObject* instance = (CliprdrDataObject*) This;
+       (void)This;
+       (void)pformatectIn;
 
        if (!pformatetcOut)
                return E_INVALIDARG;
@@ -492,18 +651,23 @@ HRESULT STDMETHODCALLTYPE CliprdrDataObject_GetCanonicalFormatEtc(IDataObject* T
        return E_NOTIMPL;
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrDataObject_SetData(IDataObject* This, FORMATETC* pformatetc, STGMEDIUM* pmedium, BOOL fRelease)
+static HRESULT STDMETHODCALLTYPE CliprdrDataObject_SetData(
+               IDataObject* This, FORMATETC* pformatetc, STGMEDIUM* pmedium, BOOL fRelease)
 {
-       CliprdrDataObject* instance = (CliprdrDataObject*) This;
+       (void)This;
+       (void)pformatetc;
+       (void)pmedium;
+       (void)fRelease;
 
        return E_NOTIMPL;
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrDataObject_EnumFormatEtc(IDataObject* This, DWORD dwDirection, IEnumFORMATETC** ppenumFormatEtc)
+static HRESULT STDMETHODCALLTYPE CliprdrDataObject_EnumFormatEtc(
+               IDataObject* This, DWORD dwDirection, IEnumFORMATETC** ppenumFormatEtc)
 {
        CliprdrDataObject* instance = (CliprdrDataObject*) This;
 
-       if (!ppenumFormatEtc)
+       if (!instance || !ppenumFormatEtc)
                return E_INVALIDARG;
 
        if (dwDirection == DATADIR_GET)
@@ -517,28 +681,39 @@ HRESULT STDMETHODCALLTYPE CliprdrDataObject_EnumFormatEtc(IDataObject* This, DWO
        }
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrDataObject_DAdvise(IDataObject* This, FORMATETC* pformatetc, DWORD advf, IAdviseSink* pAdvSink, DWORD* pdwConnection)
+static HRESULT STDMETHODCALLTYPE CliprdrDataObject_DAdvise(
+               IDataObject* This, FORMATETC* pformatetc, DWORD advf,
+               IAdviseSink* pAdvSink, DWORD* pdwConnection)
 {
-       CliprdrDataObject* instance = (CliprdrDataObject*) This;
+       (void)This;
+       (void)pformatetc;
+       (void)advf;
+       (void)pAdvSink;
+       (void)pdwConnection;
 
        return OLE_E_ADVISENOTSUPPORTED;
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrDataObject_DUnadvise(IDataObject* This, DWORD dwConnection)
+static HRESULT STDMETHODCALLTYPE CliprdrDataObject_DUnadvise(
+               IDataObject* This, DWORD dwConnection)
 {
-       CliprdrDataObject* instance = (CliprdrDataObject*) This;
+       (void)This;
+       (void)dwConnection;
 
        return OLE_E_ADVISENOTSUPPORTED;
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrDataObject_EnumDAdvise(IDataObject* This, IEnumSTATDATA** ppenumAdvise)
+static HRESULT STDMETHODCALLTYPE CliprdrDataObject_EnumDAdvise(
+               IDataObject* This, IEnumSTATDATA** ppenumAdvise)
 {
-       CliprdrDataObject* instance = (CliprdrDataObject*) This;
+       (void)This;
+       (void)ppenumAdvise;
 
        return OLE_E_ADVISENOTSUPPORTED;
 }
 
-CliprdrDataObject* CliprdrDataObject_New(FORMATETC* fmtetc, STGMEDIUM* stgmed, int count, void* data)
+static CliprdrDataObject* CliprdrDataObject_New(
+               FORMATETC* fmtetc, STGMEDIUM* stgmed, int count, void* data)
 {
        int i;
        CliprdrDataObject* instance;
@@ -546,50 +721,56 @@ CliprdrDataObject* CliprdrDataObject_New(FORMATETC* fmtetc, STGMEDIUM* stgmed, i
 
        instance = (CliprdrDataObject*) calloc(1, sizeof(CliprdrDataObject));
 
-       if (instance)
-       {
-               iDataObject = &instance->iDataObject;
-
-               iDataObject->lpVtbl = (IDataObjectVtbl*) calloc(1, sizeof(IDataObjectVtbl));
+       if (!instance)
+               goto error;
 
-               if (iDataObject->lpVtbl)
-               {
-                       iDataObject->lpVtbl->QueryInterface = CliprdrDataObject_QueryInterface;
-                       iDataObject->lpVtbl->AddRef = CliprdrDataObject_AddRef;
-                       iDataObject->lpVtbl->Release = CliprdrDataObject_Release;
-                       iDataObject->lpVtbl->GetData = CliprdrDataObject_GetData;
-                       iDataObject->lpVtbl->GetDataHere = CliprdrDataObject_GetDataHere;
-                       iDataObject->lpVtbl->QueryGetData = CliprdrDataObject_QueryGetData;
-                       iDataObject->lpVtbl->GetCanonicalFormatEtc = CliprdrDataObject_GetCanonicalFormatEtc;
-                       iDataObject->lpVtbl->SetData = CliprdrDataObject_SetData;
-                       iDataObject->lpVtbl->EnumFormatEtc = CliprdrDataObject_EnumFormatEtc;
-                       iDataObject->lpVtbl->DAdvise = CliprdrDataObject_DAdvise;
-                       iDataObject->lpVtbl->DUnadvise = CliprdrDataObject_DUnadvise;
-                       iDataObject->lpVtbl->EnumDAdvise = CliprdrDataObject_EnumDAdvise;
+       iDataObject = &instance->iDataObject;
 
-                       instance->m_lRefCount = 1;
-                       instance->m_nNumFormats = count;
-                       instance->m_pData = data;
-                       instance->m_nStreams = 0;
-                       instance->m_pStream = NULL;
+       iDataObject->lpVtbl = (IDataObjectVtbl*) calloc(1, sizeof(IDataObjectVtbl));
 
-                       instance->m_pFormatEtc = (FORMATETC*) calloc(count, sizeof(FORMATETC));
-                       instance->m_pStgMedium = (STGMEDIUM*) calloc(count, sizeof(STGMEDIUM));
+       if (!iDataObject->lpVtbl)
+               goto error;
 
-                       for (i = 0; i < count; i++)
-                       {
-                               instance->m_pFormatEtc[i] = fmtetc[i];
-                               instance->m_pStgMedium[i] = stgmed[i];
-                       }
-               }
-               else
+       iDataObject->lpVtbl->QueryInterface = CliprdrDataObject_QueryInterface;
+       iDataObject->lpVtbl->AddRef = CliprdrDataObject_AddRef;
+       iDataObject->lpVtbl->Release = CliprdrDataObject_Release;
+       iDataObject->lpVtbl->GetData = CliprdrDataObject_GetData;
+       iDataObject->lpVtbl->GetDataHere = CliprdrDataObject_GetDataHere;
+       iDataObject->lpVtbl->QueryGetData = CliprdrDataObject_QueryGetData;
+       iDataObject->lpVtbl->GetCanonicalFormatEtc = CliprdrDataObject_GetCanonicalFormatEtc;
+       iDataObject->lpVtbl->SetData = CliprdrDataObject_SetData;
+       iDataObject->lpVtbl->EnumFormatEtc = CliprdrDataObject_EnumFormatEtc;
+       iDataObject->lpVtbl->DAdvise = CliprdrDataObject_DAdvise;
+       iDataObject->lpVtbl->DUnadvise = CliprdrDataObject_DUnadvise;
+       iDataObject->lpVtbl->EnumDAdvise = CliprdrDataObject_EnumDAdvise;
+
+       instance->m_lRefCount = 1;
+       instance->m_nNumFormats = count;
+       instance->m_pData = data;
+       instance->m_nStreams = 0;
+       instance->m_pStream = NULL;
+
+       if (count > 0)
+       {
+               instance->m_pFormatEtc = (FORMATETC*) calloc(count, sizeof(FORMATETC));
+               if (!instance->m_pFormatEtc)
+                       goto error;
+               instance->m_pStgMedium = (STGMEDIUM*) calloc(count, sizeof(STGMEDIUM));
+               if (!instance->m_pStgMedium)
+                       goto error;
+
+               for (i = 0; i < count; i++)
                {
-                       free(instance);
-                       instance = NULL;
+                       instance->m_pFormatEtc[i] = fmtetc[i];
+                       instance->m_pStgMedium[i] = stgmed[i];
                }
        }
 
        return instance;
+
+error:
+       CliprdrDataObject_Delete(instance);
+       return NULL;
 }
 
 void CliprdrDataObject_Delete(CliprdrDataObject* instance)
@@ -602,12 +783,10 @@ void CliprdrDataObject_Delete(CliprdrDataObject* instance)
 
                if (instance->m_pStream)
                {
-                       int i;
+                       LONG i;
 
                        for (i = 0; i < instance->m_nStreams; i++)
-                       {
                                CliprdrStream_Release(instance->m_pStream[i]);
-                       }
 
                        free(instance->m_pStream);
                }
@@ -616,15 +795,15 @@ void CliprdrDataObject_Delete(CliprdrDataObject* instance)
        }
 }
 
-BOOL wf_create_file_obj(wfClipboard* clipboard, IDataObject** ppDataObject)
+static BOOL wf_create_file_obj(wfClipboard* clipboard, IDataObject** ppDataObject)
 {
-       FORMATETC fmtetc[3];
-       STGMEDIUM stgmeds[3];
+       FORMATETC fmtetc[2];
+       STGMEDIUM stgmeds[2];
 
        if (!ppDataObject)
                return FALSE;
 
-       fmtetc[0].cfFormat = RegisterClipboardFormatW(CFSTR_FILEDESCRIPTORW);
+       fmtetc[0].cfFormat = RegisterClipboardFormat(CFSTR_FILEDESCRIPTORW);
        fmtetc[0].dwAspect = DVASPECT_CONTENT;
        fmtetc[0].lindex = 0;
        fmtetc[0].ptd = NULL;
@@ -634,7 +813,7 @@ BOOL wf_create_file_obj(wfClipboard* clipboard, IDataObject** ppDataObject)
        stgmeds[0].hGlobal = NULL;
        stgmeds[0].pUnkForRelease = NULL;
 
-       fmtetc[1].cfFormat = RegisterClipboardFormatW(CFSTR_FILECONTENTS);
+       fmtetc[1].cfFormat = RegisterClipboardFormat(CFSTR_FILECONTENTS);
        fmtetc[1].dwAspect = DVASPECT_CONTENT;
        fmtetc[1].lindex = 0;
        fmtetc[1].ptd = NULL;
@@ -644,22 +823,12 @@ BOOL wf_create_file_obj(wfClipboard* clipboard, IDataObject** ppDataObject)
        stgmeds[1].pstm = NULL;
        stgmeds[1].pUnkForRelease = NULL;
 
-       fmtetc[2].cfFormat = RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECT);
-       fmtetc[2].dwAspect = DVASPECT_CONTENT;
-       fmtetc[2].lindex = 0;
-       fmtetc[2].ptd = NULL;
-       fmtetc[2].tymed = TYMED_HGLOBAL;
-
-       stgmeds[2].tymed = TYMED_HGLOBAL;
-       stgmeds[2].hGlobal = NULL;
-       stgmeds[2].pUnkForRelease = NULL;
-
-       *ppDataObject = (IDataObject*) CliprdrDataObject_New(fmtetc, stgmeds, 3, clipboard);
+       *ppDataObject = (IDataObject*) CliprdrDataObject_New(fmtetc, stgmeds, 2, clipboard);
 
        return (*ppDataObject) ? TRUE : FALSE;
 }
 
-void wf_destroy_file_obj(IDataObject* instance)
+static void wf_destroy_file_obj(IDataObject* instance)
 {
        if (instance)
                IDataObject_Release(instance);
@@ -676,13 +845,15 @@ static void cliprdr_format_deep_copy(FORMATETC* dest, FORMATETC* source)
        if (source->ptd)
        {
                dest->ptd = (DVTARGETDEVICE*) CoTaskMemAlloc(sizeof(DVTARGETDEVICE));
-               *(dest->ptd) = *(source->ptd);
+               if (dest->ptd)
+                       *(dest->ptd) = *(source->ptd);
        }
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_QueryInterface(IEnumFORMATETC* This, REFIID riid, void** ppvObject)
+static HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_QueryInterface(
+               IEnumFORMATETC* This, REFIID riid, void** ppvObject)
 {
-       CliprdrEnumFORMATETC* instance = (CliprdrEnumFORMATETC*) This;
+       (void)This;
 
        if (IsEqualIID(riid, &IID_IEnumFORMATETC) || IsEqualIID(riid, &IID_IUnknown))
        {
@@ -697,18 +868,24 @@ HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_QueryInterface(IEnumFORMATETC* Th
        }
 }
 
-ULONG STDMETHODCALLTYPE CliprdrEnumFORMATETC_AddRef(IEnumFORMATETC* This)
+static ULONG STDMETHODCALLTYPE CliprdrEnumFORMATETC_AddRef(IEnumFORMATETC* This)
 {
        CliprdrEnumFORMATETC* instance = (CliprdrEnumFORMATETC*) This;
 
+       if (!instance)
+               return 0;
+
        return InterlockedIncrement(&instance->m_lRefCount);
 }
 
-ULONG STDMETHODCALLTYPE CliprdrEnumFORMATETC_Release(IEnumFORMATETC* This)
+static ULONG STDMETHODCALLTYPE CliprdrEnumFORMATETC_Release(IEnumFORMATETC* This)
 {
        LONG count;
        CliprdrEnumFORMATETC* instance = (CliprdrEnumFORMATETC*) This;
 
+       if (!instance)
+               return 0;
+
        count = InterlockedDecrement(&instance->m_lRefCount);
 
        if (count == 0)
@@ -722,12 +899,13 @@ ULONG STDMETHODCALLTYPE CliprdrEnumFORMATETC_Release(IEnumFORMATETC* This)
        }
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_Next(IEnumFORMATETC* This, ULONG celt, FORMATETC* rgelt, ULONG* pceltFetched)
+static HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_Next(IEnumFORMATETC* This, ULONG celt,
+                                                                                                                  FORMATETC* rgelt, ULONG* pceltFetched)
 {
        ULONG copied  = 0;
        CliprdrEnumFORMATETC* instance = (CliprdrEnumFORMATETC*) This;
 
-       if (!celt || !rgelt)
+       if (!instance || !celt || !rgelt)
                return E_INVALIDARG;
 
        while ((instance->m_nIndex < instance->m_nNumFormats) && (copied < celt))
@@ -741,10 +919,13 @@ HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_Next(IEnumFORMATETC* This, ULONG
        return (copied == celt) ? S_OK : E_FAIL;
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_Skip(IEnumFORMATETC* This, ULONG celt)
+static HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_Skip(IEnumFORMATETC* This, ULONG celt)
 {
        CliprdrEnumFORMATETC* instance = (CliprdrEnumFORMATETC*) This;
 
+       if (!instance)
+               return E_INVALIDARG;
+
        if (instance->m_nIndex + (LONG) celt > instance->m_nNumFormats)
                return E_FAIL;
 
@@ -753,20 +934,23 @@ HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_Skip(IEnumFORMATETC* This, ULONG
        return S_OK;
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_Reset(IEnumFORMATETC* This)
+static HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_Reset(IEnumFORMATETC* This)
 {
        CliprdrEnumFORMATETC* instance = (CliprdrEnumFORMATETC*) This;
 
+       if (!instance)
+               return E_INVALIDARG;
+
        instance->m_nIndex = 0;
 
        return S_OK;
 }
 
-HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_Clone(IEnumFORMATETC* This, IEnumFORMATETC **ppEnum)
+static HRESULT STDMETHODCALLTYPE CliprdrEnumFORMATETC_Clone(IEnumFORMATETC* This, IEnumFORMATETC **ppEnum)
 {
        CliprdrEnumFORMATETC* instance = (CliprdrEnumFORMATETC*) This;
 
-       if (!ppEnum)
+       if (!instance || !ppEnum)
                return E_INVALIDARG;
 
        *ppEnum = (IEnumFORMATETC*) CliprdrEnumFORMATETC_New(instance->m_nNumFormats, instance->m_pFormatEtc);
@@ -785,50 +969,51 @@ CliprdrEnumFORMATETC* CliprdrEnumFORMATETC_New(int nFormats, FORMATETC* pFormatE
        CliprdrEnumFORMATETC* instance;
        IEnumFORMATETC* iEnumFORMATETC;
 
-       if (!pFormatEtc)
+       if ((nFormats != 0) && !pFormatEtc)
                return NULL;
 
        instance = (CliprdrEnumFORMATETC*) calloc(1, sizeof(CliprdrEnumFORMATETC));
 
-       if (instance)
-       {
-               iEnumFORMATETC = &instance->iEnumFORMATETC;
+       if (!instance)
+               goto error;
 
-               iEnumFORMATETC->lpVtbl = (IEnumFORMATETCVtbl*) calloc(1, sizeof(IEnumFORMATETCVtbl));
+       iEnumFORMATETC = &instance->iEnumFORMATETC;
 
-               if (iEnumFORMATETC->lpVtbl)
-               {
-                       iEnumFORMATETC->lpVtbl->QueryInterface = CliprdrEnumFORMATETC_QueryInterface;
-                       iEnumFORMATETC->lpVtbl->AddRef = CliprdrEnumFORMATETC_AddRef;
-                       iEnumFORMATETC->lpVtbl->Release = CliprdrEnumFORMATETC_Release;
-                       iEnumFORMATETC->lpVtbl->Next = CliprdrEnumFORMATETC_Next;
-                       iEnumFORMATETC->lpVtbl->Skip = CliprdrEnumFORMATETC_Skip;
-                       iEnumFORMATETC->lpVtbl->Reset = CliprdrEnumFORMATETC_Reset;
-                       iEnumFORMATETC->lpVtbl->Clone = CliprdrEnumFORMATETC_Clone;
-
-                       instance->m_lRefCount = 0;
-                       instance->m_nIndex = 0;
-                       instance->m_nNumFormats = nFormats;
-                       instance->m_pFormatEtc = (FORMATETC*) calloc(nFormats, sizeof(FORMATETC));
-
-                       for (i = 0; i < nFormats; i++)
-                       {
-                               cliprdr_format_deep_copy(&instance->m_pFormatEtc[i], &pFormatEtc[i]);
-                       }
-               }
-               else
-               {
-                       free(instance);
-                       instance = NULL;
-               }
-       }
+       iEnumFORMATETC->lpVtbl = (IEnumFORMATETCVtbl*) calloc(1, sizeof(IEnumFORMATETCVtbl));
+
+       if (!iEnumFORMATETC->lpVtbl)
+               goto error;
+
+       iEnumFORMATETC->lpVtbl->QueryInterface = CliprdrEnumFORMATETC_QueryInterface;
+       iEnumFORMATETC->lpVtbl->AddRef = CliprdrEnumFORMATETC_AddRef;
+       iEnumFORMATETC->lpVtbl->Release = CliprdrEnumFORMATETC_Release;
+       iEnumFORMATETC->lpVtbl->Next = CliprdrEnumFORMATETC_Next;
+       iEnumFORMATETC->lpVtbl->Skip = CliprdrEnumFORMATETC_Skip;
+       iEnumFORMATETC->lpVtbl->Reset = CliprdrEnumFORMATETC_Reset;
+       iEnumFORMATETC->lpVtbl->Clone = CliprdrEnumFORMATETC_Clone;
+
+       instance->m_lRefCount = 0;
+       instance->m_nIndex = 0;
+       instance->m_nNumFormats = nFormats;
+       if (nFormats > 0)
+       {
+               instance->m_pFormatEtc = (FORMATETC*) calloc(nFormats, sizeof(FORMATETC));
+               if (!instance->m_pFormatEtc)
+                       goto error;
 
+               for (i = 0; i < nFormats; i++)
+                       cliprdr_format_deep_copy(&instance->m_pFormatEtc[i], &pFormatEtc[i]);
+       }
        return instance;
+
+error:
+       CliprdrEnumFORMATETC_Delete(instance);
+       return NULL;
 }
 
 void CliprdrEnumFORMATETC_Delete(CliprdrEnumFORMATETC* instance)
 {
-       int i;
+       LONG i;
 
        if (instance)
        {
@@ -851,46 +1036,67 @@ void CliprdrEnumFORMATETC_Delete(CliprdrEnumFORMATETC* instance)
 
 /***********************************************************************************/
 
-static UINT32 get_local_format_id_by_name(wfClipboard* clipboard, void* format_name)
+static UINT32 get_local_format_id_by_name(wfClipboard* clipboard, const TCHAR* format_name)
 {
-       int i;
+       size_t i;
        formatMapping* map;
+       WCHAR* unicode_name;
+#if !defined(UNICODE)
+       size_t size;
+#endif
+
+       if (!clipboard || !format_name)
+               return 0;
+
+#if defined(UNICODE)
+       unicode_name = _wcsdup(format_name);
+#else
+       size = _tcslen(format_name);
+       unicode_name = calloc(size + 1, sizeof(WCHAR));
+       if (!unicode_name)
+               return 0;
+
+       MultiByteToWideChar(CP_OEMCP, 0, format_name, strlen(format_name), unicode_name, size);
+#endif
+       if (!unicode_name)
+               return 0;
 
        for (i = 0; i < clipboard->map_size; i++)
        {
                map = &clipboard->format_mappings[i];
-
-               if ((clipboard->capabilities & CB_USE_LONG_FORMAT_NAMES) != 0)
+               if (map->name)
                {
-                       if (map->name)
+                       if (wcscmp(map->name, unicode_name) == 0)
                        {
-                               if (memcmp(map->name, format_name, wcslen((LPCWSTR) format_name)) == 0)
-                                       return map->local_format_id;
+                               free (unicode_name);
+                               return map->local_format_id;
                        }
                }
        }
 
+       free (unicode_name);
        return 0;
 }
 
 static INLINE BOOL file_transferring(wfClipboard* clipboard)
 {
-       return get_local_format_id_by_name(clipboard, _T("FileGroupDescriptorW")) ? TRUE : FALSE;
+       return get_local_format_id_by_name(clipboard, CFSTR_FILEDESCRIPTORW) ? TRUE : FALSE;
 }
 
 static UINT32 get_remote_format_id(wfClipboard* clipboard, UINT32 local_format)
 {
-       int i;
+       UINT32 i;
        formatMapping* map;
 
+       if (!clipboard)
+               return 0;
+
        for (i = 0; i < clipboard->map_size; i++)
        {
                map = &clipboard->format_mappings[i];
 
                if (map->local_format_id == local_format)
-               {
                        return map->remote_format_id;
-               }
        }
 
        return local_format;
@@ -898,14 +1104,17 @@ static UINT32 get_remote_format_id(wfClipboard* clipboard, UINT32 local_format)
 
 static void map_ensure_capacity(wfClipboard* clipboard)
 {
+       if (!clipboard)
+               return;
+
        if (clipboard->map_size >= clipboard->map_capacity)
        {
-               int new_size;
+               size_t new_size;
                formatMapping *new_map;
 
                new_size = clipboard->map_capacity * 2;
                new_map = (formatMapping*) realloc(clipboard->format_mappings,
-                               sizeof(formatMapping) * new_size);
+                                                                                  sizeof(formatMapping) * new_size);
                if (!new_map)
                        return;
                clipboard->format_mappings = new_map;
@@ -913,11 +1122,14 @@ static void map_ensure_capacity(wfClipboard* clipboard)
        }
 }
 
-static void clear_format_map(wfClipboard* clipboard)
+static BOOL clear_format_map(wfClipboard* clipboard)
 {
-       int i;
+       size_t i;
        formatMapping* map;
 
+       if (!clipboard)
+               return FALSE;
+
        if (clipboard->format_mappings)
        {
                for (i = 0; i < clipboard->map_capacity; i++)
@@ -932,106 +1144,118 @@ static void clear_format_map(wfClipboard* clipboard)
        }
 
        clipboard->map_size = 0;
+       return TRUE;
 }
 
-int cliprdr_send_tempdir(wfClipboard* clipboard)
+static UINT cliprdr_send_tempdir(wfClipboard* clipboard)
 {
        CLIPRDR_TEMP_DIRECTORY tempDirectory;
 
-       GetEnvironmentVariableA("TEMP", tempDirectory.szTempDir, sizeof(tempDirectory.szTempDir));
+       if (!clipboard)
+               return -1;
 
-       clipboard->context->TempDirectory(clipboard->context, &tempDirectory);
+       if (GetEnvironmentVariableA("TEMP", tempDirectory.szTempDir, sizeof(tempDirectory.szTempDir)) == 0)
+               return -1;
 
-       return 1;
+       return clipboard->context->TempDirectory(clipboard->context, &tempDirectory);
 }
 
-static int cliprdr_send_format_list(wfClipboard* clipboard)
+static UINT cliprdr_send_format_list(wfClipboard* clipboard)
 {
+       UINT rc;
        int count;
-       int length;
        UINT32 index;
        UINT32 numFormats;
        UINT32 formatId = 0;
        char formatName[1024];
-       CLIPRDR_FORMAT* format;
        CLIPRDR_FORMAT* formats;
        CLIPRDR_FORMAT_LIST formatList;
 
+       if (!clipboard)
+               return ERROR_INTERNAL_ERROR;
+
        ZeroMemory(&formatList, sizeof(CLIPRDR_FORMAT_LIST));
 
        if (!OpenClipboard(clipboard->hwnd))
-               return -1;
+               return ERROR_INTERNAL_ERROR;
 
        count = CountClipboardFormats();
 
        numFormats = (UINT32) count;
        formats = (CLIPRDR_FORMAT*) calloc(numFormats, sizeof(CLIPRDR_FORMAT));
+       if (!formats)
+       {
+               CloseClipboard();
+               return CHANNEL_RC_NO_MEMORY;
+       }
 
        index = 0;
 
        while (formatId = EnumClipboardFormats(formatId))
-       {
-               format = &formats[index++];
-
-               format->formatId = formatId;
+               formats[index++].formatId = formatId;;
 
-               length = 0;
-               format->formatName = NULL;
+       numFormats = index;
 
-               if (formatId >= CF_MAX)
-               {
-                       length = GetClipboardFormatNameA(formatId, formatName, sizeof(formatName) - 1);
-               }
-
-               if (length > 0)
-               {
-                       format->formatName = _strdup(formatName);
-               }
+       if (!CloseClipboard())
+       {
+               free (formats);
+               return ERROR_INTERNAL_ERROR;
        }
 
-       CloseClipboard();
+       for (index = 0; index < numFormats; index++)
+       {
+               GetClipboardFormatNameA(formats[index].formatId, formatName, sizeof(formatName));
+               formats[index].formatName = _strdup(formatName);
+       }
 
-       formatList.msgFlags = 0;
        formatList.numFormats = numFormats;
        formatList.formats = formats;
 
-       clipboard->context->ClientFormatList(clipboard->context, &formatList);
+       rc = clipboard->context->ClientFormatList(clipboard->context, &formatList);
 
        for (index = 0; index < numFormats; index++)
-       {
-               format = &formats[index];
-               free(format->formatName);
-       }
+               free(formats[index].formatName);
 
        free(formats);
 
-       return 1;
+       return rc;
 }
 
-int cliprdr_send_data_request(wfClipboard* clipboard, UINT32 formatId)
+static UINT cliprdr_send_data_request(wfClipboard* clipboard, UINT32 formatId)
 {
+       UINT rc;
        CLIPRDR_FORMAT_DATA_REQUEST formatDataRequest;
 
+       if (!clipboard || !clipboard->context ||
+                       !clipboard->context->ClientFormatDataRequest)
+               return ERROR_INTERNAL_ERROR;
+
        formatDataRequest.msgType = CB_FORMAT_DATA_REQUEST;
        formatDataRequest.msgFlags = CB_RESPONSE_OK;
 
        formatDataRequest.requestedFormatId = formatId;
        clipboard->requestedFormatId = formatId;
 
-       clipboard->context->ClientFormatDataRequest(clipboard->context, &formatDataRequest);
+       rc = clipboard->context->ClientFormatDataRequest(clipboard->context, &formatDataRequest);
 
-       WaitForSingleObject(clipboard->response_data_event, INFINITE);
-       ResetEvent(clipboard->response_data_event);
+       if (WaitForSingleObject(clipboard->response_data_event, INFINITE) != WAIT_OBJECT_0)
+               rc = ERROR_INTERNAL_ERROR;
+       else if (!ResetEvent(clipboard->response_data_event))
+               rc = ERROR_INTERNAL_ERROR;
 
-       return 0;
+       return rc;
 }
 
-int cliprdr_send_request_filecontents(wfClipboard* clipboard, void* streamid,
-               int index, int flag, DWORD positionhigh, DWORD positionlow, ULONG nreq)
+static UINT cliprdr_send_request_filecontents(wfClipboard* clipboard, const void* streamid,
+                                                                                         int index, int flag, DWORD positionhigh,
+                                                                                         DWORD positionlow, ULONG nreq)
 {
+       UINT rc;
        CLIPRDR_FILE_CONTENTS_REQUEST fileContentsRequest;
 
-       ZeroMemory(&fileContentsRequest, sizeof(CLIPRDR_FILE_CONTENTS_REQUEST));
+       if (!clipboard || !clipboard->context ||
+                       !clipboard->context->ClientFileContentsRequest)
+               return ERROR_INTERNAL_ERROR;
 
        fileContentsRequest.streamId = (UINT32) streamid;
        fileContentsRequest.listIndex = index;
@@ -1041,27 +1265,32 @@ int cliprdr_send_request_filecontents(wfClipboard* clipboard, void* streamid,
        fileContentsRequest.cbRequested = nreq;
        fileContentsRequest.clipDataId = 0;
 
-       clipboard->context->ClientFileContentsRequest(clipboard->context, &fileContentsRequest);
+       rc = clipboard->context->ClientFileContentsRequest(clipboard->context, &fileContentsRequest);
 
-       WaitForSingleObject(clipboard->req_fevent, INFINITE);
-       ResetEvent(clipboard->req_fevent);
+       if (WaitForSingleObject(clipboard->req_fevent, INFINITE) != WAIT_OBJECT_0)
+               rc = ERROR_INTERNAL_ERROR;
+       else if (!ResetEvent(clipboard->req_fevent))
+               rc = ERROR_INTERNAL_ERROR;
 
-       return 0;
+       return rc;
 }
 
-int cliprdr_send_response_filecontents(wfClipboard* clipboard, UINT32 streamId, UINT32 size, BYTE* data)
+static UINT cliprdr_send_response_filecontents(wfClipboard* clipboard,
+                                                                                          UINT32 streamId, UINT32 size,
+                                                                                          BYTE* data)
 {
        CLIPRDR_FILE_CONTENTS_RESPONSE fileContentsResponse;
 
-       ZeroMemory(&fileContentsResponse, sizeof(CLIPRDR_FILE_CONTENTS_RESPONSE));
+       if (!clipboard || !clipboard->context ||
+                       !clipboard->context->ClientFileContentsResponse)
+               return ERROR_INTERNAL_ERROR;
 
        fileContentsResponse.streamId = streamId;
        fileContentsResponse.cbRequested = size;
        fileContentsResponse.requestedData = data;
-       
-       clipboard->context->ClientFileContentsResponse(clipboard->context, &fileContentsResponse);
+       fileContentsResponse.msgFlags = CB_RESPONSE_OK;
 
-       return 0;
+       return clipboard->context->ClientFileContentsResponse(clipboard->context, &fileContentsResponse);
 }
 
 static LRESULT CALLBACK cliprdr_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
@@ -1070,100 +1299,100 @@ static LRESULT CALLBACK cliprdr_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM
 
        switch (Msg)
        {
-               case WM_CREATE:
-                       DEBUG_CLIPRDR("info: WM_CREATE");
-                       clipboard = (wfClipboard*)((CREATESTRUCT*) lParam)->lpCreateParams;
-                       if (!AddClipboardFormatListener(hWnd)) {
-                               DEBUG_CLIPRDR("error: AddClipboardFormatListener failed with %#x.", GetLastError());
-                       }
-                       clipboard->hwnd = hWnd;
-                       break;
+       case WM_CREATE:
+               DEBUG_CLIPRDR("info: WM_CREATE");
+               clipboard = (wfClipboard*)((CREATESTRUCT*) lParam)->lpCreateParams;
+               if (!AddClipboardFormatListener(hWnd)) {
+                       DEBUG_CLIPRDR("error: AddClipboardFormatListener failed with %#x.", GetLastError());
+               }
+               clipboard->hwnd = hWnd;
+               break;
 
-               case WM_CLOSE:
-                       DEBUG_CLIPRDR("info: WM_CLOSE");
-                       RemoveClipboardFormatListener(hWnd);
-                       break;
+       case WM_CLOSE:
+               DEBUG_CLIPRDR("info: WM_CLOSE");
+               RemoveClipboardFormatListener(hWnd);
+               break;
 
-               case WM_CLIPBOARDUPDATE:
-                       DEBUG_CLIPRDR("info: WM_CLIPBOARDUPDATE");
-                       if (clipboard->sync)
-                       {
-                               if ((GetClipboardOwner() != clipboard->hwnd) &&
+       case WM_CLIPBOARDUPDATE:
+               DEBUG_CLIPRDR("info: WM_CLIPBOARDUPDATE");
+               if (clipboard->sync)
+               {
+                       if ((GetClipboardOwner() != clipboard->hwnd) &&
                                        (S_FALSE == OleIsCurrentClipboard(clipboard->data_obj)))
+                       {
+                               if (clipboard->hmem)
                                {
-                                               if (clipboard->hmem)
-                                               {
-                                                       GlobalFree(clipboard->hmem);
-                                                       clipboard->hmem = NULL;
-                                               }
-
-                                               cliprdr_send_format_list(clipboard);
+                                       GlobalFree(clipboard->hmem);
+                                       clipboard->hmem = NULL;
                                }
+
+                               cliprdr_send_format_list(clipboard);
                        }
+               }
+               break;
+
+       case WM_RENDERALLFORMATS:
+               DEBUG_CLIPRDR("info: WM_RENDERALLFORMATS");
+               /* discard all contexts in clipboard */
+               if (!OpenClipboard(clipboard->hwnd))
+               {
+                       DEBUG_CLIPRDR("OpenClipboard failed with 0x%x", GetLastError());
                        break;
+               }
+               EmptyClipboard();
+               CloseClipboard();
+               break;
 
-               case WM_RENDERALLFORMATS:
-                       DEBUG_CLIPRDR("info: WM_RENDERALLFORMATS");
-                       /* discard all contexts in clipboard */
-                       if (!OpenClipboard(clipboard->hwnd))
-                       {
-                               DEBUG_CLIPRDR("OpenClipboard failed with 0x%x", GetLastError());
-                               break;
-                       }
-                       EmptyClipboard();
-                       CloseClipboard();
+       case WM_RENDERFORMAT:
+               DEBUG_CLIPRDR("info: WM_RENDERFORMAT");
+               if (cliprdr_send_data_request(clipboard, (UINT32) wParam) != 0)
+               {
+                       DEBUG_CLIPRDR("error: cliprdr_send_data_request failed.");
                        break;
+               }
 
-               case WM_RENDERFORMAT:
-                       DEBUG_CLIPRDR("info: WM_RENDERFORMAT");
-                       if (cliprdr_send_data_request(clipboard, (UINT32) wParam) != 0)
+               if (!SetClipboardData((UINT) wParam, clipboard->hmem))
+               {
+                       DEBUG_CLIPRDR("SetClipboardData failed with 0x%x", GetLastError());
+
+                       if (clipboard->hmem)
                        {
-                               DEBUG_CLIPRDR("error: cliprdr_send_data_request failed.");
-                               break;
+                               GlobalFree(clipboard->hmem);
+                               clipboard->hmem = NULL;
                        }
+               }
+               /* Note: GlobalFree() is not needed when success */
+               break;
 
-                       if (!SetClipboardData((UINT) wParam, clipboard->hmem))
+       case WM_CLIPRDR_MESSAGE:
+               DEBUG_CLIPRDR("info: WM_CLIPRDR_MESSAGE");
+               switch (wParam)
+               {
+               case OLE_SETCLIPBOARD:
+                       DEBUG_CLIPRDR("info: OLE_SETCLIPBOARD");
+                       if (wf_create_file_obj(clipboard, &clipboard->data_obj))
                        {
-                               DEBUG_CLIPRDR("SetClipboardData failed with 0x%x", GetLastError());
-
-                               if (clipboard->hmem)
+                               if (OleSetClipboard(clipboard->data_obj) != S_OK)
                                {
-                                       GlobalFree(clipboard->hmem);
-                                       clipboard->hmem = NULL;
+                                       wf_destroy_file_obj(clipboard->data_obj);
+                                       clipboard->data_obj = NULL;
                                }
                        }
-                       /* Note: GlobalFree() is not needed when success */
                        break;
 
-               case WM_CLIPRDR_MESSAGE:
-                       DEBUG_CLIPRDR("info: WM_CLIPRDR_MESSAGE");
-                       switch (wParam)
-                       {
-                               case OLE_SETCLIPBOARD:
-                                       DEBUG_CLIPRDR("info: OLE_SETCLIPBOARD");
-                                       if (wf_create_file_obj(clipboard, &clipboard->data_obj))
-                                       {
-                                               if (OleSetClipboard(clipboard->data_obj) != S_OK)
-                                               {
-                                                       wf_destroy_file_obj(clipboard->data_obj);
-                                                       clipboard->data_obj = NULL;
-                                               }
-                                       }
-                                       break;
-
-                               default:
-                                       break;
-                       }
+               default:
                        break;
+               }
+               break;
 
-               case WM_DESTROYCLIPBOARD:
-               case WM_ASKCBFORMATNAME:
-               case WM_HSCROLLCLIPBOARD:
-               case WM_PAINTCLIPBOARD:
-               case WM_SIZECLIPBOARD:
-               case WM_VSCROLLCLIPBOARD:
-               default:
-                       return DefWindowProc(hWnd, Msg, wParam, lParam);
+       case WM_DESTROYCLIPBOARD:
+       case WM_ASKCBFORMATNAME:
+       case WM_HSCROLLCLIPBOARD:
+       case WM_PAINTCLIPBOARD:
+       case WM_SIZECLIPBOARD:
+       case WM_VSCROLLCLIPBOARD:
+       default:
+               return DefWindowProc(hWnd, Msg, wParam, lParam);
        }
 
        return 0;
@@ -1190,9 +1419,9 @@ static int create_cliprdr_window(wfClipboard* clipboard)
        RegisterClassEx(&wnd_cls);
 
        clipboard->hwnd = CreateWindowEx(WS_EX_LEFT,
-               _T("ClipboardHiddenMessageProcessor"),
-               _T("rdpclip"),
-               0, 0, 0, 0, 0, HWND_MESSAGE, NULL, GetModuleHandle(NULL), clipboard);
+                                                                        _T("ClipboardHiddenMessageProcessor"),
+                                                                        _T("rdpclip"),
+                                                                        0, 0, 0, 0, 0, HWND_MESSAGE, NULL, GetModuleHandle(NULL), clipboard);
 
        if (!clipboard->hwnd)
        {
@@ -1239,7 +1468,10 @@ static void* cliprdr_thread_func(void* arg)
 
 static void clear_file_array(wfClipboard* clipboard)
 {
-       int i;
+       size_t i;
+
+       if (!clipboard)
+               return;
 
        /* clear file_names array */
        if (clipboard->file_names)
@@ -1249,6 +1481,9 @@ static void clear_file_array(wfClipboard* clipboard)
                        free(clipboard->file_names[i]);
                        clipboard->file_names[i] = NULL;
                }
+
+               free (clipboard->file_names);
+               clipboard->file_names = NULL;
        }
 
        /* clear fileDescriptor array */
@@ -1259,48 +1494,59 @@ static void clear_file_array(wfClipboard* clipboard)
                        free(clipboard->fileDescriptor[i]);
                        clipboard->fileDescriptor[i] = NULL;
                }
+               free (clipboard->fileDescriptor);
+               clipboard->fileDescriptor = NULL;
        }
 
+       clipboard->file_array_size = 0;
        clipboard->nFiles = 0;
 }
 
 static BOOL wf_cliprdr_get_file_contents(WCHAR* file_name, BYTE* buffer,
-       int positionLow, int positionHigh, int nRequested, unsigned int* puSize)
+                                                                                LONG positionLow, LONG positionHigh,
+                                                                                DWORD nRequested, DWORD* puSize)
 {
+       BOOL res = FALSE;
        HANDLE hFile;
-       DWORD nGet;
+       DWORD nGet, rc;
 
        if (!file_name || !buffer || !puSize)
        {
                WLog_ERR(TAG,  "get file contents Invalid Arguments.");
                return FALSE;
        }
-       
+
        hFile = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
-               FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL);
-       
+                                               FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL);
+
        if (hFile == INVALID_HANDLE_VALUE)
-       {
                return FALSE;
-       }
 
-       SetFilePointer(hFile, positionLow, (PLONG) &positionHigh, FILE_BEGIN);
+       rc = SetFilePointer(hFile, positionLow, &positionHigh, FILE_BEGIN);
+       if (rc == INVALID_SET_FILE_POINTER)
+               goto error;
 
        if (!ReadFile(hFile, buffer, nRequested, &nGet, NULL))
        {
                DWORD err = GetLastError();
                DEBUG_CLIPRDR("ReadFile failed with 0x%x.", err);
+               goto error;
        }
 
-       CloseHandle(hFile);
+       res = TRUE;
+
+error:
+       if (!CloseHandle(hFile))
+               res = FALSE;
 
-       *puSize = nGet;
+       if (res)
+               *puSize = nGet;
 
-       return TRUE;
+       return res;
 }
 
 /* path_name has a '\' at the end. e.g. c:\newfolder\, file_name is c:\newfolder\new.txt */
-static FILEDESCRIPTORW* wf_cliprdr_get_file_descriptor(WCHAR* file_name, int pathLen)
+static FILEDESCRIPTORW* wf_cliprdr_get_file_descriptor(WCHAR* file_name, size_t pathLen)
 {
        HANDLE hFile;
        FILEDESCRIPTORW* fd;
@@ -1311,7 +1557,7 @@ static FILEDESCRIPTORW* wf_cliprdr_get_file_descriptor(WCHAR* file_name, int pat
                return NULL;
 
        hFile = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ,
-               NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL);
+                                               NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL);
 
        if (hFile == INVALID_HANDLE_VALUE)
        {
@@ -1336,17 +1582,21 @@ static FILEDESCRIPTORW* wf_cliprdr_get_file_descriptor(WCHAR* file_name, int pat
        return fd;
 }
 
-static void wf_cliprdr_array_ensure_capacity(wfClipboard* clipboard)
+static BOOL wf_cliprdr_array_ensure_capacity(wfClipboard* clipboard)
 {
+       if (!clipboard)
+               return FALSE;
+
        if (clipboard->nFiles == clipboard->file_array_size)
        {
-               int new_size;
+               size_t new_size;
                FILEDESCRIPTORW **new_fd;
                WCHAR **new_name;
 
-               new_size = clipboard->file_array_size * 2;
+               new_size = (clipboard->file_array_size + 1) * 2;
 
-               new_fd = (FILEDESCRIPTORW**) realloc(clipboard->fileDescriptor, new_size * sizeof(FILEDESCRIPTORW*));
+               new_fd = (FILEDESCRIPTORW**) realloc(clipboard->fileDescriptor,
+                                                                                        new_size * sizeof(FILEDESCRIPTORW*));
                if (new_fd)
                        clipboard->fileDescriptor = new_fd;
 
@@ -1355,32 +1605,51 @@ static void wf_cliprdr_array_ensure_capacity(wfClipboard* clipboard)
                        clipboard->file_names = new_name;
 
                if (!new_fd || !new_name)
-                       return;
+                       return FALSE;
 
-               clipboard->file_array_size *= new_size;
+               clipboard->file_array_size = new_size;
        }
+
+       return TRUE;
 }
 
-static void wf_cliprdr_add_to_file_arrays(wfClipboard* clipboard, WCHAR* full_file_name, int pathLen)
+static BOOL wf_cliprdr_add_to_file_arrays(wfClipboard* clipboard,
+                                                                                 WCHAR* full_file_name, size_t pathLen)
 {
+       if (!wf_cliprdr_array_ensure_capacity(clipboard))
+               return FALSE;
+
        /* add to name array */
        clipboard->file_names[clipboard->nFiles] = (LPWSTR) malloc(MAX_PATH * 2);
+       if (!clipboard->file_names[clipboard->nFiles])
+               return FALSE;
+
        wcscpy_s(clipboard->file_names[clipboard->nFiles], MAX_PATH, full_file_name);
 
        /* add to descriptor array */
-       clipboard->fileDescriptor[clipboard->nFiles] = wf_cliprdr_get_file_descriptor(full_file_name, pathLen);
+       clipboard->fileDescriptor[clipboard->nFiles] =
+                       wf_cliprdr_get_file_descriptor(full_file_name, pathLen);
+       if (!clipboard->fileDescriptor[clipboard->nFiles])
+       {
+               free (clipboard->file_names[clipboard->nFiles]);
+               return FALSE;
+       }
 
        clipboard->nFiles++;
 
-       wf_cliprdr_array_ensure_capacity(clipboard);
+       return TRUE;
 }
 
-static void wf_cliprdr_traverse_directory(wfClipboard* clipboard, WCHAR* Dir, int pathLen)
+static BOOL wf_cliprdr_traverse_directory(wfClipboard* clipboard,
+                                                                                 WCHAR* Dir, size_t pathLen)
 {
        HANDLE hFind;
        WCHAR DirSpec[MAX_PATH];
        WIN32_FIND_DATA FindFileData;
 
+       if (!clipboard || !Dir)
+               return FALSE;
+
        StringCchCopy(DirSpec, MAX_PATH, Dir);
        StringCchCat(DirSpec, MAX_PATH, TEXT("\\*"));
 
@@ -1389,14 +1658,14 @@ static void wf_cliprdr_traverse_directory(wfClipboard* clipboard, WCHAR* Dir, in
        if (hFind == INVALID_HANDLE_VALUE)
        {
                DEBUG_CLIPRDR("FindFirstFile failed with 0x%x.", GetLastError());
-               return;
+               return FALSE;
        }
 
        while (FindNextFile(hFind, &FindFileData))
        {
                if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0
-                       && wcscmp(FindFileData.cFileName, _T(".")) == 0
-                       || wcscmp(FindFileData.cFileName, _T("..")) == 0)
+                               && wcscmp(FindFileData.cFileName, _T(".")) == 0
+                               || wcscmp(FindFileData.cFileName, _T("..")) == 0)
                {
                        continue;
                }
@@ -1408,8 +1677,10 @@ static void wf_cliprdr_traverse_directory(wfClipboard* clipboard, WCHAR* Dir, in
                        StringCchCopy(DirAdd, MAX_PATH, Dir);
                        StringCchCat(DirAdd, MAX_PATH, _T("\\"));
                        StringCchCat(DirAdd, MAX_PATH, FindFileData.cFileName);
-                       wf_cliprdr_add_to_file_arrays(clipboard, DirAdd, pathLen);
-                       wf_cliprdr_traverse_directory(clipboard, DirAdd, pathLen);
+                       if (!wf_cliprdr_add_to_file_arrays(clipboard, DirAdd, pathLen))
+                               return FALSE;
+                       if (!wf_cliprdr_traverse_directory(clipboard, DirAdd, pathLen))
+                               return FALSE;
                }
                else
                {
@@ -1419,18 +1690,25 @@ static void wf_cliprdr_traverse_directory(wfClipboard* clipboard, WCHAR* Dir, in
                        StringCchCat(fileName, MAX_PATH, _T("\\"));
                        StringCchCat(fileName, MAX_PATH, FindFileData.cFileName);
 
-                       wf_cliprdr_add_to_file_arrays(clipboard, fileName, pathLen);
+                       if (!wf_cliprdr_add_to_file_arrays(clipboard, fileName, pathLen))
+                               return FALSE;
                }
        }
 
        FindClose(hFind);
+
+       return TRUE;
 }
 
-int wf_cliprdr_send_client_capabilities(wfClipboard* clipboard)
+static UINT wf_cliprdr_send_client_capabilities(wfClipboard* clipboard)
 {
        CLIPRDR_CAPABILITIES capabilities;
        CLIPRDR_GENERAL_CAPABILITY_SET generalCapabilitySet;
 
+       if (!clipboard || !clipboard->context ||
+                       !clipboard->context->ClientCapabilities)
+               return ERROR_INTERNAL_ERROR;
+
        capabilities.cCapabilitiesSets = 1;
        capabilities.capabilitySets = (CLIPRDR_CAPABILITY_SET*) &(generalCapabilitySet);
 
@@ -1438,11 +1716,13 @@ int wf_cliprdr_send_client_capabilities(wfClipboard* clipboard)
        generalCapabilitySet.capabilitySetLength = 12;
 
        generalCapabilitySet.version = CB_CAPS_VERSION_2;
-       generalCapabilitySet.generalFlags = CB_USE_LONG_FORMAT_NAMES;
-
-       clipboard->context->ClientCapabilities(clipboard->context, &capabilities);
+       generalCapabilitySet.generalFlags =
+                       CB_USE_LONG_FORMAT_NAMES |
+                       CB_STREAM_FILECLIP_ENABLED |
+                       CB_FILECLIP_NO_FILE_PATHS |
+                       CB_CAN_LOCK_CLIPDATA;
 
-       return 1;
+       return clipboard->context->ClientCapabilities(clipboard->context, &capabilities);
 }
 
 /**
@@ -1450,15 +1730,21 @@ int wf_cliprdr_send_client_capabilities(wfClipboard* clipboard)
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT wf_cliprdr_monitor_ready(CliprdrClientContext* context, CLIPRDR_MONITOR_READY* monitorReady)
+static UINT wf_cliprdr_monitor_ready(CliprdrClientContext* context,
+                                                                        CLIPRDR_MONITOR_READY* monitorReady)
 {
+       UINT rc;
        wfClipboard* clipboard = (wfClipboard*) context->custom;
 
+       if (!context || !monitorReady)
+               return ERROR_INTERNAL_ERROR;
+
        clipboard->sync = TRUE;
-       wf_cliprdr_send_client_capabilities(clipboard);
-       cliprdr_send_format_list(clipboard);
+       rc = wf_cliprdr_send_client_capabilities(clipboard);
+       if (rc != CHANNEL_RC_OK)
+               return rc;
 
-       return CHANNEL_RC_OK;
+       return cliprdr_send_format_list(clipboard);
 }
 
 /**
@@ -1466,27 +1752,31 @@ static UINT wf_cliprdr_monitor_ready(CliprdrClientContext* context, CLIPRDR_MONI
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT wf_cliprdr_server_capabilities(CliprdrClientContext* context, CLIPRDR_CAPABILITIES* capabilities)
+static UINT wf_cliprdr_server_capabilities(CliprdrClientContext* context,
+                                                                                  CLIPRDR_CAPABILITIES* capabilities)
 {
        UINT32 index;
        CLIPRDR_CAPABILITY_SET* capabilitySet;
        wfClipboard* clipboard = (wfClipboard*) context->custom;
 
+       if (!context || !capabilities)
+               return ERROR_INTERNAL_ERROR;
+
        for (index = 0; index < capabilities->cCapabilitiesSets; index++)
        {
                capabilitySet = &(capabilities->capabilitySets[index]);
 
                if ((capabilitySet->capabilitySetType == CB_CAPSTYPE_GENERAL) &&
-                       (capabilitySet->capabilitySetLength >= CB_CAPSTYPE_GENERAL_LEN))
+                               (capabilitySet->capabilitySetLength >= CB_CAPSTYPE_GENERAL_LEN))
                {
                        CLIPRDR_GENERAL_CAPABILITY_SET* generalCapabilitySet
-                               = (CLIPRDR_GENERAL_CAPABILITY_SET*) capabilitySet;
+                                       = (CLIPRDR_GENERAL_CAPABILITY_SET*) capabilitySet;
 
                        clipboard->capabilities = generalCapabilitySet->generalFlags;
                        break;
                }
        }
-       
+
        return CHANNEL_RC_OK;
 }
 
@@ -1495,26 +1785,36 @@ static UINT wf_cliprdr_server_capabilities(CliprdrClientContext* context, CLIPRD
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT wf_cliprdr_server_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LIST* formatList)
+static UINT wf_cliprdr_server_format_list(CliprdrClientContext* context,
+                                                                                 CLIPRDR_FORMAT_LIST* formatList)
 {
-       UINT32 i, j;
+       UINT rc = ERROR_INTERNAL_ERROR;
+       UINT32 i;
        formatMapping* mapping;
        CLIPRDR_FORMAT* format;
        wfClipboard* clipboard = (wfClipboard*) context->custom;
 
-       clear_format_map(clipboard);
+       if (!clear_format_map(clipboard))
+               return ERROR_INTERNAL_ERROR;
 
-       for (i = j = 0; i < formatList->numFormats; i++)
+       for (i = 0; i < formatList->numFormats; i++)
        {
                format = &(formatList->formats[i]);
-               mapping = &(clipboard->format_mappings[j++]);
+               mapping = &(clipboard->format_mappings[i]);
 
                mapping->remote_format_id = format->formatId;
 
                if (format->formatName)
                {
-                       mapping->name = _strdup(format->formatName);
-                       mapping->local_format_id = RegisterClipboardFormatA((LPCSTR) mapping->name);
+                       int size = MultiByteToWideChar(CP_UTF8, 0, format->formatName, strlen(format->formatName),
+                                                                                  NULL, 0);
+                       mapping->name = calloc(size + 1, sizeof(WCHAR));
+                       if (mapping->name)
+                       {
+                               MultiByteToWideChar(CP_UTF8, 0, format->formatName, strlen(format->formatName),
+                                                                       mapping->name, size);
+                               mapping->local_format_id = RegisterClipboardFormatW((LPWSTR) mapping->name);
+                       }
                }
                else
                {
@@ -1528,7 +1828,8 @@ static UINT wf_cliprdr_server_format_list(CliprdrClientContext* context, CLIPRDR
 
        if (file_transferring(clipboard))
        {
-               PostMessage(clipboard->hwnd, WM_CLIPRDR_MESSAGE, OLE_SETCLIPBOARD, 0);
+               if (PostMessage(clipboard->hwnd, WM_CLIPRDR_MESSAGE, OLE_SETCLIPBOARD, 0))
+                       rc = CHANNEL_RC_OK;
        }
        else
        {
@@ -1538,15 +1839,15 @@ static UINT wf_cliprdr_server_format_list(CliprdrClientContext* context, CLIPRDR
                if (EmptyClipboard())
                {
                        for (i = 0; i < (UINT32) clipboard->map_size; i++)
-                       {
                                SetClipboardData(clipboard->format_mappings[i].local_format_id, NULL);
-                       }
+                       rc = CHANNEL_RC_OK;
                }
 
-               CloseClipboard();
+               if (!CloseClipboard() && GetLastError())
+                       return ERROR_INTERNAL_ERROR;
        }
 
-       return CHANNEL_RC_OK;
+       return rc;
 }
 
 /**
@@ -1554,9 +1855,12 @@ static UINT wf_cliprdr_server_format_list(CliprdrClientContext* context, CLIPRDR
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT wf_cliprdr_server_format_list_response(CliprdrClientContext* context, CLIPRDR_FORMAT_LIST_RESPONSE* formatListResponse)
+static UINT wf_cliprdr_server_format_list_response(CliprdrClientContext* context,
+                                                                                                  CLIPRDR_FORMAT_LIST_RESPONSE* formatListResponse)
 {
-       wfClipboard* clipboard = (wfClipboard*) context->custom;
+       (void)context;
+       (void)formatListResponse;
+
        return CHANNEL_RC_OK;
 }
 
@@ -1565,9 +1869,12 @@ static UINT wf_cliprdr_server_format_list_response(CliprdrClientContext* context
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-UINT wf_cliprdr_server_lock_clipboard_data(CliprdrClientContext* context, CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData)
+static UINT wf_cliprdr_server_lock_clipboard_data(CliprdrClientContext* context,
+                                                                                                 CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData)
 {
-       wfClipboard* clipboard = (wfClipboard*) context->custom;
+       (void)context;
+       (void)lockClipboardData;
+
        return CHANNEL_RC_OK;
 }
 
@@ -1576,40 +1883,86 @@ UINT wf_cliprdr_server_lock_clipboard_data(CliprdrClientContext* context, CLIPRD
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-UINT wf_cliprdr_server_unlock_clipboard_data(CliprdrClientContext* context, CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData)
+static UINT wf_cliprdr_server_unlock_clipboard_data(CliprdrClientContext* context,
+                                                                                                       CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData)
 {
-       wfClipboard* clipboard = (wfClipboard*) context->custom;
+       (void)context;
+       (void)unlockClipboardData;
+
        return CHANNEL_RC_OK;
 }
 
+static BOOL wf_cliprdr_process_filename(wfClipboard* clipboard,
+                                                                               WCHAR* wFileName, size_t str_len)
+{
+       size_t pathLen;
+       size_t offset = str_len;
+
+       if (!clipboard || !wFileName)
+               return FALSE;
+
+       /* find the last '\' in full file name */
+       while(offset > 0)
+       {
+               if (wFileName[offset] == L'\\')
+                       break;
+               else
+                       offset--;
+       }
+
+       pathLen = offset + 1;
+
+       if (!wf_cliprdr_add_to_file_arrays(clipboard, wFileName, pathLen))
+               return FALSE;
+
+       if ((clipboard->fileDescriptor[clipboard->nFiles - 1]->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
+       {
+               /* this is a directory */
+               if (!wf_cliprdr_traverse_directory(clipboard, wFileName, pathLen))
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
 /**
  * Function description
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT wf_cliprdr_server_format_data_request(CliprdrClientContext* context, CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest)
+static UINT wf_cliprdr_server_format_data_request(CliprdrClientContext* context,
+                                                                                                 CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest)
 {
-       int size = 0;
-       char* buff = NULL;
+       UINT rc;
+       size_t size = 0;
+       void* buff = NULL;
        char* globlemem = NULL;
        HANDLE hClipdata = NULL;
        UINT32 requestedFormatId;
        CLIPRDR_FORMAT_DATA_RESPONSE response;
-       wfClipboard* clipboard = (wfClipboard*) context->custom;
+       wfClipboard* clipboard;
+
+       if (!context || !formatDataRequest)
+               return ERROR_INTERNAL_ERROR;
+
+       clipboard = (wfClipboard*) context->custom;
+
+       if (!clipboard)
+               return ERROR_INTERNAL_ERROR;
 
        requestedFormatId = formatDataRequest->requestedFormatId;
 
-       if (requestedFormatId == RegisterClipboardFormatW(_T("FileGroupDescriptorW")))
+       if (requestedFormatId == RegisterClipboardFormat(CFSTR_FILEDESCRIPTORW))
        {
-               int len;
-               int i;
+               size_t len;
+               size_t i;
                WCHAR* wFileName;
-               unsigned int uSize;
                HRESULT result;
                LPDATAOBJECT dataObj;
                FORMATETC format_etc;
                STGMEDIUM stg_medium;
                DROPFILES* dropFiles;
+               FILEGROUPDESCRIPTORW* groupDsc;
 
                result = OleGetClipboard(&dataObj);
 
@@ -1619,126 +1972,77 @@ static UINT wf_cliprdr_server_format_data_request(CliprdrClientContext* context,
                ZeroMemory(&format_etc, sizeof(FORMATETC));
                ZeroMemory(&stg_medium, sizeof(STGMEDIUM));
 
-               /* try to get FileGroupDescriptorW struct from OLE */
-               format_etc.cfFormat = requestedFormatId;
+               /* get DROPFILES struct from OLE */
+               format_etc.cfFormat = CF_HDROP;
                format_etc.tymed = TYMED_HGLOBAL;
                format_etc.dwAspect = 1;
                format_etc.lindex = -1;
-               format_etc.ptd = 0;
 
                result = IDataObject_GetData(dataObj, &format_etc, &stg_medium);
 
-               if (SUCCEEDED(result))
+               if (FAILED(result)) {
+                       DEBUG_CLIPRDR("dataObj->GetData failed.");
+                       goto exit;
+               }
+
+               dropFiles = (DROPFILES*) GlobalLock(stg_medium.hGlobal);
+
+               if (!dropFiles)
                {
-                       DEBUG_CLIPRDR("Got FileGroupDescriptorW.");
-                       globlemem = (char*) GlobalLock(stg_medium.hGlobal);
-                       uSize = GlobalSize(stg_medium.hGlobal);
-                       size = uSize;
-                       buff = (char*) malloc(uSize);
-                       CopyMemory(buff, globlemem, uSize);
                        GlobalUnlock(stg_medium.hGlobal);
 
                        ReleaseStgMedium(&stg_medium);
+                       clipboard->nFiles = 0;
 
-                       clear_file_array(clipboard);
+                       goto exit;
                }
-               else
-               {
-                       /* get DROPFILES struct from OLE */
-                       format_etc.cfFormat = CF_HDROP;
-                       format_etc.tymed = TYMED_HGLOBAL;
-                       format_etc.dwAspect = 1;
-                       format_etc.lindex = -1;
-
-                       result = IDataObject_GetData(dataObj, &format_etc, &stg_medium);
-
-                       if (FAILED(result)) {
-                               DEBUG_CLIPRDR("dataObj->GetData failed.");
-                       }
 
-                       globlemem = (char*) GlobalLock(stg_medium.hGlobal);
+               clear_file_array(clipboard);
 
-                       if (!globlemem)
+               if (dropFiles->fWide)
+               {
+                       /* dropFiles contains file names */
+                       for (wFileName = (WCHAR*)((char*)dropFiles + dropFiles->pFiles);
+                                (len = wcslen(wFileName)) > 0; wFileName += len + 1)
                        {
-                               GlobalUnlock(stg_medium.hGlobal);
-
-                               ReleaseStgMedium(&stg_medium);
-                               clipboard->nFiles = 0;
-
-                               goto exit;
+                               wf_cliprdr_process_filename(clipboard, wFileName, wcslen(wFileName));
                        }
-                       uSize = GlobalSize(stg_medium.hGlobal);
-
-                       dropFiles = (DROPFILES*) malloc(uSize);
-                       memcpy(dropFiles, globlemem, uSize);
-
-                       GlobalUnlock(stg_medium.hGlobal);
-
-                       ReleaseStgMedium(&stg_medium);
-
-                       clear_file_array(clipboard);
+               }
+               else
+               {
+                       char* p;
 
-                       if (dropFiles->fWide)
+                       for (p = (char*)((char*)dropFiles + dropFiles->pFiles);
+                                (len = strlen(p)) > 0; p += len + 1, clipboard->nFiles++)
                        {
-                               WCHAR* p;
-                               int str_len;
-                               int offset;
-                               int pathLen;
+                               int cchWideChar;
+                               WCHAR *wFileName;
 
-                               /* dropFiles contains file names */
-                               for (wFileName = (WCHAR*)((char*)dropFiles + dropFiles->pFiles); (len = wcslen(wFileName)) > 0; wFileName += len + 1)
-                               {
-                                       /* get path name */
-                                       str_len = wcslen(wFileName);
-                                       offset = str_len;
-                                       /* find the last '\' in full file name */
-                                       for (p = wFileName + offset; *p != L'\\'; p--)
-                                       {
-                                               ;
-                                       }
-                                       p += 1;
-                                       pathLen = wcslen(wFileName) - wcslen(p);
-
-                                       wf_cliprdr_add_to_file_arrays(clipboard, wFileName, pathLen);
+                               cchWideChar = MultiByteToWideChar(CP_ACP, MB_COMPOSITE, p, len, NULL, 0);
+                               wFileName = (LPWSTR) calloc(cchWideChar, sizeof(WCHAR));
+                               MultiByteToWideChar(CP_ACP, MB_COMPOSITE, p, len, wFileName, cchWideChar);
 
-                                       if ((clipboard->fileDescriptor[clipboard->nFiles - 1]->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
-                                       {
-                                               /* this is a directory */
-                                               wf_cliprdr_traverse_directory(clipboard, wFileName, pathLen);
-                                       }
-                               }
+                               wf_cliprdr_process_filename(clipboard, wFileName, cchWideChar);
                        }
-                       else
-                       {
-                               char* p;
+               }
 
-                               for (p = (char*)((char*)dropFiles + dropFiles->pFiles); (len = strlen(p)) > 0; p += len + 1, clipboard->nFiles++)
-                               {
-                                       int cchWideChar;
+               GlobalUnlock(stg_medium.hGlobal);
 
-                                       cchWideChar = MultiByteToWideChar(CP_ACP, MB_COMPOSITE, p, len, NULL, 0);
-                                       clipboard->file_names[clipboard->nFiles] = (LPWSTR) malloc(cchWideChar * 2);
-                                       MultiByteToWideChar(CP_ACP, MB_COMPOSITE, p, len, clipboard->file_names[clipboard->nFiles], cchWideChar);
-
-                                       map_ensure_capacity(clipboard);
-                               }
-                       }
+               ReleaseStgMedium(&stg_medium);
 
 exit:
-                       size = 4 + clipboard->nFiles * sizeof(FILEDESCRIPTORW);
-                       buff = (char*) malloc(size);
-
-                       *((UINT32*) buff) = clipboard->nFiles;
-
+               size = 4 + clipboard->nFiles * sizeof(FILEDESCRIPTORW);
+               groupDsc = (FILEGROUPDESCRIPTORW*) malloc(size);
+               if (groupDsc)
+               {
+                       groupDsc->cItems = clipboard->nFiles;
                        for (i = 0; i < clipboard->nFiles; i++)
                        {
                                if (clipboard->fileDescriptor[i])
-                               {
-                                       memcpy(buff + 4 + i * sizeof(FILEDESCRIPTORW), clipboard->fileDescriptor[i], sizeof(FILEDESCRIPTORW));
-                               }
+                                       groupDsc->fgd[i] = *clipboard->fileDescriptor[i];
                        }
+                       buff = groupDsc;
                }
-
                IDataObject_Release(dataObj);
        }
        else
@@ -1757,7 +2061,7 @@ exit:
                globlemem = (char*) GlobalLock(hClipdata);
                size = (int) GlobalSize(hClipdata);
 
-               buff = (char*) malloc(size);
+               buff = malloc(size);
                CopyMemory(buff, globlemem, size);
 
                GlobalUnlock(hClipdata);
@@ -1771,11 +2075,11 @@ exit:
        response.dataLen = size;
        response.requestedFormatData = (BYTE*) buff;
 
-       clipboard->context->ClientFormatDataResponse(clipboard->context, &response);
+       rc = clipboard->context->ClientFormatDataResponse(clipboard->context, &response);
 
        free(buff);
 
-       return CHANNEL_RC_OK;
+       return rc;
 }
 
 /**
@@ -1783,19 +2087,42 @@ exit:
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-static UINT wf_cliprdr_server_format_data_response(CliprdrClientContext* context, CLIPRDR_FORMAT_DATA_RESPONSE* formatDataResponse)
+static UINT wf_cliprdr_server_format_data_response(CliprdrClientContext* context,
+                                                                                                  CLIPRDR_FORMAT_DATA_RESPONSE* formatDataResponse)
 {
        BYTE* data;
        HANDLE hMem;
-       wfClipboard* clipboard = (wfClipboard*) context->custom;
+       wfClipboard* clipboard;
+
+       if (!context || !formatDataResponse)
+               return ERROR_INTERNAL_ERROR;
+
+       clipboard = (wfClipboard*) context->custom;
+
+       if (!clipboard)
+               return ERROR_INTERNAL_ERROR;
+
+       hMem = GlobalAlloc(GMEM_MOVEABLE, formatDataResponse->dataLen);
+       if (!hMem)
+               return ERROR_INTERNAL_ERROR;
 
-       hMem = GlobalAlloc(GMEM_FIXED, formatDataResponse->dataLen);
        data = (BYTE*) GlobalLock(hMem);
+       if (!data)
+       {
+               GlobalFree(hMem);
+               return ERROR_INTERNAL_ERROR;
+       }
+
        CopyMemory(data, formatDataResponse->requestedFormatData, formatDataResponse->dataLen);
-       GlobalUnlock(hMem);
+       if (!GlobalUnlock(hMem) && GetLastError())
+       {
+               GlobalFree(hMem);
+               return ERROR_INTERNAL_ERROR;
+       }
 
        clipboard->hmem = hMem;
-       SetEvent(clipboard->response_data_event);
+       if (!SetEvent(clipboard->response_data_event))
+               return ERROR_INTERNAL_ERROR;
 
        return CHANNEL_RC_OK;
 }
@@ -1805,25 +2132,35 @@ static UINT wf_cliprdr_server_format_data_response(CliprdrClientContext* context
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-UINT wf_cliprdr_server_file_contents_request(CliprdrClientContext* context, CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
+static UINT wf_cliprdr_server_file_contents_request(CliprdrClientContext* context,
+                                                                                                       CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
 {
-       UINT32 uSize = 0;
+       DWORD 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;
+       wfClipboard* clipboard;
+       UINT rc = ERROR_INTERNAL_ERROR;
+       UINT sRc;
+
+       if (!context || !fileContentsRequest)
+               return ERROR_INTERNAL_ERROR;
+
+       clipboard = (wfClipboard*) context->custom;
+
+       if (!clipboard)
+               return ERROR_INTERNAL_ERROR;
 
        if (fileContentsRequest->dwFlags == FILECONTENTS_SIZE)
                fileContentsRequest->cbRequested = sizeof(UINT64);
 
        pData = (BYTE*) calloc(1, fileContentsRequest->cbRequested);
-       
+
        if (!pData)
                goto error;
 
@@ -1834,11 +2171,11 @@ UINT wf_cliprdr_server_file_contents_request(CliprdrClientContext* context, CLIP
                WLog_ERR(TAG,  "filecontents: get ole clipboard failed.");
                goto error;
        }
-       
+
        ZeroMemory(&vFormatEtc, sizeof(FORMATETC));
        ZeroMemory(&vStgMedium, sizeof(STGMEDIUM));
 
-       vFormatEtc.cfFormat = clipboard->ID_FILECONTENTS;
+       vFormatEtc.cfFormat = RegisterClipboardFormat(CFSTR_FILECONTENTS);
        vFormatEtc.tymed = TYMED_ISTREAM;
        vFormatEtc.dwAspect = 1;
        vFormatEtc.lindex = fileContentsRequest->listIndex;
@@ -1869,7 +2206,7 @@ UINT wf_cliprdr_server_file_contents_request(CliprdrClientContext* context, CLIP
 
                                if (hRet == S_OK)
                                {
-                                       if (vFormatEtc2.cfFormat == clipboard->ID_FILECONTENTS)
+                                       if (vFormatEtc2.cfFormat == RegisterClipboardFormat(CFSTR_FILECONTENTS))
                                        {
                                                hRet = IDataObject_GetData(pDataObj, &vFormatEtc, &vStgMedium);
 
@@ -1915,10 +2252,7 @@ UINT wf_cliprdr_server_file_contents_request(CliprdrClientContext* context, CLIP
                        hRet = IStream_Seek(pStreamStc, dlibMove, STREAM_SEEK_SET, &dlibNewPosition);
 
                        if (SUCCEEDED(hRet))
-                       {
                                hRet = IStream_Read(pStreamStc, pData, fileContentsRequest->cbRequested, (PULONG) &uSize);
-                       }
-
                }
        }
        else
@@ -1934,8 +2268,8 @@ UINT wf_cliprdr_server_file_contents_request(CliprdrClientContext* context, CLIP
                        BOOL bRet;
 
                        bRet = wf_cliprdr_get_file_contents(clipboard->file_names[fileContentsRequest->listIndex], pData,
-                               fileContentsRequest->nPositionLow, fileContentsRequest->nPositionHigh,
-                               fileContentsRequest->cbRequested, &uSize);
+                                       fileContentsRequest->nPositionLow, fileContentsRequest->nPositionHigh,
+                                       fileContentsRequest->cbRequested, &uSize);
 
                        if (bRet == FALSE)
                        {
@@ -1946,7 +2280,11 @@ UINT wf_cliprdr_server_file_contents_request(CliprdrClientContext* context, CLIP
                }
        }
 
-       IDataObject_Release(pDataObj);
+       rc = CHANNEL_RC_OK;
+
+error:
+       if (pDataObj)
+               IDataObject_Release(pDataObj);
 
        if (uSize == 0)
        {
@@ -1954,29 +2292,15 @@ UINT wf_cliprdr_server_file_contents_request(CliprdrClientContext* context, CLIP
                pData = NULL;
        }
 
-       cliprdr_send_response_filecontents(clipboard, fileContentsRequest->streamId, uSize, pData);
+       sRc = cliprdr_send_response_filecontents(clipboard, fileContentsRequest->streamId,
+                                                                                        uSize, pData);
 
        free(pData);
 
-       return CHANNEL_RC_OK;
-
-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);
+       if (sRc != CHANNEL_RC_OK)
+               return sRc;
 
-       return ERROR_INTERNAL_ERROR;
+       return rc;
 }
 
 /**
@@ -1984,33 +2308,52 @@ error:
  *
  * @return 0 on success, otherwise a Win32 error code
  */
-UINT wf_cliprdr_server_file_contents_response(CliprdrClientContext* context, CLIPRDR_FILE_CONTENTS_RESPONSE* fileContentsResponse)
+static UINT wf_cliprdr_server_file_contents_response(CliprdrClientContext* context,
+                                                                                                        const CLIPRDR_FILE_CONTENTS_RESPONSE* fileContentsResponse)
 {
-       wfClipboard* clipboard = (wfClipboard*) context->custom;
+       wfClipboard* clipboard;
+
+       if (!context || !fileContentsResponse)
+               return ERROR_INTERNAL_ERROR;
+
+       clipboard = (wfClipboard*) context->custom;
+
+       if (!clipboard)
+               return ERROR_INTERNAL_ERROR;
 
        clipboard->req_fsize = fileContentsResponse->cbRequested;
        clipboard->req_fdata = (char*) malloc(fileContentsResponse->cbRequested);
+       if (!clipboard->req_fdata)
+               return ERROR_INTERNAL_ERROR;
+
        CopyMemory(clipboard->req_fdata, fileContentsResponse->requestedData, fileContentsResponse->cbRequested);
 
-       SetEvent(clipboard->req_fevent);
+       if (!SetEvent(clipboard->req_fevent))
+       {
+               free (clipboard->req_fdata);
+               return ERROR_INTERNAL_ERROR;
+       }
 
        return CHANNEL_RC_OK;
 }
 
-void wf_cliprdr_init(wfContext* wfc, CliprdrClientContext* cliprdr)
+BOOL wf_cliprdr_init(wfContext* wfc, CliprdrClientContext* cliprdr)
 {
        wfClipboard* clipboard;
        rdpContext* context = (rdpContext*) wfc;
 
+       if (!context || !cliprdr)
+               return FALSE;
+
        wfc->clipboard = (wfClipboard*) calloc(1, sizeof(wfClipboard));
 
        if (!wfc->clipboard)
-               return;
+               return FALSE;
 
        clipboard = wfc->clipboard;
        clipboard->wfc = wfc;
        clipboard->context = cliprdr;
-               
+
        clipboard->channels = context->channels;
        clipboard->sync = FALSE;
 
@@ -2018,27 +2361,16 @@ void wf_cliprdr_init(wfContext* wfc, CliprdrClientContext* cliprdr)
        clipboard->map_size = 0;
 
        if (!(clipboard->format_mappings = (formatMapping*) calloc(1, sizeof(formatMapping) * clipboard->map_capacity)))
-               goto fail_format_mappings;
-
-       clipboard->file_array_size = 32;
-       if (!(clipboard->file_names = (WCHAR**) calloc(1, clipboard->file_array_size * sizeof(WCHAR*))))
-               goto fail_file_names;
-
-       if (!(clipboard->fileDescriptor = (FILEDESCRIPTORW**) calloc(1, clipboard->file_array_size * sizeof(FILEDESCRIPTORW*))))
-               goto fail_file_descriptor;
+               goto error;
 
        if (!(clipboard->response_data_event = CreateEvent(NULL, TRUE, FALSE, _T("response_data_event"))))
-               goto fail_data_event;
+               goto error;
 
        if (!(clipboard->req_fevent = CreateEvent(NULL, TRUE, FALSE, _T("request_filecontents_event"))))
-               goto fail_filecontents_event;
-
-       clipboard->ID_FILEDESCRIPTORW = RegisterClipboardFormatW(CFSTR_FILEDESCRIPTORW);
-       clipboard->ID_FILECONTENTS = RegisterClipboardFormatW(CFSTR_FILECONTENTS);
-       clipboard->ID_PREFERREDDROPEFFECT = RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECT);
+               goto error;
 
        if (!(clipboard->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) cliprdr_thread_func, clipboard, 0, NULL)))
-               goto fail_clipboard_thread;
+               goto error;
 
        cliprdr->MonitorReady = wf_cliprdr_monitor_ready;
        cliprdr->ServerCapabilities = wf_cliprdr_server_capabilities;
@@ -2052,38 +2384,29 @@ void wf_cliprdr_init(wfContext* wfc, CliprdrClientContext* cliprdr)
        cliprdr->ServerFileContentsResponse = wf_cliprdr_server_file_contents_response;
        cliprdr->custom = (void*) wfc->clipboard;
 
-       return;
-
-fail_clipboard_thread:
-       CloseHandle(clipboard->req_fevent);
-       clipboard->req_fevent = NULL;
-fail_filecontents_event:
-       CloseHandle(clipboard->response_data_event);
-       clipboard->response_data_event = NULL;
-fail_data_event:
-       free(clipboard->fileDescriptor);
-       clipboard->fileDescriptor = NULL;
-fail_file_descriptor:
-       free(clipboard->file_names);
-       clipboard->file_names = NULL;
-fail_file_names:
-       free(clipboard->format_mappings);
-       clipboard->format_mappings = NULL;
-fail_format_mappings:
-       free(wfc->clipboard);
-       wfc->clipboard = NULL;
+       return TRUE;
 
-       return;
+error:
+       wf_cliprdr_uninit(wfc, cliprdr);
+       return FALSE;
 }
 
-void wf_cliprdr_uninit(wfContext* wfc, CliprdrClientContext* cliprdr)
+BOOL wf_cliprdr_uninit(wfContext* wfc, CliprdrClientContext* cliprdr)
 {
-       wfClipboard* clipboard = wfc->clipboard;
+       wfClipboard* clipboard;
+
+       if (!wfc || !cliprdr)
+               return FALSE;
+
+       clipboard = wfc->clipboard;
+
+       if (!clipboard)
+               return FALSE;
 
        cliprdr->custom = NULL;
 
        if (!clipboard)
-               return;
+               return FALSE;
 
        if (clipboard->hwnd)
                PostMessage(clipboard->hwnd, WM_QUIT, 0, 0);
@@ -2104,9 +2427,9 @@ void wf_cliprdr_uninit(wfContext* wfc, CliprdrClientContext* cliprdr)
        clear_file_array(clipboard);
        clear_format_map(clipboard);
 
-       free(clipboard->file_names);
-       free(clipboard->fileDescriptor);
        free(clipboard->format_mappings);
 
        free(clipboard);
+
+       return TRUE;
 }
index 4c1944e..69cd052 100644 (file)
 #ifndef __WF_CLIPRDR_H
 #define __WF_CLIPRDR_H
 
-#define CINTERFACE
-#define COBJMACROS
-
-#include <Ole2.h>
-#include <ShlObj.h>
-
-typedef struct wf_clipboard wfClipboard;
-
 #include "wf_client.h"
 
-#include <freerdp/log.h>
-
-#ifdef WITH_DEBUG_CLIPRDR
-#define DEBUG_CLIPRDR(fmt, ...) WLog_DBG(TAG, fmt, ## __VA_ARGS__)
-#else
-#define DEBUG_CLIPRDR(fmt, ...) do { } while (0)
-#endif
-
-struct _CliprdrStream
-{
-       IStream iStream;
-
-       LONG m_lRefCount;
-       LONG m_lIndex;
-       ULARGE_INTEGER m_lSize;
-       ULARGE_INTEGER m_lOffset;
-       void* m_pData;
-};
-typedef struct _CliprdrStream CliprdrStream;
-
-CliprdrStream* CliprdrStream_New(LONG index, void* pData);
-void CliprdrStream_Delete(CliprdrStream* instance);
-
-struct _CliprdrDataObject
-{
-       IDataObject iDataObject;
-
-       LONG m_lRefCount;
-       FORMATETC* m_pFormatEtc;
-       STGMEDIUM* m_pStgMedium;
-       LONG m_nNumFormats;
-       LONG m_nStreams;
-       IStream** m_pStream;
-       void* m_pData;
-};
-typedef struct _CliprdrDataObject CliprdrDataObject;
-
-CliprdrDataObject* CliprdrDataObject_New(FORMATETC* fmtetc, STGMEDIUM* stgmed, int count, void* data);
-void CliprdrDataObject_Delete(CliprdrDataObject* instance);
-
-struct _CliprdrEnumFORMATETC
-{
-       IEnumFORMATETC iEnumFORMATETC;
-
-       LONG m_lRefCount;
-       LONG m_nIndex;
-       LONG m_nNumFormats;
-       FORMATETC* m_pFormatEtc;
-};
-typedef struct _CliprdrEnumFORMATETC CliprdrEnumFORMATETC;
-
-CliprdrEnumFORMATETC* CliprdrEnumFORMATETC_New(int nFormats, FORMATETC* pFormatEtc);
-void CliprdrEnumFORMATETC_Delete(CliprdrEnumFORMATETC* This);
-
-struct format_mapping
-{
-       UINT32 remote_format_id;
-       UINT32 local_format_id;
-       void* name; /* Unicode or ASCII characters with NULL terminator */
-};
-typedef struct format_mapping formatMapping;
-
-struct wf_clipboard
-{
-       wfContext* wfc;
-       rdpChannels* channels;
-       CliprdrClientContext* context;
-
-       BOOL sync;
-       UINT32 capabilities;
-
-       int map_size;
-       int map_capacity;
-       formatMapping* format_mappings;
-
-       UINT32 requestedFormatId;
-
-       HWND hwnd;
-       HANDLE hmem;
-       HANDLE thread;
-       HANDLE response_data_event;
-
-       /* file clipping */
-       CLIPFORMAT ID_FILEDESCRIPTORW;
-       CLIPFORMAT ID_FILECONTENTS;
-       CLIPFORMAT ID_PREFERREDDROPEFFECT;
-
-       LPDATAOBJECT data_obj;
-       ULONG req_fsize;
-       char* req_fdata;
-       HANDLE req_fevent;
-
-       int nFiles;
-       int file_array_size;
-       WCHAR** file_names;
-       FILEDESCRIPTORW** fileDescriptor;
-};
-
-void wf_cliprdr_init(wfContext* wfc, CliprdrClientContext* cliprdr);
-void wf_cliprdr_uninit(wfContext* wfc, CliprdrClientContext* cliprdr);
-
-int cliprdr_send_data_request(wfClipboard* clipboard, UINT32 format);
-int cliprdr_send_lock(wfClipboard* clipboard);
-int cliprdr_send_unlock(wfClipboard* clipboard);
-int cliprdr_send_request_filecontents(wfClipboard* clipboard, void* streamid,
-               int index, int flag, DWORD positionhigh, DWORD positionlow, ULONG request);
+BOOL wf_cliprdr_init(wfContext* wfc, CliprdrClientContext* cliprdr);
+BOOL wf_cliprdr_uninit(wfContext* wfc, CliprdrClientContext* cliprdr);
 
 #endif /* __WF_CLIPRDR_H */