Ejemplo n.º 1
0
void guac_rdp_gdi_desktop_resize(rdpContext* context) {

    guac_client* client = ((rdp_freerdp_context*) context)->client;
    rdp_guac_client_data* data = (rdp_guac_client_data*) client->data;

    guac_common_surface_resize(data->default_surface,
            guac_rdp_get_width(context->instance),
            guac_rdp_get_height(context->instance));

    guac_common_surface_reset_clip(data->default_surface);

    guac_client_log(client, GUAC_LOG_DEBUG, "Server resized display to %ix%i",
            guac_rdp_get_width(context->instance),
            guac_rdp_get_height(context->instance));

}
Ejemplo n.º 2
0
static int __guac_receive_channel_data(freerdp* rdp_inst, UINT16 channelId,
        BYTE* data, int size, int flags, int total_size) {
#else
static int __guac_receive_channel_data(freerdp* rdp_inst, int channelId,
        UINT8* data, int size, int flags, int total_size) {
#endif
    return freerdp_channels_data(rdp_inst, channelId,
            data, size, flags, total_size);
}

#ifdef HAVE_FREERDP_EVENT_PUBSUB
/**
 * Called whenever a channel connects via the PubSub event system within
 * FreeRDP.
 *
 * @param context
 *     The rdpContext associated with the active RDP session.
 *
 * @param e
 *     Event-specific arguments, mainly the name of the channel, and a
 *     reference to the associated plugin loaded for that channel by FreeRDP.
 */
static void guac_rdp_channel_connected(rdpContext* context,
        ChannelConnectedEventArgs* e) {

    guac_client* client = ((rdp_freerdp_context*) context)->client;
    guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
    guac_rdp_settings* settings = rdp_client->settings;

    if (settings->resize_method == GUAC_RESIZE_DISPLAY_UPDATE) {
#ifdef HAVE_RDPSETTINGS_SUPPORTDISPLAYCONTROL
        /* Store reference to the display update plugin once it's connected */
        if (strcmp(e->name, DISP_DVC_CHANNEL_NAME) == 0) {

            DispClientContext* disp = (DispClientContext*) e->pInterface;

            /* Init module with current display size */
            guac_rdp_disp_set_size(rdp_client->disp, rdp_client->settings,
                    context->instance, guac_rdp_get_width(context->instance),
                    guac_rdp_get_height(context->instance));

            /* Store connected channel */
            guac_rdp_disp_connect(rdp_client->disp, disp);
            guac_client_log(client, GUAC_LOG_DEBUG,
                    "Display update channel connected.");

        }
#endif
    }

}
Ejemplo n.º 3
0
void guac_rdp_disp_update_size(guac_rdp_disp* disp,
        guac_rdp_settings* settings, freerdp* rdp_inst) {

    int width = disp->requested_width;
    int height = disp->requested_height;

    /* Do not update size if no requests have been received */
    if (width == 0 || height == 0)
        return;

    guac_timestamp now = guac_timestamp_current();

    /* Limit display update frequency */
    if (now - disp->last_request <= GUAC_RDP_DISP_UPDATE_INTERVAL)
        return;

    /* Do NOT send requests unless the size will change */
    if (rdp_inst != NULL
            && width == guac_rdp_get_width(rdp_inst)
            && height == guac_rdp_get_height(rdp_inst))
        return;

    disp->last_request = now;

    if (settings->resize_method == GUAC_RESIZE_RECONNECT) {

        /* Update settings with new dimensions */
        settings->width = width;
        settings->height = height;

        /* Signal reconnect */
        disp->reconnect_needed = 1;

    }

    else if (settings->resize_method == GUAC_RESIZE_DISPLAY_UPDATE) {
#ifdef HAVE_FREERDP_DISPLAY_UPDATE_SUPPORT
        DISPLAY_CONTROL_MONITOR_LAYOUT monitors[1] = {{
            .Flags  = 0x1, /* DISPLAYCONTROL_MONITOR_PRIMARY */
            .Left = 0,
            .Top = 0,
            .Width  = width,
            .Height = height,
            .PhysicalWidth = 0,
            .PhysicalHeight = 0,
            .Orientation = 0,
            .DesktopScaleFactor = 0,
            .DeviceScaleFactor = 0
        }};
Ejemplo n.º 4
0
int __guac_receive_channel_data(freerdp* rdp_inst, UINT16 channelId, BYTE* data, int size, int flags, int total_size) {
#else
int __guac_receive_channel_data(freerdp* rdp_inst, int channelId, UINT8* data, int size, int flags, int total_size) {
#endif
    return freerdp_channels_data(rdp_inst, channelId, data, size, flags, total_size);
}

#ifdef HAVE_FREERDP_EVENT_PUBSUB
/**
 * Called whenever a channel connects via the PubSub event system within
 * FreeRDP.
 *
 * @param context The rdpContext associated with the active RDP session.
 * @param e Event-specific arguments, mainly the name of the channel, and a
 *          reference to the associated plugin loaded for that channel by
 *          FreeRDP.
 */
static void guac_rdp_channel_connected(rdpContext* context,
        ChannelConnectedEventArgs* e) {

#ifdef HAVE_RDPSETTINGS_SUPPORTDISPLAYCONTROL
    /* Store reference to the display update plugin once it's connected */
    if (strcmp(e->name, DISP_DVC_CHANNEL_NAME) == 0) {

        DispClientContext* disp = (DispClientContext*) e->pInterface;

        guac_client* client = ((rdp_freerdp_context*) context)->client;
        rdp_guac_client_data* guac_client_data =
            (rdp_guac_client_data*) client->data;

        /* Init module with current display size */
        guac_rdp_disp_set_size(guac_client_data->disp, context,
                guac_rdp_get_width(context->instance),
                guac_rdp_get_height(context->instance));

        /* Store connected channel */
        guac_rdp_disp_connect(guac_client_data->disp, disp);
        guac_client_log(client, GUAC_LOG_DEBUG,
                "Display update channel connected.");

    }
#endif

}
#endif

BOOL rdp_freerdp_pre_connect(freerdp* instance) {

    rdpContext* context = instance->context;
    guac_client* client = ((rdp_freerdp_context*) context)->client;
    rdpChannels* channels = context->channels;
    rdpBitmap* bitmap;
    rdpGlyph* glyph;
    rdpPointer* pointer;
    rdpPrimaryUpdate* primary;
    CLRCONV* clrconv;

    rdp_guac_client_data* guac_client_data =
        (rdp_guac_client_data*) client->data;

#ifdef HAVE_FREERDP_REGISTER_ADDIN_PROVIDER
    /* Init FreeRDP add-in provider */
    freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0);
#endif

#ifdef HAVE_FREERDP_EVENT_PUBSUB
    /* Subscribe to and handle channel connected events */
    PubSub_SubscribeChannelConnected(context->pubSub,
            (pChannelConnectedEventHandler) guac_rdp_channel_connected);
#endif

#ifdef HAVE_FREERDP_DISPLAY_UPDATE_SUPPORT
    /* Load virtual channel management plugin */
    if (freerdp_channels_load_plugin(channels, instance->settings,
                "drdynvc", instance->settings))
        guac_client_log(client, GUAC_LOG_WARNING,
                "Failed to load drdynvc plugin.");

    /* Init display update plugin */
    guac_client_data->disp = guac_rdp_disp_alloc();
    guac_rdp_disp_load_plugin(instance->context);
#endif

    /* Load clipboard plugin */
    if (freerdp_channels_load_plugin(channels, instance->settings,
                "cliprdr", NULL))
        guac_client_log(client, GUAC_LOG_WARNING,
                "Failed to load cliprdr plugin. Clipboard will not work.");

    /* If audio enabled, choose an encoder */
    if (guac_client_data->settings.audio_enabled) {

        guac_client_data->audio = guac_audio_stream_alloc(client, NULL);

        /* If an encoding is available, load the sound plugin */
        if (guac_client_data->audio != NULL) {

            /* Load sound plugin */
            if (freerdp_channels_load_plugin(channels, instance->settings,
                        "guacsnd", guac_client_data->audio))
                guac_client_log(client, GUAC_LOG_WARNING,
                        "Failed to load guacsnd plugin. Audio will not work.");

        }
        else
            guac_client_log(client, GUAC_LOG_INFO,
                    "No available audio encoding. Sound disabled.");

    } /* end if audio enabled */

    /* Load filesystem if drive enabled */
    if (guac_client_data->settings.drive_enabled) {

        /* Allocate filesystem */
        guac_client_data->filesystem =
            guac_rdp_fs_alloc(client, guac_client_data->settings.drive_path,
                    guac_client_data->settings.create_drive_path);

        /* Use for basic uploads if no other handler set */
        if (client->file_handler == NULL)
            client->file_handler = guac_rdp_upload_file_handler;

    }

    /* If RDPDR required, load it */
    if (guac_client_data->settings.printing_enabled
        || guac_client_data->settings.drive_enabled
        || guac_client_data->settings.audio_enabled) {

        /* Load RDPDR plugin */
        if (freerdp_channels_load_plugin(channels, instance->settings,
                    "guacdr", client))
            guac_client_log(client, GUAC_LOG_WARNING,
                    "Failed to load guacdr plugin. Drive redirection and printing will not work.");

    }

    /* Load RAIL plugin if RemoteApp in use */
    if (guac_client_data->settings.remote_app != NULL) {

#ifdef LEGACY_FREERDP
        RDP_PLUGIN_DATA* plugin_data = malloc(sizeof(RDP_PLUGIN_DATA) * 2);

        plugin_data[0].size = sizeof(RDP_PLUGIN_DATA);
        plugin_data[0].data[0] = guac_client_data->settings.remote_app;
        plugin_data[0].data[1] = guac_client_data->settings.remote_app_dir;
        plugin_data[0].data[2] = guac_client_data->settings.remote_app_args; 
        plugin_data[0].data[3] = NULL;

        plugin_data[1].size = 0;

        /* Attempt to load rail */
        if (freerdp_channels_load_plugin(channels, instance->settings,
                    "rail", plugin_data))
            guac_client_log(client, GUAC_LOG_WARNING,
                    "Failed to load rail plugin. RemoteApp will not work.");
#else
        /* Attempt to load rail */
        if (freerdp_channels_load_plugin(channels, instance->settings,
                    "rail", instance->settings))
            guac_client_log(client, GUAC_LOG_WARNING,
                    "Failed to load rail plugin. RemoteApp will not work.");
#endif

    }

    /* Load SVC plugin instances for all static channels */
    if (guac_client_data->settings.svc_names != NULL) {

        char** current = guac_client_data->settings.svc_names;
        do {

            guac_rdp_svc* svc = guac_rdp_alloc_svc(client, *current);

            /* Attempt to load guacsvc plugin for new static channel */
            if (freerdp_channels_load_plugin(channels, instance->settings,
                        "guacsvc", svc)) {
                guac_client_log(client, GUAC_LOG_WARNING,
                        "Cannot create static channel \"%s\": failed to load guacsvc plugin.",
                        svc->name);
                guac_rdp_free_svc(svc);
            }

            /* Store and log on success */
            else {
                guac_rdp_add_svc(client, svc);
                guac_client_log(client, GUAC_LOG_INFO, "Created static channel \"%s\"...",
                        svc->name);
            }

        } while (*(++current) != NULL);

    }

    /* Init color conversion structure */
    clrconv = calloc(1, sizeof(CLRCONV));
    clrconv->alpha = 1;
    clrconv->invert = 0;
    clrconv->rgb555 = 0;
    clrconv->palette = calloc(1, sizeof(rdpPalette));
    ((rdp_freerdp_context*) context)->clrconv = clrconv;

    /* Init FreeRDP cache */
    instance->context->cache = cache_new(instance->settings);

    /* Set up bitmap handling */
    bitmap = calloc(1, sizeof(rdpBitmap));
    bitmap->size = sizeof(guac_rdp_bitmap);
    bitmap->New = guac_rdp_bitmap_new;
    bitmap->Free = guac_rdp_bitmap_free;
    bitmap->Paint = guac_rdp_bitmap_paint;
    bitmap->Decompress = guac_rdp_bitmap_decompress;
    bitmap->SetSurface = guac_rdp_bitmap_setsurface;
    graphics_register_bitmap(context->graphics, bitmap);
    free(bitmap);

    /* Set up glyph handling */
    glyph = calloc(1, sizeof(rdpGlyph));
    glyph->size = sizeof(guac_rdp_glyph);
    glyph->New = guac_rdp_glyph_new;
    glyph->Free = guac_rdp_glyph_free;
    glyph->Draw = guac_rdp_glyph_draw;
    glyph->BeginDraw = guac_rdp_glyph_begindraw;
    glyph->EndDraw = guac_rdp_glyph_enddraw;
    graphics_register_glyph(context->graphics, glyph);
    free(glyph);

    /* Set up pointer handling */
    pointer = calloc(1, sizeof(rdpPointer));
    pointer->size = sizeof(guac_rdp_pointer);
    pointer->New = guac_rdp_pointer_new;
    pointer->Free = guac_rdp_pointer_free;
    pointer->Set = guac_rdp_pointer_set;
#ifdef HAVE_RDPPOINTER_SETNULL
    pointer->SetNull = guac_rdp_pointer_set_null;
#endif
#ifdef HAVE_RDPPOINTER_SETDEFAULT
    pointer->SetDefault = guac_rdp_pointer_set_default;
#endif
    graphics_register_pointer(context->graphics, pointer);
    free(pointer);

    /* Set up GDI */
    instance->update->DesktopResize = guac_rdp_gdi_desktop_resize;
    instance->update->EndPaint = guac_rdp_gdi_end_paint;
    instance->update->Palette = guac_rdp_gdi_palette_update;
    instance->update->SetBounds = guac_rdp_gdi_set_bounds;

    primary = instance->update->primary;
    primary->DstBlt = guac_rdp_gdi_dstblt;
    primary->PatBlt = guac_rdp_gdi_patblt;
    primary->ScrBlt = guac_rdp_gdi_scrblt;
    primary->MemBlt = guac_rdp_gdi_memblt;
    primary->OpaqueRect = guac_rdp_gdi_opaquerect;

    pointer_cache_register_callbacks(instance->update);
    glyph_cache_register_callbacks(instance->update);
    brush_cache_register_callbacks(instance->update);
    bitmap_cache_register_callbacks(instance->update);
    offscreen_cache_register_callbacks(instance->update);
    palette_cache_register_callbacks(instance->update);

    /* Init channels (pre-connect) */
    if (freerdp_channels_pre_connect(channels, instance)) {
        guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Error initializing RDP client channel manager");
        return FALSE;
    }

    return TRUE;

}