/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId, const char* ChannelName) { int i; BOOL bAccept; DVCMAN_LISTENER* listener; DVCMAN_CHANNEL* channel; DrdynvcClientContext* context; IWTSVirtualChannelCallback* pCallback; DVCMAN* dvcman = (DVCMAN*) pChannelMgr; UINT error; if (!(channel = dvcman_channel_new(pChannelMgr, ChannelId, ChannelName))) { WLog_ERR(TAG, "dvcman_channel_new failed!"); return CHANNEL_RC_NO_MEMORY; } channel->status = 1; ArrayList_Add(dvcman->channels, channel); for (i = 0; i < dvcman->num_listeners; i++) { listener = (DVCMAN_LISTENER*) dvcman->listeners[i]; if (strcmp(listener->channel_name, ChannelName) == 0) { channel->iface.Write = dvcman_write_channel; channel->iface.Close = dvcman_close_channel_iface; bAccept = TRUE; pCallback = NULL; if ((error = listener->listener_callback->OnNewChannelConnection(listener->listener_callback, (IWTSVirtualChannel*) channel, NULL, &bAccept, &pCallback)) == CHANNEL_RC_OK && bAccept) { WLog_DBG(TAG, "listener %s created new channel %d", listener->channel_name, channel->channel_id); channel->status = 0; channel->channel_callback = pCallback; channel->pInterface = listener->iface.pInterface; context = dvcman->drdynvc->context; IFCALLRET(context->OnChannelConnected, error, context, ChannelName, listener->iface.pInterface); if (error) WLog_ERR(TAG, "context.ReceiveSamples failed with error %lu", error); return error; } else { if (error) { WLog_ERR(TAG, "OnNewChannelConnection failed with error %lu!", error); return error; } else { WLog_ERR(TAG, "OnNewChannelConnection returned with bAccept FALSE!"); return ERROR_INTERNAL_ERROR; } } } } return ERROR_INTERNAL_ERROR; }
int xf_SurfaceCommand_Progressive(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int i, j; int status; BYTE* DstData; RFX_RECT* rect; int nXDst, nYDst; int nXSrc, nYSrc; int nWidth, nHeight; int nbUpdateRects; xfGfxSurface* surface; REGION16 updateRegion; RECTANGLE_16 updateRect; RECTANGLE_16* updateRects; REGION16 clippingRects; RECTANGLE_16 clippingRect; RFX_PROGRESSIVE_TILE* tile; PROGRESSIVE_BLOCK_REGION* region; if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_PROGRESSIVE)) return -1; surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return -1; progressive_create_surface_context(xfc->codecs->progressive, cmd->surfaceId, surface->width, surface->height); DstData = surface->data; status = progressive_decompress(xfc->codecs->progressive, cmd->data, cmd->length, &DstData, surface->format, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height, cmd->surfaceId); if (status < 0) { WLog_ERR(TAG, "progressive_decompress failure: %d", status); return -1; } region = &(xfc->codecs->progressive->region); region16_init(&clippingRects); for (i = 0; i < region->numRects; i++) { rect = &(region->rects[i]); clippingRect.left = cmd->left + rect->x; clippingRect.top = cmd->top + rect->y; clippingRect.right = clippingRect.left + rect->width; clippingRect.bottom = clippingRect.top + rect->height; region16_union_rect(&clippingRects, &clippingRects, &clippingRect); } for (i = 0; i < region->numTiles; i++) { tile = region->tiles[i]; updateRect.left = cmd->left + tile->x; updateRect.top = cmd->top + tile->y; updateRect.right = updateRect.left + 64; updateRect.bottom = updateRect.top + 64; region16_init(&updateRegion); region16_intersect_rect(&updateRegion, &clippingRects, &updateRect); updateRects = (RECTANGLE_16*) region16_rects(&updateRegion, &nbUpdateRects); for (j = 0; j < nbUpdateRects; j++) { nXDst = updateRects[j].left; nYDst = updateRects[j].top; nWidth = updateRects[j].right - updateRects[j].left; nHeight = updateRects[j].bottom - updateRects[j].top; nXSrc = nXDst - (cmd->left + tile->x); nYSrc = nYDst - (cmd->top + tile->y); freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline, nXDst, nYDst, nWidth, nHeight, tile->data, PIXEL_FORMAT_XRGB32, 64 * 4, nXSrc, nYSrc, NULL); region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &updateRects[j]); } region16_uninit(&updateRegion); } region16_uninit(&clippingRects); if (!xfc->inGfxFrame) xf_UpdateSurfaces(xfc); return 1; }
int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int port) { int match; int index; char* common_name = NULL; int common_name_length = 0; char** alt_names = NULL; int alt_names_count = 0; int* alt_names_lengths = NULL; BOOL certificate_status; BOOL hostname_match = FALSE; BOOL verification_status = FALSE; rdpCertificateData* certificate_data; if (tls->settings->ExternalCertificateManagement) { BIO* bio; int status; int length; int offset; BYTE* pemCert; freerdp* instance = (freerdp*) tls->settings->instance; /** * Don't manage certificates internally, leave it up entirely to the external client implementation */ bio = BIO_new(BIO_s_mem()); if (!bio) { WLog_ERR(TAG, "BIO_new() failure"); return -1; } status = PEM_write_bio_X509(bio, cert->px509); if (status < 0) { WLog_ERR(TAG, "PEM_write_bio_X509 failure: %d", status); return -1; } offset = 0; length = 2048; pemCert = (BYTE*) malloc(length + 1); if (!pemCert) { WLog_ERR(TAG, "error allocating pemCert"); return -1; } status = BIO_read(bio, pemCert, length); if (status < 0) { WLog_ERR(TAG, "failed to read certificate"); return -1; } offset += status; while (offset >= length) { int new_len; BYTE *new_cert; new_len = length * 2; new_cert = (BYTE*) realloc(pemCert, new_len + 1); if (!new_cert) return -1; length = new_len; pemCert = new_cert; status = BIO_read(bio, &pemCert[offset], length); if (status < 0) break; offset += status; } if (status < 0) { WLog_ERR(TAG, "failed to read certificate"); return -1; } length = offset; pemCert[length] = '\0'; status = -1; if (instance->VerifyX509Certificate) status = instance->VerifyX509Certificate(instance, pemCert, length, hostname, port, tls->isGatewayTransport); else WLog_ERR(TAG, "No VerifyX509Certificate callback registered!"); free(pemCert); BIO_free(bio); if (status < 0) { WLog_ERR(TAG, "VerifyX509Certificate failed: (length = %d) status: [%d] %s", length, status, pemCert); return -1; } return (status == 0) ? 0 : 1; } /* ignore certificate verification if user explicitly required it (discouraged) */ if (tls->settings->IgnoreCertificate) return 1; /* success! */ /* if user explicitly specified a certificate name, use it instead of the hostname */ if (tls->settings->CertificateName) hostname = tls->settings->CertificateName; /* attempt verification using OpenSSL and the ~/.freerdp/certs certificate store */ certificate_status = x509_verify_certificate(cert, tls->certificate_store->path); /* verify certificate name match */ certificate_data = crypto_get_certificate_data(cert->px509, hostname, port); /* extra common name and alternative names */ common_name = crypto_cert_subject_common_name(cert->px509, &common_name_length); alt_names = crypto_cert_subject_alt_name(cert->px509, &alt_names_count, &alt_names_lengths); /* compare against common name */ if (common_name) { if (tls_match_hostname(common_name, common_name_length, hostname)) hostname_match = TRUE; } /* compare against alternative names */ if (alt_names) { for (index = 0; index < alt_names_count; index++) { if (tls_match_hostname(alt_names[index], alt_names_lengths[index], hostname)) { hostname_match = TRUE; break; } } } /* if the certificate is valid and the certificate name matches, verification succeeds */ if (certificate_status && hostname_match) { if (common_name) { free(common_name); common_name = NULL; } verification_status = TRUE; /* success! */ } /* if the certificate is valid but the certificate name does not match, warn user, do not accept */ if (certificate_status && !hostname_match) tls_print_certificate_name_mismatch_error(hostname, port, common_name, alt_names, alt_names_count); /* verification could not succeed with OpenSSL, use known_hosts file and prompt user for manual verification */ if (!certificate_status) { char* issuer; char* subject; char* fingerprint; freerdp* instance = (freerdp*) tls->settings->instance; BOOL accept_certificate = FALSE; issuer = crypto_cert_issuer(cert->px509); subject = crypto_cert_subject(cert->px509); fingerprint = crypto_cert_fingerprint(cert->px509); /* search for matching entry in known_hosts file */ match = certificate_data_match(tls->certificate_store, certificate_data); if (match == 1) { /* no entry was found in known_hosts file, prompt user for manual verification */ if (!hostname_match) tls_print_certificate_name_mismatch_error( hostname, port, common_name, alt_names, alt_names_count); if (instance->VerifyCertificate) { accept_certificate = instance->VerifyCertificate(instance, subject, issuer, fingerprint); } if (!accept_certificate) { /* user did not accept, abort and do not add entry in known_hosts file */ verification_status = FALSE; /* failure! */ } else { /* user accepted certificate, add entry in known_hosts file */ verification_status = certificate_data_print(tls->certificate_store, certificate_data); } } else if (match == -1) { char* old_subject = NULL; char* old_issuer = NULL; char* old_fingerprint = NULL; /* entry was found in known_hosts file, but fingerprint does not match. ask user to use it */ tls_print_certificate_error(hostname, port, fingerprint, tls->certificate_store->file); if (!certificate_get_stored_data(tls->certificate_store, certificate_data, &old_subject, &old_issuer, &old_fingerprint)) WLog_WARN(TAG, "Failed to get certificate entry for %s:hu", hostname, port); if (instance->VerifyChangedCertificate) { accept_certificate = instance->VerifyChangedCertificate( instance, subject, issuer, fingerprint, old_subject, old_issuer, old_fingerprint); } free(old_fingerprint); if (!accept_certificate) { /* user did not accept, abort and do not change known_hosts file */ verification_status = FALSE; /* failure! */ } else { /* user accepted new certificate, add replace fingerprint for this host in known_hosts file */ verification_status = certificate_data_replace(tls->certificate_store, certificate_data); } } else if (match == 0) { verification_status = TRUE; /* success! */ } free(issuer); free(subject); free(fingerprint); } certificate_data_free(certificate_data); #ifndef _WIN32 free(common_name); #endif if (alt_names) crypto_cert_subject_alt_name_free(alt_names_count, alt_names_lengths, alt_names); return (verification_status == 0) ? 0 : 1; }
static BOOL gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) { HGDI_BRUSH originalBrush; rdpGdi* gdi = context->gdi; BOOL ret = TRUE; const rdpBrush* brush = &mem3blt->brush; gdiBitmap* bitmap = (gdiBitmap*) mem3blt->bitmap; UINT32 foreColor; UINT32 backColor; UINT32 originalColor; if (!gdi_decode_color(gdi, mem3blt->foreColor, &foreColor, NULL)) return FALSE; if (!gdi_decode_color(gdi, mem3blt->backColor, &backColor, NULL)) return FALSE; originalColor = gdi_SetTextColor(gdi->drawing->hdc, foreColor); switch (brush->style) { case GDI_BS_SOLID: originalBrush = gdi->drawing->hdc->brush; gdi->drawing->hdc->brush = gdi_CreateSolidBrush(foreColor); if (!gdi->drawing->hdc->brush) { ret = FALSE; goto out_fail; } ret = gdi_BitBlt(gdi->drawing->hdc, mem3blt->nLeftRect, mem3blt->nTopRect, mem3blt->nWidth, mem3blt->nHeight, bitmap->hdc, mem3blt->nXSrc, mem3blt->nYSrc, gdi_rop3_code(mem3blt->bRop), &gdi->palette); gdi_DeleteObject((HGDIOBJECT) gdi->drawing->hdc->brush); gdi->drawing->hdc->brush = originalBrush; break; case GDI_BS_PATTERN: { HGDI_BITMAP hBmp; UINT32 brushFormat; BYTE* data = (BYTE*) _aligned_malloc(8 * 8 * GetBytesPerPixel( gdi->drawing->hdc->format), 16); if (!data) { ret = FALSE; goto out_fail; } if (brush->bpp > 1) { UINT32 bpp = brush->bpp; if ((bpp == 16) && (context->settings->ColorDepth == 15)) bpp = 15; brushFormat = gdi_get_pixel_format(bpp); if (!freerdp_image_copy(data, gdi->drawing->hdc->format, 0, 0, 0, 8, 8, brush->data, brushFormat, 0, 0, 0, &gdi->palette, FREERDP_FLIP_NONE)) { ret = FALSE; _aligned_free(data); goto out_fail; } } else { if (!freerdp_image_copy_from_monochrome(data, gdi->drawing->hdc->format, 0, 0, 0, 8, 8, brush->data, backColor, foreColor, &gdi->palette)) { ret = FALSE; _aligned_free(data); goto out_fail; } } hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->format, data); if (!hBmp) { ret = FALSE; _aligned_free(data); goto out_fail; } originalBrush = gdi->drawing->hdc->brush; gdi->drawing->hdc->brush = gdi_CreatePatternBrush(hBmp); if (!gdi->drawing->hdc->brush) { gdi_DeleteObject((HGDIOBJECT) hBmp); goto out_fail; } gdi->drawing->hdc->brush->nXOrg = brush->x; gdi->drawing->hdc->brush->nYOrg = brush->y; ret = gdi_BitBlt(gdi->drawing->hdc, mem3blt->nLeftRect, mem3blt->nTopRect, mem3blt->nWidth, mem3blt->nHeight, bitmap->hdc, mem3blt->nXSrc, mem3blt->nYSrc, gdi_rop3_code(mem3blt->bRop), &gdi->palette); gdi_DeleteObject((HGDIOBJECT) gdi->drawing->hdc->brush); gdi_DeleteObject((HGDIOBJECT) hBmp); gdi->drawing->hdc->brush = originalBrush; } break; default: WLog_ERR(TAG, "Mem3Blt unimplemented brush style:%"PRIu32"", brush->style); break; } out_fail: gdi_SetTextColor(gdi->drawing->hdc, originalColor); return ret; }
BOOL rdp_read_extended_info_packet(rdpRdp* rdp, wStream* s) { UINT16 clientAddressFamily; UINT16 cbClientAddress; UINT16 cbClientDir; UINT16 cbAutoReconnectLen; rdpSettings* settings = rdp->settings; WCHAR* wstr; if (Stream_GetRemainingLength(s) < 4) return FALSE; Stream_Read_UINT16(s, clientAddressFamily); /* clientAddressFamily (2 bytes) */ Stream_Read_UINT16(s, cbClientAddress); /* cbClientAddress (2 bytes) */ /* cbClientAddress is the size in bytes of the character data in the clientAddress field. * This size includes the length of the mandatory null terminator. * The maximum allowed value is 80 bytes */ if ((cbClientAddress % 2) || cbClientAddress < 2 || cbClientAddress > 80) { WLog_ERR(TAG, "protocol error: invalid cbClientAddress value: %u", cbClientAddress); return FALSE; } settings->IPv6Enabled = (clientAddressFamily == ADDRESS_FAMILY_INET6 ? TRUE : FALSE); if (Stream_GetRemainingLength(s) < cbClientAddress) return FALSE; if (settings->ClientAddress) { free(settings->ClientAddress); settings->ClientAddress = NULL; } wstr = (WCHAR*) Stream_Pointer(s); if (wstr[cbClientAddress / 2 - 1]) { WLog_ERR(TAG, "protocol error: clientAddress must be null terminated"); return FALSE; } if (ConvertFromUnicode(CP_UTF8, 0, wstr, -1, &settings->ClientAddress, 0, NULL, NULL) < 1) { WLog_ERR(TAG, "failed to convert client address"); return FALSE; } Stream_Seek(s, cbClientAddress); if (Stream_GetRemainingLength(s) < 2) return FALSE; Stream_Read_UINT16(s, cbClientDir); /* cbClientDir (2 bytes) */ /* cbClientDir is the size in bytes of the character data in the clientDir field. * This size includes the length of the mandatory null terminator. * The maximum allowed value is 512 bytes */ if ((cbClientDir % 2) || cbClientDir < 2 || cbClientDir > 512) { WLog_ERR(TAG, "protocol error: invalid cbClientDir value: %u", cbClientDir); return FALSE; } if (Stream_GetRemainingLength(s) < cbClientDir) return FALSE; if (settings->ClientDir) { free(settings->ClientDir); settings->ClientDir = NULL; } wstr = (WCHAR*) Stream_Pointer(s); if (wstr[cbClientDir / 2 - 1]) { WLog_ERR(TAG, "protocol error: clientDir must be null terminated"); return FALSE; } if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), -1, &settings->ClientDir, 0, NULL, NULL) < 1) { WLog_ERR(TAG, "failed to convert client directory"); return FALSE; } Stream_Seek(s, cbClientDir); if (!rdp_read_client_time_zone(s, settings)) return FALSE; if (Stream_GetRemainingLength(s) < 10) return FALSE; Stream_Seek_UINT32(s); /* clientSessionId (4 bytes), should be set to 0 */ Stream_Read_UINT32(s, settings->PerformanceFlags); /* performanceFlags (4 bytes) */ freerdp_performance_flags_split(settings); Stream_Read_UINT16(s, cbAutoReconnectLen); /* cbAutoReconnectLen (2 bytes) */ if (cbAutoReconnectLen > 0) return rdp_read_client_auto_reconnect_cookie(rdp, s); /* autoReconnectCookie */ /* reserved1 (2 bytes) */ /* reserved2 (2 bytes) */ return TRUE; }
static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder* decoder, const BYTE *data, UINT32 data_size, UINT32 extensions, UINT64 start_time, UINT64 end_time, UINT64 duration) { GstBuffer *gst_buf; TSMFGstreamerDecoder* mdecoder = (TSMFGstreamerDecoder *) decoder; UINT64 sample_time = tsmf_gstreamer_timestamp_ms_to_gst(start_time); BOOL useTimestamps = TRUE; if (!mdecoder) { WLog_ERR(TAG, "Decoder not initialized!"); return FALSE; } /* * This function is always called from a stream-specific thread. * It should be alright to block here if necessary. * We don't expect to block here often, since the pipeline should * have more than enough buffering. */ DEBUG_TSMF("%s. Start:(%"PRIu64") End:(%"PRIu64") Duration:(%"PRIu64") Last Start:(%"PRIu64")", get_type(mdecoder), start_time, end_time, duration, mdecoder->last_sample_start_time); if (mdecoder->shutdown) { WLog_ERR(TAG, "decodeEx called on shutdown decoder"); return TRUE; } if (mdecoder->gst_caps == NULL) { WLog_ERR(TAG, "tsmf_gstreamer_set_format not called or invalid format."); return FALSE; } if (!mdecoder->pipe) tsmf_gstreamer_pipeline_build(mdecoder); if (!mdecoder->src) { WLog_ERR(TAG, "failed to construct pipeline correctly. Unable to push buffer to source element."); return FALSE; } gst_buf = tsmf_get_buffer_from_data(data, data_size); if (gst_buf == NULL) { WLog_ERR(TAG, "tsmf_get_buffer_from_data(%p, %"PRIu32") failed.", (void*) data, data_size); return FALSE; } /* Relative timestamping will sometimes be set to 0 * so we ignore these timestamps just to be safe(bit 8) */ if (extensions & 0x00000080) { DEBUG_TSMF("Ignoring the timestamps - relative - bit 8"); useTimestamps = FALSE; } /* If no timestamps exist then we dont want to look at the timestamp values (bit 7) */ if (extensions & 0x00000040) { DEBUG_TSMF("Ignoring the timestamps - none - bit 7"); useTimestamps = FALSE; } /* If performing a seek */ if (mdecoder->seeking) { mdecoder->seeking = FALSE; tsmf_gstreamer_pipeline_set_state(mdecoder, GST_STATE_PAUSED); mdecoder->pipeline_start_time_valid = 0; } if (mdecoder->pipeline_start_time_valid) { DEBUG_TSMF("%s start time %"PRIu64"", get_type(mdecoder), start_time); /* Adjusted the condition for a seek to be based on start time only * WMV1 and WMV2 files in particular have bad end time and duration values * there seems to be no real side effects of just using the start time instead */ UINT64 minTime = mdecoder->last_sample_start_time - (UINT64) SEEK_TOLERANCE; UINT64 maxTime = mdecoder->last_sample_start_time + (UINT64) SEEK_TOLERANCE; /* Make sure the minTime stops at 0 , should we be at the beginning of the stream */ if (mdecoder->last_sample_start_time < (UINT64) SEEK_TOLERANCE) minTime = 0; /* If the start_time is valid and different from the previous start time by more than the seek tolerance, then we have a seek condition */ if (((start_time > maxTime) || (start_time < minTime)) && useTimestamps) { DEBUG_TSMF("tsmf_gstreamer_decodeEx: start_time=[%"PRIu64"] > last_sample_start_time=[%"PRIu64"] OR ", start_time, mdecoder->last_sample_start_time); DEBUG_TSMF("tsmf_gstreamer_decodeEx: start_time=[%"PRIu64"] < last_sample_start_time=[%"PRIu64"] with", start_time, mdecoder->last_sample_start_time); DEBUG_TSMF("tsmf_gstreamer_decodeEX: a tolerance of more than [%lu] from the last sample", SEEK_TOLERANCE); DEBUG_TSMF("tsmf_gstreamer_decodeEX: minTime=[%"PRIu64"] maxTime=[%"PRIu64"]", minTime, maxTime); mdecoder->seeking = TRUE; /* since we cant make the gstreamer pipeline jump to the new start time after a seek - we just maintain * a offset between realtime and gstreamer time */ mdecoder->seek_offset = start_time; } } else { DEBUG_TSMF("%s start time %"PRIu64"", get_type(mdecoder), start_time); /* Always set base/start time to 0. Will use seek offset to translate real buffer times * back to 0. This allows the video to be started from anywhere and the ability to handle seeks * without rebuilding the pipeline, etc. since that is costly */ gst_element_set_base_time(mdecoder->pipe, tsmf_gstreamer_timestamp_ms_to_gst(0)); gst_element_set_start_time(mdecoder->pipe, tsmf_gstreamer_timestamp_ms_to_gst(0)); mdecoder->pipeline_start_time_valid = 1; /* Set the seek offset if buffer has valid timestamps. */ if (useTimestamps) mdecoder->seek_offset = start_time; if (!gst_element_seek(mdecoder->pipe, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) { WLog_ERR(TAG, "seek failed"); } } #if GST_VERSION_MAJOR > 0 if (useTimestamps) GST_BUFFER_PTS(gst_buf) = sample_time - tsmf_gstreamer_timestamp_ms_to_gst(mdecoder->seek_offset); else GST_BUFFER_PTS(gst_buf) = GST_CLOCK_TIME_NONE; #else if (useTimestamps) GST_BUFFER_TIMESTAMP(gst_buf) = sample_time - tsmf_gstreamer_timestamp_ms_to_gst(mdecoder->seek_offset); else GST_BUFFER_TIMESTAMP(gst_buf) = GST_CLOCK_TIME_NONE; #endif GST_BUFFER_DURATION(gst_buf) = GST_CLOCK_TIME_NONE; GST_BUFFER_OFFSET(gst_buf) = GST_BUFFER_OFFSET_NONE; #if GST_VERSION_MAJOR > 0 #else gst_buffer_set_caps(gst_buf, mdecoder->gst_caps); #endif gst_app_src_push_buffer(GST_APP_SRC(mdecoder->src), gst_buf); /* Should only update the last timestamps if the current ones are valid */ if (useTimestamps) { mdecoder->last_sample_start_time = start_time; mdecoder->last_sample_end_time = end_time; } if (mdecoder->pipe && (GST_STATE(mdecoder->pipe) != GST_STATE_PLAYING)) { DEBUG_TSMF("%s: state=%s", get_type(mdecoder), gst_element_state_get_name(GST_STATE(mdecoder->pipe))); DEBUG_TSMF("%s Paused: %"PRIi32" Shutdown: %i Ready: %"PRIi32"", get_type(mdecoder), mdecoder->paused, mdecoder->shutdown, mdecoder->ready); if (!mdecoder->paused && !mdecoder->shutdown && mdecoder->ready) tsmf_gstreamer_pipeline_set_state(mdecoder, GST_STATE_PLAYING); } return TRUE; }
static BOOL gdi_surface_bits(rdpContext* context, const SURFACE_BITS_COMMAND* cmd) { BOOL result = FALSE; DWORD format; rdpGdi* gdi; REGION16 region; RECTANGLE_16 cmdRect; UINT32 i, nbRects; const RECTANGLE_16* rects; if (!context || !cmd) return FALSE; gdi = context->gdi; WLog_Print(gdi->log, WLOG_DEBUG, "destLeft %"PRIu32" destTop %"PRIu32" destRight %"PRIu32" destBottom %"PRIu32" " "bpp %"PRIu8" flags %"PRIx8" codecID %"PRIu16" width %"PRIu16" height %"PRIu16" length %"PRIu32"", cmd->destLeft, cmd->destTop, cmd->destRight, cmd->destBottom, cmd->bmp.bpp, cmd->bmp.flags, cmd->bmp.codecID, cmd->bmp.width, cmd->bmp.height, cmd->bmp.bitmapDataLength); region16_init(®ion); cmdRect.left = cmd->destLeft; cmdRect.top = cmd->destTop; cmdRect.right = cmdRect.left + cmd->bmp.width; cmdRect.bottom = cmdRect.top + cmd->bmp.height; switch (cmd->bmp.codecID) { case RDP_CODEC_ID_REMOTEFX: if (!rfx_process_message(context->codecs->rfx, cmd->bmp.bitmapData, cmd->bmp.bitmapDataLength, cmd->destLeft, cmd->destTop, gdi->primary_buffer, gdi->dstFormat, gdi->stride, gdi->height, ®ion)) { WLog_ERR(TAG, "Failed to process RemoteFX message"); goto out; } break; case RDP_CODEC_ID_NSCODEC: format = gdi->dstFormat; if (!nsc_process_message(context->codecs->nsc, cmd->bmp.bpp, cmd->bmp.width, cmd->bmp.height, cmd->bmp.bitmapData, cmd->bmp.bitmapDataLength, gdi->primary_buffer, format, gdi->stride, cmd->destLeft, cmd->destTop, cmd->bmp.width, cmd->bmp.height, FREERDP_FLIP_VERTICAL)) { WLog_ERR(TAG, "Failed to process NSCodec message"); goto out; } region16_union_rect(®ion, ®ion, &cmdRect); break; case RDP_CODEC_ID_NONE: format = gdi_get_pixel_format(cmd->bmp.bpp); if (!freerdp_image_copy(gdi->primary_buffer, gdi->dstFormat, gdi->stride, cmd->destLeft, cmd->destTop, cmd->bmp.width, cmd->bmp.height, cmd->bmp.bitmapData, format, 0, 0, 0, &gdi->palette, FREERDP_FLIP_VERTICAL)) { WLog_ERR(TAG, "Failed to process nocodec message"); goto out; } region16_union_rect(®ion, ®ion, &cmdRect); break; default: WLog_ERR(TAG, "Unsupported codecID %"PRIu32"", cmd->bmp.codecID); break; } if (!(rects = region16_rects(®ion, &nbRects))) goto out; for (i = 0; i < nbRects; i++) { UINT32 left = rects[i].left; UINT32 top = rects[i].top; UINT32 width = rects[i].right - rects[i].left; UINT32 height = rects[i].bottom - rects[i].top; if (!gdi_InvalidateRegion(gdi->primary->hdc, left, top, width, height)) { WLog_ERR(TAG, "Failed to update invalid region"); goto out; } } result = TRUE; out: region16_uninit(®ion); return result; }
static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard) { int index; int keyCount; ULONG_PTR* pKeys; SCARDCONTEXT hContext; SMARTCARD_CONTEXT* pContext; /** * On protocol termination, the following actions are performed: * For each context in rgSCardContextList, SCardCancel is called causing all SCardGetStatusChange calls to be processed. * After that, SCardReleaseContext is called on each context and the context MUST be removed from rgSCardContextList. */ /** * Call SCardCancel on existing contexts, unblocking all outstanding SCardGetStatusChange calls. */ if (ListDictionary_Count(smartcard->rgSCardContextList) > 0) { pKeys = NULL; keyCount = ListDictionary_GetKeys(smartcard->rgSCardContextList, &pKeys); for (index = 0; index < keyCount; index++) { pContext = (SMARTCARD_CONTEXT*) ListDictionary_GetItemValue( smartcard->rgSCardContextList, (void*) pKeys[index]); if (!pContext) continue; hContext = pContext->hContext; if (SCardIsValidContext(hContext) == SCARD_S_SUCCESS) { SCardCancel(hContext); } } free(pKeys); } /** * Call SCardReleaseContext on remaining contexts and remove them from rgSCardContextList. */ if (ListDictionary_Count(smartcard->rgSCardContextList) > 0) { pKeys = NULL; keyCount = ListDictionary_GetKeys(smartcard->rgSCardContextList, &pKeys); for (index = 0; index < keyCount; index++) { pContext = (SMARTCARD_CONTEXT*) ListDictionary_Remove( smartcard->rgSCardContextList, (void*) pKeys[index]); if (!pContext) continue; hContext = pContext->hContext; if (SCardIsValidContext(hContext) == SCARD_S_SUCCESS) { SCardReleaseContext(hContext); if (MessageQueue_PostQuit(pContext->IrpQueue, 0) && (WaitForSingleObject(pContext->thread, INFINITE) == WAIT_FAILED)) WLog_ERR(TAG, "WaitForSingleObject failed with error %"PRIu32"!", GetLastError()); CloseHandle(pContext->thread); MessageQueue_Free(pContext->IrpQueue); free(pContext); } } free(pKeys); } }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) { void* key; LONG status; BOOL asyncIrp = FALSE; SMARTCARD_CONTEXT* pContext = NULL; SMARTCARD_OPERATION* operation = NULL; key = (void*)(size_t) irp->CompletionId; if (!ListDictionary_Add(smartcard->rgOutstandingMessages, key, irp)) { WLog_ERR(TAG, "ListDictionary_Add failed!"); return ERROR_INTERNAL_ERROR; } if (irp->MajorFunction == IRP_MJ_DEVICE_CONTROL) { operation = (SMARTCARD_OPERATION*) calloc(1, sizeof(SMARTCARD_OPERATION)); if (!operation) { WLog_ERR(TAG, "calloc failed!"); return CHANNEL_RC_NO_MEMORY; } operation->irp = irp; status = smartcard_irp_device_control_decode(smartcard, operation); if (status != SCARD_S_SUCCESS) { irp->IoStatus = (UINT32)STATUS_UNSUCCESSFUL; if (!Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp)) { free(operation); WLog_ERR(TAG, "Queue_Enqueue failed!"); return ERROR_INTERNAL_ERROR; } free(operation); return CHANNEL_RC_OK; } asyncIrp = TRUE; switch (operation->ioControlCode) { case SCARD_IOCTL_ESTABLISHCONTEXT: case SCARD_IOCTL_RELEASECONTEXT: case SCARD_IOCTL_ISVALIDCONTEXT: case SCARD_IOCTL_CANCEL: case SCARD_IOCTL_ACCESSSTARTEDEVENT: case SCARD_IOCTL_RELEASESTARTEDEVENT: asyncIrp = FALSE; break; case SCARD_IOCTL_LISTREADERGROUPSA: case SCARD_IOCTL_LISTREADERGROUPSW: case SCARD_IOCTL_LISTREADERSA: case SCARD_IOCTL_LISTREADERSW: case SCARD_IOCTL_INTRODUCEREADERGROUPA: case SCARD_IOCTL_INTRODUCEREADERGROUPW: case SCARD_IOCTL_FORGETREADERGROUPA: case SCARD_IOCTL_FORGETREADERGROUPW: case SCARD_IOCTL_INTRODUCEREADERA: case SCARD_IOCTL_INTRODUCEREADERW: case SCARD_IOCTL_FORGETREADERA: case SCARD_IOCTL_FORGETREADERW: case SCARD_IOCTL_ADDREADERTOGROUPA: case SCARD_IOCTL_ADDREADERTOGROUPW: case SCARD_IOCTL_REMOVEREADERFROMGROUPA: case SCARD_IOCTL_REMOVEREADERFROMGROUPW: case SCARD_IOCTL_LOCATECARDSA: case SCARD_IOCTL_LOCATECARDSW: case SCARD_IOCTL_LOCATECARDSBYATRA: case SCARD_IOCTL_LOCATECARDSBYATRW: case SCARD_IOCTL_READCACHEA: case SCARD_IOCTL_READCACHEW: case SCARD_IOCTL_WRITECACHEA: case SCARD_IOCTL_WRITECACHEW: case SCARD_IOCTL_GETREADERICON: case SCARD_IOCTL_GETDEVICETYPEID: case SCARD_IOCTL_GETSTATUSCHANGEA: case SCARD_IOCTL_GETSTATUSCHANGEW: case SCARD_IOCTL_CONNECTA: case SCARD_IOCTL_CONNECTW: case SCARD_IOCTL_RECONNECT: case SCARD_IOCTL_DISCONNECT: case SCARD_IOCTL_BEGINTRANSACTION: case SCARD_IOCTL_ENDTRANSACTION: case SCARD_IOCTL_STATE: case SCARD_IOCTL_STATUSA: case SCARD_IOCTL_STATUSW: case SCARD_IOCTL_TRANSMIT: case SCARD_IOCTL_CONTROL: case SCARD_IOCTL_GETATTRIB: case SCARD_IOCTL_SETATTRIB: case SCARD_IOCTL_GETTRANSMITCOUNT: asyncIrp = TRUE; break; } pContext = ListDictionary_GetItemValue(smartcard->rgSCardContextList, (void*) operation->hContext); if (!pContext) asyncIrp = FALSE; if (!asyncIrp) { if ((status = smartcard_irp_device_control_call(smartcard, operation))) { WLog_ERR(TAG, "smartcard_irp_device_control_call failed with error %"PRId32"!", status); return (UINT32)status; } if (!Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp)) { free(operation); WLog_ERR(TAG, "Queue_Enqueue failed!"); return ERROR_INTERNAL_ERROR; } free(operation); } else { if (pContext) { if (!MessageQueue_Post(pContext->IrpQueue, NULL, 0, (void*) operation, NULL)) { WLog_ERR(TAG, "MessageQueue_Post failed!"); return ERROR_INTERNAL_ERROR; } } } } else { WLog_ERR(TAG, "Unexpected SmartCard IRP: MajorFunction 0x%08"PRIX32" MinorFunction: 0x%08"PRIX32"", irp->MajorFunction, irp->MinorFunction); irp->IoStatus = (UINT32)STATUS_NOT_SUPPORTED; if (!Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp)) { WLog_ERR(TAG, "Queue_Enqueue failed!"); return ERROR_INTERNAL_ERROR; } } return CHANNEL_RC_OK; }
static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* windowState) { xfAppWindow* appWindow = NULL; xfContext* xfc = (xfContext*) context; UINT32 fieldFlags = orderInfo->fieldFlags; BOOL position_or_size_updated = FALSE; if (fieldFlags & WINDOW_ORDER_STATE_NEW) { appWindow = (xfAppWindow*) calloc(1, sizeof(xfAppWindow)); if (!appWindow) return FALSE; appWindow->xfc = xfc; appWindow->windowId = orderInfo->windowId; appWindow->dwStyle = windowState->style; appWindow->dwExStyle = windowState->extendedStyle; appWindow->x = appWindow->windowOffsetX = windowState->windowOffsetX; appWindow->y = appWindow->windowOffsetY = windowState->windowOffsetY; appWindow->width = appWindow->windowWidth = windowState->windowWidth; appWindow->height = appWindow->windowHeight = windowState->windowHeight; /* Ensure window always gets a window title */ if (fieldFlags & WINDOW_ORDER_FIELD_TITLE) { char* title = NULL; if (windowState->titleInfo.length == 0) { if (!(title = _strdup(""))) { WLog_ERR(TAG, "failed to duplicate empty window title string"); /* error handled below */ } } else if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string, windowState->titleInfo.length / 2, &title, 0, NULL, NULL) < 1) { WLog_ERR(TAG, "failed to convert window title"); /* error handled below */ } appWindow->title = title; } else { if (!(appWindow->title = _strdup("RdpRailWindow"))) WLog_ERR(TAG, "failed to duplicate default window title string"); } if (!appWindow->title) { free(appWindow); return FALSE; } HashTable_Add(xfc->railWindows, (void*)(UINT_PTR) orderInfo->windowId, (void*) appWindow); xf_AppWindowInit(xfc, appWindow); } else { appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, (void*)(UINT_PTR) orderInfo->windowId); } if (!appWindow) return FALSE; /* Keep track of any position/size update so that we can force a refresh of the window */ if ((fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) || (fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE) || (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) || (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) || (fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) || (fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET) || (fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)) { position_or_size_updated = TRUE; } /* Update Parameters */ if (fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) { appWindow->windowOffsetX = windowState->windowOffsetX; appWindow->windowOffsetY = windowState->windowOffsetY; } if (fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE) { appWindow->windowWidth = windowState->windowWidth; appWindow->windowHeight = windowState->windowHeight; } if (fieldFlags & WINDOW_ORDER_FIELD_OWNER) { appWindow->ownerWindowId = windowState->ownerWindowId; } if (fieldFlags & WINDOW_ORDER_FIELD_STYLE) { appWindow->dwStyle = windowState->style; appWindow->dwExStyle = windowState->extendedStyle; } if (fieldFlags & WINDOW_ORDER_FIELD_SHOW) { appWindow->showState = windowState->showState; } if (fieldFlags & WINDOW_ORDER_FIELD_TITLE) { char* title = NULL; if (windowState->titleInfo.length == 0) { if (!(title = _strdup(""))) { WLog_ERR(TAG, "failed to duplicate empty window title string"); return FALSE; } } else if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string, windowState->titleInfo.length / 2, &title, 0, NULL, NULL) < 1) { WLog_ERR(TAG, "failed to convert window title"); return FALSE; } free(appWindow->title); appWindow->title = title; } if (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) { appWindow->clientOffsetX = windowState->clientOffsetX; appWindow->clientOffsetY = windowState->clientOffsetY; } if (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) { appWindow->clientAreaWidth = windowState->clientAreaWidth; appWindow->clientAreaHeight = windowState->clientAreaHeight; } if (fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) { appWindow->windowClientDeltaX = windowState->windowClientDeltaX; appWindow->windowClientDeltaY = windowState->windowClientDeltaY; } if (fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS) { if (appWindow->windowRects) { free(appWindow->windowRects); appWindow->windowRects = NULL; } appWindow->numWindowRects = windowState->numWindowRects; if (appWindow->numWindowRects) { appWindow->windowRects = (RECTANGLE_16*) calloc(appWindow->numWindowRects, sizeof(RECTANGLE_16)); if (!appWindow->windowRects) return FALSE; CopyMemory(appWindow->windowRects, windowState->windowRects, appWindow->numWindowRects * sizeof(RECTANGLE_16)); } } if (fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET) { appWindow->visibleOffsetX = windowState->visibleOffsetX; appWindow->visibleOffsetY = windowState->visibleOffsetY; } if (fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY) { if (appWindow->visibilityRects) { free(appWindow->visibilityRects); appWindow->visibilityRects = NULL; } appWindow->numVisibilityRects = windowState->numVisibilityRects; if (appWindow->numVisibilityRects) { appWindow->visibilityRects = (RECTANGLE_16*) calloc( appWindow->numVisibilityRects, sizeof(RECTANGLE_16)); if (!appWindow->visibilityRects) return FALSE; CopyMemory(appWindow->visibilityRects, windowState->visibilityRects, appWindow->numVisibilityRects * sizeof(RECTANGLE_16)); } } /* Update Window */ if (fieldFlags & WINDOW_ORDER_FIELD_STYLE) { } if (fieldFlags & WINDOW_ORDER_FIELD_SHOW) { xf_ShowWindow(xfc, appWindow, appWindow->showState); } if (fieldFlags & WINDOW_ORDER_FIELD_TITLE) { if (appWindow->title) xf_SetWindowText(xfc, appWindow, appWindow->title); } if (position_or_size_updated) { UINT32 visibilityRectsOffsetX = (appWindow->visibleOffsetX - (appWindow->clientOffsetX - appWindow->windowClientDeltaX)); UINT32 visibilityRectsOffsetY = (appWindow->visibleOffsetY - (appWindow->clientOffsetY - appWindow->windowClientDeltaY)); /* * The rail server like to set the window to a small size when it is minimized even though it is hidden * in some cases this can cause the window not to restore back to its original size. Therefore we don't * update our local window when that rail window state is minimized */ if (appWindow->rail_state != WINDOW_SHOW_MINIMIZED) { /* Redraw window area if already in the correct position */ if (appWindow->x == appWindow->windowOffsetX && appWindow->y == appWindow->windowOffsetY && appWindow->width == appWindow->windowWidth && appWindow->height == appWindow->windowHeight) { xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->windowWidth, appWindow->windowHeight); } else { xf_MoveWindow(xfc, appWindow, appWindow->windowOffsetX, appWindow->windowOffsetY, appWindow->windowWidth, appWindow->windowHeight); } xf_SetWindowVisibilityRects(xfc, appWindow, visibilityRectsOffsetX, visibilityRectsOffsetY, appWindow->visibilityRects, appWindow->numVisibilityRects); } } /* We should only be using the visibility rects for shaping the window */ /*if (fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS) { xf_SetWindowRects(xfc, appWindow, appWindow->windowRects, appWindow->numWindowRects); }*/ return TRUE; }
int shadow_capture_compare(BYTE* pData1, int nStep1, int nWidth, int nHeight, BYTE* pData2, int nStep2, RECTANGLE_16* rect) { BOOL equal; BOOL allEqual; int tw, th; int tx, ty, k; int nrow, ncol; int l, t, r, b; BYTE *p1, *p2; BOOL rows[1024]; BOOL cols[1024]; BOOL grid[1024][1024]; allEqual = TRUE; FillMemory(rows, sizeof(rows), 0xFF); FillMemory(cols, sizeof(cols), 0xFF); FillMemory(grid, sizeof(grid), 0xFF); ZeroMemory(rect, sizeof(RECTANGLE_16)); nrow = (nHeight + 15) / 16; ncol = (nWidth + 15) / 16; l = ncol + 1; r = -1; t = nrow + 1; b = -1; for (ty = 0; ty < nrow; ty++) { th = ((ty + 1) == nrow) ? (nHeight % 16) : 16; if (!th) th = 16; for (tx = 0; tx < ncol; tx++) { equal = TRUE; tw = ((tx + 1) == ncol) ? (nWidth % 16) : 16; if (!tw) tw = 16; p1 = &pData1[(ty * 16 * nStep1) + (tx * 16 * 4)]; p2 = &pData2[(ty * 16 * nStep2) + (tx * 16 * 4)]; for (k = 0; k < th; k++) { if (memcmp(p1, p2, tw * 4) != 0) { equal = FALSE; break; } p1 += nStep1; p2 += nStep2; } if (!equal) { grid[ty][tx] = FALSE; rows[ty] = FALSE; cols[tx] = FALSE; if (l > tx) l = tx; if (r < tx) r = tx; } } if (!rows[ty]) { allEqual = FALSE; if (t > ty) t = ty; if (b < ty) b = ty; } } if (allEqual) return 0; rect->left = l * 16; rect->top = t * 16; rect->right = (r + 1) * 16; rect->bottom = (b + 1) * 16; if (rect->right > nWidth) rect->right = nWidth; if (rect->bottom > nHeight) rect->bottom = nHeight; if (0) { char *col_str = calloc(ncol + 1, sizeof(char)); if (!col_str) { WLog_ERR(TAG, "calloc failed!"); return 1; } for (tx = 0; tx < ncol; tx++) sprintf(&col_str[tx], "-"); WLog_INFO(TAG, "%s", col_str); for (tx = 0; tx < ncol; tx++) sprintf(&col_str[tx], "%c", cols[tx] ? 'O' : 'X'); WLog_INFO(TAG, "%s", col_str); for (tx = 0; tx < ncol; tx++) sprintf(&col_str[tx], "-"); WLog_INFO(TAG, "%s", col_str); for (ty = 0; ty < nrow; ty++) { for (tx = 0; tx < ncol; tx++) sprintf(&col_str[tx], "%c", cols[tx] ? 'O' : 'X'); WLog_INFO(TAG, "%s", col_str); WLog_INFO(TAG, "|%s|", rows[ty] ? "O" : "X"); } WLog_INFO(TAG, "left: %d top: %d right: %d bottom: %d ncol: %d nrow: %d", l, t, r, b, ncol, nrow); free(col_str); } return 1; }
void* shw_client_thread(void* arg) { int index; int rcount; int wcount; BOOL bSuccess; void* rfds[32]; void* wfds[32]; int fds_count; HANDLE fds[64]; shwContext* shw; rdpContext* context; rdpChannels* channels; freerdp* instance = (freerdp*) arg; ZeroMemory(rfds, sizeof(rfds)); ZeroMemory(wfds, sizeof(wfds)); context = (rdpContext*) instance->context; shw = (shwContext*) context; bSuccess = freerdp_connect(instance); WLog_INFO(TAG, "freerdp_connect: %d", bSuccess); if (!bSuccess) { ExitThread(0); return NULL; } channels = instance->context->channels; while (1) { rcount = 0; wcount = 0; if (!freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount)) { WLog_ERR(TAG, "Failed to get FreeRDP file descriptor"); break; } if (!freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount)) { WLog_ERR(TAG, "Failed to get channels file descriptor"); break; } fds_count = 0; for (index = 0; index < rcount; index++) fds[fds_count++] = rfds[index]; for (index = 0; index < wcount; index++) fds[fds_count++] = wfds[index]; if (MsgWaitForMultipleObjects(fds_count, fds, FALSE, 1000, QS_ALLINPUT) == WAIT_FAILED) { WLog_ERR(TAG, "MsgWaitForMultipleObjects failure: 0x%08X", GetLastError()); break; } if (!freerdp_check_fds(instance)) { WLog_ERR(TAG, "Failed to check FreeRDP file descriptor"); break; } if (freerdp_shall_disconnect(instance)) { break; } if (!freerdp_channels_check_fds(channels, instance)) { WLog_ERR(TAG, "Failed to check channels file descriptor"); break; } } freerdp_free(instance); ExitThread(0); return NULL; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, wStream* s) { unsigned long pos; UINT status; UINT32 ChannelId; wStream* data_out; UINT channel_status; if (drdynvc->state == DRDYNVC_STATE_CAPABILITIES) { /** * For some reason the server does not always send the * capabilities pdu as it should. When this happens, * send a capabilities response. */ drdynvc->version = 3; if ((status = drdynvc_send_capability_response(drdynvc))) { WLog_ERR(TAG, "drdynvc_send_capability_response failed!"); return status; } drdynvc->state = DRDYNVC_STATE_READY; } ChannelId = drdynvc_read_variable_uint(s, cbChId); pos = Stream_GetPosition(s); WLog_DBG(TAG, "process_create_request: ChannelId=%d ChannelName=%s", ChannelId, Stream_Pointer(s)); channel_status = dvcman_create_channel(drdynvc->channel_mgr, ChannelId, (char*) Stream_Pointer(s)); data_out = Stream_New(NULL, pos + 4); if (!s) { WLog_ERR(TAG, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } Stream_Write_UINT8(data_out, 0x10 | cbChId); Stream_SetPosition(s, 1); Stream_Copy(s, data_out, pos - 1); if (channel_status == CHANNEL_RC_OK) { WLog_DBG(TAG, "channel created"); Stream_Write_UINT32(data_out, 0); } else { WLog_DBG(TAG, "no listener"); Stream_Write_UINT32(data_out, (UINT32) 0xC0000001); /* same code used by mstsc */ } status = drdynvc_send(drdynvc, data_out); if (status != CHANNEL_RC_OK) { WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", WTSErrorToString(status), status); return status; } if (channel_status == CHANNEL_RC_OK) { if ((status = dvcman_open_channel(drdynvc->channel_mgr, ChannelId))) { WLog_ERR(TAG, "dvcman_open_channel failed with error %lu!", status); return status; } } else { if ((status = dvcman_close_channel(drdynvc->channel_mgr, ChannelId))) WLog_ERR(TAG, "dvcman_close_channel failed with error %lu!", status); } return status; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, const BYTE* data, UINT32 dataSize) { wStream* data_out; unsigned long pos; UINT32 cbChId; UINT32 cbLen; unsigned long chunkLength; UINT status; WLog_DBG(TAG, "write_data: ChannelId=%d size=%d", ChannelId, dataSize); data_out = Stream_New(NULL, CHANNEL_CHUNK_LENGTH); if (!data_out) { WLog_ERR(TAG, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } Stream_SetPosition(data_out, 1); cbChId = drdynvc_write_variable_uint(data_out, ChannelId); pos = Stream_GetPosition(data_out); if (dataSize == 0) { Stream_SetPosition(data_out, 0); Stream_Write_UINT8(data_out, 0x40 | cbChId); Stream_SetPosition(data_out, pos); status = drdynvc_send(drdynvc, data_out); } else if (dataSize <= CHANNEL_CHUNK_LENGTH - pos) { Stream_SetPosition(data_out, 0); Stream_Write_UINT8(data_out, 0x30 | cbChId); Stream_SetPosition(data_out, pos); Stream_Write(data_out, data, dataSize); status = drdynvc_send(drdynvc, data_out); } else { /* Fragment the data */ cbLen = drdynvc_write_variable_uint(data_out, dataSize); pos = Stream_GetPosition(data_out); Stream_SetPosition(data_out, 0); Stream_Write_UINT8(data_out, 0x20 | cbChId | (cbLen << 2)); Stream_SetPosition(data_out, pos); chunkLength = CHANNEL_CHUNK_LENGTH - pos; Stream_Write(data_out, data, chunkLength); data += chunkLength; dataSize -= chunkLength; status = drdynvc_send(drdynvc, data_out); while (status == CHANNEL_RC_OK && dataSize > 0) { data_out = Stream_New(NULL, CHANNEL_CHUNK_LENGTH); if (!data_out) { WLog_ERR(TAG, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } Stream_SetPosition(data_out, 1); cbChId = drdynvc_write_variable_uint(data_out, ChannelId); pos = Stream_GetPosition(data_out); Stream_SetPosition(data_out, 0); Stream_Write_UINT8(data_out, 0x30 | cbChId); Stream_SetPosition(data_out, pos); chunkLength = dataSize; if (chunkLength > CHANNEL_CHUNK_LENGTH - pos) chunkLength = CHANNEL_CHUNK_LENGTH - pos; Stream_Write(data_out, data, chunkLength); data += chunkLength; dataSize -= chunkLength; status = drdynvc_send(drdynvc, data_out); } } if (status != CHANNEL_RC_OK) { WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", WTSErrorToString(status), status); return status; } return CHANNEL_RC_OK; }
static BOOL tsmf_gstreamer_set_format(ITSMFDecoder* decoder, TS_AM_MEDIA_TYPE* media_type) { TSMFGstreamerDecoder* mdecoder = (TSMFGstreamerDecoder*) decoder; if (!mdecoder) return FALSE; DEBUG_TSMF(""); switch (media_type->MajorType) { case TSMF_MAJOR_TYPE_VIDEO: mdecoder->media_type = TSMF_MAJOR_TYPE_VIDEO; break; case TSMF_MAJOR_TYPE_AUDIO: mdecoder->media_type = TSMF_MAJOR_TYPE_AUDIO; break; default: return FALSE; } switch (media_type->SubType) { case TSMF_SUB_TYPE_WVC1: mdecoder->gst_caps = gst_caps_new_simple("video/x-wmv", "bitrate", G_TYPE_UINT, media_type->BitRate, "width", G_TYPE_INT, media_type->Width, "height", G_TYPE_INT, media_type->Height, "wmvversion", G_TYPE_INT, 3, #if GST_VERSION_MAJOR > 0 "format", G_TYPE_STRING, "WVC1", #else "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('W', 'V', 'C', '1'), #endif "framerate", GST_TYPE_FRACTION, media_type->SamplesPerSecond.Numerator, media_type->SamplesPerSecond.Denominator, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1 , 1, NULL); break; case TSMF_SUB_TYPE_MP4S: mdecoder->gst_caps = gst_caps_new_simple("video/x-divx", "divxversion", G_TYPE_INT, 5, "bitrate", G_TYPE_UINT, media_type->BitRate, "width", G_TYPE_INT, media_type->Width, "height", G_TYPE_INT, media_type->Height, #if GST_VERSION_MAJOR > 0 "format", G_TYPE_STRING, "MP42", #else "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('M', 'P', '4', '2'), #endif "framerate", GST_TYPE_FRACTION, media_type->SamplesPerSecond.Numerator, media_type->SamplesPerSecond.Denominator, NULL); break; case TSMF_SUB_TYPE_MP42: mdecoder->gst_caps = gst_caps_new_simple("video/x-msmpeg", "msmpegversion", G_TYPE_INT, 42, "bitrate", G_TYPE_UINT, media_type->BitRate, "width", G_TYPE_INT, media_type->Width, "height", G_TYPE_INT, media_type->Height, #if GST_VERSION_MAJOR > 0 "format", G_TYPE_STRING, "MP42", #else "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('M', 'P', '4', '2'), #endif "framerate", GST_TYPE_FRACTION, media_type->SamplesPerSecond.Numerator, media_type->SamplesPerSecond.Denominator, NULL); break; case TSMF_SUB_TYPE_MP43: mdecoder->gst_caps = gst_caps_new_simple("video/x-msmpeg", "msmpegversion", G_TYPE_INT, 43, "bitrate", G_TYPE_UINT, media_type->BitRate, "width", G_TYPE_INT, media_type->Width, "height", G_TYPE_INT, media_type->Height, #if GST_VERSION_MAJOR > 0 "format", G_TYPE_STRING, "MP43", #else "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('M', 'P', '4', '3'), #endif "framerate", GST_TYPE_FRACTION, media_type->SamplesPerSecond.Numerator, media_type->SamplesPerSecond.Denominator, NULL); break; case TSMF_SUB_TYPE_M4S2: mdecoder->gst_caps = gst_caps_new_simple ("video/mpeg", "mpegversion", G_TYPE_INT, 4, "width", G_TYPE_INT, media_type->Width, "height", G_TYPE_INT, media_type->Height, #if GST_VERSION_MAJOR > 0 "format", G_TYPE_STRING, "M4S2", #else "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('M', '4', 'S', '2'), #endif "framerate", GST_TYPE_FRACTION, media_type->SamplesPerSecond.Numerator, media_type->SamplesPerSecond.Denominator, NULL); break; case TSMF_SUB_TYPE_WMA9: mdecoder->gst_caps = gst_caps_new_simple("audio/x-wma", "wmaversion", G_TYPE_INT, 3, "rate", G_TYPE_INT, media_type->SamplesPerSecond.Numerator, "channels", G_TYPE_INT, media_type->Channels, "bitrate", G_TYPE_INT, media_type->BitRate, "depth", G_TYPE_INT, media_type->BitsPerSample, "width", G_TYPE_INT, media_type->BitsPerSample, "block_align", G_TYPE_INT, media_type->BlockAlign, NULL); break; case TSMF_SUB_TYPE_WMA1: mdecoder->gst_caps = gst_caps_new_simple ("audio/x-wma", "wmaversion", G_TYPE_INT, 1, "rate", G_TYPE_INT, media_type->SamplesPerSecond.Numerator, "channels", G_TYPE_INT, media_type->Channels, "bitrate", G_TYPE_INT, media_type->BitRate, "depth", G_TYPE_INT, media_type->BitsPerSample, "width", G_TYPE_INT, media_type->BitsPerSample, "block_align", G_TYPE_INT, media_type->BlockAlign, NULL); break; case TSMF_SUB_TYPE_WMA2: mdecoder->gst_caps = gst_caps_new_simple("audio/x-wma", "wmaversion", G_TYPE_INT, 2, "rate", G_TYPE_INT, media_type->SamplesPerSecond.Numerator, "channels", G_TYPE_INT, media_type->Channels, "bitrate", G_TYPE_INT, media_type->BitRate, "depth", G_TYPE_INT, media_type->BitsPerSample, "width", G_TYPE_INT, media_type->BitsPerSample, "block_align", G_TYPE_INT, media_type->BlockAlign, NULL); break; case TSMF_SUB_TYPE_MP3: mdecoder->gst_caps = gst_caps_new_simple("audio/mpeg", "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 3, "rate", G_TYPE_INT, media_type->SamplesPerSecond.Numerator, "channels", G_TYPE_INT, media_type->Channels, NULL); break; case TSMF_SUB_TYPE_WMV1: mdecoder->gst_caps = gst_caps_new_simple("video/x-wmv", "bitrate", G_TYPE_UINT, media_type->BitRate, "width", G_TYPE_INT, media_type->Width, "height", G_TYPE_INT, media_type->Height, "wmvversion", G_TYPE_INT, 1, #if GST_VERSION_MAJOR > 0 "format", G_TYPE_STRING, "WMV1", #else "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('W', 'M', 'V', '1'), #endif "framerate", GST_TYPE_FRACTION, media_type->SamplesPerSecond.Numerator, media_type->SamplesPerSecond.Denominator, NULL); break; case TSMF_SUB_TYPE_WMV2: mdecoder->gst_caps = gst_caps_new_simple("video/x-wmv", "width", G_TYPE_INT, media_type->Width, "height", G_TYPE_INT, media_type->Height, "wmvversion", G_TYPE_INT, 2, #if GST_VERSION_MAJOR > 0 "format", G_TYPE_STRING, "WMV2", #else "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('W', 'M', 'V', '2'), #endif "framerate", GST_TYPE_FRACTION, media_type->SamplesPerSecond.Numerator, media_type->SamplesPerSecond.Denominator, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1 , 1, NULL); break; case TSMF_SUB_TYPE_WMV3: mdecoder->gst_caps = gst_caps_new_simple("video/x-wmv", "bitrate", G_TYPE_UINT, media_type->BitRate, "width", G_TYPE_INT, media_type->Width, "height", G_TYPE_INT, media_type->Height, "wmvversion", G_TYPE_INT, 3, #if GST_VERSION_MAJOR > 0 "format", G_TYPE_STRING, "WMV3", #else "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('W', 'M', 'V', '3'), #endif "framerate", GST_TYPE_FRACTION, media_type->SamplesPerSecond.Numerator, media_type->SamplesPerSecond.Denominator, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1 , 1, NULL); break; case TSMF_SUB_TYPE_AVC1: case TSMF_SUB_TYPE_H264: mdecoder->gst_caps = gst_caps_new_simple("video/x-h264", "width", G_TYPE_INT, media_type->Width, "height", G_TYPE_INT, media_type->Height, "framerate", GST_TYPE_FRACTION, media_type->SamplesPerSecond.Numerator, media_type->SamplesPerSecond.Denominator, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1 , 1, "stream-format", G_TYPE_STRING, "byte-stream", "alignment", G_TYPE_STRING, "nal", NULL); break; case TSMF_SUB_TYPE_AC3: mdecoder->gst_caps = gst_caps_new_simple("audio/x-ac3", "rate", G_TYPE_INT, media_type->SamplesPerSecond.Numerator, "channels", G_TYPE_INT, media_type->Channels, NULL); break; case TSMF_SUB_TYPE_AAC: /* For AAC the pFormat is a HEAACWAVEINFO struct, and the codec data is at the end of it. See http://msdn.microsoft.com/en-us/library/dd757806.aspx */ if (media_type->ExtraData) { media_type->ExtraData += 12; media_type->ExtraDataSize -= 12; } mdecoder->gst_caps = gst_caps_new_simple("audio/mpeg", "rate", G_TYPE_INT, media_type->SamplesPerSecond.Numerator, "channels", G_TYPE_INT, media_type->Channels, "mpegversion", G_TYPE_INT, 4, "framed", G_TYPE_BOOLEAN, TRUE, "stream-format", G_TYPE_STRING, "raw", NULL); break; case TSMF_SUB_TYPE_MP1A: mdecoder->gst_caps = gst_caps_new_simple("audio/mpeg", "mpegversion", G_TYPE_INT, 1, "channels", G_TYPE_INT, media_type->Channels, NULL); break; case TSMF_SUB_TYPE_MP1V: mdecoder->gst_caps = gst_caps_new_simple("video/mpeg", "mpegversion", G_TYPE_INT, 1, "width", G_TYPE_INT, media_type->Width, "height", G_TYPE_INT, media_type->Height, "systemstream", G_TYPE_BOOLEAN, FALSE, NULL); break; case TSMF_SUB_TYPE_YUY2: #if GST_VERSION_MAJOR > 0 mdecoder->gst_caps = gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING, "YUY2", "width", G_TYPE_INT, media_type->Width, "height", G_TYPE_INT, media_type->Height, NULL); #else mdecoder->gst_caps = gst_caps_new_simple("video/x-raw-yuv", "format", G_TYPE_STRING, "YUY2", "width", G_TYPE_INT, media_type->Width, "height", G_TYPE_INT, media_type->Height, "framerate", GST_TYPE_FRACTION, media_type->SamplesPerSecond.Numerator, media_type->SamplesPerSecond.Denominator, NULL); #endif break; case TSMF_SUB_TYPE_MP2V: mdecoder->gst_caps = gst_caps_new_simple("video/mpeg", "mpegversion", G_TYPE_INT, 2, "systemstream", G_TYPE_BOOLEAN, FALSE, NULL); break; case TSMF_SUB_TYPE_MP2A: mdecoder->gst_caps = gst_caps_new_simple("audio/mpeg", "mpegversion", G_TYPE_INT, 1, "rate", G_TYPE_INT, media_type->SamplesPerSecond.Numerator, "channels", G_TYPE_INT, media_type->Channels, NULL); break; case TSMF_SUB_TYPE_FLAC: mdecoder->gst_caps = gst_caps_new_simple("audio/x-flac", "", NULL); break; default: WLog_ERR(TAG, "unknown format:(%d).", media_type->SubType); return FALSE; } if (media_type->ExtraDataSize > 0) { GstBuffer *buffer; DEBUG_TSMF("Extra data available (%"PRIu32")", media_type->ExtraDataSize); buffer = tsmf_get_buffer_from_data(media_type->ExtraData, media_type->ExtraDataSize); if (!buffer) { WLog_ERR(TAG, "could not allocate GstBuffer!"); return FALSE; } gst_caps_set_simple(mdecoder->gst_caps, "codec_data", GST_TYPE_BUFFER, buffer, NULL); } DEBUG_TSMF("%p format '%s'", (void*) mdecoder, gst_caps_to_string(mdecoder->gst_caps)); tsmf_platform_set_format(mdecoder); /* Create the pipeline... */ if (!tsmf_gstreamer_pipeline_build(mdecoder)) return FALSE; return TRUE; }
static DWORD WINAPI smartcard_thread_func(LPVOID arg) { IRP* irp; DWORD nCount; DWORD status; HANDLE hEvents[2]; wMessage message; UINT error = CHANNEL_RC_OK; SMARTCARD_DEVICE* smartcard = CAST_FROM_DEVICE(arg); if (!smartcard) return ERROR_INVALID_PARAMETER; nCount = 0; hEvents[nCount++] = MessageQueue_Event(smartcard->IrpQueue); hEvents[nCount++] = Queue_Event(smartcard->CompletedIrpQueue); while (1) { status = WaitForMultipleObjects(nCount, hEvents, FALSE, INFINITE); if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForMultipleObjects failed with error %"PRIu32"!", error); break; } status = WaitForSingleObject(MessageQueue_Event(smartcard->IrpQueue), 0); if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %"PRIu32"!", error); break; } if (status == WAIT_OBJECT_0) { if (!MessageQueue_Peek(smartcard->IrpQueue, &message, TRUE)) { WLog_ERR(TAG, "MessageQueue_Peek failed!"); error = ERROR_INTERNAL_ERROR; break; } if (message.id == WMQ_QUIT) { while (1) { status = WaitForSingleObject(Queue_Event(smartcard->CompletedIrpQueue), 0); if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %"PRIu32"!", error); goto out; } if (status == WAIT_TIMEOUT) break; irp = (IRP*) Queue_Dequeue(smartcard->CompletedIrpQueue); if (irp) { if (irp->thread) { status = WaitForSingleObject(irp->thread, INFINITE); if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %"PRIu32"!", error); goto out; } CloseHandle(irp->thread); irp->thread = NULL; } if ((error = smartcard_complete_irp(smartcard, irp))) { WLog_ERR(TAG, "smartcard_complete_irp failed with error %"PRIu32"!", error); goto out; } } } break; } irp = (IRP*) message.wParam; if (irp) { if ((error = smartcard_process_irp(smartcard, irp))) { WLog_ERR(TAG, "smartcard_process_irp failed with error %"PRIu32"!", error); goto out; } } } status = WaitForSingleObject(Queue_Event(smartcard->CompletedIrpQueue), 0); if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %"PRIu32"!", error); break; } if (status == WAIT_OBJECT_0) { irp = (IRP*) Queue_Dequeue(smartcard->CompletedIrpQueue); if (irp) { if (irp->thread) { status = WaitForSingleObject(irp->thread, INFINITE); if (status == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %"PRIu32"!", error); break; } CloseHandle(irp->thread); irp->thread = NULL; } if ((error = smartcard_complete_irp(smartcard, irp))) { if (error == CHANNEL_RC_NOT_CONNECTED) { error = CHANNEL_RC_OK; goto out; } WLog_ERR(TAG, "smartcard_complete_irp failed with error %"PRIu32"!", error); goto out; } } } } out: if (error && smartcard->rdpcontext) setChannelError(smartcard->rdpcontext, error, "smartcard_thread_func reported an error"); ExitThread(error); return error; }
BOOL tsmf_gstreamer_pipeline_build(TSMFGstreamerDecoder* mdecoder) { #if GST_VERSION_MAJOR > 0 const char* video = "appsrc name=videosource ! queue2 name=videoqueue ! decodebin name=videodecoder !"; const char* audio = "appsrc name=audiosource ! queue2 name=audioqueue ! decodebin name=audiodecoder ! audioconvert ! audiorate ! audioresample ! volume name=audiovolume !"; #else const char* video = "appsrc name=videosource ! queue2 name=videoqueue ! decodebin2 name=videodecoder !"; const char* audio = "appsrc name=audiosource ! queue2 name=audioqueue ! decodebin2 name=audiodecoder ! audioconvert ! audiorate ! audioresample ! volume name=audiovolume !"; #endif char pipeline[1024]; if (!mdecoder) return FALSE; /* TODO: Construction of the pipeline from a string allows easy overwrite with arguments. * The only fixed elements necessary are appsrc and the volume element for audio streams. * The rest could easily be provided in gstreamer pipeline notation from command line. */ if (mdecoder->media_type == TSMF_MAJOR_TYPE_VIDEO) sprintf_s(pipeline, sizeof(pipeline), "%s %s name=videosink", video, tsmf_platform_get_video_sink()); else sprintf_s(pipeline, sizeof(pipeline), "%s %s name=audiosink", audio, tsmf_platform_get_audio_sink()); DEBUG_TSMF("pipeline=%s", pipeline); mdecoder->pipe = gst_parse_launch(pipeline, NULL); if (!mdecoder->pipe) { WLog_ERR(TAG, "Failed to create new pipe"); return FALSE; } if (mdecoder->media_type == TSMF_MAJOR_TYPE_VIDEO) mdecoder->src = gst_bin_get_by_name(GST_BIN(mdecoder->pipe), "videosource"); else mdecoder->src = gst_bin_get_by_name(GST_BIN(mdecoder->pipe), "audiosource"); if (!mdecoder->src) { WLog_ERR(TAG, "Failed to get appsrc"); return FALSE; } if (mdecoder->media_type == TSMF_MAJOR_TYPE_VIDEO) mdecoder->queue = gst_bin_get_by_name(GST_BIN(mdecoder->pipe), "videoqueue"); else mdecoder->queue = gst_bin_get_by_name(GST_BIN(mdecoder->pipe), "audioqueue"); if (!mdecoder->queue) { WLog_ERR(TAG, "Failed to get queue"); return FALSE; } if (mdecoder->media_type == TSMF_MAJOR_TYPE_VIDEO) mdecoder->outsink = gst_bin_get_by_name(GST_BIN(mdecoder->pipe), "videosink"); else mdecoder->outsink = gst_bin_get_by_name(GST_BIN(mdecoder->pipe), "audiosink"); if (!mdecoder->outsink) { WLog_ERR(TAG, "Failed to get sink"); return FALSE; } g_signal_connect(mdecoder->outsink, "child-added", G_CALLBACK(cb_child_added), mdecoder); if (mdecoder->media_type == TSMF_MAJOR_TYPE_AUDIO) { mdecoder->volume = gst_bin_get_by_name(GST_BIN(mdecoder->pipe), "audiovolume"); if (!mdecoder->volume) { WLog_ERR(TAG, "Failed to get volume"); return FALSE; } tsmf_gstreamer_change_volume((ITSMFDecoder*)mdecoder, mdecoder->gstVolume*((double) 10000), mdecoder->gstMuted); } tsmf_platform_register_handler(mdecoder); /* AppSrc settings */ GstAppSrcCallbacks callbacks = { tsmf_gstreamer_need_data, tsmf_gstreamer_enough_data, tsmf_gstreamer_seek_data }; g_object_set(mdecoder->src, "format", GST_FORMAT_TIME, NULL); g_object_set(mdecoder->src, "is-live", FALSE, NULL); g_object_set(mdecoder->src, "block", FALSE, NULL); g_object_set(mdecoder->src, "blocksize", 1024, NULL); gst_app_src_set_caps((GstAppSrc *) mdecoder->src, mdecoder->gst_caps); gst_app_src_set_callbacks((GstAppSrc *)mdecoder->src, &callbacks, mdecoder, NULL); gst_app_src_set_stream_type((GstAppSrc *) mdecoder->src, GST_APP_STREAM_TYPE_SEEKABLE); gst_app_src_set_latency((GstAppSrc *) mdecoder->src, 0, -1); gst_app_src_set_max_bytes((GstAppSrc *) mdecoder->src, (guint64) 0);//unlimited g_object_set(G_OBJECT(mdecoder->queue), "use-buffering", FALSE, NULL); g_object_set(G_OBJECT(mdecoder->queue), "use-rate-estimate", FALSE, NULL); g_object_set(G_OBJECT(mdecoder->queue), "max-size-buffers", 0, NULL); g_object_set(G_OBJECT(mdecoder->queue), "max-size-bytes", 0, NULL); g_object_set(G_OBJECT(mdecoder->queue), "max-size-time", (guint64) 0, NULL); /* Only set these properties if not an autosink, otherwise we will set properties when real sinks are added */ if (!g_strcmp0(G_OBJECT_TYPE_NAME(mdecoder->outsink), "GstAutoVideoSink") && !g_strcmp0(G_OBJECT_TYPE_NAME(mdecoder->outsink), "GstAutoAudioSink")) { if (mdecoder->media_type == TSMF_MAJOR_TYPE_VIDEO) { gst_base_sink_set_max_lateness((GstBaseSink *) mdecoder->outsink, 10000000); /* nanoseconds */ } else { gst_base_sink_set_max_lateness((GstBaseSink *) mdecoder->outsink, 10000000); /* nanoseconds */ g_object_set(G_OBJECT(mdecoder->outsink), "buffer-time", (gint64) 20000, NULL); /* microseconds */ g_object_set(G_OBJECT(mdecoder->outsink), "drift-tolerance", (gint64) 20000, NULL); /* microseconds */ g_object_set(G_OBJECT(mdecoder->outsink), "latency-time", (gint64) 10000, NULL); /* microseconds */ g_object_set(G_OBJECT(mdecoder->outsink), "slave-method", 1, NULL); } g_object_set(G_OBJECT(mdecoder->outsink), "sync", TRUE, NULL); /* synchronize on the clock */ g_object_set(G_OBJECT(mdecoder->outsink), "async", TRUE, NULL); /* no async state changes */ } tsmf_window_create(mdecoder); tsmf_gstreamer_pipeline_set_state(mdecoder, GST_STATE_READY); tsmf_gstreamer_pipeline_set_state(mdecoder, GST_STATE_PLAYING); mdecoder->pipeline_start_time_valid = 0; mdecoder->shutdown = 0; mdecoder->paused = FALSE; GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(mdecoder->pipe), GST_DEBUG_GRAPH_SHOW_ALL, get_type(mdecoder)); return TRUE; }
static DWORD WINAPI smartcard_context_thread(LPVOID arg) { SMARTCARD_CONTEXT* pContext = (SMARTCARD_CONTEXT*)arg; DWORD nCount; LONG status = 0; DWORD waitStatus; HANDLE hEvents[2]; wMessage message; SMARTCARD_DEVICE* smartcard; SMARTCARD_OPERATION* operation; UINT error = CHANNEL_RC_OK; smartcard = pContext->smartcard; nCount = 0; hEvents[nCount++] = MessageQueue_Event(pContext->IrpQueue); while (1) { waitStatus = WaitForMultipleObjects(nCount, hEvents, FALSE, INFINITE); if (waitStatus == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForMultipleObjects failed with error %"PRIu32"!", error); break; } waitStatus = WaitForSingleObject(MessageQueue_Event(pContext->IrpQueue), 0); if (waitStatus == WAIT_FAILED) { error = GetLastError(); WLog_ERR(TAG, "WaitForSingleObject failed with error %"PRIu32"!", error); break; } if (waitStatus == WAIT_OBJECT_0) { if (!MessageQueue_Peek(pContext->IrpQueue, &message, TRUE)) { WLog_ERR(TAG, "MessageQueue_Peek failed!"); status = ERROR_INTERNAL_ERROR; break; } if (message.id == WMQ_QUIT) break; operation = (SMARTCARD_OPERATION*) message.wParam; if (operation) { if ((status = smartcard_irp_device_control_call(smartcard, operation))) { WLog_ERR(TAG, "smartcard_irp_device_control_call failed with error %"PRIu32"", status); break; } if (!Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) operation->irp)) { WLog_ERR(TAG, "Queue_Enqueue failed!"); status = ERROR_INTERNAL_ERROR; break; } free(operation); } } } if (status && smartcard->rdpcontext) setChannelError(smartcard->rdpcontext, error, "smartcard_context_thread reported an error"); ExitThread(status); return error; }
static BOOL tsmf_gstreamer_control(ITSMFDecoder* decoder, ITSMFControlMsg control_msg, UINT32 *arg) { TSMFGstreamerDecoder* mdecoder = (TSMFGstreamerDecoder *) decoder; if (!mdecoder) { WLog_ERR(TAG, "Control called with no decoder!"); return TRUE; } if (control_msg == Control_Pause) { DEBUG_TSMF("Control_Pause %s", get_type(mdecoder)); if (mdecoder->paused) { WLog_ERR(TAG, "%s: Ignoring Control_Pause, already received!", get_type(mdecoder)); return TRUE; } tsmf_gstreamer_pipeline_set_state(mdecoder, GST_STATE_PAUSED); mdecoder->shutdown = 0; mdecoder->paused = TRUE; } else if (control_msg == Control_Resume) { DEBUG_TSMF("Control_Resume %s", get_type(mdecoder)); if (!mdecoder->paused && !mdecoder->shutdown) { WLog_ERR(TAG, "%s: Ignoring Control_Resume, already received!", get_type(mdecoder)); return TRUE; } mdecoder->shutdown = 0; mdecoder->paused = FALSE; } else if (control_msg == Control_Stop) { DEBUG_TSMF("Control_Stop %s", get_type(mdecoder)); if (mdecoder->shutdown) { WLog_ERR(TAG, "%s: Ignoring Control_Stop, already received!", get_type(mdecoder)); return TRUE; } /* Reset stamps, flush buffers, etc */ if (mdecoder->pipe) { tsmf_gstreamer_pipeline_set_state(mdecoder, GST_STATE_NULL); tsmf_window_destroy(mdecoder); tsmf_gstreamer_clean_up(mdecoder); } mdecoder->seek_offset = 0; mdecoder->pipeline_start_time_valid = 0; mdecoder->shutdown = 1; } else if (control_msg == Control_Restart) { DEBUG_TSMF("Control_Restart %s", get_type(mdecoder)); mdecoder->shutdown = 0; mdecoder->paused = FALSE; if (mdecoder->pipeline_start_time_valid) tsmf_gstreamer_pipeline_set_state(mdecoder, GST_STATE_PLAYING); } else WLog_ERR(TAG, "Unknown control message %08x", control_msg); return TRUE; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) { SMARTCARD_DEVICE* smartcard = NULL; size_t length; UINT error = CHANNEL_RC_NO_MEMORY; if (!sSmartcard) { wObject* obj; smartcard = (SMARTCARD_DEVICE*) calloc(1, sizeof(SMARTCARD_DEVICE)); if (!smartcard) { WLog_ERR(TAG, "calloc failed!"); return CHANNEL_RC_NO_MEMORY; } smartcard->device.type = RDPDR_DTYP_SMARTCARD; smartcard->device.name = "SCARD"; smartcard->device.IRPRequest = smartcard_irp_request; smartcard->device.Init = smartcard_init; smartcard->device.Free = smartcard_free; smartcard->names = LinkedList_New(); smartcard->rdpcontext = pEntryPoints->rdpcontext; length = strlen(smartcard->device.name); smartcard->device.data = Stream_New(NULL, length + 1); if (!smartcard->device.data || !smartcard->names) { WLog_ERR(TAG, "Stream_New failed!"); goto fail; } Stream_Write(smartcard->device.data, "SCARD", 6); smartcard->IrpQueue = MessageQueue_New(NULL); if (!smartcard->IrpQueue) { WLog_ERR(TAG, "MessageQueue_New failed!"); goto fail; } smartcard->CompletedIrpQueue = Queue_New(TRUE, -1, -1); if (!smartcard->CompletedIrpQueue) { WLog_ERR(TAG, "Queue_New failed!"); goto fail; } smartcard->rgSCardContextList = ListDictionary_New(TRUE); if (!smartcard->rgSCardContextList) { WLog_ERR(TAG, "ListDictionary_New failed!"); goto fail; } obj = ListDictionary_ValueObject(smartcard->rgSCardContextList); obj->fnObjectFree = smartcard_context_free; smartcard->rgOutstandingMessages = ListDictionary_New(TRUE); if (!smartcard->rgOutstandingMessages) { WLog_ERR(TAG, "ListDictionary_New failed!"); goto fail; } if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, &smartcard->device))) { WLog_ERR(TAG, "RegisterDevice failed!"); goto fail; } smartcard->thread = CreateThread(NULL, 0, smartcard_thread_func, smartcard, CREATE_SUSPENDED, NULL); if (!smartcard->thread) { WLog_ERR(TAG, "ListDictionary_New failed!"); error = ERROR_INTERNAL_ERROR; goto fail; } ResumeThread(smartcard->thread); } else smartcard = sSmartcard; if (pEntryPoints->device->Name) LinkedList_AddLast(smartcard->names, pEntryPoints->device->Name); sSmartcard = smartcard; return CHANNEL_RC_OK; fail: smartcard_free_(smartcard); return error; }
static BOOL gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) { const rdpBrush* brush = &patblt->brush; UINT32 foreColor; UINT32 backColor; UINT32 originalColor; HGDI_BRUSH originalBrush, hbrush = NULL; rdpGdi* gdi = context->gdi; BOOL ret = FALSE; const DWORD rop = gdi_rop3_code(patblt->bRop); UINT32 nXSrc = 0; UINT32 nYSrc = 0; BYTE data[8 * 8 * 4]; HGDI_BITMAP hBmp = NULL; if (!gdi_decode_color(gdi, patblt->foreColor, &foreColor, NULL)) return FALSE; if (!gdi_decode_color(gdi, patblt->backColor, &backColor, NULL)) return FALSE; originalColor = gdi_SetTextColor(gdi->drawing->hdc, foreColor); originalBrush = gdi->drawing->hdc->brush; switch (brush->style) { case GDI_BS_SOLID: hbrush = gdi_CreateSolidBrush(foreColor); break; case GDI_BS_HATCHED: { const BYTE* hatched; hatched = GDI_BS_HATCHED_PATTERNS + (8 * brush->hatch); if (!freerdp_image_copy_from_monochrome(data, gdi->drawing->hdc->format, 0, 0, 0, 8, 8, hatched, backColor, foreColor, &gdi->palette)) goto out_error; hBmp = gdi_CreateBitmapEx(8, 8, gdi->drawing->hdc->format, 0, data, NULL); if (!hBmp) goto out_error; hbrush = gdi_CreateHatchBrush(hBmp); } break; case GDI_BS_PATTERN: { UINT32 brushFormat; if (brush->bpp > 1) { UINT32 bpp = brush->bpp; if ((bpp == 16) && (context->settings->ColorDepth == 15)) bpp = 15; brushFormat = gdi_get_pixel_format(bpp); if (!freerdp_image_copy(data, gdi->drawing->hdc->format, 0, 0, 0, 8, 8, brush->data, brushFormat, 0, 0, 0, &gdi->palette, FREERDP_FLIP_NONE)) goto out_error; } else { if (!freerdp_image_copy_from_monochrome(data, gdi->drawing->hdc->format, 0, 0, 0, 8, 8, brush->data, backColor, foreColor, &gdi->palette)) goto out_error; } hBmp = gdi_CreateBitmapEx(8, 8, gdi->drawing->hdc->format, 0, data, NULL); if (!hBmp) goto out_error; hbrush = gdi_CreatePatternBrush(hBmp); } break; default: WLog_ERR(TAG, "unimplemented brush style:%"PRIu32"", brush->style); break; } if (hbrush) { hbrush->nXOrg = brush->x; hbrush->nYOrg = brush->y; gdi->drawing->hdc->brush = hbrush; ret = gdi_BitBlt(gdi->drawing->hdc, patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight, gdi->primary->hdc, nXSrc, nYSrc, rop, &gdi->palette); } out_error: gdi_DeleteObject((HGDIOBJECT) hBmp); gdi_DeleteObject((HGDIOBJECT) hbrush); gdi->drawing->hdc->brush = originalBrush; gdi_SetTextColor(gdi->drawing->hdc, originalColor); return ret; }
DWORD GetModuleFileNameW(HMODULE hModule, LPWSTR lpFilename, DWORD nSize) { WLog_ERR(TAG, "%s is not implemented", __FUNCTION__); SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return 0; }
LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs) { char* p; int length; char* pBeg; char* pEnd; char* buffer; char* pOutput; int numArgs = 0; LPSTR* pArgs; int maxNumArgs; int maxBufferSize; int cmdLineLength; BOOL* lpEscapedChars; LPSTR lpEscapedCmdLine; if (!lpCmdLine) return NULL; if (!pNumArgs) return NULL; pArgs = NULL; lpEscapedCmdLine = NULL; cmdLineLength = (int) strlen(lpCmdLine); lpEscapedChars = (BOOL*) calloc(cmdLineLength + 1, sizeof(BOOL)); if (!lpEscapedChars) return NULL; if (strstr(lpCmdLine, "\\\"")) { int i, n; char* pLastEnd = NULL; lpEscapedCmdLine = (char*) calloc(cmdLineLength + 1, sizeof(char)); if (!lpEscapedCmdLine) { free(lpEscapedChars); return NULL; } p = (char*) lpCmdLine; pLastEnd = (char*) lpCmdLine; pOutput = (char*) lpEscapedCmdLine; while (p < &lpCmdLine[cmdLineLength]) { pBeg = strstr(p, "\\\""); if (!pBeg) { length = (int) strlen(p); CopyMemory(pOutput, p, length); pOutput += length; break; } pEnd = pBeg + 2; while (pBeg >= lpCmdLine) { if (*pBeg != '\\') { pBeg++; break; } pBeg--; } n = (int)((pEnd - pBeg) - 1); length = (int)(pBeg - pLastEnd); CopyMemory(pOutput, p, length); pOutput += length; p += length; for (i = 0; i < (n / 2); i++) *pOutput++ = '\\'; p += n + 1; if ((n % 2) != 0) lpEscapedChars[pOutput - lpEscapedCmdLine] = TRUE; *pOutput++ = '"'; pLastEnd = p; } *pOutput++ = '\0'; lpCmdLine = (LPCSTR) lpEscapedCmdLine; cmdLineLength = (int) strlen(lpCmdLine); } maxNumArgs = 2; p = (char*) lpCmdLine; while (p < lpCmdLine + cmdLineLength) { p += strcspn(p, " \t"); p += strspn(p, " \t"); maxNumArgs++; } maxBufferSize = (maxNumArgs * (sizeof(char*))) + (cmdLineLength + 1); buffer = (char*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, maxBufferSize); if (!buffer) { free(lpEscapedChars); return NULL; } pArgs = (LPSTR*) buffer; pOutput = (char*) &buffer[maxNumArgs * (sizeof(char*))]; p = (char*) lpCmdLine; while (p < lpCmdLine + cmdLineLength) { pBeg = p; while (1) { p += strcspn(p, " \t\"\0"); if ((*p != '"') || !lpEscapedChars[p - lpCmdLine]) break; p++; } if (*p != '"') { /* no whitespace escaped with double quotes */ length = (int)(p - pBeg); CopyMemory(pOutput, pBeg, length); pOutput[length] = '\0'; pArgs[numArgs++] = pOutput; pOutput += (length + 1); } else { p++; while (1) { p += strcspn(p, "\"\0"); if ((*p != '"') || !lpEscapedChars[p - lpCmdLine]) break; p++; } if (*p != '"') WLog_ERR(TAG, "parsing error: uneven number of unescaped double quotes!"); if (*p && *(++p)) p += strcspn(p, " \t\0"); pArgs[numArgs++] = pOutput; while (pBeg < p) { if (*pBeg != '"') *pOutput++ = *pBeg; pBeg++; } *pOutput++ = '\0'; } p += strspn(p, " \t"); } free(lpEscapedCmdLine); free(lpEscapedChars); *pNumArgs = numArgs; return pArgs; }
DWORD GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize) { #if defined(__linux__) int status; int length; char path[64]; if (!hModule) { char buffer[4096]; sprintf_s(path, ARRAYSIZE(path), "/proc/%d/exe", getpid()); status = readlink(path, buffer, sizeof(buffer)); if (status < 0) { SetLastError(ERROR_INTERNAL_ERROR); return 0; } buffer[status] = '\0'; length = strlen(buffer); if (length < nSize) { CopyMemory(lpFilename, buffer, length); lpFilename[length] = '\0'; return length; } CopyMemory(lpFilename, buffer, nSize - 1); lpFilename[nSize - 1] = '\0'; SetLastError(ERROR_INSUFFICIENT_BUFFER); return nSize; } #elif defined(__MACOSX__) int status; int length; if (!hModule) { char path[4096]; char buffer[4096]; uint32_t size = sizeof(path); status = _NSGetExecutablePath(path, &size); if (status != 0) { /* path too small */ SetLastError(ERROR_INTERNAL_ERROR); return 0; } /* * _NSGetExecutablePath may not return the canonical path, * so use realpath to find the absolute, canonical path. */ realpath(path, buffer); length = strlen(buffer); if (length < nSize) { CopyMemory(lpFilename, buffer, length); lpFilename[length] = '\0'; return length; } CopyMemory(lpFilename, buffer, nSize - 1); lpFilename[nSize - 1] = '\0'; SetLastError(ERROR_INSUFFICIENT_BUFFER); return nSize; } #endif WLog_ERR(TAG, "%s is not implemented", __FUNCTION__); SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return 0; }
int xf_SurfaceCommand_RemoteFX(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int j; UINT16 i; RFX_RECT* rect; RFX_TILE* tile; int nXDst, nYDst; int nWidth, nHeight; int nbUpdateRects; RFX_MESSAGE* message; xfGfxSurface* surface; REGION16 updateRegion; RECTANGLE_16 updateRect; RECTANGLE_16* updateRects; REGION16 clippingRects; RECTANGLE_16 clippingRect; if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_REMOTEFX)) return -1; surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return -1; if (!(message = rfx_process_message(xfc->codecs->rfx, cmd->data, cmd->length))) { WLog_ERR(TAG, "Failed to process RemoteFX message"); return -1; } region16_init(&clippingRects); for (i = 0; i < message->numRects; i++) { rect = &(message->rects[i]); clippingRect.left = cmd->left + rect->x; clippingRect.top = cmd->top + rect->y; clippingRect.right = clippingRect.left + rect->width; clippingRect.bottom = clippingRect.top + rect->height; region16_union_rect(&clippingRects, &clippingRects, &clippingRect); } for (i = 0; i < message->numTiles; i++) { tile = message->tiles[i]; updateRect.left = cmd->left + tile->x; updateRect.top = cmd->top + tile->y; updateRect.right = updateRect.left + 64; updateRect.bottom = updateRect.top + 64; region16_init(&updateRegion); region16_intersect_rect(&updateRegion, &clippingRects, &updateRect); updateRects = (RECTANGLE_16*) region16_rects(&updateRegion, &nbUpdateRects); for (j = 0; j < nbUpdateRects; j++) { nXDst = updateRects[j].left; nYDst = updateRects[j].top; nWidth = updateRects[j].right - updateRects[j].left; nHeight = updateRects[j].bottom - updateRects[j].top; freerdp_image_copy(surface->data, surface->format, surface->scanline, nXDst, nYDst, nWidth, nHeight, tile->data, PIXEL_FORMAT_XRGB32, 64 * 4, 0, 0, NULL); region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &updateRects[j]); } region16_uninit(&updateRegion); } rfx_message_free(xfc->codecs->rfx, message); region16_uninit(&clippingRects); if (!xfc->inGfxFrame) xf_UpdateSurfaces(xfc); return 1; }
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; }
void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) { void* key; UINT32 status; BOOL asyncIrp = FALSE; SMARTCARD_CONTEXT* pContext = NULL; SMARTCARD_OPERATION* operation = NULL; key = (void*) (size_t) irp->CompletionId; ListDictionary_Add(smartcard->rgOutstandingMessages, key, irp); if (irp->MajorFunction == IRP_MJ_DEVICE_CONTROL) { operation = (SMARTCARD_OPERATION*) calloc(1, sizeof(SMARTCARD_OPERATION)); if (!operation) return; operation->irp = irp; status = smartcard_irp_device_control_decode(smartcard, operation); if (status != SCARD_S_SUCCESS) { irp->IoStatus = STATUS_UNSUCCESSFUL; Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp); return; } asyncIrp = TRUE; /** * The following matches mstsc's behavior of processing * only certain requests asynchronously while processing * those expected to return fast synchronously. */ switch (operation->ioControlCode) { case SCARD_IOCTL_ESTABLISHCONTEXT: case SCARD_IOCTL_RELEASECONTEXT: case SCARD_IOCTL_ISVALIDCONTEXT: case SCARD_IOCTL_LISTREADERGROUPSA: case SCARD_IOCTL_LISTREADERGROUPSW: case SCARD_IOCTL_LISTREADERSA: case SCARD_IOCTL_LISTREADERSW: case SCARD_IOCTL_INTRODUCEREADERGROUPA: case SCARD_IOCTL_INTRODUCEREADERGROUPW: case SCARD_IOCTL_FORGETREADERGROUPA: case SCARD_IOCTL_FORGETREADERGROUPW: case SCARD_IOCTL_INTRODUCEREADERA: case SCARD_IOCTL_INTRODUCEREADERW: case SCARD_IOCTL_FORGETREADERA: case SCARD_IOCTL_FORGETREADERW: case SCARD_IOCTL_ADDREADERTOGROUPA: case SCARD_IOCTL_ADDREADERTOGROUPW: case SCARD_IOCTL_REMOVEREADERFROMGROUPA: case SCARD_IOCTL_REMOVEREADERFROMGROUPW: case SCARD_IOCTL_LOCATECARDSA: case SCARD_IOCTL_LOCATECARDSW: case SCARD_IOCTL_LOCATECARDSBYATRA: case SCARD_IOCTL_LOCATECARDSBYATRW: case SCARD_IOCTL_CANCEL: case SCARD_IOCTL_READCACHEA: case SCARD_IOCTL_READCACHEW: case SCARD_IOCTL_WRITECACHEA: case SCARD_IOCTL_WRITECACHEW: case SCARD_IOCTL_GETREADERICON: case SCARD_IOCTL_GETDEVICETYPEID: asyncIrp = FALSE; break; case SCARD_IOCTL_GETSTATUSCHANGEA: case SCARD_IOCTL_GETSTATUSCHANGEW: asyncIrp = TRUE; break; case SCARD_IOCTL_CONNECTA: case SCARD_IOCTL_CONNECTW: case SCARD_IOCTL_RECONNECT: case SCARD_IOCTL_DISCONNECT: case SCARD_IOCTL_BEGINTRANSACTION: case SCARD_IOCTL_ENDTRANSACTION: case SCARD_IOCTL_STATE: case SCARD_IOCTL_STATUSA: case SCARD_IOCTL_STATUSW: case SCARD_IOCTL_TRANSMIT: case SCARD_IOCTL_CONTROL: case SCARD_IOCTL_GETATTRIB: case SCARD_IOCTL_SETATTRIB: case SCARD_IOCTL_GETTRANSMITCOUNT: asyncIrp = TRUE; break; case SCARD_IOCTL_ACCESSSTARTEDEVENT: case SCARD_IOCTL_RELEASESTARTEDEVENT: asyncIrp = FALSE; break; } pContext = ListDictionary_GetItemValue(smartcard->rgSCardContextList, (void*) operation->hContext); if (!pContext) asyncIrp = FALSE; if (!asyncIrp) { status = smartcard_irp_device_control_call(smartcard, operation); Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp); free(operation); } else { if (pContext) { MessageQueue_Post(pContext->IrpQueue, NULL, 0, (void*) operation, NULL); } } } else { WLog_ERR(TAG, "Unexpected SmartCard IRP: MajorFunction 0x%08X MinorFunction: 0x%08X", irp->MajorFunction, irp->MinorFunction); irp->IoStatus = STATUS_NOT_SUPPORTED; Queue_Enqueue(smartcard->CompletedIrpQueue, (void*) irp); } }
DWORD WINAPI wf_client_thread(LPVOID lpParam) { MSG msg; int width; int height; BOOL msg_ret; int quit_msg; DWORD nCount; HANDLE handles[64]; wfContext* wfc; freerdp* instance; rdpContext* context; rdpChannels* channels; rdpSettings* settings; BOOL async_input; BOOL async_transport; HANDLE input_thread; instance = (freerdp*) lpParam; context = instance->context; wfc = (wfContext*) instance->context; if (!freerdp_connect(instance)) return 0; channels = instance->context->channels; settings = instance->context->settings; async_input = settings->AsyncInput; async_transport = settings->AsyncTransport; if (async_input) { input_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) wf_input_thread, instance, 0, NULL); } while (1) { nCount = 0; if (freerdp_focus_required(instance)) { wf_event_focus_in(wfc); wf_event_focus_in(wfc); } if (!async_transport) { DWORD tmp = freerdp_get_event_handles(context, &handles[nCount], 64 - nCount); if (tmp == 0) { WLog_ERR(TAG, "freerdp_get_event_handles failed"); break; } nCount += tmp; } if (MsgWaitForMultipleObjects(nCount, handles, FALSE, 1000, QS_ALLINPUT) == WAIT_FAILED) { WLog_ERR(TAG, "wfreerdp_run: WaitForMultipleObjects failed: 0x%04X", GetLastError()); break; } if (!async_transport) { if (!freerdp_check_event_handles(context)) { if (wf_auto_reconnect(instance)) continue; WLog_ERR(TAG, "Failed to check FreeRDP file descriptor"); break; } } if (freerdp_shall_disconnect(instance)) break; quit_msg = FALSE; while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { msg_ret = GetMessage(&msg, NULL, 0, 0); if (instance->settings->EmbeddedWindow) { if ((msg.message == WM_SETFOCUS) && (msg.lParam == 1)) { PostMessage(wfc->hwnd, WM_SETFOCUS, 0, 0); } else if ((msg.message == WM_KILLFOCUS) && (msg.lParam == 1)) { PostMessage(wfc->hwnd, WM_KILLFOCUS, 0, 0); } } if (msg.message == WM_SIZE) { width = LOWORD(msg.lParam); height = HIWORD(msg.lParam); SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, width, height, SWP_FRAMECHANGED); } if ((msg_ret == 0) || (msg_ret == -1)) { quit_msg = TRUE; break; } TranslateMessage(&msg); DispatchMessage(&msg); } if (quit_msg) break; } /* cleanup */ freerdp_channels_disconnect(channels, instance); if (async_input) { wMessageQueue* input_queue; input_queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE); MessageQueue_PostQuit(input_queue, 0); WaitForSingleObject(input_thread, INFINITE); CloseHandle(input_thread); } freerdp_disconnect(instance); WLog_DBG(TAG, "Main thread exited."); ExitThread(0); return 0; }
void tls_print_certificate_error(char* hostname, UINT16 port, char* fingerprint, char *hosts_file) { WLog_ERR(TAG, "The host key for %s:%hu has changed", hostname, port); WLog_ERR(TAG, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); WLog_ERR(TAG, "@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); WLog_ERR(TAG, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); WLog_ERR(TAG, "IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!"); WLog_ERR(TAG, "Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); WLog_ERR(TAG, "It is also possible that a host key has just been changed."); WLog_ERR(TAG, "The fingerprint for the host key sent by the remote host is%s", fingerprint); WLog_ERR(TAG, "Please contact your system administrator."); WLog_ERR(TAG, "Add correct host key in %s to get rid of this message.", hosts_file); WLog_ERR(TAG, "Host key for %s has changed and you have requested strict checking.", hostname); WLog_ERR(TAG, "Host key verification failed."); }
BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) { UINT rc; drdynvcPlugin* drdynvc; DrdynvcClientContext* context; CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx; UINT error; drdynvc = (drdynvcPlugin*) calloc(1, sizeof(drdynvcPlugin)); if (!drdynvc) { WLog_ERR(TAG, "calloc failed!"); return FALSE; } drdynvc->channelDef.options = CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP | CHANNEL_OPTION_COMPRESS_RDP; strcpy(drdynvc->channelDef.name, "drdynvc"); drdynvc->state = DRDYNVC_STATE_INITIAL; pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints; if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) && (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER)) { context = (DrdynvcClientContext*) calloc(1, sizeof(DrdynvcClientContext)); if (!context) { WLog_ERR(TAG, "calloc failed!"); free(drdynvc); return FALSE; } context->handle = (void*) drdynvc; context->custom = NULL; drdynvc->context = context; context->GetVersion = drdynvc_get_version; drdynvc->rdpcontext = pEntryPointsEx->context; *(pEntryPointsEx->ppInterface) = (void*) context; } drdynvc->log = WLog_Get("com.freerdp.channels.drdynvc.client"); WLog_Print(drdynvc->log, WLOG_DEBUG, "VirtualChannelEntry"); CopyMemory(&(drdynvc->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP)); rc = drdynvc->channelEntryPoints.pVirtualChannelInit(&drdynvc->InitHandle, &drdynvc->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, drdynvc_virtual_channel_init_event); if (CHANNEL_RC_OK != rc) { WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]", WTSErrorToString(rc), rc); free(drdynvc); free(*(pEntryPointsEx->ppInterface)); *(pEntryPointsEx->ppInterface) = NULL; return FALSE; } drdynvc->channelEntryPoints.pInterface = *(drdynvc->channelEntryPoints.ppInterface); drdynvc->channelEntryPoints.ppInterface = &(drdynvc->channelEntryPoints.pInterface); if ((error = drdynvc_add_init_handle_data(drdynvc->InitHandle, (void*) drdynvc))) { WLog_ERR(TAG, "drdynvc_add_init_handle_data failed with error %lu!",error); free(drdynvc); free(*(pEntryPointsEx->ppInterface)); *(pEntryPointsEx->ppInterface) = NULL; return FALSE; } return TRUE; }