int guac_rdp_download_ack_handler(guac_client* client, guac_stream* stream, char* message, guac_protocol_status status) { guac_rdp_stream* rdp_stream = (guac_rdp_stream*) stream->data; /* Get filesystem, return error if no filesystem */ guac_rdp_fs* fs = ((rdp_guac_client_data*) client->data)->filesystem; if (fs == NULL) { guac_protocol_send_ack(client->socket, stream, "FAIL (NO FS)", GUAC_PROTOCOL_STATUS_SERVER_ERROR); guac_socket_flush(client->socket); return 0; } /* If successful, read data */ if (status == GUAC_PROTOCOL_STATUS_SUCCESS) { /* Attempt read into buffer */ char buffer[4096]; int bytes_read = guac_rdp_fs_read(fs, rdp_stream->download_status.file_id, rdp_stream->download_status.offset, buffer, sizeof(buffer)); /* If bytes read, send as blob */ if (bytes_read > 0) { rdp_stream->download_status.offset += bytes_read; guac_protocol_send_blob(client->socket, stream, buffer, bytes_read); } /* If EOF, send end */ else if (bytes_read == 0) { guac_protocol_send_end(client->socket, stream); guac_client_free_stream(client, stream); free(rdp_stream); } /* Otherwise, fail stream */ else { guac_client_log(client, GUAC_LOG_ERROR, "Error reading file for download"); guac_protocol_send_end(client->socket, stream); guac_client_free_stream(client, stream); free(rdp_stream); } guac_socket_flush(client->socket); } /* Otherwise, return stream to client */ else guac_client_free_stream(client, stream); return 0; }
void guac_rdpdr_fs_process_read(guac_rdpdr_device* device, wStream* input_stream, int file_id, int completion_id) { UINT32 length; UINT64 offset; char* buffer; int bytes_read; wStream* output_stream; /* Read packet */ Stream_Read_UINT32(input_stream, length); Stream_Read_UINT64(input_stream, offset); guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, "%s: [file_id=%i] length=%i, offset=%" PRIu64, __func__, file_id, length, (uint64_t) offset); /* Ensure buffer size does not exceed a safe maximum */ if (length > GUAC_RDP_MAX_READ_BUFFER) length = GUAC_RDP_MAX_READ_BUFFER; /* Allocate buffer */ buffer = malloc(length); /* Attempt read */ bytes_read = guac_rdp_fs_read((guac_rdp_fs*) device->data, file_id, offset, buffer, length); /* If error, return invalid parameter */ if (bytes_read < 0) { output_stream = guac_rdpdr_new_io_completion(device, completion_id, guac_rdp_fs_get_status(bytes_read), 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); free(buffer); }