/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT gdi_CreateSurface(RdpgfxClientContext* context, const RDPGFX_CREATE_SURFACE_PDU* createSurface) { gdiGfxSurface* surface; rdpGdi* gdi = (rdpGdi*) context->custom; surface = (gdiGfxSurface*) calloc(1, sizeof(gdiGfxSurface)); if (!surface) return ERROR_INTERNAL_ERROR; surface->codecs = codecs_new(gdi->context); if (!surface->codecs) { free(surface); return CHANNEL_RC_NO_MEMORY; } if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_ALL, createSurface->width, createSurface->height)) { free(surface); return ERROR_INTERNAL_ERROR; } surface->surfaceId = createSurface->surfaceId; surface->width = (UINT32) createSurface->width; surface->height = (UINT32) createSurface->height; switch (createSurface->pixelFormat) { case GFX_PIXEL_FORMAT_ARGB_8888: surface->format = PIXEL_FORMAT_BGRA32; break; case GFX_PIXEL_FORMAT_XRGB_8888: surface->format = PIXEL_FORMAT_BGRX32; break; default: free(surface); return ERROR_INTERNAL_ERROR; } surface->scanline = gfx_align_scanline(surface->width * 4, 16); surface->data = (BYTE*) calloc(1, surface->scanline * surface->height); if (!surface->data) { free(surface); return ERROR_INTERNAL_ERROR; } surface->outputMapped = FALSE; region16_init(&surface->invalidRegion); context->SetSurfaceData(context, surface->surfaceId, (void*) surface); return CHANNEL_RC_OK; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT gdi_CreateSurface(RdpgfxClientContext* context, RDPGFX_CREATE_SURFACE_PDU* createSurface) { gdiGfxSurface* surface; rdpGdi* gdi = (rdpGdi*) context->custom; surface = (gdiGfxSurface*) calloc(1, sizeof(gdiGfxSurface)); if (!surface) return ERROR_INTERNAL_ERROR; surface->codecs = codecs_new(gdi->context); if (!surface->codecs) { free (surface); return CHANNEL_RC_NO_MEMORY; } surface->surfaceId = createSurface->surfaceId; surface->width = (UINT32) createSurface->width; surface->height = (UINT32) createSurface->height; surface->alpha = (createSurface->pixelFormat == PIXEL_FORMAT_ARGB_8888) ? TRUE : FALSE; surface->format = (!gdi->invert) ? PIXEL_FORMAT_XRGB32 : PIXEL_FORMAT_XBGR32; surface->scanline = (surface->width + (surface->width % 4)) * 4; surface->data = (BYTE*) calloc(1, surface->scanline * surface->height); if (!surface->data) { free(surface); return ERROR_INTERNAL_ERROR; } surface->outputMapped = FALSE; region16_init(&surface->invalidRegion); context->SetSurfaceData(context, surface->surfaceId, (void*) surface); return CHANNEL_RC_OK; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_CreateSurface(RdpgfxClientContext* context, RDPGFX_CREATE_SURFACE_PDU* createSurface) { size_t size; UINT32 bytesPerPixel; xfGfxSurface* surface; xfContext* xfc = (xfContext*) context->custom; surface = (xfGfxSurface*) calloc(1, sizeof(xfGfxSurface)); if (!surface) return CHANNEL_RC_NO_MEMORY; surface->codecs = codecs_new((rdpContext*) xfc); if (!surface->codecs) { free (surface); return CHANNEL_RC_NO_MEMORY; } surface->surfaceId = createSurface->surfaceId; surface->width = (UINT32) createSurface->width; surface->height = (UINT32) createSurface->height; surface->alpha = (createSurface->pixelFormat == PIXEL_FORMAT_ARGB_8888) ? TRUE : FALSE; surface->format = PIXEL_FORMAT_XRGB32; surface->scanline = surface->width * 4; surface->scanline += (surface->scanline % (xfc->scanline_pad / 8)); size = surface->scanline * surface->height; surface->data = (BYTE*) _aligned_malloc(size, 16); if (!surface->data) { free(surface); return CHANNEL_RC_NO_MEMORY; } ZeroMemory(surface->data, size); if ((xfc->depth == 24) || (xfc->depth == 32)) { surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, (char*) surface->data, surface->width, surface->height, xfc->scanline_pad, surface->scanline); } else { bytesPerPixel = (FREERDP_PIXEL_FORMAT_BPP(xfc->format) / 8); surface->stageStep = surface->width * bytesPerPixel; surface->stageStep += (surface->stageStep % (xfc->scanline_pad / 8)); size = surface->stageStep * surface->height; surface->stage = (BYTE*) _aligned_malloc(size, 16); if (!surface->stage) { free(surface->data); free(surface); return CHANNEL_RC_NO_MEMORY; } ZeroMemory(surface->stage, size); surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, (char*) surface->stage, surface->width, surface->height, xfc->scanline_pad, surface->stageStep); } surface->outputMapped = FALSE; region16_init(&surface->invalidRegion); context->SetSurfaceData(context, surface->surfaceId, (void*) surface); return CHANNEL_RC_OK; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_CreateSurface(RdpgfxClientContext* context, const RDPGFX_CREATE_SURFACE_PDU* createSurface) { size_t size; xfGfxSurface* surface; rdpGdi* gdi = (rdpGdi*)context->custom; xfContext* xfc = (xfContext*) gdi->context; surface = (xfGfxSurface*) calloc(1, sizeof(xfGfxSurface)); if (!surface) return CHANNEL_RC_NO_MEMORY; surface->gdi.codecs = codecs_new(gdi->context); if (!surface->gdi.codecs) { free(surface); return CHANNEL_RC_NO_MEMORY; } if (!freerdp_client_codecs_prepare(surface->gdi.codecs, FREERDP_CODEC_ALL, createSurface->width, createSurface->height)) { free(surface); return ERROR_INTERNAL_ERROR; } surface->gdi.surfaceId = createSurface->surfaceId; surface->gdi.width = (UINT32) createSurface->width; surface->gdi.height = (UINT32) createSurface->height; switch (createSurface->pixelFormat) { case GFX_PIXEL_FORMAT_ARGB_8888: surface->gdi.format = PIXEL_FORMAT_BGRA32; break; case GFX_PIXEL_FORMAT_XRGB_8888: surface->gdi.format = PIXEL_FORMAT_BGRX32; break; default: free(surface); return ERROR_INTERNAL_ERROR; } surface->gdi.scanline = surface->gdi.width * GetBytesPerPixel( surface->gdi.format); surface->gdi.scanline = x11_pad_scanline(surface->gdi.scanline, xfc->scanline_pad); size = surface->gdi.scanline * surface->gdi.height; surface->gdi.data = (BYTE*) _aligned_malloc(size, 16); if (!surface->gdi.data) { free(surface); return CHANNEL_RC_NO_MEMORY; } ZeroMemory(surface->gdi.data, size); if (gdi->dstFormat == surface->gdi.format) { surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, (char*) surface->gdi.data, surface->gdi.width, surface->gdi.height, xfc->scanline_pad, surface->gdi.scanline); } else { UINT32 width = surface->gdi.width; UINT32 bytes = GetBytesPerPixel(gdi->dstFormat); surface->stageScanline = width * bytes; surface->stageScanline = x11_pad_scanline(surface->stageScanline, xfc->scanline_pad); size = surface->stageScanline * surface->gdi.height; surface->stage = (BYTE*) _aligned_malloc(size, 16); if (!surface->stage) { _aligned_free(surface->gdi.data); free(surface); return CHANNEL_RC_NO_MEMORY; } ZeroMemory(surface->stage, size); surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, (char*) surface->stage, surface->gdi.width, surface->gdi.height, xfc->scanline_pad, surface->gdi.scanline); } surface->gdi.outputMapped = FALSE; region16_init(&surface->gdi.invalidRegion); context->SetSurfaceData(context, surface->gdi.surfaceId, (void*) surface); return CHANNEL_RC_OK; }
/** 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) { rdpRdp* rdp; BOOL status = TRUE; rdpSettings* settings; ConnectionResultEventArgs e; /* 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); rdp = instance->context->rdp; settings = instance->settings; instance->context->codecs = codecs_new(instance->context); IFCALLRET(instance->PreConnect, status, instance); if (settings->KeyboardLayout == KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002) { settings->KeyboardType = 7; settings->KeyboardSubType = 2; settings->KeyboardFunctionKey = 12; } if (!status) { 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 %d", !status); goto freerdp_connect_finally; } if (status) { 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 || !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); 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; }