Move read/write to rdpdr_fs.

This commit is contained in:
Michael Jumper 2013-10-25 16:53:11 -07:00
parent 77db391a12
commit 28c3c7d926
3 changed files with 90 additions and 80 deletions

View File

@ -326,6 +326,52 @@ int guac_rdpdr_fs_open(guac_rdpdr_device* device, const char* path,
} }
int guac_rdpdr_fs_read(guac_rdpdr_device* device, int file_id, int offset,
void* buffer, int length) {
int bytes_read;
guac_rdpdr_fs_file* file = guac_rdpdr_fs_get_file(device, file_id);
if (file == NULL) {
GUAC_RDP_DEBUG(1, "Read from bad file_id: %i", file_id);
return GUAC_RDPDR_FS_EINVAL;
}
/* Attempt read */
lseek(file->fd, offset, SEEK_SET);
bytes_read = read(file->fd, buffer, length);
/* Translate errno on error */
if (bytes_read < 0)
return guac_rdpdr_fs_get_errorcode(errno);
return bytes_read;
}
int guac_rdpdr_fs_write(guac_rdpdr_device* device, int file_id, int offset,
void* buffer, int length) {
int bytes_written;
guac_rdpdr_fs_file* file = guac_rdpdr_fs_get_file(device, file_id);
if (file == NULL) {
GUAC_RDP_DEBUG(1, "Write to bad file_id: %i", file_id);
return GUAC_RDPDR_FS_EINVAL;
}
/* Attempt write */
lseek(file->fd, offset, SEEK_SET);
bytes_written = write(file->fd, buffer, length);
/* Translate errno on error */
if (bytes_written < 0)
return guac_rdpdr_fs_get_errorcode(errno);
return bytes_written;
}
int guac_rdpdr_fs_rename(guac_rdpdr_device* device, int file_id, int guac_rdpdr_fs_rename(guac_rdpdr_device* device, int file_id,
const char* new_path) { const char* new_path) {

View File

@ -314,6 +314,22 @@ int guac_rdpdr_fs_open(guac_rdpdr_device* device, const char* path,
int access, int file_attributes, int create_disposition, int access, int file_attributes, int create_disposition,
int create_options); int create_options);
/**
* Reads up to the given length of bytes from the given offset within the
* file having the given ID. Returns the number of bytes read, zero on EOF,
* and an error code if an error occurs.
*/
int guac_rdpdr_fs_read(guac_rdpdr_device* device, int file_id, int offset,
void* buffer, int length);
/**
* Writes up to the given length of bytes from the given offset within the
* file having the given ID. Returns the number of bytes written, and an
* error code if an error occurs.
*/
int guac_rdpdr_fs_write(guac_rdpdr_device* device, int file_id, int offset,
void* buffer, int length);
/** /**
* Renames (moves) the file with the given ID to the new path specified. * Renames (moves) the file with the given ID to the new path specified.
* Returns zero on success, or an error code if an error occurs. * Returns zero on success, or an error code if an error occurs.

View File

@ -115,60 +115,35 @@ void guac_rdpdr_fs_process_read(guac_rdpdr_device* device,
UINT32 length; UINT32 length;
UINT64 offset; UINT64 offset;
char buffer[4096]; char buffer[4096];
int bytes_read;
wStream* output_stream; wStream* output_stream;
guac_rdpdr_fs_file* file;
/* Get file */
file = guac_rdpdr_fs_get_file(device, file_id);
if (file == NULL)
return;
/* Read packet */ /* Read packet */
Stream_Read_UINT32(input_stream, length); Stream_Read_UINT32(input_stream, length);
Stream_Read_UINT64(input_stream, offset); Stream_Read_UINT64(input_stream, offset);
/* If file is a directory, fail */ /* Read no more than size of buffer */
if (file->attributes & FILE_ATTRIBUTE_DIRECTORY) { if (length > sizeof(buffer))
guac_client_log_error(device->rdpdr->client, length = sizeof(buffer);
"Refusing to read directory as a file");
/* Attempt read */
bytes_read = guac_rdpdr_fs_read(device, file_id, offset,
buffer, length);
/* If error, return invalid parameter */
if (bytes_read < 0) {
output_stream = guac_rdpdr_new_io_completion(device, completion_id, output_stream = guac_rdpdr_new_io_completion(device, completion_id,
STATUS_FILE_IS_A_DIRECTORY, 4); guac_rdpdr_fs_get_status(bytes_read), 4);
Stream_Write_UINT32(output_stream, 0); /* Length */ Stream_Write_UINT32(output_stream, 0); /* Length */
} }
/* Otherwise, perform read */ /* Otherwise, send bytes read */
else { else {
output_stream = guac_rdpdr_new_io_completion(device, completion_id,
int bytes_read; STATUS_SUCCESS, 4+bytes_read);
Stream_Write_UINT32(output_stream, bytes_read); /* Length */
/* Read no more than size of buffer */ Stream_Write(output_stream, buffer, bytes_read); /* ReadData */
if (length > sizeof(buffer))
length = sizeof(buffer);
/* Attempt read */
lseek(file->fd, offset, SEEK_SET);
bytes_read = read(file->fd, buffer, length);
/* If error, return invalid parameter */
if (bytes_read < 0) {
guac_client_log_error(device->rdpdr->client,
"Unable to read from file: %s", strerror(errno));
output_stream = guac_rdpdr_new_io_completion(device, completion_id,
STATUS_INVALID_PARAMETER, 4);
Stream_Write_UINT32(output_stream, 0); /* Length */
}
/* Otherwise, send bytes read */
else {
output_stream = guac_rdpdr_new_io_completion(device, completion_id,
STATUS_SUCCESS, 4+bytes_read);
Stream_Write_UINT32(output_stream, bytes_read); /* Length */
Stream_Write(output_stream, buffer, bytes_read); /* ReadData */
}
} }
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
@ -180,60 +155,33 @@ void guac_rdpdr_fs_process_write(guac_rdpdr_device* device,
UINT32 length; UINT32 length;
UINT64 offset; UINT64 offset;
int bytes_written;
wStream* output_stream; wStream* output_stream;
guac_rdpdr_fs_file* file;
/* Get file */
file = guac_rdpdr_fs_get_file(device, file_id);
if (file == NULL)
return;
/* Read packet */ /* Read packet */
Stream_Read_UINT32(input_stream, length); Stream_Read_UINT32(input_stream, length);
Stream_Read_UINT64(input_stream, offset); Stream_Read_UINT64(input_stream, offset);
Stream_Seek(input_stream, 20); /* Padding */ Stream_Seek(input_stream, 20); /* Padding */
/* If file is a directory, fail */ /* Attempt write */
if (file->attributes & FILE_ATTRIBUTE_DIRECTORY) { bytes_written = guac_rdpdr_fs_write(device, file_id, offset,
guac_client_log_error(device->rdpdr->client, Stream_Pointer(input_stream), length);
"Refusing to write directory as a file");
/* If error, return invalid parameter */
if (bytes_written < 0) {
output_stream = guac_rdpdr_new_io_completion(device, completion_id, output_stream = guac_rdpdr_new_io_completion(device, completion_id,
STATUS_FILE_IS_A_DIRECTORY, 5); guac_rdpdr_fs_get_status(bytes_written), 5);
Stream_Write_UINT32(output_stream, 0); /* Length */ Stream_Write_UINT32(output_stream, 0); /* Length */
Stream_Write_UINT8(output_stream, 0); /* Padding */ Stream_Write_UINT8(output_stream, 0); /* Padding */
} }
/* Otherwise, perform write */ /* Otherwise, send success */
else { else {
output_stream = guac_rdpdr_new_io_completion(device, completion_id,
int bytes_written; STATUS_SUCCESS, 5);
Stream_Write_UINT32(output_stream, bytes_written); /* Length */
/* Attempt read */ Stream_Write_UINT8(output_stream, 0); /* Padding */
lseek(file->fd, offset, SEEK_SET);
bytes_written = write(file->fd, Stream_Pointer(input_stream), length);
/* If error, return invalid parameter */
if (bytes_written < 0) {
guac_client_log_error(device->rdpdr->client,
"Unable to write to file %i: %s", file->fd,
strerror(errno));
output_stream = guac_rdpdr_new_io_completion(device, completion_id,
STATUS_ACCESS_DENIED, 5);
Stream_Write_UINT32(output_stream, 0); /* Length */
Stream_Write_UINT8(output_stream, 0); /* Padding */
}
/* Otherwise, send success */
else {
output_stream = guac_rdpdr_new_io_completion(device, completion_id,
STATUS_SUCCESS, 5);
Stream_Write_UINT32(output_stream, bytes_written); /* Length */
Stream_Write_UINT8(output_stream, 0); /* Padding */
}
} }
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);