chansrv: work on clipboard file copy
This commit is contained in:
parent
900d66dc6e
commit
e2ef19098b
@ -33,6 +33,7 @@
|
||||
#include "os_calls.h"
|
||||
#include "chansrv.h"
|
||||
#include "chansrv_fuse.h"
|
||||
#include "clipboard_file.h"
|
||||
|
||||
#define LLOG_LEVEL 1
|
||||
#define LLOGLN(_level, _args) \
|
||||
@ -56,6 +57,9 @@ static time_t g_time = 0;
|
||||
static int g_uid = 0;
|
||||
static int g_gid = 0;
|
||||
|
||||
/* used for file data request sent to client */
|
||||
static fuse_req_t g_req = 0;
|
||||
|
||||
struct dirbuf
|
||||
{
|
||||
char *p;
|
||||
@ -66,6 +70,7 @@ struct dirbuf
|
||||
struct xfuse_file_info
|
||||
{
|
||||
int ino;
|
||||
int lindex;
|
||||
char pathname[256];
|
||||
char filename[256];
|
||||
int flags;
|
||||
@ -252,8 +257,8 @@ dirbuf_add(fuse_req_t req, struct dirbuf *b, const char *name, fuse_ino_t ino)
|
||||
}
|
||||
g_memset(&stbuf, 0, sizeof(stbuf));
|
||||
stbuf.st_ino = ino;
|
||||
fuse_add_direntry(req, b->p + oldsize, b->size - oldsize, name, &stbuf,
|
||||
b->size);
|
||||
fuse_add_direntry(req, b->p + oldsize, b->size - oldsize, name,
|
||||
&stbuf, b->size);
|
||||
}
|
||||
|
||||
#define lmin(x, y) ((x) < (y) ? (x) : (y))
|
||||
@ -331,11 +336,26 @@ xrdp_ll_read(fuse_req_t req, fuse_ino_t ino, size_t size,
|
||||
off_t off, struct fuse_file_info *fi)
|
||||
{
|
||||
char *data;
|
||||
int stream_id;
|
||||
struct xfuse_file_info *ffi;
|
||||
|
||||
LLOGLN(0, ("xrdp_ll_read: %d %d %d", (int)ino, (int)off, (int)size));
|
||||
|
||||
ffi = fuse_find_file_info_by_ino(g_fuse_files, ino);
|
||||
if (ffi != 0)
|
||||
{
|
||||
stream_id = 0;
|
||||
clipboard_request_file_data(stream_id, ffi->lindex, off, size);
|
||||
g_req = req;
|
||||
/* reply later */
|
||||
return;
|
||||
}
|
||||
|
||||
LLOGLN(0, ("xrdp_ll_read: fuse_find_file_info_by_ino failed"));
|
||||
data = (char *)g_malloc(size, 1);
|
||||
reply_buf_limited(req, data, size, off, size);
|
||||
fuse_reply_buf(req, data, size);
|
||||
g_free(data);
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -409,7 +429,7 @@ fuse_clear_clip_dir(void)
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
int APP_CC
|
||||
fuse_add_clip_dir_item(char *filename, int flags, int size)
|
||||
fuse_add_clip_dir_item(char *filename, int flags, int size, int lindex)
|
||||
{
|
||||
struct xfuse_file_info *ffi;
|
||||
struct xfuse_file_info *ffi1;
|
||||
@ -422,6 +442,7 @@ fuse_add_clip_dir_item(char *filename, int flags, int size)
|
||||
g_malloc(sizeof(struct xfuse_file_info), 1);
|
||||
ffi1->flags = flags;
|
||||
ffi1->ino = g_ino++;
|
||||
ffi1->lindex = lindex;
|
||||
ffi1->size = size;
|
||||
g_strncpy(ffi1->filename, filename, 255);
|
||||
g_fuse_files = ffi1;
|
||||
@ -435,6 +456,7 @@ fuse_add_clip_dir_item(char *filename, int flags, int size)
|
||||
g_malloc(sizeof(struct xfuse_file_info), 1);
|
||||
ffi1->flags = flags;
|
||||
ffi1->ino = g_ino++;
|
||||
ffi1->lindex = lindex;
|
||||
ffi1->size = size;
|
||||
g_strncpy(ffi1->filename, filename, 255);
|
||||
ffi->next = ffi1;
|
||||
@ -549,6 +571,23 @@ fuse_deinit(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int APP_CC
|
||||
fuse_file_contents_size(int stream_id, int file_size)
|
||||
{
|
||||
LLOGLN(0, ("fuse_file_contents_size: file_size %d", file_size));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int APP_CC
|
||||
fuse_file_contents_range(int stream_id, char *data, int data_bytes)
|
||||
{
|
||||
LLOGLN(0, ("fuse_file_contents_range: data_bytes %d", data_bytes));
|
||||
fuse_reply_buf(g_req, data, data_bytes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include "arch.h"
|
||||
@ -590,7 +629,21 @@ fuse_clear_clip_dir(void)
|
||||
|
||||
/*****************************************************************************/
|
||||
int APP_CC
|
||||
fuse_add_clip_dir_item(char *filename, int flags, int size)
|
||||
fuse_add_clip_dir_item(char *filename, int flags, int size, int lindex)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int APP_CC
|
||||
fuse_file_contents_size(int stream_id, int file_size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int APP_CC
|
||||
fuse_file_contents_range(int stream_id, char *data, int data_bytes)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
int APP_CC
|
||||
fuse_clear_clip_dir(void);
|
||||
int APP_CC
|
||||
fuse_add_clip_dir_item(char *filename, int flags, int size);
|
||||
fuse_add_clip_dir_item(char *filename, int flags, int size, int lindex);
|
||||
int APP_CC
|
||||
fuse_get_wait_objs(tbus *objs, int *count, int *timeout);
|
||||
int APP_CC
|
||||
@ -15,4 +15,9 @@ fuse_init(void);
|
||||
int APP_CC
|
||||
fuse_deinit(void);
|
||||
|
||||
int APP_CC
|
||||
fuse_file_contents_size(int stream_id, int file_size);
|
||||
int APP_CC
|
||||
fuse_file_contents_range(int stream_id, char *data, int data_bytes);
|
||||
|
||||
#endif
|
||||
|
@ -42,6 +42,76 @@ TIMESTAMP
|
||||
wininfo - show window info
|
||||
xlsatoms - dump atoms
|
||||
|
||||
dolphin 1.4 KDE 4.4.5 copy one file
|
||||
text/uri-list
|
||||
text/x-moz-url
|
||||
text/plain
|
||||
UTF8_STRING
|
||||
STRING
|
||||
TEXT
|
||||
COMPOUND_TEXT
|
||||
application/x-qiconlist
|
||||
TARGETS
|
||||
MULTIPLE
|
||||
TIMESTAMP
|
||||
SAVE_TARGETS
|
||||
|
||||
kolourpaint 4.4.5 KDE 4.4.5 copy image area
|
||||
application/x-kolourpaint-selection-400
|
||||
application/x-qt-image
|
||||
image/png
|
||||
image/bw
|
||||
image/eps
|
||||
image/epsf
|
||||
image/epsi
|
||||
image/pcx
|
||||
image/rgb
|
||||
image/rgba
|
||||
image/sgi
|
||||
image/tga
|
||||
image/bmp
|
||||
image/ico
|
||||
image/jp2
|
||||
image/jpeg
|
||||
image/jpg
|
||||
image/ppm
|
||||
PIXMAP
|
||||
image/tif
|
||||
image/tiff
|
||||
image/xbm
|
||||
image/xpm
|
||||
image/xv
|
||||
TARGETS
|
||||
MULTIPLE
|
||||
TIMESTAMP
|
||||
SAVE_TARGETS
|
||||
|
||||
kate 3.4.5 KDE 4.4.5 copy text
|
||||
text/plain
|
||||
UTF8_STRING
|
||||
STRING
|
||||
TEXT
|
||||
COMPOUND_TEXT
|
||||
TARGETS
|
||||
MULTIPLE
|
||||
TIMESTAMP
|
||||
SAVE_TARGETS
|
||||
|
||||
gimp 2.6.10 copy image area
|
||||
TIMESTAMP
|
||||
TARGETS
|
||||
MULTIPLE
|
||||
SAVE_TARGETS
|
||||
image/png
|
||||
image/bmp
|
||||
image/x-bmp
|
||||
image/x-MS-bmp
|
||||
image/tiff
|
||||
image/x-icon
|
||||
image/x-ico
|
||||
image/x-win-bitmap
|
||||
image/jpeg
|
||||
|
||||
*/
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
@ -1280,6 +1350,10 @@ clipboard_data_in(struct stream *s, int chan_id, int chan_flags, int length,
|
||||
rv = clipboard_process_file_request(ls, clip_msg_status,
|
||||
clip_msg_len);
|
||||
break;
|
||||
case CB_FILECONTENTS_RESPONSE: /* 9 */
|
||||
rv = clipboard_process_file_response(ls, clip_msg_status,
|
||||
clip_msg_len);
|
||||
break;
|
||||
default:
|
||||
LLOGLN(0, ("clipboard_data_in: unknown clip_msg_id %d", clip_msg_id));
|
||||
LOGM((LOG_LEVEL_ERROR, "clipboard_data_in: unknown clip_msg_id %d",
|
||||
|
@ -77,6 +77,7 @@ struct clip_file_desc /* CLIPRDR_FILEDESCRIPTOR */
|
||||
|
||||
static struct cb_file_info g_files[64];
|
||||
static int g_num_files = 0;
|
||||
static int g_file_request_sent_type = 0;
|
||||
|
||||
/* number of seconds from 1 Jan. 1601 00:00 to 1 Jan 1970 00:00 UTC */
|
||||
#define CB_EPOCH_DIFF 11644473600LL
|
||||
@ -336,7 +337,7 @@ clipboard_send_file_size(int streamId, int lindex)
|
||||
/*****************************************************************************/
|
||||
/* ask the client to send the file size */
|
||||
int APP_CC
|
||||
clipboard_request_file_size(int streamId, int lindex)
|
||||
clipboard_request_file_size(int stream_id, int lindex)
|
||||
{
|
||||
struct stream *s;
|
||||
int size;
|
||||
@ -345,12 +346,17 @@ clipboard_request_file_size(int streamId, int lindex)
|
||||
|
||||
file_size = g_files[lindex].size;
|
||||
LLOGLN(10, ("clipboard_request_file_size:"));
|
||||
if (g_file_request_sent_type != 0)
|
||||
{
|
||||
LLOGLN(0, ("clipboard_request_file_size: warning, still waiting "
|
||||
"for CB_FILECONTENTS_RESPONSE"));
|
||||
}
|
||||
make_stream(s);
|
||||
init_stream(s, 8192);
|
||||
out_uint16_le(s, CB_FILECONTENTS_REQUEST); /* 8 */
|
||||
out_uint16_le(s, 0);
|
||||
out_uint32_le(s, 28);
|
||||
out_uint32_le(s, streamId);
|
||||
out_uint32_le(s, stream_id);
|
||||
out_uint32_le(s, lindex);
|
||||
out_uint32_le(s, CB_FILECONTENTS_SIZE);
|
||||
out_uint32_le(s, 0); /* nPositionLow */
|
||||
@ -362,6 +368,7 @@ clipboard_request_file_size(int streamId, int lindex)
|
||||
size = (int)(s->end - s->data);
|
||||
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
|
||||
free_stream(s);
|
||||
g_file_request_sent_type = CB_FILECONTENTS_SIZE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -417,6 +424,46 @@ clipboard_send_file_data(int streamId, int lindex,
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* ask the client to send the file size */
|
||||
int APP_CC
|
||||
clipboard_request_file_data(int stream_id, int lindex, int offset,
|
||||
int request_bytes)
|
||||
{
|
||||
struct stream *s;
|
||||
int size;
|
||||
int rv;
|
||||
int file_size;
|
||||
|
||||
file_size = g_files[lindex].size;
|
||||
LLOGLN(10, ("clipboard_request_file_data:"));
|
||||
if (g_file_request_sent_type != 0)
|
||||
{
|
||||
LLOGLN(0, ("clipboard_request_file_data: warning, still waiting "
|
||||
"for CB_FILECONTENTS_RESPONSE"));
|
||||
}
|
||||
make_stream(s);
|
||||
init_stream(s, 8192);
|
||||
out_uint16_le(s, CB_FILECONTENTS_REQUEST); /* 8 */
|
||||
out_uint16_le(s, 0);
|
||||
out_uint32_le(s, 28);
|
||||
out_uint32_le(s, stream_id);
|
||||
out_uint32_le(s, lindex);
|
||||
out_uint32_le(s, CB_FILECONTENTS_RANGE);
|
||||
out_uint32_le(s, offset); /* nPositionLow */
|
||||
out_uint32_le(s, 0); /* nPositionHigh */
|
||||
out_uint32_le(s, request_bytes); /* cbRequested */
|
||||
out_uint32_le(s, 0); /* clipDataId */
|
||||
out_uint32_le(s, 0);
|
||||
s_mark_end(s);
|
||||
size = (int)(s->end - s->data);
|
||||
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
|
||||
free_stream(s);
|
||||
g_file_request_sent_type = CB_FILECONTENTS_RANGE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
int APP_CC
|
||||
clipboard_process_file_request(struct stream *s, int clip_msg_status,
|
||||
@ -450,6 +497,35 @@ clipboard_process_file_request(struct stream *s, int clip_msg_status,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* server requested info about the file and this is the responce
|
||||
it's either the file size or file data */
|
||||
int APP_CC
|
||||
clipboard_process_file_response(struct stream *s, int clip_msg_status,
|
||||
int clip_msg_len)
|
||||
{
|
||||
int streamId;
|
||||
int file_size;
|
||||
char *data;
|
||||
|
||||
LLOGLN(0, ("clipboard_process_file_response:"));
|
||||
if (g_file_request_sent_type == CB_FILECONTENTS_SIZE)
|
||||
{
|
||||
in_uint32_le(s, streamId);
|
||||
in_uint32_le(s, file_size);
|
||||
LLOGLN(0, ("clipboard_process_file_response: streamId %d "
|
||||
"file_size %d", streamId, file_size));
|
||||
fuse_file_contents_size(streamId, file_size);
|
||||
}
|
||||
else if (g_file_request_sent_type == CB_FILECONTENTS_RANGE)
|
||||
{
|
||||
in_uint32_le(s, streamId);
|
||||
fuse_file_contents_range(streamId, s->p, clip_msg_len - 4);
|
||||
}
|
||||
g_file_request_sent_type = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* read in CLIPRDR_FILEDESCRIPTOR */
|
||||
static int APP_CC
|
||||
@ -487,17 +563,17 @@ clipboard_c2s_in_file_info(struct stream *s, struct clip_file_desc *cfd)
|
||||
int APP_CC
|
||||
clipboard_c2s_in_files(struct stream *s)
|
||||
{
|
||||
tui32 cItems;
|
||||
int cItems;
|
||||
int lindex;
|
||||
struct clip_file_desc cfd;
|
||||
|
||||
in_uint32_le(s, cItems);
|
||||
fuse_clear_clip_dir();
|
||||
LLOGLN(0, ("clipboard_c2s_in_files: cItems %d", cItems));
|
||||
while (cItems > 0)
|
||||
for (lindex = 0; lindex < cItems; lindex++)
|
||||
{
|
||||
clipboard_c2s_in_file_info(s, &cfd);
|
||||
fuse_add_clip_dir_item(cfd.cFileName, 0, cfd.fileSizeLow);
|
||||
cItems--;
|
||||
fuse_add_clip_dir_item(cfd.cFileName, 0, cfd.fileSizeLow, lindex);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -31,6 +31,9 @@ int APP_CC
|
||||
clipboard_c2s_in_files(struct stream *s);
|
||||
|
||||
int APP_CC
|
||||
clipboard_request_file_size(int streamId, int lindex);
|
||||
clipboard_request_file_size(int stream_id, int lindex);
|
||||
int APP_CC
|
||||
clipboard_request_file_data(int stream_id, int lindex, int offset,
|
||||
int request_bytes);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user