mirror of https://github.com/neutrinolabs/xrdp
Minor fixes to drive redirection
This commit is contained in:
parent
dc9a06f6ce
commit
a3d429b4f7
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
fuse_reply_buf(fip->req, buf, 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,10 +1963,17 @@ 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 */
|
||||
XFUSE_HANDLE *fh = g_new0(XFUSE_HANDLE, 1);
|
||||
fh->is_loc_resource = 1;
|
||||
fi->fh = (tintptr) fh;
|
||||
fuse_reply_open(req, fi);
|
||||
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
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
/* 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++;
|
||||
}
|
||||
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 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;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
int
|
||||
/**
|
||||
* Read data from previously opened file
|
||||
*
|
||||
* Errors are reported via xfuse_devredir_cb_write_file()
|
||||
*****************************************************************************/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -78,12 +78,13 @@ 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,
|
||||
tui32 Length, tui64 Offset);
|
||||
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);
|
||||
const char *buf, int Length, tui64 Offset);
|
||||
|
||||
int devredir_file_rename(
|
||||
struct state_rename *fusep, tui32 device_id,
|
||||
|
|
Loading…
Reference in New Issue