@@ -79,7 +79,7 @@ static void *clipboard_process_bmp(struct rdp_clipboard_data_source *, BOOL);
7979static void * clipboard_process_html (struct rdp_clipboard_data_source * , BOOL );
8080
8181struct rdp_clipboard_supported_format clipboard_supported_formats [] = {
82- { 0 , CF_TEXT , NULL , "text/plain;charset=utf-8" , clipboard_process_text },
82+ { 0 , CF_UNICODETEXT , NULL , "text/plain;charset=utf-8" , clipboard_process_text },
8383{ 1 , CF_DIB , NULL , "image/bmp" , clipboard_process_bmp },
8484{ 2 , CF_PRIVATE_RTF , "Rich Text Format" , "text/rtf" , clipboard_process_text }, // same as text
8585{ 3 , CF_PRIVATE_HTML , "HTML Format" , "text/html" , clipboard_process_html },
@@ -152,24 +152,74 @@ clipboard_process_text(struct rdp_clipboard_data_source *source, BOOL is_send)
152152freerdp_peer * client = (freerdp_peer * )source -> context ;
153153RdpPeerContext * peerCtx = (RdpPeerContext * )client -> context ;
154154struct rdp_backend * b = peerCtx -> rdpBackend ;
155+ struct wl_array data_contents ;
156+
157+ wl_array_init (& data_contents );
155158
156159if (!source -> is_data_processed ) {
157160if (is_send ) {
158- /* Linux to Windows */
159- assert (source -> data_contents .size <= source -> data_contents .alloc );
160- assert (((char * )source -> data_contents .data )[source -> data_contents .size ] == '\0' );
161+ /* Linux to Windows (convert utf-8 to UNICODE) */
161162/* Include terminating NULL in size */
163+ assert ((source -> data_contents .size + 1 ) <= source -> data_contents .alloc );
164+ assert (((char * )source -> data_contents .data )[source -> data_contents .size ] == '\0' );
162165source -> data_contents .size ++ ;
166+
167+ /* obtain size in UNICODE */
168+ size_t data_size = MultiByteToWideChar (CP_UTF8 , 0 ,
169+ (char * )source -> data_contents .data ,
170+ source -> data_contents .size ,
171+ NULL , 0 );
172+ if (data_size < 1 )
173+ goto error_return ;
174+
175+ data_size *= 2 ; // convert to size in bytes.
176+ if (!wl_array_add (& data_contents , data_size ))
177+ goto error_return ;
178+
179+ /* convert to UNICODE */
180+ size_t data_size_in_char = MultiByteToWideChar (CP_UTF8 , 0 ,
181+ (char * )source -> data_contents .data ,
182+ source -> data_contents .size ,
183+ (LPWSTR )data_contents .data ,
184+ data_size );
185+ assert (data_contents .size == (data_size_in_char * 2 ));
163186} else {
164- /* Windows to Linux */
165- char * data = (char * )source -> data_contents .data ;
166- size_t data_size = source -> data_contents .size ;
187+ /* Windows to Linux (UNICODE to utf-8) */
188+ LPWSTR data = (LPWSTR )source -> data_contents .data ;
189+ size_t data_size_in_char = source -> data_contents .size / 2 ;
167190
168191/* Windows's data has trailing chars, which Linux doesn't expect. */
169- while (data_size && ((data [data_size - 1 ] == '\0' ) || (data [data_size - 1 ] == '\n' )))
170- data_size -= 1 ;
171- source -> data_contents .size = data_size ;
192+ while (data_size_in_char &&
193+ ((data [data_size_in_char - 1 ] == L'\0' ) || (data [data_size_in_char - 1 ] == L'\n' )))
194+ data_size_in_char -= 1 ;
195+ if (!data_size_in_char )
196+ goto error_return ;
197+
198+ /* obtain size in utf-8 */
199+ size_t data_size = WideCharToMultiByte (CP_UTF8 , 0 ,
200+ (LPCWSTR )source -> data_contents .data ,
201+ data_size_in_char ,
202+ NULL , 0 ,
203+ NULL , NULL );
204+ if (data_size < 1 )
205+ goto error_return ;
206+
207+ if (!wl_array_add (& data_contents , data_size ))
208+ goto error_return ;
209+
210+ /* convert to utf-8 */
211+ data_size = WideCharToMultiByte (CP_UTF8 , 0 ,
212+ (LPCWSTR )source -> data_contents .data ,
213+ data_size_in_char ,
214+ (char * )data_contents .data ,
215+ data_size ,
216+ NULL , NULL );
217+ assert (data_contents .size == data_size );
172218}
219+
220+ /* swap the data_contents with new one */
221+ wl_array_release (& source -> data_contents );
222+ source -> data_contents = data_contents ;
173223source -> is_data_processed = TRUE;
174224}
175225
@@ -178,6 +228,21 @@ clipboard_process_text(struct rdp_clipboard_data_source *source, BOOL is_send)
178228is_send ? "send" : "receive" , (UINT32 )source -> data_contents .size );
179229
180230return source -> data_contents .data ;
231+
232+ error_return :
233+
234+ source -> state = RDP_CLIPBOARD_SOURCE_FAILED ;
235+ rdp_debug_clipboard_error (b , "RDP %s FAILED (%p:%s): %s (%d bytes)\n" ,
236+ __func__ , source , clipboard_data_source_state_to_string (source -> state ),
237+ is_send ? "send" : "receive" , (UINT32 )source -> data_contents .size );
238+ //rdp_debug_clipboard_verbose(b, "RDP clipboard_process_html FAILED (%p): %s \n\"%s\"\n (%d bytes)\n",
239+ // source, is_send ? "send" : "receive",
240+ // (char *)source->data_contents.data,
241+ // (UINT32)source->data_contents.size);
242+
243+ wl_array_release (& data_contents );
244+
245+ return NULL ;
181246}
182247
183248/* based off sample code at https://docs.microsoft.com/en-us/troubleshoot/cpp/add-html-code-clipboard
0 commit comments