Minor fixes to drive redirection

This commit is contained in:
matt335672 2020-03-03 10:02:32 +00:00
parent dc9a06f6ce
commit a3d429b4f7
6 changed files with 100 additions and 60 deletions

View File

@ -36,7 +36,8 @@ enum NTSTATUS
STATUS_ACCESS_DENIED = 0xc0000022,
STATUS_OBJECT_NAME_INVALID = 0xc0000033,
STATUS_OBJECT_NAME_NOT_FOUND = 0xc0000034,
STATUS_SHARING_VIOLATION = 0xc0000043
STATUS_SHARING_VIOLATION = 0xc0000043,
STATUS_NOT_SUPPORTED = 0xc00000bb
};
#endif /* MS_ERREF_H */

View File

@ -78,6 +78,7 @@ void xfuse_devredir_cb_open_file(struct state_open *fip,
tui32 DeviceId, tui32 FileId)
{}
void xfuse_devredir_cb_read_file(struct state_read *fip,
enum NTSTATUS IoStatus,
const char *buf, size_t length)
{}
void xfuse_devredir_cb_write_file(
@ -1313,9 +1314,18 @@ void xfuse_devredir_cb_open_file(struct state_open *fip,
}
void xfuse_devredir_cb_read_file(struct state_read *fip,
enum NTSTATUS IoStatus,
const char *buf, size_t length)
{
if (IoStatus != STATUS_SUCCESS)
{
log_error("Read NTSTATUS is %d", (int) IoStatus);
fuse_reply_err(fip->req, EIO);
}
else
{
fuse_reply_buf(fip->req, buf, length);
}
free(fip);
}
@ -1679,7 +1689,7 @@ static void xfuse_cb_unlink(fuse_req_t req, fuse_ino_t parent,
//XFUSE_HANDLE *fh;
log_debug("LK_TODO: this is still a TODO");
fuse_reply_err(req, EINVAL);
fuse_reply_err(req, EROFS);
}
else
{
@ -1744,26 +1754,26 @@ static void xfuse_cb_rename(fuse_req_t req,
else if (!(new_parent_xinode = xfs_get(g_xfs, new_parent)))
{
log_error("inode %ld is not valid", new_parent);
fuse_reply_err(req, EINVAL);
fuse_reply_err(req, ENOENT);
}
else if (!xfs_check_move_entry(g_xfs, old_xinode->inum,
new_parent, new_name))
{
/* Catchall -see rename(2). Fix when logging is improved */
fuse_reply_err(req, EINVAL);
}
else if (new_parent_xinode->device_id != old_xinode->device_id)
{
log_error("rename across file systems not supported");
fuse_reply_err(req, EINVAL);
fuse_reply_err(req, EXDEV);
}
else if (old_xinode->device_id == 0)
{
/* specified file is a local resource */
log_debug("LK_TODO: this is still a TODO");
fuse_reply_err(req, EINVAL);
fuse_reply_err(req, EROFS);
}
else
@ -1853,20 +1863,25 @@ static void xfuse_create_dir_or_file(fuse_req_t req, fuse_ino_t parent,
}
/* is parent inode valid? */
if (parent == FUSE_ROOT_ID ||
(xinode = xfs_get(g_xfs, parent)) == NULL ||
(xinode->mode & S_IFDIR) == 0)
if (parent == FUSE_ROOT_ID)
{
fuse_reply_err(req, EROFS);
}
else if ((xinode = xfs_get(g_xfs, parent)) == NULL)
{
log_error("inode %ld is not valid", parent);
fuse_reply_err(req, ENOENT);
}
else if ((xinode->mode & S_IFDIR) == 0)
{
fuse_reply_err(req, ENOTDIR);
}
else if (xinode->device_id == 0)
{
/* specified file is a local resource */
//XFUSE_HANDLE *fh;
log_debug("LK_TODO: this is still a TODO");
fuse_reply_err(req, EINVAL);
fuse_reply_err(req, EROFS);
}
else
{
@ -1948,11 +1963,18 @@ static void xfuse_cb_open(fuse_req_t req, fuse_ino_t ino,
else if (xinode->device_id == 0)
{
/* specified file is a local resource */
if ((fi->flags & O_ACCMODE) != O_RDONLY)
{
fuse_reply_err(req, EROFS);
}
else
{
XFUSE_HANDLE *fh = g_new0(XFUSE_HANDLE, 1);
fh->is_loc_resource = 1;
fi->fh = (tintptr) fh;
fuse_reply_open(req, fi);
}
}
else
{
/* specified file resides on redirected share */
@ -2153,7 +2175,7 @@ static void xfuse_cb_write(fuse_req_t req, fuse_ino_t ino, const char *buf,
{
/* target file is in .clipboard dir */
log_debug("THIS IS STILL A TODO!");
fuse_reply_err(req, EINVAL);
fuse_reply_err(req, EROFS);
}
else
{

View File

@ -98,6 +98,7 @@ void xfuse_devredir_cb_open_file(struct state_open *fip,
tui32 DeviceId, tui32 FileId);
void xfuse_devredir_cb_read_file(struct state_read *fip,
enum NTSTATUS IoStatus,
const char *buf, size_t length);
void xfuse_devredir_cb_write_file(
struct state_write *fip,

View File

@ -565,7 +565,7 @@ xfs_get_full_path(struct xfs_fs *xfs, fuse_ino_t inum)
*/
size_t len = 0;
XFS_INODE_ALL *p;
for (p = xino ; p->pub.inum != FUSE_ROOT_ID ; p = p->parent)
for (p = xino ; p && p->pub.inum != FUSE_ROOT_ID ; p = p->parent)
{
len += strlen(p->pub.name);
++len; /* Allow for '/' prefix */
@ -578,7 +578,7 @@ xfs_get_full_path(struct xfs_fs *xfs, fuse_ino_t inum)
char *end = result + len;
*end = '\0';
for (p = xino ; p->pub.inum != FUSE_ROOT_ID ; p = p->parent)
for (p = xino ; p && p->pub.inum != FUSE_ROOT_ID ; p = p->parent)
{
len = strlen(p->pub.name);
end -= (len + 1);

View File

@ -560,7 +560,8 @@ devredir_send_server_user_logged_on(void)
}
static void
devredir_send_server_device_announce_resp(tui32 device_id)
devredir_send_server_device_announce_resp(tui32 device_id,
enum NTSTATUS result_code)
{
struct stream *s;
int bytes;
@ -571,7 +572,7 @@ devredir_send_server_device_announce_resp(tui32 device_id)
xstream_wr_u16_le(s, RDPDR_CTYP_CORE);
xstream_wr_u16_le(s, PAKID_CORE_DEVICE_REPLY);
xstream_wr_u32_le(s, device_id);
xstream_wr_u32_le(s, 0); /* ResultCode */
xstream_wr_u32_le(s, (tui32)result_code);
/* send to client */
bytes = xstream_len(s);
@ -811,6 +812,7 @@ devredir_proc_client_devlist_announce_req(struct stream *s)
tui32 device_type;
tui32 device_data_len;
char preferred_dos_name[9];
enum NTSTATUS response_status;
/* get number of devices being announced */
xstream_rd_u32_le(s, device_count);
@ -821,19 +823,20 @@ devredir_proc_client_devlist_announce_req(struct stream *s)
{
xstream_rd_u32_le(s, device_type);
xstream_rd_u32_le(s, g_device_id);
switch (device_type)
{
case RDPDR_DTYP_FILESYSTEM:
/* get preferred DOS name */
/* get preferred DOS name
* DOS names that are 8 chars long are not NULL terminated */
for (j = 0; j < 8; j++)
{
preferred_dos_name[j] = *s->p++;
}
/* DOS names that are 8 chars long are not NULL terminated */
preferred_dos_name[8] = 0;
/* Assume this device isn't supported by us */
response_status = STATUS_NOT_SUPPORTED;
switch (device_type)
{
case RDPDR_DTYP_FILESYSTEM:
/* get device data len */
xstream_rd_u32_le(s, device_data_len);
if (device_data_len)
@ -847,7 +850,7 @@ devredir_proc_client_devlist_announce_req(struct stream *s)
preferred_dos_name,
device_data_len, g_full_name_for_filesystem);
devredir_send_server_device_announce_resp(g_device_id);
response_status = STATUS_SUCCESS;
/* create share directory in xrdp file system; */
/* think of this as the mount point for this share */
@ -855,31 +858,44 @@ devredir_proc_client_devlist_announce_req(struct stream *s)
break;
case RDPDR_DTYP_SMARTCARD:
/* get preferred DOS name */
for (j = 0; j < 8; j++)
{
preferred_dos_name[j] = *s->p++;
}
/* DOS names that are 8 chars long are not NULL terminated */
preferred_dos_name[8] = 0;
/* for smart cards, device data len always 0 */
log_debug("device_type=SMARTCARD device_id=0x%x dosname=%s",
g_device_id, preferred_dos_name);
devredir_send_server_device_announce_resp(g_device_id);
response_status = STATUS_SUCCESS;
scard_device_announce(g_device_id);
break;
/* we don't yet support these devices */
case RDPDR_DTYP_SERIAL:
log_debug(
"device_type=SERIAL device_id=0x%x dosname=%s",
g_device_id, preferred_dos_name);
break;
case RDPDR_DTYP_PARALLEL:
log_debug(
"device_type=PARALLEL device_id=0x%x dosname=%s",
g_device_id, preferred_dos_name);
break;
case RDPDR_DTYP_PRINT:
log_debug("unsupported dev: 0x%x", device_type);
log_debug(
"device_type=PRINT device_id=0x%x dosname=%s",
g_device_id, preferred_dos_name);
break;
default:
log_debug(
"device_type=UNKNOWN device_id=0x%x dosname=%s",
g_device_id, preferred_dos_name);
break;
}
/* Tell the client wheth or not we're supporting this one */
devredir_send_server_device_announce_resp(g_device_id,
response_status);
}
}
@ -993,6 +1009,7 @@ devredir_proc_device_iocompletion(struct stream *s)
case CID_READ:
xstream_rd_u32_le(s, Length);
xfuse_devredir_cb_read_file((struct state_read *) irp->fuse_info,
IoStatus,
s->p, Length);
devredir_irp_delete(irp);
break;
@ -1511,10 +1528,10 @@ devredir_rmdir_or_file(struct state_remove *fusep, tui32 device_id,
/**
* Read data from previously opened file
*
* @return 0 on success, -1 on failure
* Errors are reported via xfuse_devredir_cb_read_file()
*****************************************************************************/
int
void
devredir_file_read(struct state_read *fusep, tui32 DeviceId, tui32 FileId,
tui32 Length, tui64 Offset)
{
@ -1522,7 +1539,6 @@ devredir_file_read(struct state_read *fusep, tui32 DeviceId, tui32 FileId,
IRP *irp;
IRP *new_irp;
int bytes;
int rval = -1;
xstream_new(s, 1024);
@ -1530,14 +1546,14 @@ devredir_file_read(struct state_read *fusep, tui32 DeviceId, tui32 FileId,
if ((irp = devredir_irp_find_by_fileid(FileId)) == NULL)
{
log_error("no IRP found with FileId = %d", FileId);
xfuse_devredir_cb_read_file(fusep, NULL, 0);
xfuse_devredir_cb_read_file(fusep, STATUS_UNSUCCESSFUL, NULL, 0);
xstream_free(s);
}
/* create a new IRP for this request */
else if ((new_irp = devredir_irp_new()) == NULL)
{
/* system out of memory */
xfuse_devredir_cb_read_file(fusep, NULL, 0);
xfuse_devredir_cb_read_file(fusep, STATUS_UNSUCCESSFUL, NULL, 0);
xstream_free(s);
}
else
@ -1563,13 +1579,16 @@ devredir_file_read(struct state_read *fusep, tui32 DeviceId, tui32 FileId,
bytes = xstream_len(s);
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
xstream_free(s);
rval = 0;
}
}
return rval;
}
/**
* Read data from previously opened file
*
* Errors are reported via xfuse_devredir_cb_write_file()
*****************************************************************************/
int
void
devredir_file_write(struct state_write *fusep, tui32 DeviceId, tui32 FileId,
const char *buf, int Length, tui64 Offset)
{
@ -1577,7 +1596,6 @@ devredir_file_write(struct state_write *fusep, tui32 DeviceId, tui32 FileId,
IRP *irp;
IRP *new_irp;
int bytes;
int rval = -1;
log_debug("DeviceId=%d FileId=%d Length=%d Offset=%lld",
DeviceId, FileId, Length, (long long)Offset);
@ -1625,10 +1643,7 @@ devredir_file_write(struct state_write *fusep, tui32 DeviceId, tui32 FileId,
bytes = xstream_len(s);
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
xstream_free(s);
rval = 0;
}
return rval;
}

View File

@ -78,10 +78,11 @@ int devredir_file_open(struct state_open *fusep, tui32 device_id,
int devredir_file_close(struct state_close *fusep, tui32 device_id,
tui32 file_id);
int devredir_file_read(struct state_read *fusep, tui32 device_id, tui32 FileId,
void
devredir_file_read(struct state_read *fusep, tui32 device_id, tui32 FileId,
tui32 Length, tui64 Offset);
int
void
devredir_file_write(struct state_write *fusep, tui32 DeviceId, tui32 FileId,
const char *buf, int Length, tui64 Offset);