|
|
|
@ -22,12 +22,94 @@
|
|
|
|
|
|
|
|
|
|
#include "vnc.h"
|
|
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
/* returns error */
|
|
|
|
|
int lib_recv(struct vnc* v, char* data, int len)
|
|
|
|
|
{
|
|
|
|
|
int rcvd;
|
|
|
|
|
|
|
|
|
|
if (v->sck_closed)
|
|
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
while (len > 0)
|
|
|
|
|
{
|
|
|
|
|
rcvd = g_tcp_recv(v->sck, data, len, 0);
|
|
|
|
|
if (rcvd == -1)
|
|
|
|
|
{
|
|
|
|
|
if (g_tcp_last_error_would_block(v->sck))
|
|
|
|
|
{
|
|
|
|
|
g_sleep(1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (rcvd == 0)
|
|
|
|
|
{
|
|
|
|
|
v->sck_closed = 1;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
data += rcvd;
|
|
|
|
|
len -= rcvd;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/* returns error */
|
|
|
|
|
int lib_send(struct vnc* v, char* data, int len)
|
|
|
|
|
{
|
|
|
|
|
int sent;
|
|
|
|
|
|
|
|
|
|
if (v->sck_closed)
|
|
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
while (len > 0)
|
|
|
|
|
{
|
|
|
|
|
sent = g_tcp_send(v->sck, data, len, 0);
|
|
|
|
|
if (sent == -1)
|
|
|
|
|
{
|
|
|
|
|
if (g_tcp_last_error_would_block(v->sck))
|
|
|
|
|
{
|
|
|
|
|
g_sleep(1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (sent == 0)
|
|
|
|
|
{
|
|
|
|
|
v->sck_closed = 1;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
data += sent;
|
|
|
|
|
len -= sent;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
int lib_mod_event(struct vnc* v, int msg, int param1, int param2)
|
|
|
|
|
{
|
|
|
|
|
struct stream* s;
|
|
|
|
|
int key;
|
|
|
|
|
int error;
|
|
|
|
|
int x;
|
|
|
|
|
int y;
|
|
|
|
|
int cx;
|
|
|
|
|
int cy;
|
|
|
|
|
|
|
|
|
|
error = 0;
|
|
|
|
|
make_stream(s);
|
|
|
|
|
if (msg >= 15 && msg <= 16) /* key events */
|
|
|
|
|
{
|
|
|
|
@ -81,13 +163,7 @@ int lib_mod_event(struct vnc* v, int msg, int param1, int param2)
|
|
|
|
|
out_uint8(s, msg == 15); /* down flag */
|
|
|
|
|
out_uint8s(s, 2);
|
|
|
|
|
out_uint32_be(s, key);
|
|
|
|
|
if (g_tcp_force_send(v->sck, s->data, 8) != 0)
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
v->sck = 0;
|
|
|
|
|
free_stream(s);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
error = lib_send(v, s->data, 8);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (msg >= 100 && msg <= 110) /* mouse events */
|
|
|
|
@ -111,16 +187,26 @@ int lib_mod_event(struct vnc* v, int msg, int param1, int param2)
|
|
|
|
|
out_uint8(s, v->mod_mouse_state);
|
|
|
|
|
out_uint16_be(s, param1);
|
|
|
|
|
out_uint16_be(s, param2);
|
|
|
|
|
if (g_tcp_force_send(v->sck, s->data, 6) != 0)
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
v->sck = 0;
|
|
|
|
|
free_stream(s);
|
|
|
|
|
return 1;
|
|
|
|
|
error = lib_send(v, s->data, 6);
|
|
|
|
|
}
|
|
|
|
|
else if (msg == 200) /* invalidate */
|
|
|
|
|
{
|
|
|
|
|
/* FrambufferUpdateRequest */
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
out_uint8(s, 3);
|
|
|
|
|
out_uint8(s, 0);
|
|
|
|
|
x = (param1 >> 16) & 0xffff;
|
|
|
|
|
out_uint16_be(s, x);
|
|
|
|
|
y = param1 & 0xffff;
|
|
|
|
|
out_uint16_be(s, y);
|
|
|
|
|
cx = (param2 >> 16) & 0xffff;
|
|
|
|
|
out_uint16_be(s, cx);
|
|
|
|
|
cy = param2 & 0xffff;
|
|
|
|
|
out_uint16_be(s, cy);
|
|
|
|
|
error = lib_send(v, s->data, 10);
|
|
|
|
|
}
|
|
|
|
|
free_stream(s);
|
|
|
|
|
return 0;
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//******************************************************************************
|
|
|
|
@ -130,13 +216,21 @@ int get_pixel_safe(char* data, int x, int y, int width, int height, int bpp)
|
|
|
|
|
int shift;
|
|
|
|
|
|
|
|
|
|
if (x < 0)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (y < 0)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (x >= width)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (y >= height)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (bpp == 1)
|
|
|
|
|
{
|
|
|
|
|
width = (width + 7) / 8;
|
|
|
|
@ -150,10 +244,14 @@ int get_pixel_safe(char* data, int x, int y, int width, int height, int bpp)
|
|
|
|
|
start = y * width + x / 2;
|
|
|
|
|
shift = x % 2;
|
|
|
|
|
if (shift == 0)
|
|
|
|
|
{
|
|
|
|
|
return (data[start] & 0xf0) >> 4;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return data[start] & 0x0f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (bpp == 8)
|
|
|
|
|
{
|
|
|
|
|
return *(((unsigned char*)data) + (y * width + x));
|
|
|
|
@ -173,23 +271,35 @@ void set_pixel_safe(char* data, int x, int y, int width, int height, int bpp,
|
|
|
|
|
int shift;
|
|
|
|
|
|
|
|
|
|
if (x < 0)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (y < 0)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (x >= width)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (y >= height)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (bpp == 1)
|
|
|
|
|
{
|
|
|
|
|
width = (width + 7) / 8;
|
|
|
|
|
start = (y * width) + x / 8;
|
|
|
|
|
shift = x % 8;
|
|
|
|
|
if (pixel & 1)
|
|
|
|
|
{
|
|
|
|
|
data[start] = data[start] | (0x80 >> shift);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
data[start] = data[start] & ~(0x80 >> shift);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (bpp == 15 || bpp == 16)
|
|
|
|
|
{
|
|
|
|
|
*(((unsigned short*)data) + (y * width + x)) = pixel;
|
|
|
|
@ -259,30 +369,32 @@ int lib_framebuffer_update(struct vnc* v)
|
|
|
|
|
int b;
|
|
|
|
|
int data_size;
|
|
|
|
|
int need_size;
|
|
|
|
|
int error;
|
|
|
|
|
struct stream* s;
|
|
|
|
|
|
|
|
|
|
data_size = 0;
|
|
|
|
|
data = 0;
|
|
|
|
|
num_recs = 0;
|
|
|
|
|
Bpp = (v->mod_bpp + 7) / 8;
|
|
|
|
|
make_stream(s);
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
if (g_tcp_force_recv(v->sck, s->data, 3) != 0)
|
|
|
|
|
error = lib_recv(v, s->data, 3);
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
free_stream(s);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
in_uint8s(s, 1);
|
|
|
|
|
in_uint16_be(s, num_recs);
|
|
|
|
|
|
|
|
|
|
v->server_begin_update(v);
|
|
|
|
|
error = v->server_begin_update(v);
|
|
|
|
|
}
|
|
|
|
|
for (i = 0; i < num_recs; i++)
|
|
|
|
|
{
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
if (g_tcp_force_recv(v->sck, s->data, 12) != 0)
|
|
|
|
|
if (error != 0)
|
|
|
|
|
{
|
|
|
|
|
free_stream(s);
|
|
|
|
|
return 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
error = lib_recv(v, s->data, 12);
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
in_uint16_be(s, x);
|
|
|
|
|
in_uint16_be(s, y);
|
|
|
|
|
in_uint16_be(s, cx);
|
|
|
|
@ -297,35 +409,22 @@ int lib_framebuffer_update(struct vnc* v)
|
|
|
|
|
data = (char*)g_malloc(need_size, 0);
|
|
|
|
|
data_size = need_size;
|
|
|
|
|
}
|
|
|
|
|
if (g_tcp_force_recv(v->sck, data, cx * cy * Bpp) != 0)
|
|
|
|
|
{
|
|
|
|
|
g_free(data);
|
|
|
|
|
free_stream(s);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
if (v->server_paint_rect(v, x, y, cx, cy, data) != 0)
|
|
|
|
|
error = lib_recv(v, data, need_size);
|
|
|
|
|
/*g_printf("%d %d\n", i, need_size);*/
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
g_free(data);
|
|
|
|
|
free_stream(s);
|
|
|
|
|
return 1;
|
|
|
|
|
error = v->server_paint_rect(v, x, y, cx, cy, data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (encoding == 1) /* copy rect */
|
|
|
|
|
{
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
if (g_tcp_force_recv(v->sck, s->data, 4) != 0)
|
|
|
|
|
error = lib_recv(v, s->data, 4);
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
g_free(data);
|
|
|
|
|
free_stream(s);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
in_uint16_be(s, srcx);
|
|
|
|
|
in_uint16_be(s, srcy);
|
|
|
|
|
if (v->server_screen_blt(v, x, y, cx, cy, srcx, srcy) != 0)
|
|
|
|
|
{
|
|
|
|
|
g_free(data);
|
|
|
|
|
free_stream(s);
|
|
|
|
|
return 1;
|
|
|
|
|
error = v->server_screen_blt(v, x, y, cx, cy, srcx, srcy);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (encoding == 0xffffff11) /* cursor */
|
|
|
|
@ -333,13 +432,9 @@ int lib_framebuffer_update(struct vnc* v)
|
|
|
|
|
g_memset(cursor_data, 0, 32 * (32 * 3));
|
|
|
|
|
g_memset(cursor_mask, 0, 32 * (32 / 8));
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
if (g_tcp_force_recv(v->sck, s->data,
|
|
|
|
|
cx * cy * Bpp + ((cx + 7) / 8) * cy) != 0)
|
|
|
|
|
error = lib_recv(v, s->data, cx * cy * Bpp + ((cx + 7) / 8) * cy);
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
g_free(data);
|
|
|
|
|
free_stream(s);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
in_uint8p(s, d1, cx * cy * Bpp);
|
|
|
|
|
in_uint8p(s, d2, ((cx + 7) / 8) * cy);
|
|
|
|
|
for (j = 0; j < 32; j++)
|
|
|
|
@ -357,11 +452,7 @@ int lib_framebuffer_update(struct vnc* v)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (v->server_set_cursor(v, x, y, cursor_data, cursor_mask) != 0)
|
|
|
|
|
{
|
|
|
|
|
g_free(data);
|
|
|
|
|
free_stream(s);
|
|
|
|
|
return 1;
|
|
|
|
|
error = v->server_set_cursor(v, x, y, cursor_data, cursor_mask);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
@ -369,9 +460,14 @@ int lib_framebuffer_update(struct vnc* v)
|
|
|
|
|
g_printf("error in lib_framebuffer_update\n\r");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
v->server_end_update(v);
|
|
|
|
|
}
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
error = v->server_end_update(v);
|
|
|
|
|
}
|
|
|
|
|
g_free(data);
|
|
|
|
|
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
/* FrambufferUpdateRequest */
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
out_uint8(s, 3);
|
|
|
|
@ -380,13 +476,10 @@ int lib_framebuffer_update(struct vnc* v)
|
|
|
|
|
out_uint16_be(s, 0);
|
|
|
|
|
out_uint16_be(s, v->mod_width);
|
|
|
|
|
out_uint16_be(s, v->mod_height);
|
|
|
|
|
if (g_tcp_force_send(v->sck, s->data, 10) != 0)
|
|
|
|
|
{
|
|
|
|
|
free_stream(s);
|
|
|
|
|
return 1;
|
|
|
|
|
error = lib_send(v, s->data, 10);
|
|
|
|
|
}
|
|
|
|
|
free_stream(s);
|
|
|
|
|
return 0;
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
@ -394,24 +487,20 @@ int lib_clip_data(struct vnc* v)
|
|
|
|
|
{
|
|
|
|
|
struct stream* s;
|
|
|
|
|
int size;
|
|
|
|
|
int error;
|
|
|
|
|
|
|
|
|
|
make_stream(s);
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
if (g_tcp_force_recv(v->sck, s->data, 7) != 0)
|
|
|
|
|
error = lib_recv(v, s->data, 7);
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
free_stream(s);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
in_uint8s(s, 3);
|
|
|
|
|
in_uint32_be(s, size);
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
if (g_tcp_force_recv(v->sck, s->data, size) != 0)
|
|
|
|
|
{
|
|
|
|
|
free_stream(s);
|
|
|
|
|
return 1;
|
|
|
|
|
error = lib_recv(v, s->data, size);
|
|
|
|
|
}
|
|
|
|
|
free_stream(s);
|
|
|
|
|
return 0;
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
@ -424,23 +513,21 @@ int lib_palette_update(struct vnc* v)
|
|
|
|
|
int r;
|
|
|
|
|
int g;
|
|
|
|
|
int b;
|
|
|
|
|
int error;
|
|
|
|
|
|
|
|
|
|
make_stream(s);
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
if (g_tcp_force_recv(v->sck, s->data, 5) != 0)
|
|
|
|
|
error = lib_recv(v, s->data, 5);
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
free_stream(s);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
in_uint8s(s, 1);
|
|
|
|
|
in_uint16_be(s, first_color);
|
|
|
|
|
in_uint16_be(s, num_colors);
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
if (g_tcp_force_recv(v->sck, s->data, num_colors * 6) != 0)
|
|
|
|
|
{
|
|
|
|
|
free_stream(s);
|
|
|
|
|
return 1;
|
|
|
|
|
error = lib_recv(v, s->data, num_colors * 6);
|
|
|
|
|
}
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
for (i = 0; i < num_colors; i++)
|
|
|
|
|
{
|
|
|
|
|
in_uint16_be(s, r);
|
|
|
|
@ -451,56 +538,47 @@ int lib_palette_update(struct vnc* v)
|
|
|
|
|
b = b >> 8;
|
|
|
|
|
v->palette[first_color + i] = (r << 16) | (g << 8) | b;
|
|
|
|
|
}
|
|
|
|
|
v->server_begin_update(v);
|
|
|
|
|
v->server_palette(v, v->palette);
|
|
|
|
|
v->server_end_update(v);
|
|
|
|
|
error = v->server_begin_update(v);
|
|
|
|
|
}
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
error = v->server_palette(v, v->palette);
|
|
|
|
|
}
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
error = v->server_end_update(v);
|
|
|
|
|
}
|
|
|
|
|
free_stream(s);
|
|
|
|
|
return 0;
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
int lib_mod_signal(struct vnc* v)
|
|
|
|
|
{
|
|
|
|
|
char type;
|
|
|
|
|
int error;
|
|
|
|
|
|
|
|
|
|
if (g_tcp_force_recv(v->sck, &type, 1) != 0)
|
|
|
|
|
error = lib_recv(v, &type, 1);
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
v->sck = 0;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
if (type == 0) /* framebuffer update */
|
|
|
|
|
{
|
|
|
|
|
if (lib_framebuffer_update(v) != 0)
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
v->sck = 0;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
error = lib_framebuffer_update(v);
|
|
|
|
|
}
|
|
|
|
|
else if (type == 1) /* palette */
|
|
|
|
|
{
|
|
|
|
|
if (lib_palette_update(v) != 0)
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
v->sck = 0;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
error = lib_palette_update(v);
|
|
|
|
|
}
|
|
|
|
|
else if (type == 3) /* clipboard */
|
|
|
|
|
{
|
|
|
|
|
if (lib_clip_data(v) != 0)
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
v->sck = 0;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
error = lib_clip_data(v);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
g_printf("unknown in lib_mod_signal %d\n\r", type);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
@ -536,7 +614,6 @@ int lib_mod_connect(struct vnc* v)
|
|
|
|
|
int error;
|
|
|
|
|
int i;
|
|
|
|
|
int check_sec_result;
|
|
|
|
|
int sck;
|
|
|
|
|
int version;
|
|
|
|
|
int size;
|
|
|
|
|
int code;
|
|
|
|
@ -554,8 +631,9 @@ int lib_mod_connect(struct vnc* v)
|
|
|
|
|
i = 0;
|
|
|
|
|
error = 0;
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
sck = g_tcp_socket();
|
|
|
|
|
if (g_tcp_connect(sck, v->ip, "3350") == 0)
|
|
|
|
|
v->sck = g_tcp_socket();
|
|
|
|
|
v->sck_closed = 0;
|
|
|
|
|
if (g_tcp_connect(v->sck, v->ip, "3350") == 0)
|
|
|
|
|
{
|
|
|
|
|
s_push_layer(s, channel_hdr, 8);
|
|
|
|
|
out_uint16_be(s, 0); // code
|
|
|
|
@ -572,19 +650,20 @@ int lib_mod_connect(struct vnc* v)
|
|
|
|
|
s_pop_layer(s, channel_hdr);
|
|
|
|
|
out_uint32_be(s, 0); // version
|
|
|
|
|
out_uint32_be(s, s->end - s->data); // size
|
|
|
|
|
if (g_tcp_force_send(sck, s->data, s->end - s->data) != 0)
|
|
|
|
|
error = lib_send(v, s->data, s->end - s->data);
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(sck);
|
|
|
|
|
free_stream(s);
|
|
|
|
|
return 7;
|
|
|
|
|
}
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
if (g_tcp_force_recv(sck, s->data, 8) == 0)
|
|
|
|
|
error = lib_recv(v, s->data, 8);
|
|
|
|
|
}
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
in_uint32_be(s, version);
|
|
|
|
|
in_uint32_be(s, size);
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
if (g_tcp_force_recv(sck, s->data, size - 8) == 0)
|
|
|
|
|
error = lib_recv(v, s->data, size - 8);
|
|
|
|
|
}
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
if (version == 0)
|
|
|
|
|
{
|
|
|
|
@ -600,21 +679,8 @@ int lib_mod_connect(struct vnc* v)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(sck);
|
|
|
|
|
free_stream(s);
|
|
|
|
|
return 7;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(sck);
|
|
|
|
|
free_stream(s);
|
|
|
|
|
return 7;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
g_tcp_close(sck);
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
if (error != 0 || i == 0)
|
|
|
|
|
{
|
|
|
|
|
free_stream(s);
|
|
|
|
@ -629,38 +695,27 @@ int lib_mod_connect(struct vnc* v)
|
|
|
|
|
}
|
|
|
|
|
make_stream(pixel_format);
|
|
|
|
|
v->sck = g_tcp_socket();
|
|
|
|
|
v->sck_closed = 0;
|
|
|
|
|
error = g_tcp_connect(v->sck, v->ip, con_port);
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
g_tcp_set_non_blocking(v->sck);
|
|
|
|
|
g_tcp_set_no_delay(v->sck);
|
|
|
|
|
/* protocal version */
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
if (g_tcp_force_recv(v->sck, s->data, 12) != 0)
|
|
|
|
|
error = lib_recv(v, s->data, 12);
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
v->sck = 0;
|
|
|
|
|
free_stream(s);
|
|
|
|
|
free_stream(pixel_format);
|
|
|
|
|
return 7;
|
|
|
|
|
}
|
|
|
|
|
if (g_tcp_force_send(v->sck, "RFB 003.003\n", 12) != 0)
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
v->sck = 0;
|
|
|
|
|
free_stream(s);
|
|
|
|
|
free_stream(pixel_format);
|
|
|
|
|
return 7;
|
|
|
|
|
error = lib_send(v, "RFB 003.003\n", 12);
|
|
|
|
|
}
|
|
|
|
|
/* sec type */
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
if (g_tcp_force_recv(v->sck, s->data, 4) != 0)
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
v->sck = 0;
|
|
|
|
|
free_stream(s);
|
|
|
|
|
free_stream(pixel_format);
|
|
|
|
|
return 7;
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
error = lib_recv(v, s->data, 4);
|
|
|
|
|
}
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
in_uint32_be(s, i);
|
|
|
|
|
if (i == 1) /* none */
|
|
|
|
|
{
|
|
|
|
@ -669,22 +724,11 @@ int lib_mod_connect(struct vnc* v)
|
|
|
|
|
else if (i == 2) /* dec the password and the server random */
|
|
|
|
|
{
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
if (g_tcp_force_recv(v->sck, s->data, 16) != 0)
|
|
|
|
|
error = lib_recv(v, s->data, 16);
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
v->sck = 0;
|
|
|
|
|
free_stream(s);
|
|
|
|
|
free_stream(pixel_format);
|
|
|
|
|
return 7;
|
|
|
|
|
}
|
|
|
|
|
rfbEncryptBytes((unsigned char*)s->data, v->password);
|
|
|
|
|
if (g_tcp_force_send(v->sck, s->data, 16) != 0)
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
v->sck = 0;
|
|
|
|
|
free_stream(s);
|
|
|
|
|
free_stream(pixel_format);
|
|
|
|
|
return 7;
|
|
|
|
|
error = lib_send(v, s->data, 16);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
@ -692,65 +736,46 @@ int lib_mod_connect(struct vnc* v)
|
|
|
|
|
error = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (error == 0 && check_sec_result)
|
|
|
|
|
{
|
|
|
|
|
/* sec result */
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
if (g_tcp_force_recv(v->sck, s->data, 4) != 0)
|
|
|
|
|
error = lib_recv(v, s->data, 4);
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
v->sck = 0;
|
|
|
|
|
free_stream(s);
|
|
|
|
|
free_stream(pixel_format);
|
|
|
|
|
return 7;
|
|
|
|
|
}
|
|
|
|
|
in_uint32_be(s, i);
|
|
|
|
|
if (i != 0)
|
|
|
|
|
{
|
|
|
|
|
error = 2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
s->data[0] = 1;
|
|
|
|
|
if (g_tcp_force_send(v->sck, s->data, 1) != 0) /* share flag */
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
v->sck = 0;
|
|
|
|
|
free_stream(s);
|
|
|
|
|
free_stream(pixel_format);
|
|
|
|
|
return 7;
|
|
|
|
|
error = lib_send(v, s->data, 1); /* share flag */
|
|
|
|
|
}
|
|
|
|
|
if (g_tcp_force_recv(v->sck, s->data, 4) != 0) /* server init */
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
v->sck = 0;
|
|
|
|
|
free_stream(s);
|
|
|
|
|
free_stream(pixel_format);
|
|
|
|
|
return 7;
|
|
|
|
|
error = lib_recv(v, s->data, 4); /* server init */
|
|
|
|
|
}
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
in_uint16_be(s, v->mod_width);
|
|
|
|
|
in_uint16_be(s, v->mod_height);
|
|
|
|
|
init_stream(pixel_format, 8192);
|
|
|
|
|
if (g_tcp_force_recv(v->sck, pixel_format->data, 16) != 0)
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
v->sck = 0;
|
|
|
|
|
free_stream(s);
|
|
|
|
|
free_stream(pixel_format);
|
|
|
|
|
return 7;
|
|
|
|
|
error = lib_recv(v, pixel_format->data, 16);
|
|
|
|
|
}
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
in_uint8(pixel_format, v->mod_bpp);
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
if (g_tcp_force_recv(v->sck, s->data, 4) != 0) /* name len */
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
v->sck = 0;
|
|
|
|
|
free_stream(s);
|
|
|
|
|
free_stream(pixel_format);
|
|
|
|
|
return 7;
|
|
|
|
|
error = lib_recv(v, s->data, 4); /* name len */
|
|
|
|
|
}
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
in_uint32_be(s, i);
|
|
|
|
|
if (i > 255 || i < 0)
|
|
|
|
|
{
|
|
|
|
@ -758,18 +783,11 @@ int lib_mod_connect(struct vnc* v)
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (g_tcp_force_recv(v->sck, v->mod_name, i) != 0)
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
v->sck = 0;
|
|
|
|
|
free_stream(s);
|
|
|
|
|
free_stream(pixel_format);
|
|
|
|
|
return 7;
|
|
|
|
|
}
|
|
|
|
|
error = lib_recv(v, v->mod_name, i);
|
|
|
|
|
v->mod_name[i] = 0;
|
|
|
|
|
}
|
|
|
|
|
/* should be connected */
|
|
|
|
|
}
|
|
|
|
|
/* should be connected */
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
/* SetPixelFormat */
|
|
|
|
@ -794,14 +812,10 @@ int lib_mod_connect(struct vnc* v)
|
|
|
|
|
out_uint8s(pixel_format, 3); /* pad */
|
|
|
|
|
}
|
|
|
|
|
out_uint8a(s, pixel_format->data, 16);
|
|
|
|
|
if (g_tcp_force_send(v->sck, s->data, 20) != 0)
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
v->sck = 0;
|
|
|
|
|
free_stream(s);
|
|
|
|
|
free_stream(pixel_format);
|
|
|
|
|
return 7;
|
|
|
|
|
error = lib_send(v, s->data, 20);
|
|
|
|
|
}
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
/* SetEncodings */
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
out_uint8(s, 2);
|
|
|
|
@ -810,14 +824,10 @@ int lib_mod_connect(struct vnc* v)
|
|
|
|
|
out_uint32_be(s, 0); /* raw */
|
|
|
|
|
out_uint32_be(s, 1); /* copy rect */
|
|
|
|
|
out_uint32_be(s, 0xffffff11); /* cursor */
|
|
|
|
|
if (g_tcp_force_send(v->sck, s->data, 4 + 3 * 4) != 0)
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
v->sck = 0;
|
|
|
|
|
free_stream(s);
|
|
|
|
|
free_stream(pixel_format);
|
|
|
|
|
return 7;
|
|
|
|
|
error = lib_send(v, s->data, 4 + 3 * 4);
|
|
|
|
|
}
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
/* FrambufferUpdateRequest */
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
out_uint8(s, 3);
|
|
|
|
@ -826,14 +836,7 @@ int lib_mod_connect(struct vnc* v)
|
|
|
|
|
out_uint16_be(s, 0);
|
|
|
|
|
out_uint16_be(s, v->mod_width);
|
|
|
|
|
out_uint16_be(s, v->mod_height);
|
|
|
|
|
if (g_tcp_force_send(v->sck, s->data, 10) != 0)
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
v->sck = 0;
|
|
|
|
|
free_stream(s);
|
|
|
|
|
free_stream(pixel_format);
|
|
|
|
|
return 7;
|
|
|
|
|
}
|
|
|
|
|
error = lib_send(v, s->data, 10);
|
|
|
|
|
}
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
@ -843,48 +846,21 @@ int lib_mod_connect(struct vnc* v)
|
|
|
|
|
error = 4;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
/* set almost null cursor */
|
|
|
|
|
g_memset(cursor_data, 0, 32 * (32 * 3));
|
|
|
|
|
g_memset(cursor_data + (32 * (32 * 3) - 1 * 32 * 3), 0xff, 9);
|
|
|
|
|
g_memset(cursor_data + (32 * (32 * 3) - 2 * 32 * 3), 0xff, 9);
|
|
|
|
|
g_memset(cursor_data + (32 * (32 * 3) - 3 * 32 * 3), 0xff, 9);
|
|
|
|
|
g_memset(cursor_mask, 0xff, 32 * (32 / 8));
|
|
|
|
|
v->server_set_cursor(v, 0, 0, cursor_data, cursor_mask);
|
|
|
|
|
error = v->server_set_cursor(v, 0, 0, cursor_data, cursor_mask);
|
|
|
|
|
}
|
|
|
|
|
free_stream(s);
|
|
|
|
|
free_stream(pixel_format);
|
|
|
|
|
if (error != 0)
|
|
|
|
|
{
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
v->sck = 0;
|
|
|
|
|
}
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
int lib_mod_invalidate(struct vnc* v, int x, int y, int cx, int cy)
|
|
|
|
|
{
|
|
|
|
|
struct stream* s;
|
|
|
|
|
|
|
|
|
|
make_stream(s);
|
|
|
|
|
/* FrambufferUpdateRequest */
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
out_uint8(s, 3);
|
|
|
|
|
out_uint8(s, 0);
|
|
|
|
|
out_uint16_be(s, x);
|
|
|
|
|
out_uint16_be(s, y);
|
|
|
|
|
out_uint16_be(s, cx);
|
|
|
|
|
out_uint16_be(s, cy);
|
|
|
|
|
if (g_tcp_force_send(v->sck, s->data, 10) != 0)
|
|
|
|
|
{
|
|
|
|
|
free_stream(s);
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
v->sck = 0;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
free_stream(s);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
int lib_mod_end(struct vnc* v)
|
|
|
|
|
{
|
|
|
|
@ -924,12 +900,11 @@ int mod_init()
|
|
|
|
|
v = (struct vnc*)g_malloc(sizeof(struct vnc), 1);
|
|
|
|
|
/* set client functions */
|
|
|
|
|
v->size = sizeof(struct vnc);
|
|
|
|
|
v->handle = (int)v;
|
|
|
|
|
v->handle = (long)v;
|
|
|
|
|
v->mod_connect = lib_mod_connect;
|
|
|
|
|
v->mod_start = lib_mod_start;
|
|
|
|
|
v->mod_event = lib_mod_event;
|
|
|
|
|
v->mod_signal = lib_mod_signal;
|
|
|
|
|
v->mod_invalidate = lib_mod_invalidate;
|
|
|
|
|
v->mod_end = lib_mod_end;
|
|
|
|
|
v->mod_set_param = lib_mod_set_param;
|
|
|
|
|
return (int)v;
|
|
|
|
@ -939,7 +914,9 @@ int mod_init()
|
|
|
|
|
int mod_exit(struct vnc* v)
|
|
|
|
|
{
|
|
|
|
|
if (v == 0)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
g_free(v);
|
|
|
|
|
return 0;
|
|
|
|
|