in src/protocols/rdp/channels/rdpdr/rdpdr-fs-messages.c [40:134]
void guac_rdpdr_fs_process_create(guac_rdp_common_svc* svc,
guac_rdpdr_device* device, guac_rdpdr_iorequest* iorequest,
wStream* input_stream) {
wStream* output_stream;
int file_id;
int desired_access, file_attributes;
int create_disposition, create_options, path_length;
char path[GUAC_RDP_FS_MAX_PATH];
/* Check remaining stream data prior to reading. */
if (Stream_GetRemainingLength(input_stream) < 32) {
guac_client_log(svc->client, GUAC_LOG_WARNING, "Server Create Drive "
"Request PDU does not contain the expected number of bytes. "
"Drive redirection may not work as expected.");
return;
}
/* Read "create" information */
Stream_Read_UINT32(input_stream, desired_access);
Stream_Seek_UINT64(input_stream); /* allocation size */
Stream_Read_UINT32(input_stream, file_attributes);
Stream_Seek_UINT32(input_stream); /* shared access */
Stream_Read_UINT32(input_stream, create_disposition);
Stream_Read_UINT32(input_stream, create_options);
Stream_Read_UINT32(input_stream, path_length);
/* Check to make sure the stream contains path_length bytes. */
if(Stream_GetRemainingLength(input_stream) < path_length) {
guac_client_log(svc->client, GUAC_LOG_WARNING, "Server Create Drive "
"Request PDU does not contain the expected number of bytes. "
"Drive redirection may not work as expected.");
return;
}
/* Convert path to UTF-8 */
guac_rdp_utf16_to_utf8(Stream_Pointer(input_stream), path_length/2 - 1,
path, sizeof(path));
/* Open file */
file_id = guac_rdp_fs_open((guac_rdp_fs*) device->data, path,
desired_access, file_attributes,
create_disposition, create_options);
guac_client_log(svc->client, GUAC_LOG_DEBUG,
"%s: [file_id=%i] "
"desired_access=0x%x, file_attributes=0x%x, "
"create_disposition=0x%x, create_options=0x%x, path=\"%s\"",
__func__, file_id,
desired_access, file_attributes,
create_disposition, create_options, path);
/* If an error occurred, notify server */
if (file_id < 0) {
guac_client_log(svc->client, GUAC_LOG_ERROR,
"File open refused (%i): \"%s\"", file_id, path);
output_stream = guac_rdpdr_new_io_completion(device,
iorequest->completion_id, guac_rdp_fs_get_status(file_id), 5);
Stream_Write_UINT32(output_stream, 0); /* fileId */
Stream_Write_UINT8(output_stream, 0); /* information */
}
/* Otherwise, open succeeded */
else {
guac_rdp_fs_file* file;
output_stream = guac_rdpdr_new_io_completion(device,
iorequest->completion_id, STATUS_SUCCESS, 5);
Stream_Write_UINT32(output_stream, file_id); /* fileId */
Stream_Write_UINT8(output_stream, 0); /* information */
/* Create \Download if it doesn't exist */
file = guac_rdp_fs_get_file((guac_rdp_fs*) device->data, file_id);
if (file != NULL && strcmp(file->absolute_path, "\\") == 0) {
/* Only create Download folder if downloads are enabled. */
if (!((guac_rdp_fs*) device->data)->disable_download) {
int download_id =
guac_rdp_fs_open((guac_rdp_fs*) device->data, "\\Download",
GENERIC_READ, 0, FILE_OPEN_IF, FILE_DIRECTORY_FILE);
if (download_id >= 0)
guac_rdp_fs_close((guac_rdp_fs*) device->data, download_id);
}
}
}
guac_rdp_common_svc_write(svc, output_stream);
}