void rdpdr_send_completion(uint32 device, uint32 id, uint32 status, uint32 result, uint8 * buffer, uint32 length) { uint8 magic[4] = "rDCI"; STREAM s; #ifdef WITH_SCARD scard_lock(SCARD_LOCK_RDPDR); #endif s = channel_init(rdpdr_channel, 20 + length); out_uint8a(s, magic, 4); out_uint32_le(s, device); out_uint32_le(s, id); out_uint32_le(s, status); out_uint32_le(s, result); out_uint8p(s, buffer, length); s_mark_end(s); /* JIF */ #ifdef WITH_DEBUG_RDP5 printf("--> rdpdr_send_completion\n"); /* hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8); */ #endif channel_send(s, rdpdr_channel); #ifdef WITH_SCARD scard_unlock(SCARD_LOCK_RDPDR); #endif }
/* Initialise TCP transport data packet */ STREAM tcp_init(uint32 maxlen) { static int cur_stream_id = 0; STREAM result = NULL; #ifdef WITH_SCARD scard_lock(SCARD_LOCK_TCP); #endif result = &g_out[cur_stream_id]; cur_stream_id = (cur_stream_id + 1) % STREAM_COUNT; if (maxlen > result->size) { result->data = (uint8 *) xrealloc(result->data, maxlen); result->size = maxlen; } result->p = result->data; result->end = result->data + result->size; #ifdef WITH_SCARD scard_unlock(SCARD_LOCK_TCP); #endif return result; }
/* Send TCP transport data packet */ void tcp_send(STREAM s) { int length = s->end - s->data; int sent, total = 0; #ifdef WITH_SCARD scard_lock(SCARD_LOCK_TCP); #endif while (total < length) { sent = send(g_sock, s->data + total, length - total, 0); if (sent <= 0) { if (sent == -1 && TCP_BLOCKS) { tcp_can_send(g_sock, 100); sent = 0; } else { error("send: %s\n", TCP_STRERROR); return; } } total += sent; } #ifdef WITH_SCARD scard_unlock(SCARD_LOCK_TCP); #endif }
void channel_send(STREAM s, VCHANNEL * channel) { uint32 length, flags; uint32 thislength, remaining; uint8 *data; #ifdef WITH_SCARD scard_lock(SCARD_LOCK_CHANNEL); #endif /* first fragment sent in-place */ s_pop_layer(s, channel_hdr); length = s->end - s->p - 8; DEBUG_CHANNEL(("channel_send, length = %d\n", length)); thislength = MIN(length, CHANNEL_CHUNK_LENGTH); /* Note: In the original clipboard implementation, this number was 1592, not 1600. However, I don't remember the reason and 1600 seems to work so.. This applies only to *this* length, not the length of continuation or ending packets. */ remaining = length - thislength; flags = (remaining == 0) ? CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST : CHANNEL_FLAG_FIRST; if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL) flags |= CHANNEL_FLAG_SHOW_PROTOCOL; out_uint32_le(s, length); out_uint32_le(s, flags); data = s->end = s->p + thislength; DEBUG_CHANNEL(("Sending %d bytes with FLAG_FIRST\n", thislength)); sec_send_to_channel(s, g_encryption ? SEC_ENCRYPT : 0, channel->mcs_id); /* subsequent segments copied (otherwise would have to generate headers backwards) */ while (remaining > 0) { thislength = MIN(remaining, CHANNEL_CHUNK_LENGTH); remaining -= thislength; flags = (remaining == 0) ? CHANNEL_FLAG_LAST : 0; if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL) flags |= CHANNEL_FLAG_SHOW_PROTOCOL; DEBUG_CHANNEL(("Sending %d bytes with flags %d\n", thislength, flags)); s = sec_init(g_encryption ? SEC_ENCRYPT : 0, thislength + 8); out_uint32_le(s, length); out_uint32_le(s, flags); out_uint8p(s, data, thislength); s_mark_end(s); sec_send_to_channel(s, g_encryption ? SEC_ENCRYPT : 0, channel->mcs_id); data += thislength; } #ifdef WITH_SCARD scard_unlock(SCARD_LOCK_CHANNEL); #endif }
/* Send TCP transport data packet */ void tcp_send(STREAM s) { int ssl_err; int length = s->end - s->data; int sent, total = 0; if (g_network_error == True) return; #ifdef WITH_SCARD scard_lock(SCARD_LOCK_TCP); #endif while (total < length) { if (g_ssl) { sent = SSL_write(g_ssl, s->data + total, length - total); if (sent <= 0) { ssl_err = SSL_get_error(g_ssl, sent); if (sent < 0 && (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE)) { tcp_can_send(g_sock, 100); sent = 0; } else { #ifdef WITH_SCARD scard_unlock(SCARD_LOCK_TCP); #endif error("SSL_write: %d (%s)\n", ssl_err, TCP_STRERROR); g_network_error = True; return; } } } else { sent = send(g_sock, s->data + total, length - total, 0); if (sent <= 0) { if (sent == -1 && TCP_BLOCKS) { tcp_can_send(g_sock, 100); sent = 0; } else { #ifdef WITH_SCARD scard_unlock(SCARD_LOCK_TCP); #endif error("send: %s\n", TCP_STRERROR); g_network_error = True; return; } } } total += sent; } #ifdef WITH_SCARD scard_unlock(SCARD_LOCK_TCP); #endif }