BOOL wl_pre_connect(freerdp* instance) { struct display* display; struct wl_context* context; freerdp_channels_pre_connect(instance->context->channels, instance); display = malloc(sizeof(*display)); display->display = wl_display_connect(NULL); if (!display->display) { fprintf(stderr, "wl_pre_connect: failed to connect to Wayland compositor\n"); fprintf(stderr, "Please check that the XDG_RUNTIME_DIR environment variable is properly set.\n"); free(display); return FALSE; } display->registry = wl_display_get_registry(display->display); wl_registry_add_listener(display->registry, &wl_registry_listener, display); wl_display_roundtrip(display->display); if (!display->compositor || !display->shell || !display->shm) { fprintf(stderr, "wl_pre_connect: failed to find needed compositor interfaces\n"); free(display); return FALSE; } /* put Wayland data in the context here */ context = (struct wl_context*) instance->context; context->display = display; return TRUE; }
void test_channels(void) { rdpChannels* chan_man; rdpSettings settings = { 0 }; freerdp instance = { 0 }; RDP_EVENT* event; settings.hostname = "testhost"; instance.settings = &settings; instance.SendChannelData = test_rdp_channel_data; chan_man = freerdp_channels_new(); freerdp_channels_load_plugin(chan_man, &settings, "../channels/rdpdbg/rdpdbg.so", NULL); freerdp_channels_pre_connect(chan_man, &instance); freerdp_channels_post_connect(chan_man, &instance); freerdp_channels_data(&instance, 0, "testdata", 8, CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, 8); freerdp_channels_data(&instance, 0, "testdata1", 9, CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, 9); freerdp_channels_data(&instance, 0, "testdata11", 10, CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, 10); freerdp_channels_data(&instance, 0, "testdata111", 11, CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, 11); event = freerdp_event_new(RDP_EVENT_CLASS_DEBUG, 0, NULL, NULL); freerdp_channels_send_event(chan_man, event); while ((event = freerdp_channels_pop_event(chan_man)) == NULL) { freerdp_channels_check_fds(chan_man, &instance); } printf("responded event_type %d\n", event->event_type); freerdp_event_free(event); freerdp_channels_close(chan_man, &instance); freerdp_channels_free(chan_man); }
static boolean remmina_rdp_pre_connect(freerdp* instance) { rfContext* rfi; rdpSettings* settings; RemminaProtocolWidget* gp; rfi = (rfContext*) instance->context; settings = instance->settings; gp = rfi->protocol_widget; settings->bitmap_cache = True; settings->offscreen_bitmap_cache = True; settings->order_support[NEG_DSTBLT_INDEX] = True; settings->order_support[NEG_PATBLT_INDEX] = True; settings->order_support[NEG_SCRBLT_INDEX] = True; settings->order_support[NEG_OPAQUE_RECT_INDEX] = True; settings->order_support[NEG_DRAWNINEGRID_INDEX] = False; settings->order_support[NEG_MULTIDSTBLT_INDEX] = False; settings->order_support[NEG_MULTIPATBLT_INDEX] = False; settings->order_support[NEG_MULTISCRBLT_INDEX] = False; settings->order_support[NEG_MULTIOPAQUERECT_INDEX] = True; settings->order_support[NEG_MULTI_DRAWNINEGRID_INDEX] = False; settings->order_support[NEG_LINETO_INDEX] = True; settings->order_support[NEG_POLYLINE_INDEX] = True; settings->order_support[NEG_MEMBLT_INDEX] = True; settings->order_support[NEG_MEM3BLT_INDEX] = False; settings->order_support[NEG_MEMBLT_V2_INDEX] = True; settings->order_support[NEG_MEM3BLT_V2_INDEX] = False; settings->order_support[NEG_SAVEBITMAP_INDEX] = False; settings->order_support[NEG_GLYPH_INDEX_INDEX] = True; settings->order_support[NEG_FAST_INDEX_INDEX] = True; settings->order_support[NEG_FAST_GLYPH_INDEX] = False; settings->order_support[NEG_POLYGON_SC_INDEX] = False; settings->order_support[NEG_POLYGON_CB_INDEX] = False; settings->order_support[NEG_ELLIPSE_SC_INDEX] = False; settings->order_support[NEG_ELLIPSE_CB_INDEX] = False; if (settings->rfx_codec == True) { settings->frame_acknowledge = False; settings->large_pointer = True; settings->performance_flags = PERF_FLAG_NONE; rfi->rfx_context = rfx_context_new(); rfx_context_set_cpu_opt(rfi->rfx_context, CPU_SSE2); } freerdp_channels_pre_connect(rfi->channels, instance); rfi->clrconv = xnew(CLRCONV); rfi->clrconv->alpha = true; rfi->clrconv->invert = false; rfi->clrconv->rgb555 = false; rfi->clrconv->palette = xnew(rdpPalette); instance->context->cache = cache_new(instance->settings); return True; }
static BOOL wl_pre_connect(freerdp* instance) { wlfDisplay* display; wlfInput* input; wlfContext* context; if (freerdp_channels_pre_connect(instance->context->channels, instance)) return FALSE; context = (wlfContext*) instance->context; if (!context) return FALSE; display = wlf_CreateDisplay(); if (!display) return FALSE; context->display = display; input = wlf_CreateInput(context); if (!input) return FALSE; context->input = input; return TRUE; }
void test_drdynvc(void) { rdpChannels* chan_man; rdpSettings settings = { 0 }; freerdp instance = { 0 }; settings.Hostname = "testhost"; instance.settings = &settings; instance.SendChannelData = test_rdp_channel_data; chan_man = freerdp_channels_new(); freerdp_channels_load_plugin(chan_man, &settings, "../channels/drdynvc/drdynvc.so", NULL); freerdp_channels_pre_connect(chan_man, &instance); freerdp_channels_post_connect(chan_man, &instance); /* server sends capability request PDU */ freerdp_channels_data(&instance, 0, (char*)test_capability_request_data, sizeof(test_capability_request_data) - 1, CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, sizeof(test_capability_request_data) - 1); /* drdynvc sends capability response PDU to server */ data_received = 0; while (!data_received) { freerdp_channels_check_fds(chan_man, &instance); } freerdp_channels_close(chan_man, &instance); freerdp_channels_free(chan_man); }
static BOOL remmina_rdp_pre_connect(freerdp* instance) { rfContext* rfi; ALIGN64 rdpSettings* settings; RemminaProtocolWidget* gp; rdpChannels *channels; rfi = (rfContext*) instance->context; settings = instance->settings; gp = rfi->protocol_widget; channels = instance->context->channels; settings->BitmapCacheEnabled = True; settings->OffscreenSupportLevel = True; settings->OrderSupport[NEG_DSTBLT_INDEX] = True; settings->OrderSupport[NEG_PATBLT_INDEX] = True; settings->OrderSupport[NEG_SCRBLT_INDEX] = True; settings->OrderSupport[NEG_OPAQUE_RECT_INDEX] = True; settings->OrderSupport[NEG_DRAWNINEGRID_INDEX] = False; settings->OrderSupport[NEG_MULTIDSTBLT_INDEX] = False; settings->OrderSupport[NEG_MULTIPATBLT_INDEX] = False; settings->OrderSupport[NEG_MULTISCRBLT_INDEX] = False; settings->OrderSupport[NEG_MULTIOPAQUERECT_INDEX] = True; settings->OrderSupport[NEG_MULTI_DRAWNINEGRID_INDEX] = False; settings->OrderSupport[NEG_LINETO_INDEX] = True; settings->OrderSupport[NEG_POLYLINE_INDEX] = True; settings->OrderSupport[NEG_MEMBLT_INDEX] = settings->BitmapCacheEnabled; settings->OrderSupport[NEG_MEM3BLT_INDEX] = True; settings->OrderSupport[NEG_MEMBLT_V2_INDEX] = settings->BitmapCacheEnabled; settings->OrderSupport[NEG_MEM3BLT_V2_INDEX] = False; settings->OrderSupport[NEG_SAVEBITMAP_INDEX] = False; settings->OrderSupport[NEG_GLYPH_INDEX_INDEX] = True; settings->OrderSupport[NEG_FAST_INDEX_INDEX] = True; settings->OrderSupport[NEG_FAST_GLYPH_INDEX] = True; settings->OrderSupport[NEG_POLYGON_SC_INDEX] = False; settings->OrderSupport[NEG_POLYGON_CB_INDEX] = False; settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = False; settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = False; if (settings->RemoteFxCodec == True) { settings->FrameAcknowledge = False; settings->LargePointerFlag = True; settings->PerformanceFlags = PERF_FLAG_NONE; rfi->rfx_context = rfx_context_new(); } freerdp_client_load_addins(instance->context->channels, instance->settings); freerdp_channels_pre_connect(instance->context->channels, instance); rfi->clrconv = freerdp_clrconv_new(CLRCONV_ALPHA); instance->context->cache = cache_new(instance->settings); return True; }
BOOL df_pre_connect(freerdp* instance) { dfInfo* dfi; BOOL bitmap_cache; dfContext* context; rdpSettings* settings; dfi = (dfInfo*) malloc(sizeof(dfInfo)); ZeroMemory(dfi, sizeof(dfInfo)); context = ((dfContext*) instance->context); context->dfi = dfi; settings = instance->settings; bitmap_cache = settings->BitmapCacheEnabled; settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE; settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE; settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE; settings->OrderSupport[NEG_OPAQUE_RECT_INDEX] = TRUE; settings->OrderSupport[NEG_DRAWNINEGRID_INDEX] = FALSE; settings->OrderSupport[NEG_MULTIDSTBLT_INDEX] = FALSE; settings->OrderSupport[NEG_MULTIPATBLT_INDEX] = FALSE; settings->OrderSupport[NEG_MULTISCRBLT_INDEX] = FALSE; settings->OrderSupport[NEG_MULTIOPAQUERECT_INDEX] = TRUE; settings->OrderSupport[NEG_MULTI_DRAWNINEGRID_INDEX] = FALSE; settings->OrderSupport[NEG_LINETO_INDEX] = TRUE; settings->OrderSupport[NEG_POLYLINE_INDEX] = TRUE; settings->OrderSupport[NEG_MEMBLT_INDEX] = bitmap_cache; settings->OrderSupport[NEG_MEM3BLT_INDEX] = FALSE; settings->OrderSupport[NEG_MEMBLT_V2_INDEX] = bitmap_cache; settings->OrderSupport[NEG_MEM3BLT_V2_INDEX] = FALSE; settings->OrderSupport[NEG_SAVEBITMAP_INDEX] = FALSE; settings->OrderSupport[NEG_GLYPH_INDEX_INDEX] = FALSE; settings->OrderSupport[NEG_FAST_INDEX_INDEX] = FALSE; settings->OrderSupport[NEG_FAST_GLYPH_INDEX] = FALSE; settings->OrderSupport[NEG_POLYGON_SC_INDEX] = FALSE; settings->OrderSupport[NEG_POLYGON_CB_INDEX] = FALSE; settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE; settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE; dfi->clrconv = (CLRCONV*) malloc(sizeof(CLRCONV)); ZeroMemory(dfi->clrconv, sizeof(CLRCONV)); dfi->clrconv->alpha = 1; dfi->clrconv->invert = 0; dfi->clrconv->rgb555 = 0; dfi->clrconv->palette = (rdpPalette*) malloc(sizeof(rdpPalette)); ZeroMemory(dfi->clrconv->palette, sizeof(rdpPalette)); freerdp_channels_pre_connect(instance->context->channels, instance); instance->context->cache = cache_new(instance->settings); return TRUE; }
static BOOL wl_pre_connect(freerdp* instance) { wlfContext* context; if (freerdp_channels_pre_connect(instance->context->channels, instance)) return FALSE; context = (wlfContext*) instance->context; if (!context) return FALSE; context->display = g_display; return TRUE; }
static BOOL android_pre_connect(freerdp* instance) { DEBUG_ANDROID("android_pre_connect"); rdpSettings* settings = instance->settings; BOOL bitmap_cache = settings->BitmapCacheEnabled; settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE; settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE; settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE; settings->OrderSupport[NEG_OPAQUE_RECT_INDEX] = TRUE; settings->OrderSupport[NEG_DRAWNINEGRID_INDEX] = FALSE; settings->OrderSupport[NEG_MULTIDSTBLT_INDEX] = FALSE; settings->OrderSupport[NEG_MULTIPATBLT_INDEX] = FALSE; settings->OrderSupport[NEG_MULTISCRBLT_INDEX] = FALSE; settings->OrderSupport[NEG_MULTIOPAQUERECT_INDEX] = TRUE; settings->OrderSupport[NEG_MULTI_DRAWNINEGRID_INDEX] = FALSE; settings->OrderSupport[NEG_LINETO_INDEX] = TRUE; settings->OrderSupport[NEG_POLYLINE_INDEX] = TRUE; settings->OrderSupport[NEG_MEMBLT_INDEX] = bitmap_cache; settings->OrderSupport[NEG_MEM3BLT_INDEX] = TRUE; settings->OrderSupport[NEG_MEMBLT_V2_INDEX] = bitmap_cache; settings->OrderSupport[NEG_MEM3BLT_V2_INDEX] = FALSE; settings->OrderSupport[NEG_SAVEBITMAP_INDEX] = FALSE; settings->OrderSupport[NEG_GLYPH_INDEX_INDEX] = TRUE; settings->OrderSupport[NEG_FAST_INDEX_INDEX] = TRUE; settings->OrderSupport[NEG_FAST_GLYPH_INDEX] = TRUE; settings->OrderSupport[NEG_POLYGON_SC_INDEX] = FALSE; settings->OrderSupport[NEG_POLYGON_CB_INDEX] = FALSE; settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE; settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE; settings->FrameAcknowledge = 10; PubSub_SubscribeChannelConnected(instance->context->pubSub, (pChannelConnectedEventHandler) android_OnChannelConnectedEventHandler); PubSub_SubscribeChannelDisconnected(instance->context->pubSub, (pChannelDisconnectedEventHandler) android_OnChannelDisconnectedEventHandler); freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0); freerdp_client_load_addins(instance->context->channels, instance->settings); freerdp_channels_pre_connect(instance->context->channels, instance); return TRUE; }
boolean df_pre_connect(freerdp* instance) { dfInfo* dfi; dfContext* context; rdpSettings* settings; dfi = (dfInfo*) xzalloc(sizeof(dfInfo)); context = ((dfContext*) instance->context); context->dfi = dfi; settings = instance->settings; settings->order_support[NEG_DSTBLT_INDEX] = true; settings->order_support[NEG_PATBLT_INDEX] = true; settings->order_support[NEG_SCRBLT_INDEX] = true; settings->order_support[NEG_OPAQUE_RECT_INDEX] = true; settings->order_support[NEG_DRAWNINEGRID_INDEX] = false; settings->order_support[NEG_MULTIDSTBLT_INDEX] = false; settings->order_support[NEG_MULTIPATBLT_INDEX] = false; settings->order_support[NEG_MULTISCRBLT_INDEX] = false; settings->order_support[NEG_MULTIOPAQUERECT_INDEX] = true; settings->order_support[NEG_MULTI_DRAWNINEGRID_INDEX] = false; settings->order_support[NEG_LINETO_INDEX] = true; settings->order_support[NEG_POLYLINE_INDEX] = true; settings->order_support[NEG_MEMBLT_INDEX] = true; settings->order_support[NEG_MEM3BLT_INDEX] = false; settings->order_support[NEG_SAVEBITMAP_INDEX] = false; settings->order_support[NEG_GLYPH_INDEX_INDEX] = false; settings->order_support[NEG_FAST_INDEX_INDEX] = false; settings->order_support[NEG_FAST_GLYPH_INDEX] = false; settings->order_support[NEG_POLYGON_SC_INDEX] = false; settings->order_support[NEG_POLYGON_CB_INDEX] = false; settings->order_support[NEG_ELLIPSE_SC_INDEX] = false; settings->order_support[NEG_ELLIPSE_CB_INDEX] = false; dfi->clrconv = xnew(CLRCONV); dfi->clrconv->alpha = 1; dfi->clrconv->invert = 0; dfi->clrconv->rgb555 = 0; dfi->clrconv->palette = xnew(rdpPalette); freerdp_channels_pre_connect(instance->context->channels, instance); return true; }
BOOL tf_pre_connect(freerdp* instance) { tfInfo* tfi; tfContext* context; rdpSettings* settings; context = (tfContext*) instance->context; tfi = (tfInfo*) malloc(sizeof(tfInfo)); ZeroMemory(tfi, sizeof(tfInfo)); context->tfi = tfi; settings = instance->settings; settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE; settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE; settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE; settings->OrderSupport[NEG_OPAQUE_RECT_INDEX] = TRUE; settings->OrderSupport[NEG_DRAWNINEGRID_INDEX] = TRUE; settings->OrderSupport[NEG_MULTIDSTBLT_INDEX] = TRUE; settings->OrderSupport[NEG_MULTIPATBLT_INDEX] = TRUE; settings->OrderSupport[NEG_MULTISCRBLT_INDEX] = TRUE; settings->OrderSupport[NEG_MULTIOPAQUERECT_INDEX] = TRUE; settings->OrderSupport[NEG_MULTI_DRAWNINEGRID_INDEX] = TRUE; settings->OrderSupport[NEG_LINETO_INDEX] = TRUE; settings->OrderSupport[NEG_POLYLINE_INDEX] = TRUE; settings->OrderSupport[NEG_MEMBLT_INDEX] = TRUE; settings->OrderSupport[NEG_MEM3BLT_INDEX] = TRUE; settings->OrderSupport[NEG_SAVEBITMAP_INDEX] = TRUE; settings->OrderSupport[NEG_GLYPH_INDEX_INDEX] = TRUE; settings->OrderSupport[NEG_FAST_INDEX_INDEX] = TRUE; settings->OrderSupport[NEG_FAST_GLYPH_INDEX] = TRUE; settings->OrderSupport[NEG_POLYGON_SC_INDEX] = TRUE; settings->OrderSupport[NEG_POLYGON_CB_INDEX] = TRUE; settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = TRUE; settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = TRUE; freerdp_channels_pre_connect(instance->context->channels, instance); return TRUE; }
BOOL shw_pre_connect(freerdp* instance) { shwContext* shw; rdpContext* context = instance->context; shw = (shwContext*) context; PubSub_SubscribeConnectionResult(context->pubSub, (pConnectionResultEventHandler) shw_OnConnectionResultEventHandler); PubSub_SubscribeChannelConnected(context->pubSub, (pChannelConnectedEventHandler) shw_OnChannelConnectedEventHandler); PubSub_SubscribeChannelDisconnected(context->pubSub, (pChannelDisconnectedEventHandler) shw_OnChannelDisconnectedEventHandler); freerdp_client_load_addins(context->channels, instance->settings); freerdp_channels_pre_connect(context->channels, instance); return TRUE; }
BOOL tf_pre_connect(freerdp* instance) { tfContext* tfc; rdpSettings* settings; tfc = (tfContext*) instance->context; settings = instance->settings; settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE; settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE; settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE; settings->OrderSupport[NEG_OPAQUE_RECT_INDEX] = TRUE; settings->OrderSupport[NEG_DRAWNINEGRID_INDEX] = TRUE; settings->OrderSupport[NEG_MULTIDSTBLT_INDEX] = TRUE; settings->OrderSupport[NEG_MULTIPATBLT_INDEX] = TRUE; settings->OrderSupport[NEG_MULTISCRBLT_INDEX] = TRUE; settings->OrderSupport[NEG_MULTIOPAQUERECT_INDEX] = TRUE; settings->OrderSupport[NEG_MULTI_DRAWNINEGRID_INDEX] = TRUE; settings->OrderSupport[NEG_LINETO_INDEX] = TRUE; settings->OrderSupport[NEG_POLYLINE_INDEX] = TRUE; settings->OrderSupport[NEG_MEMBLT_INDEX] = TRUE; settings->OrderSupport[NEG_MEM3BLT_INDEX] = TRUE; settings->OrderSupport[NEG_SAVEBITMAP_INDEX] = TRUE; settings->OrderSupport[NEG_GLYPH_INDEX_INDEX] = TRUE; settings->OrderSupport[NEG_FAST_INDEX_INDEX] = TRUE; settings->OrderSupport[NEG_FAST_GLYPH_INDEX] = TRUE; settings->OrderSupport[NEG_POLYGON_SC_INDEX] = TRUE; settings->OrderSupport[NEG_POLYGON_CB_INDEX] = TRUE; settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = TRUE; settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = TRUE; freerdp_channels_pre_connect(instance->context->channels, instance); return TRUE; }
boolean 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; int i; rdp_guac_client_data* guac_client_data = (rdp_guac_client_data*) client->data; /* Load clipboard plugin */ if (freerdp_channels_load_plugin(channels, instance->settings, "cliprdr", NULL)) guac_client_log_error(client, "Failed to load cliprdr plugin."); /* If audio enabled, choose an encoder */ if (guac_client_data->audio_enabled) { /* Choose an encoding */ 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) { guac_client_log_info(client, "Loading Ogg Vorbis encoder."); guac_client_data->audio = audio_stream_alloc(client, ogg_encoder); break; } #endif /* If wav is supported, done. */ if (strcmp(mimetype, wav_encoder->mimetype) == 0) { guac_client_log_info(client, "Loading wav encoder."); guac_client_data->audio = audio_stream_alloc(client, wav_encoder); break; } } /* 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, "guac_rdpsnd", guac_client_data->audio)) guac_client_log_error(client, "Failed to load guac_rdpsnd plugin."); } else guac_client_log_info(client, "No available audio encoding. Sound disabled."); } /* end if audio enabled */ /* If printing enabled, load rdpdr */ if (guac_client_data->printing_enabled) { /* Load RDPDR plugin */ if (freerdp_channels_load_plugin(channels, instance->settings, "guac_rdpdr", client)) guac_client_log_error(client, "Failed to load guac_rdpdr plugin."); } /* end if printing enabled */ /* Init color conversion structure */ clrconv = xnew(CLRCONV); clrconv->alpha = 1; clrconv->invert = 0; clrconv->rgb555 = 0; clrconv->palette = xnew(rdpPalette); ((rdp_freerdp_context*) context)->clrconv = clrconv; /* Init FreeRDP cache */ instance->context->cache = cache_new(instance->settings); /* Set up bitmap handling */ bitmap = xnew(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); xfree(bitmap); /* Set up glyph handling */ glyph = xnew(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); xfree(glyph); /* Set up pointer handling */ pointer = xnew(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); xfree(pointer); /* Set up GDI */ 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_protocol_send_error(client->socket, "Error initializing RDP client channel manager"); guac_socket_flush(client->socket); return false; } return true; }
void test_cliprdr(void) { int i; rdpChannels* channels; rdpSettings settings = { 0 }; freerdp instance = { 0 }; RDP_EVENT* event; RDP_CB_FORMAT_LIST_EVENT* format_list_event; RDP_CB_DATA_REQUEST_EVENT* data_request_event; RDP_CB_DATA_RESPONSE_EVENT* data_response_event; settings.hostname = "testhost"; instance.settings = &settings; instance.SendChannelData = test_rdp_channel_data; channels = freerdp_channels_new(); freerdp_channels_load_plugin(channels, &settings, "../channels/cliprdr/cliprdr.so", NULL); freerdp_channels_pre_connect(channels, &instance); freerdp_channels_post_connect(channels, &instance); /* server sends cliprdr capabilities and monitor ready PDU */ freerdp_channels_data(&instance, 0, (char*)test_clip_caps_data, sizeof(test_clip_caps_data) - 1, CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, sizeof(test_clip_caps_data) - 1); freerdp_channels_data(&instance, 0, (char*)test_monitor_ready_data, sizeof(test_monitor_ready_data) - 1, CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, sizeof(test_monitor_ready_data) - 1); /* cliprdr sends clipboard_sync event to UI */ while ((event = freerdp_channels_pop_event(channels)) == NULL) { freerdp_channels_check_fds(channels, &instance); } printf("Got event %d\n", event->event_type); CU_ASSERT(event->event_type == RDP_EVENT_TYPE_CB_MONITOR_READY); freerdp_event_free(event); /* UI sends format_list event to cliprdr */ event = freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_FORMAT_LIST, event_process_callback, NULL); format_list_event = (RDP_CB_FORMAT_LIST_EVENT*) event; format_list_event->num_formats = 2; format_list_event->formats = (uint32*) xmalloc(sizeof(uint32) * 2); format_list_event->formats[0] = CB_FORMAT_TEXT; format_list_event->formats[1] = CB_FORMAT_HTML; event_processed = 0; freerdp_channels_send_event(channels, event); /* cliprdr sends format list PDU to server */ while (!event_processed) { freerdp_channels_check_fds(channels, &instance); } /* server sends format list response PDU to cliprdr */ freerdp_channels_data(&instance, 0, (char*)test_format_list_response_data, sizeof(test_format_list_response_data) - 1, CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, sizeof(test_format_list_response_data) - 1); /* server sends format list PDU to cliprdr */ freerdp_channels_data(&instance, 0, (char*)test_format_list_data, sizeof(test_format_list_data) - 1, CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, sizeof(test_format_list_data) - 1); /* cliprdr sends format_list event to UI */ while ((event = freerdp_channels_pop_event(channels)) == NULL) { freerdp_channels_check_fds(channels, &instance); } printf("Got event %d\n", event->event_type); CU_ASSERT(event->event_type == RDP_EVENT_TYPE_CB_FORMAT_LIST); if (event->event_type == RDP_EVENT_TYPE_CB_FORMAT_LIST) { format_list_event = (RDP_CB_FORMAT_LIST_EVENT*)event; for (i = 0; i < format_list_event->num_formats; i++) printf("Format: 0x%X\n", format_list_event->formats[i]); } freerdp_event_free(event); /* server sends data request PDU to cliprdr */ freerdp_channels_data(&instance, 0, (char*)test_data_request_data, sizeof(test_data_request_data) - 1, CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, sizeof(test_data_request_data) - 1); /* cliprdr sends data request event to UI */ while ((event = freerdp_channels_pop_event(channels)) == NULL) { freerdp_channels_check_fds(channels, &instance); } printf("Got event %d\n", event->event_type); CU_ASSERT(event->event_type == RDP_EVENT_TYPE_CB_DATA_REQUEST); if (event->event_type == RDP_EVENT_TYPE_CB_DATA_REQUEST) { data_request_event = (RDP_CB_DATA_REQUEST_EVENT*)event; printf("Requested format: 0x%X\n", data_request_event->format); } freerdp_event_free(event); /* UI sends data response event to cliprdr */ event = freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_DATA_RESPONSE, event_process_callback, NULL); data_response_event = (RDP_CB_DATA_RESPONSE_EVENT*)event; data_response_event->data = (uint8*)xmalloc(6); strcpy((char*)data_response_event->data, "hello"); data_response_event->size = 6; event_processed = 0; freerdp_channels_send_event(channels, event); /* cliprdr sends data response PDU to server */ while (!event_processed) { freerdp_channels_check_fds(channels, &instance); } /* UI sends data request event to cliprdr */ event = freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_DATA_REQUEST, event_process_callback, NULL); data_request_event = (RDP_CB_DATA_REQUEST_EVENT*)event; data_request_event->format = CB_FORMAT_UNICODETEXT; event_processed = 0; freerdp_channels_send_event(channels, event); /* cliprdr sends data request PDU to server */ while (!event_processed) { freerdp_channels_check_fds(channels, &instance); } /* server sends data response PDU to cliprdr */ freerdp_channels_data(&instance, 0, (char*)test_data_response_data, sizeof(test_data_response_data) - 1, CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, sizeof(test_data_response_data) - 1); /* cliprdr sends data response event to UI */ while ((event = freerdp_channels_pop_event(channels)) == NULL) { freerdp_channels_check_fds(channels, &instance); } printf("Got event %d\n", event->event_type); CU_ASSERT(event->event_type == RDP_EVENT_TYPE_CB_DATA_RESPONSE); if (event->event_type == RDP_EVENT_TYPE_CB_DATA_RESPONSE) { data_response_event = (RDP_CB_DATA_RESPONSE_EVENT*)event; printf("Data response size: %d\n", data_response_event->size); freerdp_hexdump(data_response_event->data, data_response_event->size); } freerdp_event_free(event); freerdp_channels_close(channels, &instance); freerdp_channels_free(channels); }
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; }
/** Creates a new connection based on the settings found in the "instance" parameter * It will use the callbacks registered on the structure to process the pre/post connect operations * that the caller requires. * @see struct rdp_freerdp in freerdp.h * * @param instance - pointer to a rdp_freerdp structure that contains base information to establish the connection. * On return, this function will be initialized with the new connection's settings. * * @return TRUE if successful. FALSE otherwise. * */ BOOL freerdp_connect(freerdp* instance) { UINT status2 = CHANNEL_RC_OK; rdpRdp* rdp; BOOL status = TRUE; rdpSettings* settings; ConnectionResultEventArgs e; if (!instance) return FALSE; /* We always set the return code to 0 before we start the connect sequence*/ connectErrorCode = 0; freerdp_set_last_error(instance->context, FREERDP_ERROR_SUCCESS); clearChannelError(instance->context); ResetEvent(instance->context->abortEvent); rdp = instance->context->rdp; settings = instance->settings; instance->context->codecs = codecs_new(instance->context); IFCALLRET(instance->PreConnect, status, instance); if (status) status2 = freerdp_channels_pre_connect(instance->context->channels, instance); if (settings->KeyboardLayout == KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002) { settings->KeyboardType = 7; settings->KeyboardSubType = 2; settings->KeyboardFunctionKey = 12; } if (!status || (status2 != CHANNEL_RC_OK)) { if (!freerdp_get_last_error(rdp->context)) freerdp_set_last_error(instance->context, FREERDP_ERROR_PRE_CONNECT_FAILED); WLog_ERR(TAG, "freerdp_pre_connect failed"); goto freerdp_connect_finally; } status = rdp_client_connect(rdp); /* --authonly tests the connection without a UI */ if (instance->settings->AuthenticationOnly) { WLog_ERR(TAG, "Authentication only, exit status %"PRId32"", !status); goto freerdp_connect_finally; } if (!status) goto freerdp_connect_finally; if (status) { UINT status2; if (instance->settings->DumpRemoteFx) { instance->update->pcap_rfx = pcap_open(instance->settings->DumpRemoteFxFile, TRUE); if (instance->update->pcap_rfx) instance->update->dump_rfx = TRUE; } IFCALLRET(instance->PostConnect, status, instance); if (status) status2 = freerdp_channels_post_connect(instance->context->channels, instance); if (!status || (status2 != CHANNEL_RC_OK) || !update_post_connect(instance->update)) { WLog_ERR(TAG, "freerdp_post_connect failed"); if (!freerdp_get_last_error(rdp->context)) freerdp_set_last_error(instance->context, FREERDP_ERROR_POST_CONNECT_FAILED); status = FALSE; goto freerdp_connect_finally; } if (instance->settings->PlayRemoteFx) { wStream* s; rdpUpdate* update; pcap_record record; update = instance->update; update->pcap_rfx = pcap_open(settings->PlayRemoteFxFile, FALSE); if (!update->pcap_rfx) { status = FALSE; goto freerdp_connect_finally; } else { update->play_rfx = TRUE; } while (pcap_has_next_record(update->pcap_rfx)) { pcap_get_next_record_header(update->pcap_rfx, &record); if (!(s = StreamPool_Take(rdp->transport->ReceivePool, record.length))) break; record.data = Stream_Buffer(s); pcap_get_next_record_content(update->pcap_rfx, &record); Stream_SetLength(s, record.length); Stream_SetPosition(s, 0); update->BeginPaint(update->context); update_recv_surfcmds(update, Stream_Length(s), s); update->EndPaint(update->context); Stream_Release(s); } pcap_close(update->pcap_rfx); update->pcap_rfx = NULL; status = TRUE; goto freerdp_connect_finally; } } if (rdp->errorInfo == ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES) freerdp_set_last_error(instance->context, FREERDP_ERROR_INSUFFICIENT_PRIVILEGES); SetEvent(rdp->transport->connectedEvent); freerdp_connect_finally: EventArgsInit(&e, "freerdp"); e.result = status ? 0 : -1; PubSub_OnConnectionResult(instance->context->pubSub, instance->context, &e); return status; }
BOOL wf_pre_connect(freerdp* instance) { wfContext* wfc; int desktopWidth; int desktopHeight; rdpContext* context; rdpSettings* settings; context = instance->context; wfc = (wfContext*) instance->context; wfc->instance = instance; wfc->codecs = instance->context->codecs; settings = instance->settings; if (settings->ConnectionFile) { if (wfc->connectionRdpFile) { freerdp_client_rdp_file_free(wfc->connectionRdpFile); } wfc->connectionRdpFile = freerdp_client_rdp_file_new(); WLog_INFO(TAG, "Using connection file: %s", settings->ConnectionFile); freerdp_client_parse_rdp_file(wfc->connectionRdpFile, settings->ConnectionFile); freerdp_client_populate_settings_from_rdp_file(wfc->connectionRdpFile, settings); } settings->OsMajorType = OSMAJORTYPE_WINDOWS; settings->OsMinorType = OSMINORTYPE_WINDOWS_NT; settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE; settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE; settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE; settings->OrderSupport[NEG_OPAQUE_RECT_INDEX] = TRUE; settings->OrderSupport[NEG_DRAWNINEGRID_INDEX] = FALSE; settings->OrderSupport[NEG_MULTIDSTBLT_INDEX] = FALSE; settings->OrderSupport[NEG_MULTIPATBLT_INDEX] = FALSE; settings->OrderSupport[NEG_MULTISCRBLT_INDEX] = FALSE; settings->OrderSupport[NEG_MULTIOPAQUERECT_INDEX] = TRUE; settings->OrderSupport[NEG_MULTI_DRAWNINEGRID_INDEX] = FALSE; settings->OrderSupport[NEG_LINETO_INDEX] = TRUE; settings->OrderSupport[NEG_POLYLINE_INDEX] = TRUE; settings->OrderSupport[NEG_MEMBLT_INDEX] = TRUE; settings->OrderSupport[NEG_MEM3BLT_INDEX] = FALSE; settings->OrderSupport[NEG_SAVEBITMAP_INDEX] = FALSE; settings->OrderSupport[NEG_GLYPH_INDEX_INDEX] = FALSE; settings->OrderSupport[NEG_FAST_INDEX_INDEX] = FALSE; settings->OrderSupport[NEG_FAST_GLYPH_INDEX] = FALSE; settings->OrderSupport[NEG_POLYGON_SC_INDEX] = FALSE; settings->OrderSupport[NEG_POLYGON_CB_INDEX] = FALSE; settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE; settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE; settings->GlyphSupportLevel = GLYPH_SUPPORT_NONE; wfc->fullscreen = settings->Fullscreen; if (wfc->fullscreen) wfc->fs_toggle = 1; wfc->clrconv = (HCLRCONV) malloc(sizeof(CLRCONV)); ZeroMemory(wfc->clrconv, sizeof(CLRCONV)); wfc->clrconv->palette = NULL; wfc->clrconv->alpha = FALSE; instance->context->cache = cache_new(settings); desktopWidth = settings->DesktopWidth; desktopHeight = settings->DesktopHeight; if (wfc->percentscreen > 0) { desktopWidth = (GetSystemMetrics(SM_CXSCREEN) * wfc->percentscreen) / 100; settings->DesktopWidth = desktopWidth; desktopHeight = (GetSystemMetrics(SM_CYSCREEN) * wfc->percentscreen) / 100; settings->DesktopHeight = desktopHeight; } if (wfc->fullscreen) { if (settings->UseMultimon) { desktopWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN); desktopHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN); } else { desktopWidth = GetSystemMetrics(SM_CXSCREEN); desktopHeight = GetSystemMetrics(SM_CYSCREEN); } } /* FIXME: desktopWidth has a limitation that it should be divisible by 4, * otherwise the screen will crash when connecting to an XP desktop.*/ desktopWidth = (desktopWidth + 3) & (~3); if (desktopWidth != settings->DesktopWidth) { freerdp_set_param_uint32(settings, FreeRDP_DesktopWidth, desktopWidth); } if (desktopHeight != settings->DesktopHeight) { freerdp_set_param_uint32(settings, FreeRDP_DesktopHeight, desktopHeight); } if ((settings->DesktopWidth < 64) || (settings->DesktopHeight < 64) || (settings->DesktopWidth > 4096) || (settings->DesktopHeight > 4096)) { WLog_ERR(TAG, "invalid dimensions %d %d", settings->DesktopWidth, settings->DesktopHeight); return 1; } freerdp_set_param_uint32(settings, FreeRDP_KeyboardLayout, (int) GetKeyboardLayout(0) & 0x0000FFFF); PubSub_SubscribeChannelConnected(instance->context->pubSub, (pChannelConnectedEventHandler) wf_OnChannelConnectedEventHandler); PubSub_SubscribeChannelDisconnected(instance->context->pubSub, (pChannelDisconnectedEventHandler) wf_OnChannelDisconnectedEventHandler); freerdp_channels_pre_connect(instance->context->channels, instance); return TRUE; }
BOOL wf_pre_connect(freerdp* instance) { int i1; wfInfo* wfi; rdpFile* file; wfContext* context; rdpSettings* settings; context = (wfContext*) instance->context; wfi = context->wfi; wfi->instance = instance; settings = instance->settings; if (settings->ConnectionFile) { file = freerdp_client_rdp_file_new(); fprintf(stderr, "Using connection file: %s\n", settings->ConnectionFile); freerdp_client_parse_rdp_file(file, settings->ConnectionFile); freerdp_client_populate_settings_from_rdp_file(file, settings); freerdp_client_rdp_file_free(file); } settings->OsMajorType = OSMAJORTYPE_WINDOWS; settings->OsMinorType = OSMINORTYPE_WINDOWS_NT; settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE; settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE; settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE; settings->OrderSupport[NEG_OPAQUE_RECT_INDEX] = TRUE; settings->OrderSupport[NEG_DRAWNINEGRID_INDEX] = FALSE; settings->OrderSupport[NEG_MULTIDSTBLT_INDEX] = FALSE; settings->OrderSupport[NEG_MULTIPATBLT_INDEX] = FALSE; settings->OrderSupport[NEG_MULTISCRBLT_INDEX] = FALSE; settings->OrderSupport[NEG_MULTIOPAQUERECT_INDEX] = TRUE; settings->OrderSupport[NEG_MULTI_DRAWNINEGRID_INDEX] = FALSE; settings->OrderSupport[NEG_LINETO_INDEX] = TRUE; settings->OrderSupport[NEG_POLYLINE_INDEX] = TRUE; settings->OrderSupport[NEG_MEMBLT_INDEX] = TRUE; settings->OrderSupport[NEG_MEM3BLT_INDEX] = FALSE; settings->OrderSupport[NEG_SAVEBITMAP_INDEX] = FALSE; settings->OrderSupport[NEG_GLYPH_INDEX_INDEX] = FALSE; settings->OrderSupport[NEG_FAST_INDEX_INDEX] = FALSE; settings->OrderSupport[NEG_FAST_GLYPH_INDEX] = FALSE; settings->OrderSupport[NEG_POLYGON_SC_INDEX] = FALSE; settings->OrderSupport[NEG_POLYGON_CB_INDEX] = FALSE; settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE; settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE; settings->GlyphSupportLevel = GLYPH_SUPPORT_NONE; wfi->fullscreen = settings->Fullscreen; wfi->fs_toggle = 1; wfi->sw_gdi = settings->SoftwareGdi; wfi->clrconv = (HCLRCONV) malloc(sizeof(CLRCONV)); ZeroMemory(wfi->clrconv, sizeof(CLRCONV)); wfi->clrconv->palette = NULL; wfi->clrconv->alpha = FALSE; instance->context->cache = cache_new(settings); if (wfi->percentscreen > 0) { i1 = (GetSystemMetrics(SM_CXSCREEN) * wfi->percentscreen) / 100; settings->DesktopWidth = i1; i1 = (GetSystemMetrics(SM_CYSCREEN) * wfi->percentscreen) / 100; settings->DesktopHeight = i1; } if (wfi->fullscreen) { settings->DesktopWidth = GetSystemMetrics(SM_CXSCREEN); settings->DesktopHeight = GetSystemMetrics(SM_CYSCREEN); } i1 = settings->DesktopWidth; i1 = (i1 + 3) & (~3); settings->DesktopWidth = i1; if ((settings->DesktopWidth < 64) || (settings->DesktopHeight < 64) || (settings->DesktopWidth > 4096) || (settings->DesktopHeight > 4096)) { fprintf(stderr, "wf_pre_connect: invalid dimensions %d %d\n", settings->DesktopWidth, settings->DesktopHeight); return 1; } settings->KeyboardLayout = (int) GetKeyboardLayout(0) & 0x0000FFFF; freerdp_channels_pre_connect(instance->context->channels, instance); return TRUE; }
boolean wf_pre_connect(freerdp* instance) { int i1; wfInfo* wfi; wfContext* context; rdpSettings* settings; wfi = (wfInfo*) xzalloc(sizeof(wfInfo)); context = (wfContext*) instance->context; wfi->instance = instance; context->wfi = wfi; settings = instance->settings; settings->os_major_type = OSMAJORTYPE_WINDOWS; settings->os_minor_type = OSMINORTYPE_WINDOWS_NT; settings->order_support[NEG_DSTBLT_INDEX] = true; settings->order_support[NEG_PATBLT_INDEX] = true; settings->order_support[NEG_SCRBLT_INDEX] = true; settings->order_support[NEG_OPAQUE_RECT_INDEX] = true; settings->order_support[NEG_DRAWNINEGRID_INDEX] = false; settings->order_support[NEG_MULTIDSTBLT_INDEX] = false; settings->order_support[NEG_MULTIPATBLT_INDEX] = false; settings->order_support[NEG_MULTISCRBLT_INDEX] = false; settings->order_support[NEG_MULTIOPAQUERECT_INDEX] = true; settings->order_support[NEG_MULTI_DRAWNINEGRID_INDEX] = false; settings->order_support[NEG_LINETO_INDEX] = true; settings->order_support[NEG_POLYLINE_INDEX] = true; settings->order_support[NEG_MEMBLT_INDEX] = true; settings->order_support[NEG_MEM3BLT_INDEX] = false; settings->order_support[NEG_SAVEBITMAP_INDEX] = false; settings->order_support[NEG_GLYPH_INDEX_INDEX] = false; settings->order_support[NEG_FAST_INDEX_INDEX] = false; settings->order_support[NEG_FAST_GLYPH_INDEX] = false; settings->order_support[NEG_POLYGON_SC_INDEX] = false; settings->order_support[NEG_POLYGON_CB_INDEX] = false; settings->order_support[NEG_ELLIPSE_SC_INDEX] = false; settings->order_support[NEG_ELLIPSE_CB_INDEX] = false; settings->glyph_cache = false; wfi->cursor = g_default_cursor; wfi->fullscreen = settings->fullscreen; wfi->fs_toggle = wfi->fullscreen; wfi->sw_gdi = settings->sw_gdi; wfi->clrconv = (HCLRCONV) xzalloc(sizeof(CLRCONV)); wfi->clrconv->palette = NULL; wfi->clrconv->alpha = false; instance->context->cache = cache_new(settings); if (wfi->percentscreen > 0) { i1 = (GetSystemMetrics(SM_CXSCREEN) * wfi->percentscreen) / 100; settings->width = i1; i1 = (GetSystemMetrics(SM_CYSCREEN) * wfi->percentscreen) / 100; settings->height = i1; } if (wfi->fs_toggle) { settings->width = GetSystemMetrics(SM_CXSCREEN); settings->height = GetSystemMetrics(SM_CYSCREEN); } i1 = settings->width; i1 = (i1 + 3) & (~3); settings->width = i1; if ((settings->width < 64) || (settings->height < 64) || (settings->width > 4096) || (settings->height > 4096)) { printf("wf_pre_connect: invalid dimensions %d %d\n", settings->width, settings->height); return 1; } settings->kbd_layout = (int) GetKeyboardLayout(0) & 0x0000FFFF; freerdp_channels_pre_connect(instance->context->channels, instance); return true; }
//----------------------------------------------------------------------------- void test_rail_plugin(void) { thread_param param; pthread_t thread; rdpChannels* chan_man; rdpSettings settings = { 0 }; freerdp s_inst = { 0 }; freerdp* inst = &s_inst; size_t sn = 0; size_t en = 0; STREAM* ss = NULL; RAIL_EVENT* ee = NULL; printf("\n"); settings.hostname = "testhost"; inst->settings = &settings; inst->SendChannelData = emulate_client_send_channel_data; chan_man = freerdp_channels_new(); freerdp_channels_load_plugin(chan_man, &settings, "../channels/rail/rail.so", NULL); freerdp_channels_pre_connect(chan_man, inst); freerdp_channels_post_connect(chan_man, inst); memset(¶m, 0, sizeof(param)); param.chan_man = chan_man; param.instance = inst; param.th_count = 0; param.th_to_finish = 0; global_thread_params = ¶m; pthread_create(&thread, 0, thread_func, ¶m); // 1. Emulate server handshake binary EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_handshake); EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_exec_result_pdu); EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_sysparam1_pdu); EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_sysparam2_pdu); EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_localmovesize_start_pdu); EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_localmovesize_stop_pdu); EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_minmaxinfo_pdu); EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_langbar_pdu); EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_app_get_resp_pdu); // 2. Send UI events param.out_rail_orders.sysparam.params = 0; param.out_rail_orders.sysparam.params |= SPI_MASK_SET_HIGH_CONTRAST; param.out_rail_orders.sysparam.highContrast.flags = 0x7e; param.out_rail_orders.sysparam.highContrast.colorScheme.length = 0; param.out_rail_orders.sysparam.highContrast.colorScheme.string = NULL; param.out_rail_orders.sysparam.params |= SPI_MASK_TASKBAR_POS; param.out_rail_orders.sysparam.taskbarPos.left = 0; param.out_rail_orders.sysparam.taskbarPos.top = 0x039a; param.out_rail_orders.sysparam.taskbarPos.right = 0x0690; param.out_rail_orders.sysparam.taskbarPos.bottom = 0x03c2; param.out_rail_orders.sysparam.params |= SPI_MASK_SET_MOUSE_BUTTON_SWAP; param.out_rail_orders.sysparam.mouseButtonSwap = False; param.out_rail_orders.sysparam.params |= SPI_MASK_SET_KEYBOARD_PREF; param.out_rail_orders.sysparam.keyboardPref = False; param.out_rail_orders.sysparam.params |= SPI_MASK_SET_DRAG_FULL_WINDOWS; param.out_rail_orders.sysparam.dragFullWindows = True; param.out_rail_orders.sysparam.params |= SPI_MASK_SET_KEYBOARD_CUES; param.out_rail_orders.sysparam.keyboardCues = False; param.out_rail_orders.sysparam.params |= SPI_MASK_SET_WORK_AREA; param.out_rail_orders.sysparam.workArea.left = 0; param.out_rail_orders.sysparam.workArea.top = 0; param.out_rail_orders.sysparam.workArea.right = 0x0690; param.out_rail_orders.sysparam.workArea.bottom = 0x039a; send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_SET_SYSPARAMS, ¶m.out_rail_orders.sysparam); param.plugin_data.size = sizeof(RDP_PLUGIN_DATA); param.plugin_data.data[0] = "||iexplore"; param.plugin_data.data[1] = "f:\\windows\\system32"; param.plugin_data.data[2] = "www.bing.com"; send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_EXEC_REMOTE_APP, ¶m.plugin_data); param.out_rail_orders.activate.enabled = True; param.out_rail_orders.activate.windowId = 0x0007008e; send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_ACTIVATE, ¶m.out_rail_orders.activate); param.out_rail_orders.syscommand.windowId = 0x00020052; param.out_rail_orders.syscommand.command = 0xf020; send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_SYSCOMMAND, ¶m.out_rail_orders.syscommand); param.out_rail_orders.notify_event.windowId = 0x000201aa; param.out_rail_orders.notify_event.notifyIconId = 0x02; param.out_rail_orders.notify_event.message = 0x0204; send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_NOTIFY_EVENT, ¶m.out_rail_orders.notify_event); param.out_rail_orders.window_move.windowId = 0x00020020; param.out_rail_orders.window_move.left = 0x0309; param.out_rail_orders.window_move.top = 0x0100; param.out_rail_orders.window_move.right = 0x05db; param.out_rail_orders.window_move.bottom = 0x0188; send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, ¶m.out_rail_orders.window_move); param.out_rail_orders.sysmenu.windowId = 0x00090122; param.out_rail_orders.sysmenu.left = 0xffa4; // TODO: possible negative values? param.out_rail_orders.sysmenu.top = 0x024a; send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_SYSMENU, ¶m.out_rail_orders.sysmenu); param.out_rail_orders.langbar_info.languageBarStatus = 0x00000001; send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_LANGBARINFO, ¶m.out_rail_orders.langbar_info); param.out_rail_orders.get_appid_req.windowId = 0x00020052; send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_APPID_REQ, ¶m.out_rail_orders.get_appid_req); // Waiting for possible events or data sleep(1); // Finishing thread and wait for it param.th_to_finish = 1; while (param.th_count > 0) { usleep(1000); } // We need to collected all events and data dumps and then to. // create CU_ASSERT series here! sn = param.in_streams_number; en = param.in_events_number; ss = ¶m.in_streams[0]; ee = ¶m.in_events[0]; CU_ASSERT(sn > 0 && STREAM_EQUAL_TO_DUMP(&ss[ 0], client_handshake)); CU_ASSERT(sn > 1 && STREAM_EQUAL_TO_DUMP(&ss[ 1], client_info_pdu)); CU_ASSERT(sn > 2 && STREAM_EQUAL_TO_DUMP(&ss[ 2], client_sysparam_highcontrast_pdu)); CU_ASSERT(sn > 3 && STREAM_EQUAL_TO_DUMP(&ss[ 3], client_sysparam_taskbarpos_pdu)); CU_ASSERT(sn > 4 && STREAM_EQUAL_TO_DUMP(&ss[ 4], client_sysparam_mousebuttonswap_pdu)); CU_ASSERT(sn > 5 && STREAM_EQUAL_TO_DUMP(&ss[ 5], client_sysparam_keyboardpref_pdu)); CU_ASSERT(sn > 6 && STREAM_EQUAL_TO_DUMP(&ss[ 6], client_sysparam_dragfullwindow_pdu)); CU_ASSERT(sn > 7 && STREAM_EQUAL_TO_DUMP(&ss[ 7], client_sysparam_keyboardcues_pdu)); CU_ASSERT(sn > 8 && STREAM_EQUAL_TO_DUMP(&ss[ 8], client_sysparam_setworkarea_pdu)); CU_ASSERT(sn > 9 && STREAM_EQUAL_TO_DUMP(&ss[ 9], client_execute_pdu)); CU_ASSERT(sn >10 && STREAM_EQUAL_TO_DUMP(&ss[10], client_activate_pdu)); CU_ASSERT(sn >11 && STREAM_EQUAL_TO_DUMP(&ss[11], client_syscommand_pdu)); CU_ASSERT(sn >12 && STREAM_EQUAL_TO_DUMP(&ss[12], client_notify_pdu)); CU_ASSERT(sn >13 && STREAM_EQUAL_TO_DUMP(&ss[13], client_windowmove_pdu)); CU_ASSERT(sn >14 && STREAM_EQUAL_TO_DUMP(&ss[14], client_system_menu_pdu)); CU_ASSERT(sn >15 && STREAM_EQUAL_TO_DUMP(&ss[15], client_langbar_pdu)); CU_ASSERT(sn >16 && STREAM_EQUAL_TO_DUMP(&ss[16], client_get_app_id_req_pdu)); CU_ASSERT(en > 0 && ee[ 0].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_GET_SYSPARAMS); CU_ASSERT(en > 1 && ee[ 1].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_EXEC_RESULTS && ee[ 1].order_info.exec_result.flags == 0x08 && ee[ 1].order_info.exec_result.execResult == 0x03 && UNICODE_STRING_EQUAL_TO_DUMP( &ee[ 1].order_info.exec_result.exeOrFile, server_exec_result_exe_or_file) ); CU_ASSERT(en > 2 && ee[ 2].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_SYSPARAM && ee[ 2].order_info.sysparam.setScreenSaveSecure == False ); CU_ASSERT(en > 3 && ee[ 3].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_SYSPARAM && ee[ 3].order_info.sysparam.setScreenSaveActive == False ); CU_ASSERT(en > 4 && ee[ 4].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_LOCALMOVESIZE && ee[ 4].order_info.localmovesize.windowId == 0x0007008e && ee[ 4].order_info.localmovesize.isMoveSizeStart == True && ee[ 4].order_info.localmovesize.moveSizeType == RAIL_WMSZ_MOVE && ee[ 4].order_info.localmovesize.posX == 0x017e && ee[ 4].order_info.localmovesize.posY == 0x000a ); CU_ASSERT(en > 5 && ee[ 5].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_LOCALMOVESIZE && ee[ 5].order_info.localmovesize.windowId == 0x0007008e && ee[ 5].order_info.localmovesize.isMoveSizeStart == False && ee[ 5].order_info.localmovesize.moveSizeType == RAIL_WMSZ_MOVE && ee[ 5].order_info.localmovesize.posX == 0x00a6 && ee[ 5].order_info.localmovesize.posY == 0x0044 ); CU_ASSERT(en > 6 && ee[ 6].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_MINMAXINFO && ee[ 6].order_info.minmaxinfo.windowId == 0x0007008e && ee[ 6].order_info.minmaxinfo.maxWidth == 0x0408 && ee[ 6].order_info.minmaxinfo.maxHeight == 0x02d6 && ee[ 6].order_info.minmaxinfo.maxPosX == 0x0000 && ee[ 6].order_info.minmaxinfo.maxPosY == 0x0000 && ee[ 6].order_info.minmaxinfo.minTrackWidth == 0x0070 && ee[ 6].order_info.minmaxinfo.minTrackHeight == 0x001b && ee[ 6].order_info.minmaxinfo.maxTrackWidth == 0x040c && ee[ 6].order_info.minmaxinfo.maxTrackHeight == 0x030c ); CU_ASSERT(en > 7 && ee[ 7].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_LANGBARINFO && ee[ 7].order_info.langbar_info.languageBarStatus == TF_SFT_SHOWNORMAL ); CU_ASSERT(en > 8 && ee[ 8].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_APPID_RESP && ee[ 8].order_info.get_appid_resp.windowId == 0x00020052 && UNICODE_STRING_EQUAL_TO_DUMP( &ee[ 8].order_info.get_appid_resp.applicationId, server_app_get_resp_app_id ) ); freerdp_channels_close(chan_man, inst); freerdp_channels_free(chan_man); }
BOOL rdp_freerdp_pre_connect(freerdp* instance) { rdpContext* context = instance->context; rdpChannels* channels = context->channels; 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; rdpBitmap* bitmap; rdpGlyph* glyph; rdpPointer* pointer; rdpPrimaryUpdate* primary; CLRCONV* clrconv; guac_rdp_dvc_list* dvc_list = guac_rdp_dvc_list_alloc(); #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 "disp" plugin for display update */ if (settings->resize_method == GUAC_RESIZE_DISPLAY_UPDATE) guac_rdp_disp_load_plugin(instance->context, dvc_list); #endif /* Load "AUDIO_INPUT" plugin for audio input*/ if (settings->enable_audio_input) { rdp_client->audio_input = guac_rdp_audio_buffer_alloc(); guac_rdp_audio_load_plugin(instance->context, dvc_list); } /* 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 RDPSND/RDPDR required, load them */ if (settings->printing_enabled || settings->drive_enabled || 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. Sound MAY not work."); /* Load RDPSND plugin */ if (freerdp_channels_load_plugin(channels, instance->settings, "guacsnd", client)) guac_client_log(client, GUAC_LOG_WARNING, "Failed to load guacsnd alongside guacdr plugin. Sound " "will not work. Drive redirection and printing MAY not " "work."); } /* Load RAIL plugin if RemoteApp in use */ if (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] = settings->remote_app; plugin_data[0].data[1] = settings->remote_app_dir; plugin_data[0].data[2] = 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 (settings->svc_names != NULL) { char** current = 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); } /* Load DRDYNVC plugin if required */ if (guac_rdp_load_drdynvc(instance->context, dvc_list)) guac_client_log(client, GUAC_LOG_WARNING, "Failed to load drdynvc plugin. Display update and audio " "input support will be disabled."); /* Dynamic virtual channel list is no longer needed */ guac_rdp_dvc_list_free(dvc_list); /* 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; }