boolean license_send(rdpLicense* license, STREAM* s, uint8 type) { int length; uint8 flags; uint16 wMsgSize; uint16 sec_flags; DEBUG_LICENSE("Sending %s Packet", LICENSE_MESSAGE_STRINGS[type & 0x1F]); length = stream_get_length(s); stream_set_pos(s, 0); sec_flags = SEC_LICENSE_PKT; wMsgSize = length - LICENSE_PACKET_HEADER_MAX_LENGTH + 4; /** * Using EXTENDED_ERROR_MSG_SUPPORTED here would cause mstsc to crash when * running in server mode! This flag seems to be incorrectly documented. */ flags = PREAMBLE_VERSION_3_0; rdp_write_header(license->rdp, s, length, MCS_GLOBAL_CHANNEL_ID); rdp_write_security_header(s, sec_flags); license_write_preamble(s, type, flags, wMsgSize); #ifdef WITH_DEBUG_LICENSE printf("Sending %s Packet, length %d\n", LICENSE_MESSAGE_STRINGS[type & 0x1F], wMsgSize); freerdp_hexdump(s->p - 4, wMsgSize); #endif stream_set_pos(s, length); if (transport_write(license->rdp->transport, s) < 0) return false; return true; }
BOOL rdp_send_data_pdu(rdpRdp* rdp, STREAM* s, BYTE type, UINT16 channel_id) { UINT16 length; UINT32 sec_bytes; BYTE* sec_hold; length = stream_get_length(s); stream_set_pos(s, 0); rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID); sec_bytes = rdp_get_sec_bytes(rdp); sec_hold = s->p; stream_seek(s, sec_bytes); rdp_write_share_control_header(s, length - sec_bytes, PDU_TYPE_DATA, channel_id); rdp_write_share_data_header(s, length - sec_bytes, type, rdp->settings->ShareId); s->p = sec_hold; length += rdp_security_stream_out(rdp, s, length); stream_set_pos(s, length); if (transport_write(rdp->transport, s) < 0) return FALSE; return TRUE; }
static void WTSProcessChannelData(rdpPeerChannel* channel, int channelId, BYTE* data, int size, int flags, int total_size) { if (flags & CHANNEL_FLAG_FIRST) { stream_set_pos(channel->receive_data, 0); } stream_check_size(channel->receive_data, size); stream_write(channel->receive_data, data, size); if (flags & CHANNEL_FLAG_LAST) { if (stream_get_length(channel->receive_data) != total_size) { fprintf(stderr, "WTSProcessChannelData: read error\n"); } if (channel == channel->vcm->drdynvc_channel) { wts_read_drdynvc_pdu(channel); } else { wts_queue_receive_data(channel, stream_get_head(channel->receive_data), stream_get_length(channel->receive_data)); } stream_set_pos(channel->receive_data, 0); } }
boolean rdp_send_data_pdu(rdpRdp* rdp, STREAM* s, uint8 type, uint16 channel_id) { uint16 length; uint32 sec_bytes; uint8* sec_hold; length = stream_get_length(s); stream_set_pos(s, 0); rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID); sec_bytes = rdp_get_sec_bytes(rdp); sec_hold = s->p; stream_seek(s, sec_bytes); rdp_write_share_control_header(s, length - sec_bytes, PDU_TYPE_DATA, channel_id); rdp_write_share_data_header(s, length - sec_bytes, type, rdp->settings->share_id); s->p = sec_hold; length += rdp_security_stream_out(rdp, s, length); stream_set_pos(s, length); if (transport_write(rdp->transport, s) < 0) return false; return true; }
BOOL rdp_send(rdpRdp* rdp, STREAM* s, UINT16 channel_id) { UINT16 length; UINT32 sec_bytes; BYTE* sec_hold; length = stream_get_length(s); stream_set_pos(s, 0); rdp_write_header(rdp, s, length, channel_id); sec_bytes = rdp_get_sec_bytes(rdp); sec_hold = s->p; stream_seek(s, sec_bytes); s->p = sec_hold; length += rdp_security_stream_out(rdp, s, length); stream_set_pos(s, length); if (transport_write(rdp->transport, s) < 0) return FALSE; return TRUE; }
static void* tf_debug_channel_thread_func(void* arg) { void* fd; STREAM* s; void* buffer; UINT32 bytes_returned = 0; testPeerContext* context = (testPeerContext*) arg; freerdp_thread* thread = context->debug_channel_thread; if (WTSVirtualChannelQuery(context->debug_channel, WTSVirtualFileHandle, &buffer, &bytes_returned) == TRUE) { fd = *((void**) buffer); WTSFreeMemory(buffer); thread->signals[thread->num_signals++] = CreateFileDescriptorEvent(NULL, TRUE, FALSE, ((int) (long) fd)); } s = stream_new(4096); WTSVirtualChannelWrite(context->debug_channel, (BYTE*) "test1", 5, NULL); while (1) { freerdp_thread_wait(thread); if (freerdp_thread_is_stopped(thread)) break; stream_set_pos(s, 0); if (WTSVirtualChannelRead(context->debug_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == FALSE) { if (bytes_returned == 0) break; stream_check_size(s, bytes_returned); if (WTSVirtualChannelRead(context->debug_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == FALSE) { /* should not happen */ break; } } stream_set_pos(s, bytes_returned); printf("got %d bytes\n", bytes_returned); } stream_free(s); freerdp_thread_quit(thread); return 0; }
void rdp_send(rdpRdp* rdp, STREAM* s) { int length; length = stream_get_length(s); stream_set_pos(s, 0); rdp_write_header(rdp, s, length); stream_set_pos(s, length); transport_write(rdp->transport, s); }
void cliprdr_packet_send(cliprdrPlugin* cliprdr, STREAM* s) { int pos; uint32 dataLen; pos = stream_get_pos(s); dataLen = pos - 8; stream_set_pos(s, 4); stream_write_uint32(s, dataLen); stream_set_pos(s, pos); svc_plugin_send((rdpSvcPlugin*) cliprdr, s); }
void rdp_send_pdu(rdpRdp* rdp, STREAM* s, uint16 type, uint16 channel_id) { int length; length = stream_get_length(s); stream_set_pos(s, 0); rdp_write_header(rdp, s, length); rdp_write_share_control_header(s, length, type, channel_id); stream_set_pos(s, length); transport_write(rdp->transport, s); }
static void* tf_debug_channel_thread_func(void* arg) { void* fd; STREAM* s; void* buffer; uint32 bytes_returned = 0; testPeerContext* context = (testPeerContext*) arg; freerdp_thread* thread = context->debug_channel_thread; if (WTSVirtualChannelQuery(context->debug_channel, WTSVirtualFileHandle, &buffer, &bytes_returned) == true) { fd = *((void**)buffer); WTSFreeMemory(buffer); thread->signals[thread->num_signals++] = wait_obj_new_with_fd(fd); } s = stream_new(4096); WTSVirtualChannelWrite(context->debug_channel, (uint8*) "test1", 5, NULL); while (1) { freerdp_thread_wait(thread); if (freerdp_thread_is_stopped(thread)) break; stream_set_pos(s, 0); if (WTSVirtualChannelRead(context->debug_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == false) { if (bytes_returned == 0) break; stream_check_size(s, bytes_returned); if (WTSVirtualChannelRead(context->debug_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == false) { /* should not happen */ break; } } stream_set_pos(s, bytes_returned); printf("got %d bytes\n", bytes_returned); } stream_free(s); freerdp_thread_quit(thread); return 0; }
static void audin_server_send_open(audin_server* audin, STREAM* s) { if (audin->context.selected_client_format < 0) return; audin->opened = TRUE; stream_set_pos(s, 0); stream_write_BYTE(s, MSG_SNDIN_OPEN); stream_write_UINT32(s, audin->context.frames_per_packet); /* FramesPerPacket (4 bytes) */ stream_write_UINT32(s, audin->context.selected_client_format); /* initialFormat (4 bytes) */ /* * [MS-RDPEAI] 3.2.5.1.6 * The second format specify the format that SHOULD be used to capture data from * the actual audio input device. */ stream_write_UINT16(s, 1); /* wFormatTag = PCM */ stream_write_UINT16(s, 2); /* nChannels */ stream_write_UINT32(s, 44100); /* nSamplesPerSec */ stream_write_UINT32(s, 44100 * 2 * 2); /* nAvgBytesPerSec */ stream_write_UINT16(s, 4); /* nBlockAlign */ stream_write_UINT16(s, 16); /* wBitsPerSample */ stream_write_UINT16(s, 0); /* cbSize */ WTSVirtualChannelWrite(audin->audin_channel, stream_get_head(s), stream_get_length(s), NULL); }
void test_stream(void) { STREAM * stream; int pos; uint32 n; uint64 n64; stream = stream_new(1); pos = stream_get_pos(stream); stream_write_uint8(stream, 0xFE); stream_check_size(stream, 14); stream_write_uint16(stream, 0x0102); stream_write_uint32(stream, 0x03040506); stream_write_uint64(stream, 0x0708091011121314LL); /* freerdp_hexdump(stream->buffer, 15); */ stream_set_pos(stream, pos); stream_seek(stream, 3); stream_read_uint32(stream, n); stream_read_uint64(stream, n64); CU_ASSERT(n == 0x03040506); CU_ASSERT(n64 == 0x0708091011121314LL); stream_free(stream); }
void test_decode(void) { RFX_CONTEXT* context; BYTE decode_buffer[4096 * 3]; STREAM* s; s = stream_new(sizeof(y_data) + sizeof(cb_data) + sizeof(cr_data)); stream_write(s, y_data, sizeof(y_data)); stream_write(s, cb_data, sizeof(cb_data)); stream_write(s, cr_data, sizeof(cr_data)); stream_set_pos(s, 0); context = rfx_context_new(); context->mode = RLGR3; rfx_context_set_pixel_format(context, RDP_PIXEL_FORMAT_R8G8B8); rfx_decode_rgb(context, s, sizeof(y_data), test_quantization_values, sizeof(cb_data), test_quantization_values, sizeof(cr_data), test_quantization_values, decode_buffer); rfx_context_free(context); stream_free(s); dump_ppm_image(decode_buffer); }
STREAM* transport_recv_stream_init(rdpTransport* transport, int size) { STREAM* s = transport->ReceiveStream; stream_check_size(s, size); stream_set_pos(s, 0); return s; }
void test_nsc_encode(void) { int i; uint8* rgb_data; STREAM* enc_stream; NSC_CONTEXT* context; rgb_data = (uint8 *) malloc(64 * 64 * 3); for (i = 0; i < 64; i++) memcpy(rgb_data + i * 64 * 3, rgb_scanline_data, 64 * 3); context = nsc_context_new(); nsc_context_set_cpu_opt(context, CPU_SSE2); nsc_context_set_pixel_format(context, RDP_PIXEL_FORMAT_R8G8B8); enc_stream = stream_new(65536); stream_clear(enc_stream); for (i = 0; i < 30000; i++) { stream_set_pos(enc_stream, 0); nsc_compose_message(context, enc_stream, rgb_data, 64, 64, 64 * 3); } /*freerdp_hexdump(stream_get_head(enc_stream), stream_get_length(enc_stream));*/ nsc_process_message(context, 32, 64, 64, stream_get_head(enc_stream), stream_get_length(enc_stream)); /*freerdp_hexdump(context->bmpdata, 64 * 64 * 4);*/ stream_free(enc_stream); nsc_context_free(context); }
static void svc_plugin_process_received(rdpSvcPlugin* plugin, void* pData, uint32 dataLength, uint32 totalLength, uint32 dataFlags) { STREAM* data_in; if (dataFlags & CHANNEL_FLAG_FIRST) { if (plugin->priv->data_in != NULL) stream_free(plugin->priv->data_in); plugin->priv->data_in = stream_new(totalLength); } data_in = plugin->priv->data_in; stream_check_size(data_in, dataLength); stream_write(data_in, pData, dataLength); if (dataFlags & CHANNEL_FLAG_LAST) { if (stream_get_size(data_in) != stream_get_length(data_in)) { printf("svc_plugin_process_received: read error\n"); } /* the stream ownership is passed to the callback who is responsible for freeing it. */ plugin->priv->data_in = NULL; stream_set_pos(data_in, 0); plugin->receive_callback(plugin, data_in); } }
static void irp_complete(IRP* irp) { int pos; DEBUG_SVC("DeviceId %d FileId %d CompletionId %d", irp->device->id, irp->FileId, irp->CompletionId); pos = stream_get_pos(irp->output); stream_set_pos(irp->output, 12); stream_write_uint32(irp->output, irp->IoStatus); stream_set_pos(irp->output, pos); svc_plugin_send(irp->devman->plugin, irp->output); irp->output = NULL; irp_free(irp); }
void rail_send_pdu(rdpRailOrder* rail_order, STREAM* s, uint16 orderType) { uint16 orderLength; orderLength = stream_get_length(s); stream_set_pos(s, 0); rail_write_pdu_header(s, orderType, orderLength); stream_set_pos(s, orderLength); /* send */ DEBUG_RAIL("Sending %s PDU, length:%d", RAIL_ORDER_TYPE_STRINGS[((orderType & 0xF0) >> 3) + (orderType & 0x0F)], orderLength); rail_send_channel_data(rail_order->plugin, s->data, orderLength); }
STREAM* transport_send_stream_init(rdpTransport* transport, int size) { STREAM* s = transport->send_stream; stream_check_size(s, size); stream_set_pos(s, 0); return s; }
static void audin_server_send_formats(audin_server* audin, STREAM* s) { int i; UINT32 nAvgBytesPerSec; stream_set_pos(s, 0); stream_write_BYTE(s, MSG_SNDIN_FORMATS); stream_write_UINT32(s, audin->context.num_server_formats); /* NumFormats (4 bytes) */ stream_write_UINT32(s, 0); /* cbSizeFormatsPacket (4 bytes), client-to-server only */ for (i = 0; i < audin->context.num_server_formats; i++) { nAvgBytesPerSec = audin->context.server_formats[i].nSamplesPerSec * audin->context.server_formats[i].nChannels * audin->context.server_formats[i].wBitsPerSample / 8; stream_check_size(s, 18); stream_write_UINT16(s, audin->context.server_formats[i].wFormatTag); stream_write_UINT16(s, audin->context.server_formats[i].nChannels); stream_write_UINT32(s, audin->context.server_formats[i].nSamplesPerSec); stream_write_UINT32(s, nAvgBytesPerSec); stream_write_UINT16(s, audin->context.server_formats[i].nBlockAlign); stream_write_UINT16(s, audin->context.server_formats[i].wBitsPerSample); stream_write_UINT16(s, audin->context.server_formats[i].cbSize); if (audin->context.server_formats[i].cbSize) { stream_check_size(s, audin->context.server_formats[i].cbSize); stream_write(s, audin->context.server_formats[i].data, audin->context.server_formats[i].cbSize); } } WTSVirtualChannelWrite(audin->audin_channel, stream_get_head(s), stream_get_length(s), NULL); }
static BOOL update_recv_surfcmd_surface_bits(rdpUpdate* update, STREAM* s, UINT32 *length) { int pos; SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command; if(stream_get_left(s) < 20) return FALSE; stream_read_UINT16(s, cmd->destLeft); stream_read_UINT16(s, cmd->destTop); stream_read_UINT16(s, cmd->destRight); stream_read_UINT16(s, cmd->destBottom); stream_read_BYTE(s, cmd->bpp); stream_seek(s, 2); /* reserved1, reserved2 */ stream_read_BYTE(s, cmd->codecID); stream_read_UINT16(s, cmd->width); stream_read_UINT16(s, cmd->height); stream_read_UINT32(s, cmd->bitmapDataLength); if(stream_get_left(s) < cmd->bitmapDataLength) return FALSE; pos = stream_get_pos(s) + cmd->bitmapDataLength; cmd->bitmapData = stream_get_tail(s); IFCALL(update->SurfaceBits, update->context, cmd); stream_set_pos(s, pos); *length = 20 + cmd->bitmapDataLength; return TRUE; }
void rdp_send_data_pdu(rdpRdp* rdp, STREAM* s, uint16 type, uint16 channel_id) { int length; length = stream_get_length(s); stream_set_pos(s, 0); rdp_write_header(rdp, s, length); rdp_write_share_control_header(s, length, PDU_TYPE_DATA, channel_id); rdp_write_share_data_header(s, length, type, rdp->settings->share_id); printf("send %s Data PDU (0x%02X), length:%d\n", DATA_PDU_TYPE_STRINGS[type], type, length); stream_set_pos(s, length); transport_write(rdp->transport, s); }
int transport_write(rdpTransport* transport, STREAM* s) { int status = -1; int length; length = stream_get_length(s); stream_set_pos(s, 0); #ifdef WITH_DEBUG_TRANSPORT if (length > 0) { printf("Local > Remote\n"); winpr_HexDump(s->data, length); } #endif while (length > 0) { if (transport->layer == TRANSPORT_LAYER_TLS) status = tls_write(transport->TlsOut, stream_get_tail(s), length); else if (transport->layer == TRANSPORT_LAYER_TCP) status = tcp_write(transport->TcpOut, stream_get_tail(s), length); else if (transport->layer == TRANSPORT_LAYER_TSG) status = tsg_write(transport->tsg, stream_get_tail(s), length); if (status < 0) break; /* error occurred */ if (status == 0) { /* when sending is blocked in nonblocking mode, the receiving buffer should be checked */ if (!transport->blocking) { /* and in case we do have buffered some data, we set the event so next loop will get it */ if (transport_read_nonblocking(transport) > 0) SetEvent(transport->ReceiveEvent); } if (transport->layer == TRANSPORT_LAYER_TLS) tls_wait_write(transport->TlsOut); else if (transport->layer == TRANSPORT_LAYER_TCP) tcp_wait_write(transport->TcpOut); else USleep(transport->SleepInterval); } length -= status; stream_seek(s, status); } if (status < 0) { /* A write error indicates that the peer has dropped the connection */ transport->layer = TRANSPORT_LAYER_CLOSED; } return status; }
void scard_error(SCARD_DEVICE* scard, IRP* irp, uint32 ntstatus) { /* [MS-RDPESC] 3.1.4.4 */ printf("scard processing error %x\n", ntstatus); stream_set_pos(irp->output, 0); /* CHECKME */ irp->IoStatus = ntstatus; irp->Complete(irp); }
boolean freerdp_connect(freerdp* instance) { rdpRdp* rdp; boolean status; rdp = instance->context->rdp; IFCALL(instance->PreConnect, instance); status = rdp_client_connect(rdp); if (status) { if (instance->settings->dump_rfx) { instance->update->pcap_rfx = pcap_open(instance->settings->dump_rfx_file, True); if (instance->update->pcap_rfx) instance->update->dump_rfx = True; } IFCALL(instance->PostConnect, instance); if (instance->settings->play_rfx) { STREAM* s; rdpUpdate* update; pcap_record record; s = stream_new(1024); instance->update->pcap_rfx = pcap_open(instance->settings->play_rfx_file, False); if (instance->update->pcap_rfx) instance->update->play_rfx = True; update = instance->update; while (instance->update->play_rfx && pcap_has_next_record(update->pcap_rfx)) { pcap_get_next_record_header(update->pcap_rfx, &record); s->data = xrealloc(s->data, record.length); record.data = s->data; s->size = record.length; pcap_get_next_record_content(update->pcap_rfx, &record); stream_set_pos(s, 0); update->BeginPaint(update); update_recv_surfcmds(update, s->size, s); update->EndPaint(update); } xfree(s->data); return True; } } return status; }
static void scard_irp_complete(IRP* irp) { /* This function is (mostly) a copy of the statically-declared "irp_complete()" * function except that this function adds extra operations for the * smart card's handling of duplicate "CompletionID"s. This function needs * to be in this file so that "scard_irp_request()" can reference it. */ int pos; boolean duplicate; SCARD_DEVICE* scard = (SCARD_DEVICE*)irp->device; DEBUG_SVC("DeviceId %d FileId %d CompletionId %d", irp->device->id, irp->FileId, irp->CompletionId); pos = stream_get_pos(irp->output); stream_set_pos(irp->output, 12); stream_write_uint32(irp->output, irp->IoStatus); stream_set_pos(irp->output, pos); /* Begin TS Client defect workaround. */ freerdp_mutex_lock(scard->CompletionIdsMutex); /* Remove from the list the item identified by the CompletionID. * The function returns whether or not it was a duplicate CompletionID. */ duplicate = scard_check_for_duplicate_id(scard, irp->CompletionId); freerdp_mutex_unlock(scard->CompletionIdsMutex); if (false == duplicate) { svc_plugin_send(irp->devman->plugin, irp->output); irp->output = NULL; } /* End TS Client defect workaround. */ /* irp_free(irp); The "irp_free()" function is statically-declared * and so is not available to be called * here. Instead, call it indirectly by calling * the IRP's "Discard()" function, * which has already been assigned * to point to "irp_free()" in "irp_new()". */ irp->Discard(irp); }
static void rfx_compose_message_tile(RFX_CONTEXT* context, STREAM* s, BYTE* tile_data, int tile_width, int tile_height, int rowstride, const UINT32* quantVals, int quantIdxY, int quantIdxCb, int quantIdxCr, int xIdx, int yIdx) { int YLen = 0; int CbLen = 0; int CrLen = 0; int start_pos, end_pos; stream_check_size(s, 19); start_pos = stream_get_pos(s); stream_write_UINT16(s, CBT_TILE); /* BlockT.blockType */ stream_seek_UINT32(s); /* set BlockT.blockLen later */ stream_write_BYTE(s, quantIdxY); stream_write_BYTE(s, quantIdxCb); stream_write_BYTE(s, quantIdxCr); stream_write_UINT16(s, xIdx); stream_write_UINT16(s, yIdx); stream_seek(s, 6); /* YLen, CbLen, CrLen */ rfx_encode_rgb(context, tile_data, tile_width, tile_height, rowstride, quantVals + quantIdxY * 10, quantVals + quantIdxCb * 10, quantVals + quantIdxCr * 10, s, &YLen, &CbLen, &CrLen); DEBUG_RFX("xIdx=%d yIdx=%d width=%d height=%d YLen=%d CbLen=%d CrLen=%d", xIdx, yIdx, tile_width, tile_height, YLen, CbLen, CrLen); end_pos = stream_get_pos(s); stream_set_pos(s, start_pos + 2); stream_write_UINT32(s, 19 + YLen + CbLen + CrLen); /* BlockT.blockLen */ stream_set_pos(s, start_pos + 13); stream_write_UINT16(s, YLen); stream_write_UINT16(s, CbLen); stream_write_UINT16(s, CrLen); stream_set_pos(s, end_pos); }
int transport_write(rdpTransport* transport, STREAM* s) { int status = -1; int length; int sent = 0; length = stream_get_length(s); stream_set_pos(s, 0); #ifdef WITH_DEBUG_TRANSPORT if (length > 0) { printf("Local > Remote\n"); freerdp_hexdump(s->data, length); } #endif while (sent < length) { if (transport->layer == TRANSPORT_LAYER_TLS) status = tls_write(transport->tls, stream_get_tail(s), length); else if (transport->layer == TRANSPORT_LAYER_TCP) status = tcp_write(transport->tcp, stream_get_tail(s), length); if (status < 0) break; /* error occurred */ if (status == 0) { /* blocking while sending */ freerdp_usleep(transport->usleep_interval); /* when sending is blocked in nonblocking mode, the receiving buffer should be checked */ if (!transport->blocking) { /* and in case we do have buffered some data, we set the event so next loop will get it */ if (transport_read_nonblocking(transport) > 0) wait_obj_set(transport->recv_event); } } sent += status; stream_seek(s, status); } if (status < 0) { /* A write error indicates that the peer has dropped the connection */ transport->layer = TRANSPORT_LAYER_CLOSED; } return status; }
static void WTSProcessChannelData(rdpPeerChannel* channel, int channelId, uint8* data, int size, int flags, int total_size) { wts_data_item* item; if (flags & CHANNEL_FLAG_FIRST) { stream_set_pos(channel->receive_data, 0); } stream_check_size(channel->receive_data, size); stream_write(channel->receive_data, data, size); if (flags & CHANNEL_FLAG_LAST) { if (stream_get_length(channel->receive_data) != total_size) { printf("WTSProcessChannelData: read error\n"); } if (channel->channel_type == RDP_PEER_CHANNEL_TYPE_DVC) { /* TODO: Receive DVC channel data */ } else { item = xnew(wts_data_item); item->length = stream_get_length(channel->receive_data); item->buffer = xmalloc(item->length); memcpy(item->buffer, stream_get_head(channel->receive_data), item->length); freerdp_mutex_lock(channel->mutex); list_enqueue(channel->receive_queue, item); freerdp_mutex_unlock(channel->mutex); wait_obj_set(channel->receive_event); } stream_set_pos(channel->receive_data, 0); } }
void stream_extend(STREAM* stream, int request_size) { int original_size; int increased_size; int pos; pos = stream_get_pos(stream); original_size = stream->size; increased_size = (request_size > original_size ? request_size : original_size); stream->size += increased_size; stream->data = (uint8*)xrealloc(stream->data, stream->size); memset(stream->data + original_size, 0, increased_size); stream_set_pos(stream, pos); }