示例#1
0
void guac_rdpdr_register_printer(guac_rdpdrPlugin* rdpdr) {

    int id = rdpdr->devices_registered++;

    /* Get new device */
    guac_rdpdr_device* device = &(rdpdr->devices[id]);
    guac_rdpdr_printer_data* printer_data;

    /* Init device */
    device->rdpdr       = rdpdr;
    device->device_id   = id;
    device->device_name = "Guacamole Printer";
//    device->device_name = "V2 Cloud Printer";

    /* Set handlers */
    device->announce_handler  = guac_rdpdr_device_printer_announce_handler;
    device->iorequest_handler = guac_rdpdr_device_printer_iorequest_handler;
    device->free_handler      = guac_rdpdr_device_printer_free_handler;

    /* Init data */
    printer_data = malloc(sizeof(guac_rdpdr_printer_data));
    printer_data->stream = guac_client_alloc_stream(rdpdr->client);
    device->data = printer_data;

}
示例#2
0
guac_stream* guac_sftp_download_file(guac_client* client,
        char* filename) {

    ssh_guac_client_data* client_data = (ssh_guac_client_data*) client->data;
    guac_stream* stream;
    LIBSSH2_SFTP_HANDLE* file;

    /* Attempt to open file for reading */
    file = libssh2_sftp_open(client_data->sftp_session, filename,
            LIBSSH2_FXF_READ, 0);
    if (file == NULL) {
        guac_client_log_error(client, "Unable to read file \"%s\": %s",
                filename,
                libssh2_sftp_last_error(client_data->sftp_session));
        return NULL;
    }

    /* Allocate stream */
    stream = guac_client_alloc_stream(client);
    stream->ack_handler = guac_sftp_ack_handler;
    stream->data = file;

    /* Send stream start, strip name */
    filename = basename(filename);
    guac_protocol_send_file(client->socket, stream,
            "application/octet-stream", filename);
    guac_socket_flush(client->socket);

    return stream;

}
示例#3
0
guac_audio_stream* guac_audio_stream_alloc(guac_client* client,
        guac_audio_encoder* encoder, int rate, int channels, int bps) {

    guac_audio_stream* audio;

    /* Allocate stream */
    audio = (guac_audio_stream*) calloc(1, sizeof(guac_audio_stream));
    audio->client = client;
    audio->stream = guac_client_alloc_stream(client);

    /* Load PCM properties */
    audio->rate = rate;
    audio->channels = channels;
    audio->bps = bps;

    /* Assign encoder for owner, abort if no encoder can be found */
    if (!guac_client_for_owner(client, guac_audio_assign_encoder, audio)) {
        guac_client_free_stream(client, audio->stream);
        free(audio);
        return NULL;
    }

    /* Call handler, if defined */
    if (audio->encoder->begin_handler)
        audio->encoder->begin_handler(audio);

    return audio;

}
示例#4
0
guac_audio_stream* guac_audio_stream_alloc(guac_client* client, guac_audio_encoder* encoder) {

    guac_audio_stream* audio;

    /* Choose an encoding if not specified */
    if (encoder == NULL) {

        int i;

        /* For each supported mimetype, check for an associated encoder */
        for (i=0; client->info.audio_mimetypes[i] != NULL; i++) {

            const char* mimetype = client->info.audio_mimetypes[i];

#ifdef ENABLE_OGG
            /* If Ogg is supported, done. */
            if (strcmp(mimetype, ogg_encoder->mimetype) == 0) {
                encoder = ogg_encoder;
                break;
            }
#endif

            /* If wav is supported, done. */
            if (strcmp(mimetype, wav_encoder->mimetype) == 0) {
                encoder = wav_encoder;
                break;
            }

        } /* end for each mimetype */

        /* If still no encoder could be found, fail */
        if (encoder == NULL)
            return NULL;

    }

    /* Allocate stream */
    audio = (guac_audio_stream*) malloc(sizeof(guac_audio_stream));
    audio->client = client;

    /* Reset buffer stats */
    audio->used = 0;
    audio->length = 0x40000;

    audio->encoded_data_used = 0;
    audio->encoded_data_length = 0x40000;

    /* Allocate buffers */
    audio->pcm_data = malloc(audio->length);
    audio->encoded_data = malloc(audio->encoded_data_length);

    /* Assign encoder */
    audio->encoder = encoder;
    audio->stream = guac_client_alloc_stream(client);

    return audio;
}
示例#5
0
void guac_rdpdr_start_download(guac_rdpdr_device* device, const char* path) {

    /* Get client and stream */
    guac_client* client = device->rdpdr->client;

    int file_id = guac_rdp_fs_open((guac_rdp_fs*) device->data, path,
            ACCESS_FILE_READ_DATA, 0, DISP_FILE_OPEN, 0);

    /* If file opened successfully, start stream */
    if (file_id >= 0) {

        guac_rdp_stream* rdp_stream;
        const char* basename;

        int i;
        char c;

        /* Associate stream with transfer status */
        guac_stream* stream = guac_client_alloc_stream(client);
        stream->data = rdp_stream = malloc(sizeof(guac_rdp_stream));
        stream->ack_handler = guac_rdp_download_ack_handler;
        rdp_stream->type = GUAC_RDP_DOWNLOAD_STREAM;
        rdp_stream->download_status.file_id = file_id;
        rdp_stream->download_status.offset = 0;

        /* Get basename from absolute path */
        i=0;
        basename = path;
        do {

            c = path[i];
            if (c == '/' || c == '\\')
                basename = &(path[i+1]);

            i++;

        } while (c != '\0');

        GUAC_RDP_DEBUG(2, "Initiating download of \"%s\"", path);

        /* Begin stream */
        guac_protocol_send_file(client->socket, stream,
                "application/octet-stream", basename);
        guac_socket_flush(client->socket);

    }
    else
        guac_client_log(client, GUAC_LOG_ERROR, "Unable to download \"%s\"", path);

}
示例#6
0
void guac_client_stream_jpeg(guac_client* client, guac_socket* socket,
        guac_composite_mode mode, const guac_layer* layer, int x, int y,
        cairo_surface_t* surface, int quality) {

    /* Allocate new stream for image */
    guac_stream* stream = guac_client_alloc_stream(client);

    /* Declare stream as containing image data */
    guac_protocol_send_img(socket, stream, mode, layer, "image/jpeg", x, y);

    /* Write JPEG data */
    guac_jpeg_write(socket, stream, surface, quality);

    /* Terminate stream */
    guac_protocol_send_end(socket, stream);

    /* Free allocated stream */
    guac_client_free_stream(client, stream);

}
void guac_svc_process_connect(rdpSvcPlugin* plugin) {

    /* Get corresponding guac_rdp_svc */
    guac_svcPlugin* svc_plugin = (guac_svcPlugin*) plugin;
    guac_rdp_svc* svc = svc_plugin->svc;

    /* NULL out pExtendedData so we don't lose our guac_rdp_svc due to an
     * automatic free() within libfreerdp */
    plugin->channel_entry_points.pExtendedData = NULL;

    /* Create pipe */
    svc->output_pipe = guac_client_alloc_stream(svc->client);

    /* Notify of pipe's existence */
    guac_rdp_svc_send_pipe(svc->client->socket, svc);

    /* Log connection to static channel */
    guac_client_log(svc->client, GUAC_LOG_INFO,
            "Static channel \"%s\" connected.", svc->name);

}
示例#8
0
void guac_client_stream_webp(guac_client* client, guac_socket* socket,
        guac_composite_mode mode, const guac_layer* layer, int x, int y,
        cairo_surface_t* surface, int quality, int lossless) {

#ifdef ENABLE_WEBP
    /* Allocate new stream for image */
    guac_stream* stream = guac_client_alloc_stream(client);

    /* Declare stream as containing image data */
    guac_protocol_send_img(socket, stream, mode, layer, "image/webp", x, y);

    /* Write WebP data */
    guac_webp_write(socket, stream, surface, quality, lossless);

    /* Terminate stream */
    guac_protocol_send_end(socket, stream);

    /* Free allocated stream */
    guac_client_free_stream(client, stream);
#else
    /* Do nothing if WebP support is not built in */
#endif

}
示例#9
0
int guac_rdp_download_get_handler(guac_client* client, guac_object* object,
        char* name) {

    /* Get filesystem, ignore request if no filesystem */
    guac_rdp_fs* fs = ((rdp_guac_client_data*) client->data)->filesystem;
    if (fs == NULL)
        return 0;

    /* Attempt to open file for reading */
    int file_id = guac_rdp_fs_open(fs, name, ACCESS_GENERIC_READ, 0,
            DISP_FILE_OPEN, 0);
    if (file_id < 0) {
        guac_client_log(client, GUAC_LOG_INFO, "Unable to read file \"%s\"",
                name);
        return 0;
    }

    /* Get opened file */
    guac_rdp_fs_file* file = guac_rdp_fs_get_file(fs, file_id);
    if (file == NULL) {
        guac_client_log(fs->client, GUAC_LOG_DEBUG,
                "%s: Successful open produced bad file_id: %i",
                __func__, file_id);
        return 0;
    }

    /* If directory, send contents of directory */
    if (file->attributes & FILE_ATTRIBUTE_DIRECTORY) {

        /* Create stream data */
        guac_rdp_stream* rdp_stream = malloc(sizeof(guac_rdp_stream));
        rdp_stream->type = GUAC_RDP_LS_STREAM;
        rdp_stream->ls_status.fs = fs;
        rdp_stream->ls_status.file_id = file_id;
        strncpy(rdp_stream->ls_status.directory_name, name,
                sizeof(rdp_stream->ls_status.directory_name));

        /* Allocate stream for body */
        guac_stream* stream = guac_client_alloc_stream(client);
        stream->ack_handler = guac_rdp_ls_ack_handler;
        stream->data = rdp_stream;

        /* Init JSON object state */
        guac_common_json_begin_object(client, stream,
                &rdp_stream->ls_status.json_state);

        /* Associate new stream with get request */
        guac_protocol_send_body(client->socket, object, stream,
                GUAC_CLIENT_STREAM_INDEX_MIMETYPE, name);

    }

    /* Otherwise, send file contents */
    else {

        /* Create stream data */
        guac_rdp_stream* rdp_stream = malloc(sizeof(guac_rdp_stream));
        rdp_stream->type = GUAC_RDP_DOWNLOAD_STREAM;
        rdp_stream->download_status.file_id = file_id;
        rdp_stream->download_status.offset = 0;

        /* Allocate stream for body */
        guac_stream* stream = guac_client_alloc_stream(client);
        stream->data = rdp_stream;
        stream->ack_handler = guac_rdp_download_ack_handler;

        /* Associate new stream with get request */
        guac_protocol_send_body(client->socket, object, stream,
                "application/octet-stream", name);

    }

    guac_socket_flush(client->socket);
    return 0;
}
/**
 * Guacamole client plugin entry point. This function will be called by guacd
 * when the protocol associated with this plugin is selected.
 *
 * @param client
 *     A newly-allocated guac_client structure representing the client which
 *     connected to guacd.
 *
 * @param argc
 *     The number of arguments within the argv array.
 *
 * @param argv
 *     All arguments passed during the Guacamole protocol handshake. These
 *     arguments correspond identically in both order and number to the
 *     arguments listed in GUAC_CLIENT_ARGS.
 */
int guac_client_init(guac_client* client, int argc, char** argv) {

    /* Validate argument count */
    if (argc != STREAMTEST_ARGS_COUNT) {
        guac_client_log(client, GUAC_LOG_ERROR, "Wrong number of arguments.");
        return 1;
    }

    /* Allocate stream for media */
    streamtest_playback_mode mode;
    guac_stream* stream = guac_client_alloc_stream(client);

    /* Determine playback mode from mimetype */
    if (strncmp(argv[IDX_MIMETYPE], "audio/", 6) == 0) {
        mode = STREAMTEST_AUDIO;
        guac_client_log(client, GUAC_LOG_DEBUG,
                "Recognized type \"%s\" as audio",
                argv[IDX_MIMETYPE]);
    }
    else if (strncmp(argv[IDX_MIMETYPE], "video/", 6) == 0) {
        mode = STREAMTEST_VIDEO;
        guac_client_log(client, GUAC_LOG_DEBUG,
                "Recognized type \"%s\" as video",
                argv[IDX_MIMETYPE]);
    }

    /* Abort if type cannot be recognized */
    else {
        guac_client_log(client, GUAC_LOG_ERROR,
                "Invalid media type \"%s\" (not audio nor video)",
                argv[IDX_MIMETYPE]);
        return 1;
    }

    /* Initialize streaming depending on playback mode */
    switch (mode) {

        /* Set up progress bar for audio streams */
        case STREAMTEST_AUDIO:

            /* Begin audio stream */
            guac_protocol_send_audio(client->socket, stream,
                    argv[IDX_MIMETYPE]);

            /* Init display */
            guac_protocol_send_size(client->socket, GUAC_DEFAULT_LAYER,
                    STREAMTEST_PROGRESS_WIDTH,
                    STREAMTEST_PROGRESS_HEIGHT);
            break;

        /* Set up generic video area for video streams */
        case STREAMTEST_VIDEO:

            /* Begin video stream */
            guac_protocol_send_video(client->socket, stream,
                    GUAC_DEFAULT_LAYER, argv[IDX_MIMETYPE]);

            /* Init display */
            guac_protocol_send_size(client->socket, GUAC_DEFAULT_LAYER,
                    client->info.optimal_width,
                    client->info.optimal_height);
            break;

        /* There are no other playback modes */
        default:
            assert(false);

    }

    /* Attempt to open specified file, abort on error */
    int fd = open(argv[IDX_FILENAME], O_RDONLY);
    if (fd == -1) {
        guac_client_log(client, GUAC_LOG_ERROR,
                "Unable to open \"%s\": %s",
                argv[IDX_FILENAME], strerror(errno));
        return 1;
    }

    int file_size = streamtest_get_file_size(fd);
    if (file_size == -1) {
        guac_client_log(client, GUAC_LOG_ERROR,
                "Unable to determine size of file \"%s\": %s",
                argv[IDX_FILENAME], strerror(errno));
        return 1;
    }

    guac_client_log(client, GUAC_LOG_DEBUG,
            "Successfully opened file \"%s\" (%i bytes)",
            argv[IDX_FILENAME], file_size);

    /* Allocate state structure */
    streamtest_state* state = malloc(sizeof(streamtest_state));

    /* Set frame duration/size */
    state->frame_duration = atoi(argv[IDX_FRAME_USECS]);
    state->frame_bytes    = atoi(argv[IDX_BYTES_PER_FRAME]);
    state->frame_buffer   = malloc(state->frame_bytes);

    guac_client_log(client, GUAC_LOG_DEBUG,
            "Frames will last %i microseconds and contain %i bytes",
            state->frame_duration, state->frame_bytes);

    /* Start with the file closed, playback not paused */
    state->mode = mode;
    state->stream = stream;
    state->fd = fd;
    state->paused = false;
    state->file_size = file_size;

    /* Set client handlers and data */
    client->handle_messages = streamtest_client_message_handler;
    client->key_handler     = streamtest_client_key_handler;
    client->free_handler    = streamtest_client_free_handler;
    client->data = state;

    /* Render initial progress bar */
    streamtest_render_progress(client);
    guac_socket_flush(client->socket);

    /* Initialization complete */
    return 0;

}