|
|
@ -196,6 +196,7 @@ struct xfuse_handle
|
|
|
|
{
|
|
|
|
{
|
|
|
|
tui32 DeviceId;
|
|
|
|
tui32 DeviceId;
|
|
|
|
tui32 FileId;
|
|
|
|
tui32 FileId;
|
|
|
|
|
|
|
|
int is_loc_resource; /* this is not a redirected resource */
|
|
|
|
};
|
|
|
|
};
|
|
|
|
typedef struct xfuse_handle XFUSE_HANDLE;
|
|
|
|
typedef struct xfuse_handle XFUSE_HANDLE;
|
|
|
|
|
|
|
|
|
|
|
@ -684,6 +685,7 @@ int xfuse_add_clip_dir_item(char *filename, int flags, int size, int lindex)
|
|
|
|
S_IFREG);
|
|
|
|
S_IFREG);
|
|
|
|
xinode->size = size;
|
|
|
|
xinode->size = size;
|
|
|
|
xinode->lindex = lindex;
|
|
|
|
xinode->lindex = lindex;
|
|
|
|
|
|
|
|
xinode->is_loc_resource = 1;
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -840,6 +842,7 @@ static int xfuse_init_xrdp_fs()
|
|
|
|
xino->atime = time(0);
|
|
|
|
xino->atime = time(0);
|
|
|
|
xino->mtime = time(0);
|
|
|
|
xino->mtime = time(0);
|
|
|
|
xino->ctime = time(0);
|
|
|
|
xino->ctime = time(0);
|
|
|
|
|
|
|
|
xino->is_loc_resource = 1;
|
|
|
|
strcpy(xino->name, ".clipboard");
|
|
|
|
strcpy(xino->name, ".clipboard");
|
|
|
|
|
|
|
|
|
|
|
|
g_xrdp_fs.max_entries = 4096;
|
|
|
|
g_xrdp_fs.max_entries = 4096;
|
|
|
@ -961,9 +964,9 @@ static void xfuse_dump_fs()
|
|
|
|
if ((xinode = g_xrdp_fs.inode_table[i]) == NULL)
|
|
|
|
if ((xinode = g_xrdp_fs.inode_table[i]) == NULL)
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
log_debug("pinode=%d inode=%d nentries=%d dev_id=%d is_synced=%d name=%s",
|
|
|
|
log_debug("pinode=%d inode=%d nentries=%d nopen=%d is_synced=%d name=%s",
|
|
|
|
(int) xinode->parent_inode, (int) xinode->inode,
|
|
|
|
(int) xinode->parent_inode, (int) xinode->inode,
|
|
|
|
xinode->nentries, xinode->device_id, xinode->is_synced,
|
|
|
|
xinode->nentries, xinode->nopen, xinode->is_synced,
|
|
|
|
xinode->name);
|
|
|
|
xinode->name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
log_debug("");
|
|
|
|
log_debug("");
|
|
|
@ -1466,6 +1469,7 @@ void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log_debug("fip->req=%p", fip->req);
|
|
|
|
|
|
|
|
|
|
|
|
if (!xfuse_is_inode_valid(fip->inode))
|
|
|
|
if (!xfuse_is_inode_valid(fip->inode))
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -1527,6 +1531,8 @@ void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus)
|
|
|
|
goto done;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log_debug("fip->req=%p", fip->req);
|
|
|
|
|
|
|
|
|
|
|
|
if (IoStatus != 0)
|
|
|
|
if (IoStatus != 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
/* command failed */
|
|
|
|
/* command failed */
|
|
|
@ -1586,18 +1592,23 @@ void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus)
|
|
|
|
fuse_reply_buf(fip->req, b.p + fip->off,
|
|
|
|
fuse_reply_buf(fip->req, b.p + fip->off,
|
|
|
|
min(b.size - fip->off, fip->size));
|
|
|
|
min(b.size - fip->off, fip->size));
|
|
|
|
#else
|
|
|
|
#else
|
|
|
|
|
|
|
|
log_debug("calling fuse_reply_buf() with data...");
|
|
|
|
fuse_reply_buf(fip->req, b.buf, b.bytes_in_buf);
|
|
|
|
fuse_reply_buf(fip->req, b.buf, b.bytes_in_buf);
|
|
|
|
|
|
|
|
log_debug("calling fuse_reply_buf() with data...done");
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
fuse_reply_buf(fip->req, NULL, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
log_debug("calling fuse_reply_buf() with NULL...");
|
|
|
|
fuse_reply_buf(fip->req, NULL, 0);
|
|
|
|
fuse_reply_buf(fip->req, NULL, 0);
|
|
|
|
|
|
|
|
log_debug("calling fuse_reply_buf() with NULL...done");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
log_debug("calling fuse_reply_err()...");
|
|
|
|
fuse_reply_err(fip->req, ENOENT);
|
|
|
|
fuse_reply_err(fip->req, ENOENT);
|
|
|
|
|
|
|
|
log_debug("calling fuse_reply_err()...done");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
done:
|
|
|
|
done:
|
|
|
@ -1608,7 +1619,7 @@ done:
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
if (!fip)
|
|
|
|
if (!fip)
|
|
|
|
printf("###### %s : %s : %d: fip is NULL\n", __FILE__, __func__, __LINE__);
|
|
|
|
log_error("fip is NULL");
|
|
|
|
|
|
|
|
|
|
|
|
if (fip)
|
|
|
|
if (fip)
|
|
|
|
free(fip);
|
|
|
|
free(fip);
|
|
|
@ -1815,10 +1826,14 @@ void xfuse_devredir_cb_write_file(void *vp, char *buf, size_t length)
|
|
|
|
XRDP_INODE *xinode;
|
|
|
|
XRDP_INODE *xinode;
|
|
|
|
XFUSE_INFO *fip;
|
|
|
|
XFUSE_INFO *fip;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log_debug("entered: length=%lld", (long long) length);
|
|
|
|
|
|
|
|
|
|
|
|
fip = (XFUSE_INFO *) vp;
|
|
|
|
fip = (XFUSE_INFO *) vp;
|
|
|
|
if (fip == NULL)
|
|
|
|
if (fip == NULL)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log_debug("letting FUSE know that we wrote %lld bytes", (long long) length);
|
|
|
|
|
|
|
|
|
|
|
|
fuse_reply_write(fip->req, length);
|
|
|
|
fuse_reply_write(fip->req, length);
|
|
|
|
|
|
|
|
|
|
|
|
/* update file size */
|
|
|
|
/* update file size */
|
|
|
@ -1878,6 +1893,7 @@ void xfuse_devredir_cb_rename_file(void *vp, tui32 IoStatus)
|
|
|
|
|
|
|
|
|
|
|
|
if (IoStatus != 0)
|
|
|
|
if (IoStatus != 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
log_debug("rename failed with IoStatus=0x%x", IoStatus);
|
|
|
|
fuse_reply_err(fip->req, EEXIST);
|
|
|
|
fuse_reply_err(fip->req, EEXIST);
|
|
|
|
free(fip);
|
|
|
|
free(fip);
|
|
|
|
return;
|
|
|
|
return;
|
|
|
@ -1904,6 +1920,7 @@ void xfuse_devredir_cb_rename_file(void *vp, tui32 IoStatus)
|
|
|
|
old_xinode = xfuse_get_inode_from_pinode_name(fip->inode, fip->name);
|
|
|
|
old_xinode = xfuse_get_inode_from_pinode_name(fip->inode, fip->name);
|
|
|
|
if (old_xinode == NULL)
|
|
|
|
if (old_xinode == NULL)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
log_debug("rename failed");
|
|
|
|
fuse_reply_err(fip->req, EBADF);
|
|
|
|
fuse_reply_err(fip->req, EBADF);
|
|
|
|
free(fip);
|
|
|
|
free(fip);
|
|
|
|
return;
|
|
|
|
return;
|
|
|
@ -1942,7 +1959,10 @@ void xfuse_devredir_cb_file_close(void *vp)
|
|
|
|
xinode->nopen--;
|
|
|
|
xinode->nopen--;
|
|
|
|
|
|
|
|
|
|
|
|
if ((xinode->nopen == 0) && fip->fi && fip->fi->fh)
|
|
|
|
if ((xinode->nopen == 0) && fip->fi && fip->fi->fh)
|
|
|
|
|
|
|
|
{
|
|
|
|
free((char *) fip->fi->fh);
|
|
|
|
free((char *) fip->fi->fh);
|
|
|
|
|
|
|
|
fip->fi->fh = NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fuse_reply_err(fip->req, 0);
|
|
|
|
fuse_reply_err(fip->req, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -2106,8 +2126,16 @@ static void xfuse_cb_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (ino == 1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/* special case; enumerate top level dir */
|
|
|
|
|
|
|
|
log_debug("enumerating top level dir");
|
|
|
|
|
|
|
|
xfuse_enum_dir(req, ino, size, off, fi);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
xinode = g_xrdp_fs.inode_table[ino];
|
|
|
|
xinode = g_xrdp_fs.inode_table[ino];
|
|
|
|
if (xinode->device_id == 0)
|
|
|
|
if (xinode->is_loc_resource)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
/* enumerate local resources */
|
|
|
|
/* enumerate local resources */
|
|
|
|
xfuse_enum_dir(req, ino, size, off, fi);
|
|
|
|
xfuse_enum_dir(req, ino, size, off, fi);
|
|
|
@ -2152,6 +2180,8 @@ do_remote_lookup:
|
|
|
|
fip->invoke_fuse = 1;
|
|
|
|
fip->invoke_fuse = 1;
|
|
|
|
fip->device_id = device_id;
|
|
|
|
fip->device_id = device_id;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log_debug("fip->req=%p", fip->req);
|
|
|
|
|
|
|
|
|
|
|
|
/* we want path minus 'root node of the share' */
|
|
|
|
/* we want path minus 'root node of the share' */
|
|
|
|
if ((cptr = strchr(full_path, '/')) == NULL)
|
|
|
|
if ((cptr = strchr(full_path, '/')) == NULL)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -2277,7 +2307,7 @@ static void xfuse_remove_dir_or_file(fuse_req_t req, fuse_ino_t parent,
|
|
|
|
strcat(full_path, "/");
|
|
|
|
strcat(full_path, "/");
|
|
|
|
strcat(full_path, name);
|
|
|
|
strcat(full_path, name);
|
|
|
|
|
|
|
|
|
|
|
|
if (device_id == 0)
|
|
|
|
if (xinode->is_loc_resource)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
/* specified file is a local resource */
|
|
|
|
/* specified file is a local resource */
|
|
|
|
//XFUSE_HANDLE *fh;
|
|
|
|
//XFUSE_HANDLE *fh;
|
|
|
@ -2402,7 +2432,7 @@ static void xfuse_cb_rename(fuse_req_t req,
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (old_xinode->device_id == 0)
|
|
|
|
if (old_xinode->is_loc_resource)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
/* specified file is a local resource */
|
|
|
|
/* specified file is a local resource */
|
|
|
|
log_debug("LK_TODO: this is still a TODO");
|
|
|
|
log_debug("LK_TODO: this is still a TODO");
|
|
|
@ -2508,7 +2538,8 @@ static void xfuse_create_dir_or_file(fuse_req_t req, fuse_ino_t parent,
|
|
|
|
strcat(full_path, "/");
|
|
|
|
strcat(full_path, "/");
|
|
|
|
strcat(full_path, name);
|
|
|
|
strcat(full_path, name);
|
|
|
|
|
|
|
|
|
|
|
|
if (device_id == 0)
|
|
|
|
XRDP_INODE *xinode = g_xrdp_fs.inode_table[parent];
|
|
|
|
|
|
|
|
if (xinode->is_loc_resource)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
/* specified file is a local resource */
|
|
|
|
/* specified file is a local resource */
|
|
|
|
//XFUSE_HANDLE *fh;
|
|
|
|
//XFUSE_HANDLE *fh;
|
|
|
@ -2574,6 +2605,8 @@ static void xfuse_cb_open(fuse_req_t req, fuse_ino_t ino,
|
|
|
|
char full_path[4096];
|
|
|
|
char full_path[4096];
|
|
|
|
tui32 device_id;
|
|
|
|
tui32 device_id;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log_debug("entered: ino=%d", (int) ino);
|
|
|
|
|
|
|
|
|
|
|
|
if (!xfuse_is_inode_valid(ino))
|
|
|
|
if (!xfuse_is_inode_valid(ino))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
log_error("inode %d is not valid", ino);
|
|
|
|
log_error("inode %d is not valid", ino);
|
|
|
@ -2591,10 +2624,12 @@ static void xfuse_cb_open(fuse_req_t req, fuse_ino_t ino,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
device_id = xfuse_get_device_id_for_inode((tui32) ino, full_path);
|
|
|
|
device_id = xfuse_get_device_id_for_inode((tui32) ino, full_path);
|
|
|
|
if (device_id == 0)
|
|
|
|
|
|
|
|
|
|
|
|
if (xinode->is_loc_resource)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
/* specified file is a local resource */
|
|
|
|
/* specified file is a local resource */
|
|
|
|
XFUSE_HANDLE *fh = calloc(1, sizeof(XFUSE_HANDLE));
|
|
|
|
XFUSE_HANDLE *fh = calloc(1, sizeof(XFUSE_HANDLE));
|
|
|
|
|
|
|
|
fh->is_loc_resource = 1;
|
|
|
|
fi->fh = (uint64_t) ((long) fh);
|
|
|
|
fi->fh = (uint64_t) ((long) fh);
|
|
|
|
fuse_reply_open(req, fi);
|
|
|
|
fuse_reply_open(req, fi);
|
|
|
|
return;
|
|
|
|
return;
|
|
|
@ -2647,6 +2682,8 @@ static void xfuse_cb_flush(fuse_req_t req, fuse_ino_t ino, struct
|
|
|
|
XFUSE_INFO *fip = NULL;
|
|
|
|
XFUSE_INFO *fip = NULL;
|
|
|
|
XFUSE_HANDLE *handle = (XFUSE_HANDLE *) fi->fh;
|
|
|
|
XFUSE_HANDLE *handle = (XFUSE_HANDLE *) fi->fh;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log_debug("ino=%d", (int) ino);
|
|
|
|
|
|
|
|
|
|
|
|
if (!xfuse_is_inode_valid(ino))
|
|
|
|
if (!xfuse_is_inode_valid(ino))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
log_error("inode %d is not valid", ino);
|
|
|
|
log_error("inode %d is not valid", ino);
|
|
|
@ -2654,7 +2691,8 @@ static void xfuse_cb_flush(fuse_req_t req, fuse_ino_t ino, struct
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (handle->DeviceId == 0)
|
|
|
|
XRDP_INODE *xinode = g_xrdp_fs.inode_table[ino];
|
|
|
|
|
|
|
|
if (xinode->is_loc_resource)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
/* specified file is a local resource */
|
|
|
|
/* specified file is a local resource */
|
|
|
|
fuse_reply_err(req, 0);
|
|
|
|
fuse_reply_err(req, 0);
|
|
|
@ -2706,7 +2744,7 @@ static void xfuse_cb_read(fuse_req_t req, fuse_ino_t ino, size_t size,
|
|
|
|
handle = fi->fh;
|
|
|
|
handle = fi->fh;
|
|
|
|
fh = (XFUSE_HANDLE *) handle;
|
|
|
|
fh = (XFUSE_HANDLE *) handle;
|
|
|
|
|
|
|
|
|
|
|
|
if (fh->DeviceId == 0)
|
|
|
|
if (fh->is_loc_resource)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
/* target file is in .clipboard dir */
|
|
|
|
/* target file is in .clipboard dir */
|
|
|
|
|
|
|
|
|
|
|
@ -2776,7 +2814,7 @@ static void xfuse_cb_write(fuse_req_t req, fuse_ino_t ino, const char *buf,
|
|
|
|
handle = fi->fh;
|
|
|
|
handle = fi->fh;
|
|
|
|
fh = (XFUSE_HANDLE *) handle;
|
|
|
|
fh = (XFUSE_HANDLE *) handle;
|
|
|
|
|
|
|
|
|
|
|
|
if (fh->DeviceId == 0)
|
|
|
|
if (fh->is_loc_resource)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
/* target file is in .clipboard dir */
|
|
|
|
/* target file is in .clipboard dir */
|
|
|
|
log_debug(">>>>>>>>>>>>>>>>> THIS IS STILL A TODO!");
|
|
|
|
log_debug(">>>>>>>>>>>>>>>>> THIS IS STILL A TODO!");
|
|
|
|