Add an mstsc (remote desktop client) which is based on the GPL WinRDesktop.

It's a VS project at the moment, not yet converted to be buildable via rbuild, and still pretty incomplete.

svn path=/trunk/; revision=30094
This commit is contained in:
Ged Murphy 2007-11-03 22:02:59 +00:00
parent 1477901eb4
commit 782962b8cf
43 changed files with 15624 additions and 0 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,838 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Generics backingstore operations
Copyright (C) Jay Sorg 2005-2006
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdlib.h>
#include <string.h>
#include "bsops.h"
/* globals */
static char * g_bs = 0;
static int g_bs_size = 0;
static int g_width = 800;
static int g_height = 600;
static int g_bpp = 8;
static int g_Bpp = 1;
static int g_clip_left = 0;
static int g_clip_top = 0;
static int g_clip_right = 800;
static int g_clip_bottom = 600;
/* for bs_patblt */
static unsigned char g_hatch_patterns[] =
{
0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0 - bsHorizontal */
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 1 - bsVertical */
0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, /* 2 - bsFDiagonal */
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, /* 3 - bsBDiagonal */
0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08, /* 4 - bsCross */
0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 /* 5 - bsDiagCross */
};
/*****************************************************************************/
/* do a raster op */
int
bs_do_rop(int rop, int src, int dst)
{
switch (rop)
{
case 0x0: return 0;
case 0x1: return ~(src | dst);
case 0x2: return (~src) & dst;
case 0x3: return ~src;
case 0x4: return src & (~dst);
case 0x5: return ~(dst);
case 0x6: return src ^ dst;
case 0x7: return ~(src & dst);
case 0x8: return src & dst;
case 0x9: return ~(src) ^ dst;
case 0xa: return dst;
case 0xb: return (~src) | dst;
case 0xc: return src;
case 0xd: return src | (~dst);
case 0xe: return src | dst;
case 0xf: return ~0;
}
return dst;
}
/*****************************************************************************/
/* get a pixel from the in memory copy of whats on the screen */
int
bs_get_pixel(int x, int y)
{
char * p;
if (x >= 0 && x < g_width && y >= 0 && y < g_height)
{
p = g_bs + (y * g_width * g_Bpp) + (x * g_Bpp);
if (g_Bpp == 1)
{
return *((unsigned char *) p);
}
else if (g_Bpp == 2)
{
return *((unsigned short *) p);
}
else
{
return *((unsigned int *) p);
}
}
else
{
return 0;
}
}
/*****************************************************************************/
/* set a pixel on the screen using the clip */
void
bs_set_pixel(int x, int y, int pixel, int rop, int use_clip)
{
char * p;
if (!use_clip ||
(x >= g_clip_left && x < g_clip_right &&
y >= g_clip_top && y < g_clip_bottom))
{
if (x >= 0 && x < g_width && y >= 0 && y < g_height)
{
p = g_bs + (y * g_width * g_Bpp) + (x * g_Bpp);
if (rop != 12)
{
pixel = bs_do_rop(rop, pixel, bs_get_pixel(x, y));
}
if (g_Bpp == 1)
{
*((unsigned char *) p) = pixel;
}
else if (g_Bpp == 2)
{
*((unsigned short *) p) = pixel;
}
else
{
*((unsigned int *) p) = pixel;
}
}
}
}
/*****************************************************************************/
static char *
get_bs_ptr(int x, int y)
{
char * p;
if (x >= 0 && x < g_width && y >= 0 && y < g_height)
{
p = g_bs + (y * g_width * g_Bpp) + (x * g_Bpp);
return p;
}
else
{
return 0;
}
}
/*****************************************************************************/
void
bs_init(int width, int height, int bpp)
{
if (g_bs != 0)
{
free(g_bs);
}
g_width = width;
g_height = height;
g_bpp = bpp;
g_Bpp = (bpp + 7) / 8;
g_bs_size = width * height * g_Bpp;
g_bs = malloc(g_bs_size);
memset(g_bs, 0, g_bs_size);
g_clip_left = 0;
g_clip_top = 0;
g_clip_right = width;
g_clip_bottom = height;
}
/*****************************************************************************/
void
bs_exit(void)
{
if (g_bs != 0)
{
free(g_bs);
}
}
/*****************************************************************************/
void
bs_set_clip(int x, int y, int cx, int cy)
{
g_clip_left = x;
g_clip_top = y;
g_clip_right = x + cx;
g_clip_bottom = y + cy;
}
/*****************************************************************************/
void
bs_reset_clip(void)
{
g_clip_left = 0;
g_clip_top = 0;
g_clip_right = g_width;
g_clip_bottom = g_height;
}
/*****************************************************************************/
/* check if a certain pixel is set in a bitmap */
int
bs_is_pixel_on(char * data, int x, int y, int width, int bpp)
{
int start;
int shift;
if (bpp == 1)
{
width = (width + 7) / 8;
start = (y * width) + x / 8;
shift = x % 8;
return (data[start] & (0x80 >> shift)) != 0;
}
else if (bpp == 8)
{
return data[y * width + x] != 0;
}
else if (bpp == 24)
{
return data[(y * 3) * width + (x * 3)] != 0 &&
data[(y * 3) * width + (x * 3) + 1] != 0 &&
data[(y * 3) * width + (x * 3) + 2] != 0;
}
else
{
return 0;
}
}
/*****************************************************************************/
void
bs_set_pixel_on(char * data, int x, int y, int width, int bpp,
int pixel)
{
int start;
int shift;
if (bpp == 1)
{
width = (width + 7) / 8;
start = (y * width) + x / 8;
shift = x % 8;
if (pixel != 0)
{
data[start] = data[start] | (0x80 >> shift);
}
else
{
data[start] = data[start] & ~(0x80 >> shift);
}
}
else if (bpp == 8)
{
data[y * width + x] = pixel;
}
else if (bpp == 15 || bpp == 16)
{
((unsigned short *) data)[y * width + x] = pixel;
}
}
/*****************************************************************************/
void
bs_copy_mem(char * d, char * s, int n)
{
while (n & (~7))
{
*(d++) = *(s++);
*(d++) = *(s++);
*(d++) = *(s++);
*(d++) = *(s++);
*(d++) = *(s++);
*(d++) = *(s++);
*(d++) = *(s++);
*(d++) = *(s++);
n = n - 8;
}
while (n > 0)
{
*(d++) = *(s++);
n--;
}
}
/*****************************************************************************/
void
bs_copy_memb(char * d, char * s, int n)
{
d = (d + n) - 1;
s = (s + n) - 1;
while (n & (~7))
{
*(d--) = *(s--);
*(d--) = *(s--);
*(d--) = *(s--);
*(d--) = *(s--);
*(d--) = *(s--);
*(d--) = *(s--);
*(d--) = *(s--);
*(d--) = *(s--);
n = n - 8;
}
while (n > 0)
{
*(d--) = *(s--);
n--;
}
}
/*****************************************************************************/
/* return true is the is something to draw */
int
bs_warp_coords(int * x, int * y, int * cx, int * cy,
int * srcx, int * srcy)
{
int dx;
int dy;
if (g_clip_left > *x)
{
dx = g_clip_left - *x;
}
else
{
dx = 0;
}
if (g_clip_top > *y)
{
dy = g_clip_top - *y;
}
else
{
dy = 0;
}
if (*x + *cx > g_clip_right)
{
*cx = (*cx - ((*x + *cx) - g_clip_right));
}
if (*y + *cy > g_clip_bottom)
{
*cy = (*cy - ((*y + *cy) - g_clip_bottom));
}
*cx = *cx - dx;
*cy = *cy - dy;
if (*cx <= 0)
{
return 0;
}
if (*cy <= 0)
{
return 0;
}
*x = *x + dx;
*y = *y + dy;
if (srcx != 0)
{
*srcx = *srcx + dx;
}
if (srcy != 0)
{
*srcy = *srcy + dy;
}
return 1;
}
/*****************************************************************************/
void
bs_rect(int x, int y, int cx, int cy, int colour, int rop)
{
int i;
int j;
unsigned char * p8;
unsigned short * p16;
unsigned int * p32;
if (bs_warp_coords(&x, &y, &cx, &cy, 0, 0))
{
if (rop == 0) /* black */
{
rop = 12;
colour = 0;
}
else if (rop == 15) /* white */
{
rop = 12;
colour = 0xffffff;
}
if (rop == 12) /* copy */
{
if (g_Bpp == 1)
{
for (i = 0; i < cy; i++)
{
p8 = (unsigned char *) get_bs_ptr(x, y + i);
if (p8 != 0)
{
for (j = 0; j < cx; j++)
{
*p8 = colour;
p8++;
}
}
}
}
else if (g_Bpp == 2)
{
for (i = 0; i < cy; i++)
{
p16 = (unsigned short *) get_bs_ptr(x, y + i);
if (p16 != 0)
{
for (j = 0; j < cx; j++)
{
*p16 = colour;
p16++;
}
}
}
}
else
{
for (i = 0; i < cy; i++)
{
p32 = (unsigned int *) get_bs_ptr(x, y + i);
if (p32 != 0)
{
for (j = 0; j < cx; j++)
{
*p32 = colour;
p32++;
}
}
}
}
}
else /* slow */
{
for (i = 0; i < cy; i++)
{
for (j = 0; j < cx; j++)
{
bs_set_pixel(j + x, i + y, colour, rop, 0);
}
}
}
}
}
/*****************************************************************************/
void
bs_screenblt(int rop, int x, int y, int cx, int cy,
int srcx, int srcy)
{
int p;
int i;
int j;
char * src;
char * dst;
if (bs_warp_coords(&x, &y, &cx, &cy, &srcx, &srcy))
{
if (rop == 12) /* copy */
{
if (srcy < y) /* copy down - bottom to top */
{
for (i = cy - 1; i >= 0; i--)
{
src = get_bs_ptr(srcx, srcy + i);
dst = get_bs_ptr(x, y + i);
if (src != 0 && dst != 0)
{
bs_copy_mem(dst, src, cx * g_Bpp);
}
}
}
else if (srcy > y || srcx > x) /* copy up or left - top to bottom */
{
for (i = 0; i < cy; i++)
{
src = get_bs_ptr(srcx, srcy + i);
dst = get_bs_ptr(x, y + i);
if (src != 0 && dst != 0)
{
bs_copy_mem(dst, src, cx * g_Bpp);
}
}
}
else /* copy straight right */
{
for (i = 0; i < cy; i++)
{
src = get_bs_ptr(srcx, srcy + i);
dst = get_bs_ptr(x, y + i);
if (src != 0 && dst != 0)
{
bs_copy_memb(dst, src, cx * g_Bpp);
}
}
}
}
else /* slow */
{
if (srcy < y) /* copy down - bottom to top */
{
for (i = cy - 1; i >= 0; i--)
{
for (j = 0; j < cx; j++)
{
p = bs_get_pixel(srcx + j, srcy + i);
bs_set_pixel(x + j, y + i, p, rop, 0);
}
}
}
else if (srcy > y || srcx > x) /* copy up or left - top to bottom */
{
for (i = 0; i < cy; i++)
{
for (j = 0; j < cx; j++)
{
p = bs_get_pixel(srcx + j, srcy + i);
bs_set_pixel(x + j, y + i, p, rop, 0);
}
}
}
else /* copy straight right */
{
for (i = 0; i < cy; i++)
{
for (j = cx - 1; j >= 0; j--)
{
p = bs_get_pixel(srcx + j, srcy + i);
bs_set_pixel(x + j, y + i, p, rop, 0);
}
}
}
}
}
}
/*****************************************************************************/
void
bs_memblt(int opcode, int x, int y, int cx, int cy,
void * srcdata, int srcwidth, int srcheight,
int srcx, int srcy)
{
int i;
int j;
int p;
char * dst;
char * src;
if (bs_warp_coords(&x, &y, &cx, &cy, &srcx, &srcy))
{
if (opcode == 12) /* copy */
{
if (g_Bpp == 1)
{
src = (char *) (((unsigned char *) srcdata) + srcy * srcwidth + srcx);
}
else if (g_Bpp == 2)
{
src = (char *) (((unsigned short *) srcdata) + srcy * srcwidth + srcx);
}
else
{
src = (char *) (((unsigned int *) srcdata) + srcy * srcwidth + srcx);
}
for (i = 0; i < cy; i++)
{
dst = get_bs_ptr(x, y + i);
if (dst != 0)
{
bs_copy_mem(dst, src, cx * g_Bpp);
src += srcwidth * g_Bpp;
}
}
}
else /* slow */
{
if (g_Bpp == 1)
{
for (i = 0; i < cy; i++)
{
for (j = 0; j < cx; j++)
{
p = *(((unsigned char *) srcdata) +
((i + srcy) * srcwidth + (j + srcx)));
bs_set_pixel(x + j, y + i, p, opcode, 0);
}
}
}
else if (g_Bpp == 2)
{
for (i = 0; i < cy; i++)
{
for (j = 0; j < cx; j++)
{
p = *(((unsigned short *) srcdata) +
((i + srcy) * srcwidth + (j + srcx)));
bs_set_pixel(x + j, y + i, p, opcode, 0);
}
}
}
else
{
for (i = 0; i < cy; i++)
{
for (j = 0; j < cx; j++)
{
p = *(((unsigned int *) srcdata) +
((i + srcy) * srcwidth + (j + srcx)));
bs_set_pixel(x + j, y + i, p, opcode, 0);
}
}
}
}
}
}
/*****************************************************************************/
void
bs_draw_glyph(int x, int y, char * glyph_data, int glyph_width,
int glyph_height, int fgcolour)
{
int i;
int j;
for (i = 0; i < glyph_height; i++)
{
for (j = 0; j < glyph_width; j++)
{
if (bs_is_pixel_on(glyph_data, j, i, glyph_width, 8))
{
bs_set_pixel(x + j, y + i, fgcolour, 12, 1);
}
}
}
}
/*****************************************************************************/
/* Bresenham's line drawing algorithm */
void
bs_line(int opcode, int startx, int starty, int endx, int endy,
int pen_width, int pen_style, int pen_colour)
{
int dx;
int dy;
int incx;
int incy;
int dpr;
int dpru;
int p;
if (startx > endx)
{
dx = startx - endx;
incx = -1;
}
else
{
dx = endx - startx;
incx = 1;
}
if (starty > endy)
{
dy = starty - endy;
incy = -1;
}
else
{
dy = endy - starty;
incy = 1;
}
if (dx >= dy)
{
dpr = dy << 1;
dpru = dpr - (dx << 1);
p = dpr - dx;
for (; dx >= 0; dx--)
{
if (startx != endx || starty != endy)
{
bs_set_pixel(startx, starty, pen_colour, opcode, 1);
}
if (p > 0)
{
startx += incx;
starty += incy;
p += dpru;
}
else
{
startx += incx;
p += dpr;
}
}
}
else
{
dpr = dx << 1;
dpru = dpr - (dy << 1);
p = dpr - dy;
for (; dy >= 0; dy--)
{
if (startx != endx || starty != endy)
{
bs_set_pixel(startx, starty, pen_colour, opcode, 1);
}
if (p > 0)
{
startx += incx;
starty += incy;
p += dpru;
}
else
{
starty += incy;
p += dpr;
}
}
}
}
/*****************************************************************************/
void
bs_patblt(int opcode, int x, int y, int cx, int cy,
int brush_style, char * brush_pattern,
int brush_x_org, int brush_y_org,
int bgcolour, int fgcolour)
{
int i;
int j;
char ipattern[8];
char * b;
b = 0;
switch (brush_style)
{
case 0:
bs_rect(x, y, cx, cy, fgcolour, opcode);
break;
case 2: /* Hatch */
b = g_hatch_patterns + brush_pattern[0] * 8;
break;
case 3:
for (i = 0; i < 8; i++)
{
ipattern[i] = ~brush_pattern[7 - i];
}
b = ipattern;
break;
}
if (b != 0)
{
for (i = 0; i < cy; i++)
{
for (j = 0; j < cx; j++)
{
if (bs_is_pixel_on(b, (x + j + brush_x_org) % 8,
(y + i + brush_y_org) % 8, 8, 1))
{
bs_set_pixel(x + j, y + i, fgcolour, opcode, 1);
}
else
{
bs_set_pixel(x + j, y + i, bgcolour, opcode, 1);
}
}
}
}
}
/*****************************************************************************/
void
bs_copy_box(char * dst, int x, int y, int cx, int cy, int line_size)
{
char * src;
int i;
/* shouldn't happen */
if (cx < 1 || cy < 1)
{
return;
}
/* nothing to draw, memset and leave */
if (x + cx < 0 || y + cy < 0 || x >= g_width || y >= g_height)
{
memset(dst, 0, cx * cy * g_Bpp);
return;
}
/* check if it goes over an edge */
if (x < 0 || y < 0 || x + cx > g_width || y + cy > g_height)
{
memset(dst, 0, cx * cy * g_Bpp);
if (x < 0)
{
cx += x;
dst += -x * g_Bpp;
x = 0;
}
if (x + cx > g_width)
{
cx = g_width - x;
}
for (i = 0; i < cy; i++)
{
src = get_bs_ptr(x, y + i);
if (src != 0)
{
bs_copy_mem(dst, src, cx * g_Bpp);
}
dst += line_size;
}
}
else /* whole box is within */
{
for (i = 0; i < cy; i++)
{
src = get_bs_ptr(x, y + i);
if (src != 0)
{
bs_copy_mem(dst, src, cx * g_Bpp);
}
dst += line_size;
}
}
}

View file

@ -0,0 +1,49 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Generics backingstore operations
Copyright (C) Jay Sorg 2005-2006
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
int bs_get_pixel(int x, int y);
void bs_set_pixel(int x, int y, int pixel, int rop, int use_clip);
int bs_do_rop(int rop, int src, int dst);
void bs_init(int width, int height, int bpp);
void bs_exit(void);
void bs_set_clip(int x, int y, int cx, int cy);
void bs_reset_clip(void);
void bs_set_pixel_on(char * data, int x, int y, int width, int bpp,
int pixel);
int bs_is_pixel_on(char * data, int x, int y, int width, int bpp);
void bs_copy_mem(char * d, char * s, int n);
void bs_copy_memb(char * d, char * s, int n);
int bs_warp_coords(int * x, int * y, int * cx, int * cy,
int * srcx, int * srcy);
void bs_rect(int x, int y, int cx, int cy, int colour, int rop);
void bs_screenblt(int opcode, int x, int y, int cx, int cy,
int srcx, int srcy);
void bs_memblt(int opcode, int x, int y, int cx, int cy,
void * srcdata, int srcwidth, int srcheight,
int srcx, int srcy);
void bs_copy_box(char * dst, int x, int y, int cx, int cy, int line_size);
void bs_draw_glyph(int x, int y, char * glyph_data, int glyph_width,
int glyph_height, int fgcolour);
void bs_line(int opcode, int startx, int starty, int endx, int endy,
int pen_width, int pen_style, int pen_colour);
void bs_patblt(int opcode, int x, int y, int cx, int cy,
int brush_style, char * brush_pattern,
int brush_x_org, int brush_y_org,
int bgcolour, int fgcolour);

View file

@ -0,0 +1,432 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Cache routines
Copyright (C) Matthew Chapman 1999-2005
Copyright (C) Jeroen Meijer 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
/* BITMAP CACHE */
extern int g_pstcache_fd[];
#define NUM_ELEMENTS(array) (sizeof(array) / sizeof(array[0]))
#define IS_PERSISTENT(id) (g_pstcache_fd[id] > 0)
#define TO_TOP -1
#define NOT_SET -1
#define IS_SET(idx) (idx >= 0)
/*
* TODO: Test for optimal value of BUMP_COUNT. TO_TOP gives lowest cpu utilisation but using
* a positive value will hopefully result in less frequently used bitmaps having a greater chance
* of being evicted from the cache, and therby reducing the need to load bitmaps from disk.
* (Jeroen)
*/
#define BUMP_COUNT 40
struct bmpcache_entry
{
RD_HBITMAP bitmap;
sint16 previous;
sint16 next;
};
static struct bmpcache_entry g_bmpcache[3][0xa00];
static RD_HBITMAP g_volatile_bc[3];
static int g_bmpcache_lru[3] = { NOT_SET, NOT_SET, NOT_SET };
static int g_bmpcache_mru[3] = { NOT_SET, NOT_SET, NOT_SET };
static int g_bmpcache_count[3];
/* Setup the bitmap cache lru/mru linked list */
void
cache_rebuild_bmpcache_linked_list(uint8 id, sint16 * idx, int count)
{
int n = count, c = 0;
sint16 n_idx;
/* find top, skip evicted bitmaps */
while (--n >= 0 && g_bmpcache[id][idx[n]].bitmap == NULL);
if (n < 0)
{
g_bmpcache_mru[id] = g_bmpcache_lru[id] = NOT_SET;
return;
}
g_bmpcache_mru[id] = idx[n];
g_bmpcache[id][idx[n]].next = NOT_SET;
n_idx = idx[n];
c++;
/* link list */
while (n >= 0)
{
/* skip evicted bitmaps */
while (--n >= 0 && g_bmpcache[id][idx[n]].bitmap == NULL);
if (n < 0)
break;
g_bmpcache[id][n_idx].previous = idx[n];
g_bmpcache[id][idx[n]].next = n_idx;
n_idx = idx[n];
c++;
}
g_bmpcache[id][n_idx].previous = NOT_SET;
g_bmpcache_lru[id] = n_idx;
if (c != g_bmpcache_count[id])
{
error("Oops. %d in bitmap cache linked list, %d in ui cache...\n", c,
g_bmpcache_count[id]);
exit(1);
}
}
/* Move a bitmap to a new position in the linked list. */
void
cache_bump_bitmap(uint8 id, uint16 idx, int bump)
{
int p_idx, n_idx, n;
if (!IS_PERSISTENT(id))
return;
if (g_bmpcache_mru[id] == idx)
return;
DEBUG_RDP5(("bump bitmap: id=%d, idx=%d, bump=%d\n", id, idx, bump));
n_idx = g_bmpcache[id][idx].next;
p_idx = g_bmpcache[id][idx].previous;
if (IS_SET(n_idx))
{
/* remove */
--g_bmpcache_count[id];
if (IS_SET(p_idx))
g_bmpcache[id][p_idx].next = n_idx;
else
g_bmpcache_lru[id] = n_idx;
if (IS_SET(n_idx))
g_bmpcache[id][n_idx].previous = p_idx;
else
g_bmpcache_mru[id] = p_idx;
}
else
{
p_idx = NOT_SET;
n_idx = g_bmpcache_lru[id];
}
if (bump >= 0)
{
for (n = 0; n < bump && IS_SET(n_idx); n++)
{
p_idx = n_idx;
n_idx = g_bmpcache[id][p_idx].next;
}
}
else
{
p_idx = g_bmpcache_mru[id];
n_idx = NOT_SET;
}
/* insert */
++g_bmpcache_count[id];
g_bmpcache[id][idx].previous = p_idx;
g_bmpcache[id][idx].next = n_idx;
if (p_idx >= 0)
g_bmpcache[id][p_idx].next = idx;
else
g_bmpcache_lru[id] = idx;
if (n_idx >= 0)
g_bmpcache[id][n_idx].previous = idx;
else
g_bmpcache_mru[id] = idx;
}
/* Evict the least-recently used bitmap from the cache */
void
cache_evict_bitmap(uint8 id)
{
uint16 idx;
int n_idx;
if (!IS_PERSISTENT(id))
return;
idx = g_bmpcache_lru[id];
n_idx = g_bmpcache[id][idx].next;
DEBUG_RDP5(("evict bitmap: id=%d idx=%d n_idx=%d bmp=0x%x\n", id, idx, n_idx,
g_bmpcache[id][idx].bitmap));
ui_destroy_bitmap(g_bmpcache[id][idx].bitmap);
--g_bmpcache_count[id];
g_bmpcache[id][idx].bitmap = 0;
g_bmpcache_lru[id] = n_idx;
g_bmpcache[id][n_idx].previous = NOT_SET;
pstcache_touch_bitmap(id, idx, 0);
}
/* Retrieve a bitmap from the cache */
RD_HBITMAP
cache_get_bitmap(uint8 id, uint16 idx)
{
if ((id < NUM_ELEMENTS(g_bmpcache)) && (idx < NUM_ELEMENTS(g_bmpcache[0])))
{
if (g_bmpcache[id][idx].bitmap || pstcache_load_bitmap(id, idx))
{
if (IS_PERSISTENT(id))
cache_bump_bitmap(id, idx, BUMP_COUNT);
return g_bmpcache[id][idx].bitmap;
}
}
else if ((id < NUM_ELEMENTS(g_volatile_bc)) && (idx == 0x7fff))
{
return g_volatile_bc[id];
}
error("get bitmap %d:%d\n", id, idx);
return NULL;
}
/* Store a bitmap in the cache */
void
cache_put_bitmap(uint8 id, uint16 idx, RD_HBITMAP bitmap)
{
RD_HBITMAP old;
if ((id < NUM_ELEMENTS(g_bmpcache)) && (idx < NUM_ELEMENTS(g_bmpcache[0])))
{
old = g_bmpcache[id][idx].bitmap;
if (old != NULL)
ui_destroy_bitmap(old);
g_bmpcache[id][idx].bitmap = bitmap;
if (IS_PERSISTENT(id))
{
if (old == NULL)
g_bmpcache[id][idx].previous = g_bmpcache[id][idx].next = NOT_SET;
cache_bump_bitmap(id, idx, TO_TOP);
if (g_bmpcache_count[id] > BMPCACHE2_C2_CELLS)
cache_evict_bitmap(id);
}
}
else if ((id < NUM_ELEMENTS(g_volatile_bc)) && (idx == 0x7fff))
{
old = g_volatile_bc[id];
if (old != NULL)
ui_destroy_bitmap(old);
g_volatile_bc[id] = bitmap;
}
else
{
error("put bitmap %d:%d\n", id, idx);
}
}
/* Updates the persistent bitmap cache MRU information on exit */
void
cache_save_state(void)
{
uint32 id = 0, t = 0;
int idx;
for (id = 0; id < NUM_ELEMENTS(g_bmpcache); id++)
if (IS_PERSISTENT(id))
{
DEBUG_RDP5(("Saving cache state for bitmap cache %d...", id));
idx = g_bmpcache_lru[id];
while (idx >= 0)
{
pstcache_touch_bitmap((uint8) id, (uint16) idx, ++t);
idx = g_bmpcache[id][idx].next;
}
DEBUG_RDP5((" %d stamps written.\n", t));
}
}
/* FONT CACHE */
static FONTGLYPH g_fontcache[12][256];
/* Retrieve a glyph from the font cache */
FONTGLYPH *
cache_get_font(uint8 font, uint16 character)
{
FONTGLYPH *glyph;
if ((font < NUM_ELEMENTS(g_fontcache)) && (character < NUM_ELEMENTS(g_fontcache[0])))
{
glyph = &g_fontcache[font][character];
if (glyph->pixmap != NULL)
return glyph;
}
error("get font %d:%d\n", font, character);
return NULL;
}
/* Store a glyph in the font cache */
void
cache_put_font(uint8 font, uint16 character, uint16 offset,
uint16 baseline, uint16 width, uint16 height, RD_HGLYPH pixmap)
{
FONTGLYPH *glyph;
if ((font < NUM_ELEMENTS(g_fontcache)) && (character < NUM_ELEMENTS(g_fontcache[0])))
{
glyph = &g_fontcache[font][character];
if (glyph->pixmap != NULL)
ui_destroy_glyph(glyph->pixmap);
glyph->offset = offset;
glyph->baseline = baseline;
glyph->width = width;
glyph->height = height;
glyph->pixmap = pixmap;
}
else
{
error("put font %d:%d\n", font, character);
}
}
/* TEXT CACHE */
static DATABLOB g_textcache[256];
/* Retrieve a text item from the cache */
DATABLOB *
cache_get_text(uint8 cache_id)
{
DATABLOB *text;
text = &g_textcache[cache_id];
return text;
}
/* Store a text item in the cache */
void
cache_put_text(uint8 cache_id, void *data, int length)
{
DATABLOB *text;
text = &g_textcache[cache_id];
if (text->data != NULL)
xfree(text->data);
text->data = xmalloc(length);
text->size = length;
memcpy(text->data, data, length);
}
/* DESKTOP CACHE */
static uint8 g_deskcache[0x38400 * 4];
/* Retrieve desktop data from the cache */
uint8 *
cache_get_desktop(uint32 offset, int cx, int cy, int bytes_per_pixel)
{
int length = cx * cy * bytes_per_pixel;
if (offset > sizeof(g_deskcache))
offset = 0;
if ((offset + length) <= sizeof(g_deskcache))
{
return &g_deskcache[offset];
}
error("get desktop %d:%d\n", offset, length);
return NULL;
}
/* Store desktop data in the cache */
void
cache_put_desktop(uint32 offset, int cx, int cy, int scanline, int bytes_per_pixel, uint8 * data)
{
int length = cx * cy * bytes_per_pixel;
if (offset > sizeof(g_deskcache))
offset = 0;
if ((offset + length) <= sizeof(g_deskcache))
{
cx *= bytes_per_pixel;
while (cy--)
{
memcpy(&g_deskcache[offset], data, cx);
data += scanline;
offset += cx;
}
}
else
{
error("put desktop %d:%d\n", offset, length);
}
}
/* CURSOR CACHE */
static RD_HCURSOR g_cursorcache[0x20];
/* Retrieve cursor from cache */
RD_HCURSOR
cache_get_cursor(uint16 cache_idx)
{
RD_HCURSOR cursor;
if (cache_idx < NUM_ELEMENTS(g_cursorcache))
{
cursor = g_cursorcache[cache_idx];
if (cursor != NULL)
return cursor;
}
error("get cursor %d\n", cache_idx);
return NULL;
}
/* Store cursor in cache */
void
cache_put_cursor(uint16 cache_idx, RD_HCURSOR cursor)
{
RD_HCURSOR old;
if (cache_idx < NUM_ELEMENTS(g_cursorcache))
{
old = g_cursorcache[cache_idx];
if (old != NULL)
ui_destroy_cursor(old);
g_cursorcache[cache_idx] = cursor;
}
else
{
error("put cursor %d\n", cache_idx);
}
}

View file

@ -0,0 +1,181 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Protocol services - Virtual channels
Copyright (C) Erik Forsberg <forsberg@cendio.se> 2003
Copyright (C) Matthew Chapman 2003-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
#define MAX_CHANNELS 6
#define CHANNEL_CHUNK_LENGTH 1600
#define CHANNEL_FLAG_FIRST 0x01
#define CHANNEL_FLAG_LAST 0x02
#define CHANNEL_FLAG_SHOW_PROTOCOL 0x10
extern BOOL g_use_rdp5;
extern BOOL g_encryption;
VCHANNEL g_channels[MAX_CHANNELS];
unsigned int g_num_channels;
/* FIXME: We should use the information in TAG_SRV_CHANNELS to map RDP5
channels to MCS channels.
The format of TAG_SRV_CHANNELS seems to be
global_channel_no (uint16le)
number_of_other_channels (uint16le)
..followed by uint16les for the other channels.
*/
VCHANNEL *
channel_register(char *name, uint32 flags, void (*callback) (STREAM))
{
VCHANNEL *channel;
if (!g_use_rdp5)
return NULL;
if (g_num_channels >= MAX_CHANNELS)
{
error("Channel table full, increase MAX_CHANNELS\n");
return NULL;
}
channel = &g_channels[g_num_channels];
channel->mcs_id = MCS_GLOBAL_CHANNEL + 1 + g_num_channels;
strncpy(channel->name, name, 8);
channel->flags = flags;
channel->process = callback;
g_num_channels++;
return channel;
}
STREAM
channel_init(VCHANNEL * channel, uint32 length)
{
STREAM s;
s = sec_init(g_encryption ? SEC_ENCRYPT : 0, length + 8);
s_push_layer(s, channel_hdr, 8);
return s;
}
void
channel_send(STREAM s, VCHANNEL * channel)
{
uint32 length, flags;
uint32 thislength, remaining;
uint8 *data;
/* 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;
}
}
void
channel_process(STREAM s, uint16 mcs_channel)
{
uint32 length, flags;
uint32 thislength;
VCHANNEL *channel = NULL;
unsigned int i;
STREAM in;
for (i = 0; i < g_num_channels; i++)
{
channel = &g_channels[i];
if (channel->mcs_id == mcs_channel)
break;
}
if (i >= g_num_channels)
return;
in_uint32_le(s, length);
in_uint32_le(s, flags);
if ((flags & CHANNEL_FLAG_FIRST) && (flags & CHANNEL_FLAG_LAST))
{
/* single fragment - pass straight up */
channel->process(s);
}
else
{
/* add fragment to defragmentation buffer */
in = &channel->in;
if (flags & CHANNEL_FLAG_FIRST)
{
if (length > in->size)
{
in->data = (uint8 *) xrealloc(in->data, length);
in->size = length;
}
in->p = in->data;
}
thislength = MIN(s->end - s->p, in->data + in->size - in->p);
memcpy(in->p, s->p, thislength);
in->p += thislength;
if (flags & CHANNEL_FLAG_LAST)
{
in->end = in->p;
in->p = in->data;
channel->process(in);
}
}
}

View file

@ -0,0 +1,439 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Connection settings dialog
Copyright (C) Ged Murphy 2007
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <windows.h>
#include <commctrl.h>
#include "resource.h"
typedef struct _INFO
{
HWND hSelf;
HWND hTab;
HWND hGeneralPage;
HWND hDisplayPage;
HBITMAP hHeader;
BITMAP headerbitmap;
} INFO, *PINFO;
HINSTANCE hInst;
void OnTabWndSelChange(PINFO pInfo)
{
switch (TabCtrl_GetCurSel(pInfo->hTab))
{
case 0: //General
ShowWindow(pInfo->hGeneralPage, SW_SHOW);
ShowWindow(pInfo->hDisplayPage, SW_HIDE);
BringWindowToTop(pInfo->hGeneralPage);
break;
case 1: //Display
ShowWindow(pInfo->hGeneralPage, SW_HIDE);
ShowWindow(pInfo->hDisplayPage, SW_SHOW);
BringWindowToTop(pInfo->hDisplayPage);
break;
}
}
INT_PTR CALLBACK
GeneralDlgProc(HWND hDlg,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
static HICON hLogon, hConn;
HWND hParent = GetParent(hDlg);
PINFO pInfo = (PINFO)GetWindowLongPtr(hParent,
GWLP_USERDATA);
switch (message)
{
case WM_INITDIALOG:
{
SetWindowPos(hDlg,
NULL,
15,
122,
0,
0,
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
hLogon = LoadImage(hInst,
MAKEINTRESOURCE(IDI_LOGON),
IMAGE_ICON,
32,
32,
LR_DEFAULTCOLOR);
if (hLogon)
{
SendDlgItemMessage(hDlg,
IDC_LOGONICON,
STM_SETICON,
(WPARAM)hLogon,
0);
}
hConn = LoadImage(hInst,
MAKEINTRESOURCE(IDI_CONN),
IMAGE_ICON,
32,
32,
LR_DEFAULTCOLOR);
if (hConn)
{
SendDlgItemMessage(hDlg,
IDC_CONNICON,
STM_SETICON,
(WPARAM)hConn,
0);
}
return TRUE;
}
case WM_CLOSE:
{
if (hLogon)
DestroyIcon(hLogon);
if (hConn)
DestroyIcon(hConn);
break;
}
}
return 0;
}
INT_PTR CALLBACK
DisplayDlgProc(HWND hDlg,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
static HICON hRemote, hColor;
static HBITMAP hSpectrum;
static BITMAP bitmap;
PINFO pInfo = (PINFO)GetWindowLongPtr(GetParent(hDlg),
GWLP_USERDATA);
switch (message)
{
case WM_INITDIALOG:
{
SetWindowPos(hDlg,
NULL,
15,
122,
0,
0,
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
hRemote = LoadImage(hInst,
MAKEINTRESOURCE(IDI_REMOTE),
IMAGE_ICON,
32,
32,
LR_DEFAULTCOLOR);
if (hRemote)
{
SendDlgItemMessage(hDlg,
IDC_REMICON,
STM_SETICON,
(WPARAM)hRemote,
0);
}
hColor = LoadImage(hInst,
MAKEINTRESOURCE(IDI_COLORS),
IMAGE_ICON,
32,
32,
LR_DEFAULTCOLOR);
if (hColor)
{
SendDlgItemMessage(hDlg,
IDC_COLORSICON,
STM_SETICON,
(WPARAM)hColor,
0);
}
hSpectrum = LoadImage(hInst,
MAKEINTRESOURCE(IDB_SPECT),
IMAGE_BITMAP,
0,
0,
LR_DEFAULTCOLOR);
if (hSpectrum)
{
GetObject(hSpectrum, sizeof(BITMAP), &bitmap);
}
return TRUE;
}
case WM_DRAWITEM:
{
LPDRAWITEMSTRUCT lpDrawItem;
lpDrawItem = (LPDRAWITEMSTRUCT) lParam;
if(lpDrawItem->CtlID == IDC_COLORIMAGE)
{
HDC hdcMem;
hdcMem = CreateCompatibleDC(lpDrawItem->hDC);
if (hdcMem != NULL)
{
SelectObject(hdcMem, hSpectrum);
StretchBlt(lpDrawItem->hDC,
lpDrawItem->rcItem.left,
lpDrawItem->rcItem.top,
lpDrawItem->rcItem.right - lpDrawItem->rcItem.left,
lpDrawItem->rcItem.bottom - lpDrawItem->rcItem.top,
hdcMem,
0,
0,
bitmap.bmWidth,
bitmap.bmHeight,
SRCCOPY);
DeleteDC(hdcMem);
}
}
break;
}
case WM_CLOSE:
{
if (hRemote)
DestroyIcon(hRemote);
if (hColor)
DestroyIcon(hColor);
if (hSpectrum)
DeleteObject(hSpectrum);
break;
}
break;
}
return 0;
}
static BOOL
OnCreate(HWND hwnd)
{
PINFO pInfo;
TCITEM item;
BOOL bRet = FALSE;
pInfo = HeapAlloc(GetProcessHeap(),
0,
sizeof(INFO));
if (pInfo)
{
SetWindowLongPtr(hwnd,
GWLP_USERDATA,
(LONG_PTR)pInfo);
pInfo->hHeader = LoadImage(hInst,
MAKEINTRESOURCE(IDB_HEADER),
IMAGE_BITMAP,
0,
0,
LR_DEFAULTCOLOR);
if (pInfo->hHeader)
{
GetObject(pInfo->hHeader, sizeof(BITMAP), &pInfo->headerbitmap);
}
pInfo->hTab = GetDlgItem(hwnd, IDC_TAB);
if (pInfo->hTab)
{
pInfo->hGeneralPage = CreateDialog(hInst,
MAKEINTRESOURCE(IDD_GENERAL),
hwnd,
(DLGPROC)GeneralDlgProc);
if (pInfo->hGeneralPage)
{
char str[256];
LoadString(hInst, IDS_TAB_GENERAL, str, 256);
ZeroMemory(&item, sizeof(TCITEM));
item.mask = TCIF_TEXT;
item.pszText = str;
item.cchTextMax = 256;
(void)TabCtrl_InsertItem(pInfo->hTab, 0, &item);
}
pInfo->hDisplayPage = CreateDialog(hInst,
MAKEINTRESOURCE(IDD_DISPLAY),
hwnd,
(DLGPROC)DisplayDlgProc);
if (pInfo->hDisplayPage)
{
char str[256];
LoadString(hInst, IDS_TAB_DISPLAY, str, 256);
ZeroMemory(&item, sizeof(TCITEM));
item.mask = TCIF_TEXT;
item.pszText = str;
item.cchTextMax = 256;
(void)TabCtrl_InsertItem(pInfo->hTab, 1, &item);
}
OnTabWndSelChange(pInfo);
bRet = TRUE;
}
}
return bRet;
}
static BOOL CALLBACK
DlgProc(HWND hDlg,
UINT Message,
WPARAM wParam,
LPARAM lParam)
{
PINFO pInfo;
/* Get the window context */
pInfo = (PINFO)GetWindowLongPtr(hDlg,
GWLP_USERDATA);
if (pInfo == NULL && Message != WM_INITDIALOG)
{
goto HandleDefaultMessage;
}
switch(Message)
{
case WM_INITDIALOG:
OnCreate(hDlg);
break;
case WM_COMMAND:
{
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
if (pInfo)
{
HeapFree(GetProcessHeap(),
0,
pInfo);
}
EndDialog(hDlg, LOWORD(wParam));
}
switch(LOWORD(wParam))
{
break;
}
break;
}
case WM_NOTIFY:
{
INT idctrl;
LPNMHDR pnmh;
idctrl = (int)wParam;
pnmh = (LPNMHDR)lParam;
if (//(pnmh->hwndFrom == pInfo->hSelf) &&
(pnmh->idFrom == IDC_TAB) &&
(pnmh->code == TCN_SELCHANGE))
{
OnTabWndSelChange(pInfo);
}
break;
}
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc, hdcMem;
hdc = BeginPaint(hDlg, &ps);
if (hdc != NULL)
{
HDC hdcMem = CreateCompatibleDC(hdc);
if (hdcMem)
{
SelectObject(hdcMem, pInfo->hHeader);
BitBlt(hdc,
0,
0,
pInfo->headerbitmap.bmWidth,
pInfo->headerbitmap.bmHeight,
hdcMem,
0,
0,
SRCCOPY);
DeleteDC(hdcMem);
}
EndPaint(hDlg, &ps);
}
break;
}
case WM_CLOSE:
{
if (pInfo)
HeapFree(GetProcessHeap(),
0,
pInfo);
EndDialog(hDlg, 0);
}
break;
HandleDefaultMessage:
default:
return FALSE;
}
return FALSE;
}
BOOL
OpenRDPConnectDialog(HINSTANCE hInstance)
{
INITCOMMONCONTROLSEX iccx;
hInst = hInstance;
iccx.dwSize = sizeof(INITCOMMONCONTROLSEX);
iccx.dwICC = ICC_TAB_CLASSES;
InitCommonControlsEx(&iccx);
return (DialogBox(hInst,
MAKEINTRESOURCE(IDD_CONNECTDIALOG),
NULL,
(DLGPROC)DlgProc) == IDOK);
}

View file

@ -0,0 +1,435 @@
/*
rdesktop: A Remote Desktop Protocol client.
Miscellaneous protocol constants
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* TCP port for Remote Desktop Protocol */
#define TCP_PORT_RDP 3389
#define DEFAULT_CODEPAGE "UTF-8"
#define WINDOWS_CODEPAGE "UTF-16LE"
/* ISO PDU codes */
enum ISO_PDU_CODE
{
ISO_PDU_CR = 0xE0, /* Connection Request */
ISO_PDU_CC = 0xD0, /* Connection Confirm */
ISO_PDU_DR = 0x80, /* Disconnect Request */
ISO_PDU_DT = 0xF0, /* Data */
ISO_PDU_ER = 0x70 /* Error */
};
/* MCS PDU codes */
enum MCS_PDU_TYPE
{
MCS_EDRQ = 1, /* Erect Domain Request */
MCS_DPUM = 8, /* Disconnect Provider Ultimatum */
MCS_AURQ = 10, /* Attach User Request */
MCS_AUCF = 11, /* Attach User Confirm */
MCS_CJRQ = 14, /* Channel Join Request */
MCS_CJCF = 15, /* Channel Join Confirm */
MCS_SDRQ = 25, /* Send Data Request */
MCS_SDIN = 26 /* Send Data Indication */
};
#define MCS_CONNECT_INITIAL 0x7f65
#define MCS_CONNECT_RESPONSE 0x7f66
#define BER_TAG_BOOLEAN 1
#define BER_TAG_INTEGER 2
#define BER_TAG_OCTET_STRING 4
#define BER_TAG_RESULT 10
#define MCS_TAG_DOMAIN_PARAMS 0x30
#define MCS_GLOBAL_CHANNEL 1003
#define MCS_USERCHANNEL_BASE 1001
/* RDP secure transport constants */
#define SEC_RANDOM_SIZE 32
#define SEC_MODULUS_SIZE 64
#define SEC_PADDING_SIZE 8
#define SEC_EXPONENT_SIZE 4
#define SEC_CLIENT_RANDOM 0x0001
#define SEC_ENCRYPT 0x0008
#define SEC_LOGON_INFO 0x0040
#define SEC_LICENCE_NEG 0x0080
#define SEC_REDIRECT_ENCRYPT 0x0C00
#define SEC_TAG_SRV_INFO 0x0c01
#define SEC_TAG_SRV_CRYPT 0x0c02
#define SEC_TAG_SRV_CHANNELS 0x0c03
#define SEC_TAG_CLI_INFO 0xc001
#define SEC_TAG_CLI_CRYPT 0xc002
#define SEC_TAG_CLI_CHANNELS 0xc003
#define SEC_TAG_CLI_4 0xc004
#define SEC_TAG_PUBKEY 0x0006
#define SEC_TAG_KEYSIG 0x0008
#define SEC_RSA_MAGIC 0x31415352 /* RSA1 */
/* RDP licensing constants */
#define LICENCE_TOKEN_SIZE 10
#define LICENCE_HWID_SIZE 20
#define LICENCE_SIGNATURE_SIZE 16
#define LICENCE_TAG_DEMAND 0x01
#define LICENCE_TAG_AUTHREQ 0x02
#define LICENCE_TAG_ISSUE 0x03
#define LICENCE_TAG_REISSUE 0x04
#define LICENCE_TAG_PRESENT 0x12
#define LICENCE_TAG_REQUEST 0x13
#define LICENCE_TAG_AUTHRESP 0x15
#define LICENCE_TAG_RESULT 0xff
#define LICENCE_TAG_USER 0x000f
#define LICENCE_TAG_HOST 0x0010
/* RDP PDU codes */
enum RDP_PDU_TYPE
{
RDP_PDU_DEMAND_ACTIVE = 1,
RDP_PDU_CONFIRM_ACTIVE = 3,
RDP_PDU_REDIRECT = 4, /* MS Server 2003 Session Redirect */
RDP_PDU_DEACTIVATE = 6,
RDP_PDU_DATA = 7
};
enum RDP_DATA_PDU_TYPE
{
RDP_DATA_PDU_UPDATE = 2,
RDP_DATA_PDU_CONTROL = 20,
RDP_DATA_PDU_POINTER = 27,
RDP_DATA_PDU_INPUT = 28,
RDP_DATA_PDU_SYNCHRONISE = 31,
RDP_DATA_PDU_BELL = 34,
RDP_DATA_PDU_CLIENT_WINDOW_STATUS = 35,
RDP_DATA_PDU_LOGON = 38,
RDP_DATA_PDU_FONT2 = 39,
RDP_DATA_PDU_KEYBOARD_INDICATORS = 41,
RDP_DATA_PDU_DISCONNECT = 47
};
enum RDP_CONTROL_PDU_TYPE
{
RDP_CTL_REQUEST_CONTROL = 1,
RDP_CTL_GRANT_CONTROL = 2,
RDP_CTL_DETACH = 3,
RDP_CTL_COOPERATE = 4
};
enum RDP_UPDATE_PDU_TYPE
{
RDP_UPDATE_ORDERS = 0,
RDP_UPDATE_BITMAP = 1,
RDP_UPDATE_PALETTE = 2,
RDP_UPDATE_SYNCHRONIZE = 3
};
enum RDP_POINTER_PDU_TYPE
{
RDP_POINTER_SYSTEM = 1,
RDP_POINTER_MOVE = 3,
RDP_POINTER_COLOR = 6,
RDP_POINTER_CACHED = 7
};
enum RDP_SYSTEM_POINTER_TYPE
{
RDP_NULL_POINTER = 0,
RDP_DEFAULT_POINTER = 0x7F00
};
enum RDP_INPUT_DEVICE
{
RDP_INPUT_SYNCHRONIZE = 0,
RDP_INPUT_CODEPOINT = 1,
RDP_INPUT_VIRTKEY = 2,
RDP_INPUT_SCANCODE = 4,
RDP_INPUT_MOUSE = 0x8001
};
/* Device flags */
#define KBD_FLAG_RIGHT 0x0001
#define KBD_FLAG_EXT 0x0100
#define KBD_FLAG_QUIET 0x1000
#define KBD_FLAG_DOWN 0x4000
#define KBD_FLAG_UP 0x8000
/* These are for synchronization; not for keystrokes */
#define KBD_FLAG_SCROLL 0x0001
#define KBD_FLAG_NUMLOCK 0x0002
#define KBD_FLAG_CAPITAL 0x0004
/* See T.128 */
#define RDP_KEYPRESS 0
#define RDP_KEYRELEASE (KBD_FLAG_DOWN | KBD_FLAG_UP)
#define MOUSE_FLAG_MOVE 0x0800
#define MOUSE_FLAG_BUTTON1 0x1000
#define MOUSE_FLAG_BUTTON2 0x2000
#define MOUSE_FLAG_BUTTON3 0x4000
#define MOUSE_FLAG_BUTTON4 0x0280
#define MOUSE_FLAG_BUTTON5 0x0380
#define MOUSE_FLAG_DOWN 0x8000
/* Raster operation masks */
#define ROP2_S(rop3) ((uint8) (rop3 & 0xf))
#define ROP2_P(rop3) ((uint8) ((rop3 & 0x3) | ((rop3 & 0x30) >> 2)))
#define ROP_MINUS_1(rop) ((uint8) (rop - 1))
#define ROP2_COPY 0xc
#define ROP2_XOR 0x6
#define ROP2_AND 0x8
#define ROP2_NXOR 0x9
#define ROP2_OR 0xe
#define MIX_TRANSPARENT 0
#define MIX_OPAQUE 1
#define TEXT2_VERTICAL 0x04
#define TEXT2_IMPLICIT_X 0x20
#define ALTERNATE 1
#define WINDING 2
/* RDP bitmap cache (version 2) constants */
#define BMPCACHE2_C0_CELLS 0x78
#define BMPCACHE2_C1_CELLS 0x78
#define BMPCACHE2_C2_CELLS 0x150
#define BMPCACHE2_NUM_PSTCELLS 0x9f6
#define PDU_FLAG_FIRST 0x01
#define PDU_FLAG_LAST 0x02
/* RDP capabilities */
#define RDP_CAPSET_GENERAL 1 /* Maps to generalCapabilitySet in T.128 page 138 */
#define RDP_CAPLEN_GENERAL 0x18
#define OS_MAJOR_TYPE_UNIX 4
#define OS_MINOR_TYPE_XSERVER 7
#define RDP_CAPSET_BITMAP 2
#define RDP_CAPLEN_BITMAP 0x1C
#define RDP_CAPSET_ORDER 3
#define RDP_CAPLEN_ORDER 0x58
#define ORDER_CAP_NEGOTIATE 2
#define ORDER_CAP_NOSUPPORT 4
#define RDP_CAPSET_BMPCACHE 4
#define RDP_CAPLEN_BMPCACHE 0x28
#define RDP_CAPSET_CONTROL 5
#define RDP_CAPLEN_CONTROL 0x0C
#define RDP_CAPSET_ACTIVATE 7
#define RDP_CAPLEN_ACTIVATE 0x0C
#define RDP_CAPSET_POINTER 8
#define RDP_CAPLEN_POINTER 0x08
#define RDP_CAPSET_SHARE 9
#define RDP_CAPLEN_SHARE 0x08
#define RDP_CAPSET_COLCACHE 10
#define RDP_CAPLEN_COLCACHE 0x08
#define RDP_CAPSET_BMPCACHE2 19
#define RDP_CAPLEN_BMPCACHE2 0x28
#define BMPCACHE2_FLAG_PERSIST ((uint32)1<<31)
#define RDP_SOURCE "MSTSC"
/* Logon flags */
#define RDP_LOGON_AUTO 0x0008
#define RDP_LOGON_NORMAL 0x0033
#define RDP_LOGON_COMPRESSION 0x0080 /* mppc compression with 8kB histroy buffer */
#define RDP_LOGON_BLOB 0x0100
#define RDP_LOGON_COMPRESSION2 0x0200 /* rdp5 mppc compression with 64kB history buffer */
#define RDP_LOGON_LEAVE_AUDIO 0x2000
#define RDP5_DISABLE_NOTHING 0x00
#define RDP5_NO_WALLPAPER 0x01
#define RDP5_NO_FULLWINDOWDRAG 0x02
#define RDP5_NO_MENUANIMATIONS 0x04
#define RDP5_NO_THEMING 0x08
#define RDP5_NO_CURSOR_SHADOW 0x20
#define RDP5_NO_CURSORSETTINGS 0x40 /* disables cursor blinking */
/* compression types */
#define RDP_MPPC_BIG 0x01
#define RDP_MPPC_COMPRESSED 0x20
#define RDP_MPPC_RESET 0x40
#define RDP_MPPC_FLUSH 0x80
#define RDP_MPPC_DICT_SIZE 65536
#define RDP5_COMPRESSED 0x80
/* Keymap flags */
#define MapRightShiftMask (1<<0)
#define MapLeftShiftMask (1<<1)
#define MapShiftMask (MapRightShiftMask | MapLeftShiftMask)
#define MapRightAltMask (1<<2)
#define MapLeftAltMask (1<<3)
#define MapAltGrMask MapRightAltMask
#define MapRightCtrlMask (1<<4)
#define MapLeftCtrlMask (1<<5)
#define MapCtrlMask (MapRightCtrlMask | MapLeftCtrlMask)
#define MapRightWinMask (1<<6)
#define MapLeftWinMask (1<<7)
#define MapWinMask (MapRightWinMask | MapLeftWinMask)
#define MapNumLockMask (1<<8)
#define MapCapsLockMask (1<<9)
#define MapLocalStateMask (1<<10)
#define MapInhibitMask (1<<11)
#define MASK_ADD_BITS(var, mask) (var |= mask)
#define MASK_REMOVE_BITS(var, mask) (var &= ~mask)
#define MASK_HAS_BITS(var, mask) ((var & mask)>0)
#define MASK_CHANGE_BIT(var, mask, active) (var = ((var & ~mask) | (active ? mask : 0)))
/* Clipboard constants, "borrowed" from GCC system headers in
the w32 cross compiler */
#ifndef CF_TEXT
#define CF_TEXT 1
#define CF_BITMAP 2
#define CF_METAFILEPICT 3
#define CF_SYLK 4
#define CF_DIF 5
#define CF_TIFF 6
#define CF_OEMTEXT 7
#define CF_DIB 8
#define CF_PALETTE 9
#define CF_PENDATA 10
#define CF_RIFF 11
#define CF_WAVE 12
#define CF_UNICODETEXT 13
#define CF_ENHMETAFILE 14
#define CF_HDROP 15
#define CF_LOCALE 16
#define CF_MAX 17
#define CF_OWNERDISPLAY 128
#define CF_DSPTEXT 129
#define CF_DSPBITMAP 130
#define CF_DSPMETAFILEPICT 131
#define CF_DSPENHMETAFILE 142
#define CF_PRIVATEFIRST 512
#define CF_PRIVATELAST 767
#define CF_GDIOBJFIRST 768
#define CF_GDIOBJLAST 1023
#endif
/* Sound format constants */
#define WAVE_FORMAT_PCM 1
#define WAVE_FORMAT_ADPCM 2
#define WAVE_FORMAT_ALAW 6
#define WAVE_FORMAT_MULAW 7
/* Virtual channel options */
#define CHANNEL_OPTION_INITIALIZED 0x80000000
#define CHANNEL_OPTION_ENCRYPT_RDP 0x40000000
#define CHANNEL_OPTION_COMPRESS_RDP 0x00800000
#define CHANNEL_OPTION_SHOW_PROTOCOL 0x00200000
/* NT status codes for RDPDR */
#undef STATUS_SUCCESS
#define STATUS_SUCCESS 0x00000000
#undef STATUS_NOT_IMPLEMENTED
#define STATUS_NOT_IMPLEMENTED 0x00000001
#undef STATUS_PENDING
#define STATUS_PENDING 0x00000103
#ifndef STATUS_NO_MORE_FILES
#define STATUS_NO_MORE_FILES 0x80000006
#define STATUS_DEVICE_PAPER_EMPTY 0x8000000e
#define STATUS_DEVICE_POWERED_OFF 0x8000000f
#define STATUS_DEVICE_OFF_LINE 0x80000010
#define STATUS_DEVICE_BUSY 0x80000011
#endif
#ifndef STATUS_INVALID_HANDLE
#define STATUS_INVALID_HANDLE 0xc0000008
#define STATUS_INVALID_PARAMETER 0xc000000d
#define STATUS_NO_SUCH_FILE 0xc000000f
#define STATUS_INVALID_DEVICE_REQUEST 0xc0000010
#define STATUS_ACCESS_DENIED 0xc0000022
#define STATUS_OBJECT_NAME_COLLISION 0xc0000035
#define STATUS_DISK_FULL 0xc000007f
#define STATUS_FILE_IS_A_DIRECTORY 0xc00000ba
#define STATUS_NOT_SUPPORTED 0xc00000bb
#define STATUS_TIMEOUT 0xc0000102
#define STATUS_NOTIFY_ENUM_DIR 0xc000010c
#define STATUS_CANCELLED 0xc0000120
#endif
/* RDPDR constants */
#define RDPDR_MAX_DEVICES 0x10
#define DEVICE_TYPE_SERIAL 0x01
#define DEVICE_TYPE_PARALLEL 0x02
#define DEVICE_TYPE_PRINTER 0x04
#define DEVICE_TYPE_DISK 0x08
#define DEVICE_TYPE_SCARD 0x20
#define FILE_DIRECTORY_FILE 0x00000001
#define FILE_NON_DIRECTORY_FILE 0x00000040
#define FILE_COMPLETE_IF_OPLOCKED 0x00000100
#define FILE_DELETE_ON_CLOSE 0x00001000
#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000
/* RDP5 disconnect PDU */
#define exDiscReasonNoInfo 0x0000
#define exDiscReasonAPIInitiatedDisconnect 0x0001
#define exDiscReasonAPIInitiatedLogoff 0x0002
#define exDiscReasonServerIdleTimeout 0x0003
#define exDiscReasonServerLogonTimeout 0x0004
#define exDiscReasonReplacedByOtherConnection 0x0005
#define exDiscReasonOutOfMemory 0x0006
#define exDiscReasonServerDeniedConnection 0x0007
#define exDiscReasonServerDeniedConnectionFips 0x0008
#define exDiscReasonLicenseInternal 0x0100
#define exDiscReasonLicenseNoLicenseServer 0x0101
#define exDiscReasonLicenseNoLicense 0x0102
#define exDiscReasonLicenseErrClientMsg 0x0103
#define exDiscReasonLicenseHwidDoesntMatchLicense 0x0104
#define exDiscReasonLicenseErrClientLicense 0x0105
#define exDiscReasonLicenseCantFinishProtocol 0x0106
#define exDiscReasonLicenseClientEndedProtocol 0x0107
#define exDiscReasonLicenseErrClientEncryption 0x0108
#define exDiscReasonLicenseCantUpgradeLicense 0x0109
#define exDiscReasonLicenseNoRemoteConnections 0x010a
/* SeamlessRDP constants */
#define SEAMLESSRDP_NOTYETMAPPED -1
#define SEAMLESSRDP_NORMAL 0
#define SEAMLESSRDP_MINIMIZED 1
#define SEAMLESSRDP_MAXIMIZED 2
#define SEAMLESSRDP_POSITION_TIMER 200000
#define SEAMLESSRDP_CREATE_MODAL 0x0001
#define SEAMLESSRDP_HELLO_RECONNECT 0x0001
#define SEAMLESSRDP_HELLO_HIDDEN 0x0002

View file

@ -0,0 +1,231 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Protocol services - ISO layer
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
/* Send a self-contained ISO PDU */
static void
iso_send_msg(uint8 code)
{
STREAM s;
s = tcp_init(11);
out_uint8(s, 3); /* version */
out_uint8(s, 0); /* reserved */
out_uint16_be(s, 11); /* length */
out_uint8(s, 6); /* hdrlen */
out_uint8(s, code);
out_uint16(s, 0); /* dst_ref */
out_uint16(s, 0); /* src_ref */
out_uint8(s, 0); /* class */
s_mark_end(s);
tcp_send(s);
}
static void
iso_send_connection_request(char *username)
{
STREAM s;
int length = 30 + strlen(username);
s = tcp_init(length);
out_uint8(s, 3); /* version */
out_uint8(s, 0); /* reserved */
out_uint16_be(s, length); /* length */
out_uint8(s, length - 5); /* hdrlen */
out_uint8(s, ISO_PDU_CR);
out_uint16(s, 0); /* dst_ref */
out_uint16(s, 0); /* src_ref */
out_uint8(s, 0); /* class */
out_uint8p(s, "Cookie: mstshash=", strlen("Cookie: mstshash="));
out_uint8p(s, username, strlen(username));
out_uint8(s, 0x0d); /* Unknown */
out_uint8(s, 0x0a); /* Unknown */
s_mark_end(s);
tcp_send(s);
}
/* Receive a message on the ISO layer, return code */
static STREAM
iso_recv_msg(uint8 * code, uint8 * rdpver)
{
STREAM s;
uint16 length;
uint8 version;
s = tcp_recv(NULL, 4);
if (s == NULL)
return NULL;
in_uint8(s, version);
if (rdpver != NULL)
*rdpver = version;
if (version == 3)
{
in_uint8s(s, 1); /* pad */
in_uint16_be(s, length);
}
else
{
in_uint8(s, length);
if (length & 0x80)
{
length &= ~0x80;
next_be(s, length);
}
}
s = tcp_recv(s, length - 4);
if (s == NULL)
return NULL;
if (version != 3)
return s;
in_uint8s(s, 1); /* hdrlen */
in_uint8(s, *code);
if (*code == ISO_PDU_DT)
{
in_uint8s(s, 1); /* eot */
return s;
}
in_uint8s(s, 5); /* dst_ref, src_ref, class */
return s;
}
/* Initialise ISO transport data packet */
STREAM
iso_init(int length)
{
STREAM s;
s = tcp_init(length + 7);
s_push_layer(s, iso_hdr, 7);
return s;
}
/* Send an ISO data PDU */
void
iso_send(STREAM s)
{
uint16 length;
s_pop_layer(s, iso_hdr);
length = s->end - s->p;
out_uint8(s, 3); /* version */
out_uint8(s, 0); /* reserved */
out_uint16_be(s, length);
out_uint8(s, 2); /* hdrlen */
out_uint8(s, ISO_PDU_DT); /* code */
out_uint8(s, 0x80); /* eot */
tcp_send(s);
}
/* Receive ISO transport data packet */
STREAM
iso_recv(uint8 * rdpver)
{
STREAM s;
uint8 code = 0;
s = iso_recv_msg(&code, rdpver);
if (s == NULL)
return NULL;
if (rdpver != NULL)
if (*rdpver != 3)
return s;
if (code != ISO_PDU_DT)
{
error("expected DT, got 0x%x\n", code);
return NULL;
}
return s;
}
/* Establish a connection up to the ISO layer */
BOOL
iso_connect(char *server, char *username)
{
uint8 code = 0;
if (!tcp_connect(server))
return False;
iso_send_connection_request(username);
if (iso_recv_msg(&code, NULL) == NULL)
return False;
if (code != ISO_PDU_CC)
{
error("expected CC, got 0x%x\n", code);
tcp_disconnect();
return False;
}
return True;
}
/* Establish a reconnection up to the ISO layer */
BOOL
iso_reconnect(char *server)
{
uint8 code = 0;
if (!tcp_connect(server))
return False;
iso_send_msg(ISO_PDU_CR);
if (iso_recv_msg(&code, NULL) == NULL)
return False;
if (code != ISO_PDU_CC)
{
error("expected CC, got 0x%x\n", code);
tcp_disconnect();
return False;
}
return True;
}
/* Disconnect from the ISO layer */
void
iso_disconnect(void)
{
iso_send_msg(ISO_PDU_DR);
tcp_disconnect();
}
/* reset the state to support reconnecting */
void
iso_reset_state(void)
{
tcp_reset_state();
}

View file

@ -0,0 +1,53 @@
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
IDD_GENERAL DIALOGEX 0, 0, 242, 175
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
GROUPBOX "Logon settings",IDC_STATIC,7,7,228,89
GROUPBOX "Connection settings",IDC_STATIC,7,103,228,65
ICON "", IDC_LOGONICON, 15,19,20,20
LTEXT "Enter the server address",IDC_STATIC,47,24,81,8
LTEXT "Server:",IDC_STATIC,47,41,25,8
LTEXT "User name:",IDC_STATIC,47,58,38,8
COMBOBOX IDC_SERVERCOMBO,79,39,141,30,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Save",IDC_SAVE,67,139,50,14
PUSHBUTTON "SaveAs...",IDC_SAVEAS,123,139,50,14
PUSHBUTTON "Open...",IDC_OPEN,177,139,50,14
ICON "", IDC_CONNICON, 16,114,20,20
LTEXT "Save the current connection settings or open an existing config",IDC_STATIC,50,115,172,20
END
IDD_DISPLAY DIALOGEX 0, 0, 242, 175
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
GROUPBOX "Remote desktop size",IDC_STATIC,7,7,228,68
GROUPBOX "Colors",IDC_STATIC,7,83,228,85
ICON "", IDC_REMICON, 15,19,20,20
ICON "", IDC_COLORSICON, 15,98,20,20
LTEXT "Set the screen size of your remote desktop. Drag the slider to the far right to go fullscreen",IDC_STATIC,53,22,175,21
CONTROL "",IDC_GEOSLIDER,"msctls_trackbar32",WS_TABSTOP,56,49,124,15
COMBOBOX IDC_BPPCOMBO,56,102,128,30,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
CONTROL "",IDC_COLORIMAGE,"Static",SS_OWNERDRAW | SS_SUNKEN, 56,121,127,13
LTEXT "Note: Settings on the remote computer might override this setting.",IDC_STATIC,56,143,165,18
LTEXT "Less",IDC_STATIC,35,52,15,8
LTEXT "More",IDC_STATIC,189,51,17,8
END
IDD_CONNECTDIALOG DIALOGEX 0, 0, 260, 277
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Remote Desktop Connection"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Connect",IDOK,147,256,50,14
PUSHBUTTON "Cancel",IDCANCEL,203,256,50,14
CONTROL "",IDC_TAB,"SysTabControl32",0x0,7,54,246,198
END
STRINGTABLE
BEGIN
IDS_TAB_GENERAL "General"
IDS_TAB_DISPLAY "Display"
END

View file

@ -0,0 +1,345 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
RDP licensing negotiation
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
//#include <openssl/rc4.h>
void *
ssl_rc4_info_create(void);
void
ssl_rc4_info_delete(void * rc4_info);
void
ssl_rc4_set_key(void * rc4_info, char * key, int len);
void
ssl_rc4_crypt(void * rc4_info, char * in_data, char * out_data, int len);
int
ssl_mod_exp(char* out, int out_len, char* in, int in_len,
char* mod, int mod_len, char* exp, int exp_len);
extern char g_username[64];
extern char g_hostname[16];
static uint8 g_licence_key[16];
static uint8 g_licence_sign_key[16];
BOOL g_licence_issued = False;
/* Generate a session key and RC4 keys, given client and server randoms */
static void
licence_generate_keys(uint8 * client_random, uint8 * server_random, uint8 * pre_master_secret)
{
uint8 master_secret[48];
uint8 key_block[48];
/* Generate master secret and then key material */
sec_hash_48(master_secret, pre_master_secret, client_random, server_random, 'A');
sec_hash_48(key_block, master_secret, server_random, client_random, 'A');
/* Store first 16 bytes of session key as MAC secret */
memcpy(g_licence_sign_key, key_block, 16);
/* Generate RC4 key from next 16 bytes */
sec_hash_16(g_licence_key, &key_block[16], client_random, server_random);
}
static void
licence_generate_hwid(uint8 * hwid)
{
buf_out_uint32(hwid, 2);
strncpy((char *) (hwid + 4), g_hostname, LICENCE_HWID_SIZE - 4);
}
/* Present an existing licence to the server */
static void
licence_present(uint8 * client_random, uint8 * rsa_data,
uint8 * licence_data, int licence_size, uint8 * hwid, uint8 * signature)
{
uint32 sec_flags = SEC_LICENCE_NEG;
uint16 length =
16 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE +
licence_size + LICENCE_HWID_SIZE + LICENCE_SIGNATURE_SIZE;
STREAM s;
s = sec_init(sec_flags, length + 4);
out_uint8(s, LICENCE_TAG_PRESENT);
out_uint8(s, 2); /* version */
out_uint16_le(s, length);
out_uint32_le(s, 1);
out_uint16(s, 0);
out_uint16_le(s, 0x0201);
out_uint8p(s, client_random, SEC_RANDOM_SIZE);
out_uint16(s, 0);
out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE));
out_uint8p(s, rsa_data, SEC_MODULUS_SIZE);
out_uint8s(s, SEC_PADDING_SIZE);
out_uint16_le(s, 1);
out_uint16_le(s, licence_size);
out_uint8p(s, licence_data, licence_size);
out_uint16_le(s, 1);
out_uint16_le(s, LICENCE_HWID_SIZE);
out_uint8p(s, hwid, LICENCE_HWID_SIZE);
out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE);
s_mark_end(s);
sec_send(s, sec_flags);
}
/* Send a licence request packet */
static void
licence_send_request(uint8 * client_random, uint8 * rsa_data, char *user, char *host)
{
uint32 sec_flags = SEC_LICENCE_NEG;
uint16 userlen = strlen(user) + 1;
uint16 hostlen = strlen(host) + 1;
uint16 length = 128 + userlen + hostlen;
STREAM s;
s = sec_init(sec_flags, length + 2);
out_uint8(s, LICENCE_TAG_REQUEST);
out_uint8(s, 2); /* version */
out_uint16_le(s, length);
out_uint32_le(s, 1);
out_uint16(s, 0);
out_uint16_le(s, 0xff01);
out_uint8p(s, client_random, SEC_RANDOM_SIZE);
out_uint16(s, 0);
out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE));
out_uint8p(s, rsa_data, SEC_MODULUS_SIZE);
out_uint8s(s, SEC_PADDING_SIZE);
out_uint16_le(s, LICENCE_TAG_USER);
out_uint16_le(s, userlen);
out_uint8p(s, user, userlen);
out_uint16_le(s, LICENCE_TAG_HOST);
out_uint16_le(s, hostlen);
out_uint8p(s, host, hostlen);
s_mark_end(s);
sec_send(s, sec_flags);
}
/* Process a licence demand packet */
static void
licence_process_demand(STREAM s)
{
uint8 null_data[SEC_MODULUS_SIZE];
uint8 *server_random;
uint8 signature[LICENCE_SIGNATURE_SIZE];
uint8 hwid[LICENCE_HWID_SIZE];
uint8 *licence_data;
int licence_size;
void * crypt_key;
/* Retrieve the server random from the incoming packet */
in_uint8p(s, server_random, SEC_RANDOM_SIZE);
/* We currently use null client keys. This is a bit naughty but, hey,
the security of licence negotiation isn't exactly paramount. */
memset(null_data, 0, sizeof(null_data));
licence_generate_keys(null_data, server_random, null_data);
licence_size = load_licence(&licence_data);
if (licence_size > 0)
{
/* Generate a signature for the HWID buffer */
licence_generate_hwid(hwid);
sec_sign(signature, 16, g_licence_sign_key, 16, hwid, sizeof(hwid));
/* Now encrypt the HWID */
crypt_key = ssl_rc4_info_create();
ssl_rc4_set_key(crypt_key, g_licence_key, 16);
ssl_rc4_crypt(crypt_key, hwid, hwid, sizeof(hwid));
ssl_rc4_info_delete(crypt_key);
licence_present(null_data, null_data, licence_data, licence_size, hwid, signature);
xfree(licence_data);
return;
}
licence_send_request(null_data, null_data, g_username, g_hostname);
}
/* Send an authentication response packet */
static void
licence_send_authresp(uint8 * token, uint8 * crypt_hwid, uint8 * signature)
{
uint32 sec_flags = SEC_LICENCE_NEG;
uint16 length = 58;
STREAM s;
s = sec_init(sec_flags, length + 2);
out_uint8(s, LICENCE_TAG_AUTHRESP);
out_uint8(s, 2); /* version */
out_uint16_le(s, length);
out_uint16_le(s, 1);
out_uint16_le(s, LICENCE_TOKEN_SIZE);
out_uint8p(s, token, LICENCE_TOKEN_SIZE);
out_uint16_le(s, 1);
out_uint16_le(s, LICENCE_HWID_SIZE);
out_uint8p(s, crypt_hwid, LICENCE_HWID_SIZE);
out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE);
s_mark_end(s);
sec_send(s, sec_flags);
}
/* Parse an authentication request packet */
static BOOL
licence_parse_authreq(STREAM s, uint8 ** token, uint8 ** signature)
{
uint16 tokenlen;
in_uint8s(s, 6); /* unknown: f8 3d 15 00 04 f6 */
in_uint16_le(s, tokenlen);
if (tokenlen != LICENCE_TOKEN_SIZE)
{
error("token len %d\n", tokenlen);
return False;
}
in_uint8p(s, *token, tokenlen);
in_uint8p(s, *signature, LICENCE_SIGNATURE_SIZE);
return s_check_end(s);
}
/* Process an authentication request packet */
static void
licence_process_authreq(STREAM s)
{
uint8 *in_token, *in_sig;
uint8 out_token[LICENCE_TOKEN_SIZE], decrypt_token[LICENCE_TOKEN_SIZE];
uint8 hwid[LICENCE_HWID_SIZE], crypt_hwid[LICENCE_HWID_SIZE];
uint8 sealed_buffer[LICENCE_TOKEN_SIZE + LICENCE_HWID_SIZE];
uint8 out_sig[LICENCE_SIGNATURE_SIZE];
void * crypt_key;
/* Parse incoming packet and save the encrypted token */
licence_parse_authreq(s, &in_token, &in_sig);
memcpy(out_token, in_token, LICENCE_TOKEN_SIZE);
/* Decrypt the token. It should read TEST in Unicode. */
crypt_key = ssl_rc4_info_create();
ssl_rc4_set_key(crypt_key, g_licence_key, 16);
ssl_rc4_crypt(crypt_key, in_token, decrypt_token, LICENCE_TOKEN_SIZE);
ssl_rc4_info_delete(crypt_key);
/* Generate a signature for a buffer of token and HWID */
licence_generate_hwid(hwid);
memcpy(sealed_buffer, decrypt_token, LICENCE_TOKEN_SIZE);
memcpy(sealed_buffer + LICENCE_TOKEN_SIZE, hwid, LICENCE_HWID_SIZE);
sec_sign(out_sig, 16, g_licence_sign_key, 16, sealed_buffer, sizeof(sealed_buffer));
/* Now encrypt the HWID */
crypt_key = ssl_rc4_info_create();
ssl_rc4_set_key(crypt_key, g_licence_key, 16);
ssl_rc4_crypt(crypt_key, hwid, crypt_hwid, LICENCE_HWID_SIZE);
ssl_rc4_info_delete(crypt_key);
licence_send_authresp(out_token, crypt_hwid, out_sig);
}
/* Process an licence issue packet */
static void
licence_process_issue(STREAM s)
{
void * crypt_key;
uint32 length;
uint16 check;
int i;
in_uint8s(s, 2); /* 3d 45 - unknown */
in_uint16_le(s, length);
if (!s_check_rem(s, length))
return;
crypt_key = ssl_rc4_info_create();
ssl_rc4_set_key(crypt_key, g_licence_key, 16);
ssl_rc4_crypt(crypt_key, s->p, s->p, length);
ssl_rc4_info_delete(crypt_key);
in_uint16(s, check);
if (check != 0)
return;
g_licence_issued = True;
in_uint8s(s, 2); /* pad */
/* advance to fourth string */
length = 0;
for (i = 0; i < 4; i++)
{
in_uint8s(s, length);
in_uint32_le(s, length);
if (!s_check_rem(s, length))
return;
}
g_licence_issued = True;
save_licence(s->p, length);
}
/* Process a licence packet */
void
licence_process(STREAM s)
{
uint8 tag;
in_uint8(s, tag);
in_uint8s(s, 3); /* version, length */
switch (tag)
{
case LICENCE_TAG_DEMAND:
licence_process_demand(s);
break;
case LICENCE_TAG_AUTHREQ:
licence_process_authreq(s);
break;
case LICENCE_TAG_ISSUE:
licence_process_issue(s);
break;
case LICENCE_TAG_REISSUE:
case LICENCE_TAG_RESULT:
break;
default:
unimpl("licence tag 0x%x\n", tag);
}
}

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly
xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0">
<assemblyIdentity
name="Win32 Application.default.App"
processorArchitecture="x86"
version="1.0.0.0"
type="win32"/>
<description>ReactOS Service Manager</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="x86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>

View file

@ -0,0 +1,469 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Protocol services - Multipoint Communications Service
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
uint16 g_mcs_userid;
extern VCHANNEL g_channels[];
extern unsigned int g_num_channels;
/* Parse an ASN.1 BER header */
static BOOL
ber_parse_header(STREAM s, int tagval, int *length)
{
int tag, len;
if (tagval > 0xff)
{
in_uint16_be(s, tag);
}
else
{
in_uint8(s, tag)}
if (tag != tagval)
{
error("expected tag %d, got %d\n", tagval, tag);
return False;
}
in_uint8(s, len);
if (len & 0x80)
{
len &= ~0x80;
*length = 0;
while (len--)
next_be(s, *length);
}
else
*length = len;
return s_check(s);
}
/* Output an ASN.1 BER header */
static void
ber_out_header(STREAM s, int tagval, int length)
{
if (tagval > 0xff)
{
out_uint16_be(s, tagval);
}
else
{
out_uint8(s, tagval);
}
if (length >= 0x80)
{
out_uint8(s, 0x82);
out_uint16_be(s, length);
}
else
out_uint8(s, length);
}
/* Output an ASN.1 BER integer */
static void
ber_out_integer(STREAM s, int value)
{
ber_out_header(s, BER_TAG_INTEGER, 2);
out_uint16_be(s, value);
}
/* Output a DOMAIN_PARAMS structure (ASN.1 BER) */
static void
mcs_out_domain_params(STREAM s, int max_channels, int max_users, int max_tokens, int max_pdusize)
{
ber_out_header(s, MCS_TAG_DOMAIN_PARAMS, 32);
ber_out_integer(s, max_channels);
ber_out_integer(s, max_users);
ber_out_integer(s, max_tokens);
ber_out_integer(s, 1); /* num_priorities */
ber_out_integer(s, 0); /* min_throughput */
ber_out_integer(s, 1); /* max_height */
ber_out_integer(s, max_pdusize);
ber_out_integer(s, 2); /* ver_protocol */
}
/* Parse a DOMAIN_PARAMS structure (ASN.1 BER) */
static BOOL
mcs_parse_domain_params(STREAM s)
{
int length;
ber_parse_header(s, MCS_TAG_DOMAIN_PARAMS, &length);
in_uint8s(s, length);
return s_check(s);
}
/* Send an MCS_CONNECT_INITIAL message (ASN.1 BER) */
static void
mcs_send_connect_initial(STREAM mcs_data)
{
int datalen = mcs_data->end - mcs_data->data;
int length = 9 + 3 * 34 + 4 + datalen;
STREAM s;
s = iso_init(length + 5);
ber_out_header(s, MCS_CONNECT_INITIAL, length);
ber_out_header(s, BER_TAG_OCTET_STRING, 1); /* calling domain */
out_uint8(s, 1);
ber_out_header(s, BER_TAG_OCTET_STRING, 1); /* called domain */
out_uint8(s, 1);
ber_out_header(s, BER_TAG_BOOLEAN, 1);
out_uint8(s, 0xff); /* upward flag */
mcs_out_domain_params(s, 34, 2, 0, 0xffff); /* target params */
mcs_out_domain_params(s, 1, 1, 1, 0x420); /* min params */
mcs_out_domain_params(s, 0xffff, 0xfc17, 0xffff, 0xffff); /* max params */
ber_out_header(s, BER_TAG_OCTET_STRING, datalen);
out_uint8p(s, mcs_data->data, datalen);
s_mark_end(s);
iso_send(s);
}
/* Expect a MCS_CONNECT_RESPONSE message (ASN.1 BER) */
static BOOL
mcs_recv_connect_response(STREAM mcs_data)
{
uint8 result;
int length;
STREAM s;
s = iso_recv(NULL);
if (s == NULL)
return False;
ber_parse_header(s, MCS_CONNECT_RESPONSE, &length);
ber_parse_header(s, BER_TAG_RESULT, &length);
in_uint8(s, result);
if (result != 0)
{
error("MCS connect: %d\n", result);
return False;
}
ber_parse_header(s, BER_TAG_INTEGER, &length);
in_uint8s(s, length); /* connect id */
mcs_parse_domain_params(s);
ber_parse_header(s, BER_TAG_OCTET_STRING, &length);
sec_process_mcs_data(s);
/*
if (length > mcs_data->size)
{
error("MCS data length %d, expected %d\n", length,
mcs_data->size);
length = mcs_data->size;
}
in_uint8a(s, mcs_data->data, length);
mcs_data->p = mcs_data->data;
mcs_data->end = mcs_data->data + length;
*/
return s_check_end(s);
}
/* Send an EDrq message (ASN.1 PER) */
static void
mcs_send_edrq(void)
{
STREAM s;
s = iso_init(5);
out_uint8(s, (MCS_EDRQ << 2));
out_uint16_be(s, 1); /* height */
out_uint16_be(s, 1); /* interval */
s_mark_end(s);
iso_send(s);
}
/* Send an AUrq message (ASN.1 PER) */
static void
mcs_send_aurq(void)
{
STREAM s;
s = iso_init(1);
out_uint8(s, (MCS_AURQ << 2));
s_mark_end(s);
iso_send(s);
}
/* Expect a AUcf message (ASN.1 PER) */
static BOOL
mcs_recv_aucf(uint16 * mcs_userid)
{
uint8 opcode, result;
STREAM s;
s = iso_recv(NULL);
if (s == NULL)
return False;
in_uint8(s, opcode);
if ((opcode >> 2) != MCS_AUCF)
{
error("expected AUcf, got %d\n", opcode);
return False;
}
in_uint8(s, result);
if (result != 0)
{
error("AUrq: %d\n", result);
return False;
}
if (opcode & 2)
in_uint16_be(s, *mcs_userid);
return s_check_end(s);
}
/* Send a CJrq message (ASN.1 PER) */
static void
mcs_send_cjrq(uint16 chanid)
{
STREAM s;
DEBUG_RDP5(("Sending CJRQ for channel #%d\n", chanid));
s = iso_init(5);
out_uint8(s, (MCS_CJRQ << 2));
out_uint16_be(s, g_mcs_userid);
out_uint16_be(s, chanid);
s_mark_end(s);
iso_send(s);
}
/* Expect a CJcf message (ASN.1 PER) */
static BOOL
mcs_recv_cjcf(void)
{
uint8 opcode, result;
STREAM s;
s = iso_recv(NULL);
if (s == NULL)
return False;
in_uint8(s, opcode);
if ((opcode >> 2) != MCS_CJCF)
{
error("expected CJcf, got %d\n", opcode);
return False;
}
in_uint8(s, result);
if (result != 0)
{
error("CJrq: %d\n", result);
return False;
}
in_uint8s(s, 4); /* mcs_userid, req_chanid */
if (opcode & 2)
in_uint8s(s, 2); /* join_chanid */
return s_check_end(s);
}
/* Initialise an MCS transport data packet */
STREAM
mcs_init(int length)
{
STREAM s;
s = iso_init(length + 8);
s_push_layer(s, mcs_hdr, 8);
return s;
}
/* Send an MCS transport data packet to a specific channel */
void
mcs_send_to_channel(STREAM s, uint16 channel)
{
uint16 length;
s_pop_layer(s, mcs_hdr);
length = s->end - s->p - 8;
length |= 0x8000;
out_uint8(s, (MCS_SDRQ << 2));
out_uint16_be(s, g_mcs_userid);
out_uint16_be(s, channel);
out_uint8(s, 0x70); /* flags */
out_uint16_be(s, length);
iso_send(s);
}
/* Send an MCS transport data packet to the global channel */
void
mcs_send(STREAM s)
{
mcs_send_to_channel(s, MCS_GLOBAL_CHANNEL);
}
/* Receive an MCS transport data packet */
STREAM
mcs_recv(uint16 * channel, uint8 * rdpver)
{
uint8 opcode, appid, length;
STREAM s;
s = iso_recv(rdpver);
if (s == NULL)
return NULL;
if (rdpver != NULL)
if (*rdpver != 3)
return s;
in_uint8(s, opcode);
appid = opcode >> 2;
if (appid != MCS_SDIN)
{
if (appid != MCS_DPUM)
{
error("expected data, got %d\n", opcode);
}
return NULL;
}
in_uint8s(s, 2); /* userid */
in_uint16_be(s, *channel);
in_uint8s(s, 1); /* flags */
in_uint8(s, length);
if (length & 0x80)
in_uint8s(s, 1); /* second byte of length */
return s;
}
/* Establish a connection up to the MCS layer */
BOOL
mcs_connect(char *server, STREAM mcs_data, char *username)
{
unsigned int i;
if (!iso_connect(server, username))
return False;
mcs_send_connect_initial(mcs_data);
if (!mcs_recv_connect_response(mcs_data))
goto error;
mcs_send_edrq();
mcs_send_aurq();
if (!mcs_recv_aucf(&g_mcs_userid))
goto error;
mcs_send_cjrq((uint16) (g_mcs_userid + MCS_USERCHANNEL_BASE));
if (!mcs_recv_cjcf())
goto error;
mcs_send_cjrq(MCS_GLOBAL_CHANNEL);
if (!mcs_recv_cjcf())
goto error;
for (i = 0; i < g_num_channels; i++)
{
mcs_send_cjrq(g_channels[i].mcs_id);
if (!mcs_recv_cjcf())
goto error;
}
return True;
error:
iso_disconnect();
return False;
}
/* Establish a connection up to the MCS layer */
BOOL
mcs_reconnect(char *server, STREAM mcs_data)
{
unsigned int i;
if (!iso_reconnect(server))
return False;
mcs_send_connect_initial(mcs_data);
if (!mcs_recv_connect_response(mcs_data))
goto error;
mcs_send_edrq();
mcs_send_aurq();
if (!mcs_recv_aucf(&g_mcs_userid))
goto error;
mcs_send_cjrq((uint16) (g_mcs_userid + MCS_USERCHANNEL_BASE));
if (!mcs_recv_cjcf())
goto error;
mcs_send_cjrq(MCS_GLOBAL_CHANNEL);
if (!mcs_recv_cjcf())
goto error;
for (i = 0; i < g_num_channels; i++)
{
mcs_send_cjrq(g_channels[i].mcs_id);
if (!mcs_recv_cjcf())
goto error;
}
return True;
error:
iso_disconnect();
return False;
}
/* Disconnect from the MCS layer */
void
mcs_disconnect(void)
{
iso_disconnect();
}
/* reset the state of the mcs layer */
void
mcs_reset_state(void)
{
g_mcs_userid = 0;
iso_reset_state();
}

View file

@ -0,0 +1,380 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Protocol services - RDP decompression
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <string.h>
#include "rdesktop.h"
/* mppc decompression */
/* http://www.faqs.org/rfcs/rfc2118.html */
/* Contacts: */
/* hifn contact mentioned in the faq is */
/* Robert Friend rfriend at hifn dot com */
/* if you have questions regarding MPPC */
/* our contact is */
/* Guus Dhaeze GDhaeze at hifn dot com */
/* Licensing: */
/* decompression is alright as long as we */
/* don't compress data */
/* Algorithm: */
/* as the rfc states the algorithm seems to */
/* be LZ77 with a sliding buffer */
/* that is empty at init. */
/* the algorithm is called LZS and is */
/* patented for another couple of years. */
/* more information is available in */
/* http://www.ietf.org/ietf/IPR/hifn-ipr-draft-friend-tls-lzs-compression.txt */
RDPCOMP g_mppc_dict;
int
mppc_expand(uint8 * data, uint32 clen, uint8 ctype, uint32 * roff, uint32 * rlen)
{
int k, walker_len = 0, walker;
uint32 i = 0;
int next_offset, match_off;
int match_len;
int old_offset, match_bits;
BOOL big = ctype & RDP_MPPC_BIG ? True : False;
uint8 *dict = g_mppc_dict.hist;
if ((ctype & RDP_MPPC_COMPRESSED) == 0)
{
*roff = 0;
*rlen = clen;
return 0;
}
if ((ctype & RDP_MPPC_RESET) != 0)
{
g_mppc_dict.roff = 0;
}
if ((ctype & RDP_MPPC_FLUSH) != 0)
{
memset(dict, 0, RDP_MPPC_DICT_SIZE);
g_mppc_dict.roff = 0;
}
*roff = 0;
*rlen = 0;
walker = g_mppc_dict.roff;
next_offset = walker;
old_offset = next_offset;
*roff = old_offset;
if (clen == 0)
return 0;
clen += i;
do
{
if (walker_len == 0)
{
if (i >= clen)
break;
walker = data[i++] << 24;
walker_len = 8;
}
if (walker >= 0)
{
if (walker_len < 8)
{
if (i >= clen)
{
if (walker != 0)
return -1;
break;
}
walker |= (data[i++] & 0xff) << (24 - walker_len);
walker_len += 8;
}
if (next_offset >= RDP_MPPC_DICT_SIZE)
return -1;
dict[next_offset++] = (((uint32) walker) >> ((uint32) 24));
walker <<= 8;
walker_len -= 8;
continue;
}
walker <<= 1;
/* fetch next 8-bits */
if (--walker_len == 0)
{
if (i >= clen)
return -1;
walker = data[i++] << 24;
walker_len = 8;
}
/* literal decoding */
if (walker >= 0)
{
if (walker_len < 8)
{
if (i >= clen)
return -1;
walker |= (data[i++] & 0xff) << (24 - walker_len);
walker_len += 8;
}
if (next_offset >= RDP_MPPC_DICT_SIZE)
return -1;
dict[next_offset++] = (uint8) (walker >> 24 | 0x80);
walker <<= 8;
walker_len -= 8;
continue;
}
/* decode offset */
/* length pair */
walker <<= 1;
if (--walker_len < (big ? 3 : 2))
{
if (i >= clen)
return -1;
walker |= (data[i++] & 0xff) << (24 - walker_len);
walker_len += 8;
}
if (big)
{
/* offset decoding where offset len is:
-63: 11111 followed by the lower 6 bits of the value
64-319: 11110 followed by the lower 8 bits of the value ( value - 64 )
320-2367: 1110 followed by lower 11 bits of the value ( value - 320 )
2368-65535: 110 followed by lower 16 bits of the value ( value - 2368 )
*/
switch (((uint32) walker) >> ((uint32) 29))
{
case 7: /* - 63 */
for (; walker_len < 9; walker_len += 8)
{
if (i >= clen)
return -1;
walker |= (data[i++] & 0xff) << (24 - walker_len);
}
walker <<= 3;
match_off = ((uint32) walker) >> ((uint32) 26);
walker <<= 6;
walker_len -= 9;
break;
case 6: /* 64 - 319 */
for (; walker_len < 11; walker_len += 8)
{
if (i >= clen)
return -1;
walker |= (data[i++] & 0xff) << (24 - walker_len);
}
walker <<= 3;
match_off = (((uint32) walker) >> ((uint32) 24)) + 64;
walker <<= 8;
walker_len -= 11;
break;
case 5:
case 4: /* 320 - 2367 */
for (; walker_len < 13; walker_len += 8)
{
if (i >= clen)
return -1;
walker |= (data[i++] & 0xff) << (24 - walker_len);
}
walker <<= 2;
match_off = (((uint32) walker) >> ((uint32) 21)) + 320;
walker <<= 11;
walker_len -= 13;
break;
default: /* 2368 - 65535 */
for (; walker_len < 17; walker_len += 8)
{
if (i >= clen)
return -1;
walker |= (data[i++] & 0xff) << (24 - walker_len);
}
walker <<= 1;
match_off = (((uint32) walker) >> ((uint32) 16)) + 2368;
walker <<= 16;
walker_len -= 17;
break;
}
}
else
{
/* offset decoding where offset len is:
-63: 1111 followed by the lower 6 bits of the value
64-319: 1110 followed by the lower 8 bits of the value ( value - 64 )
320-8191: 110 followed by the lower 13 bits of the value ( value - 320 )
*/
switch (((uint32) walker) >> ((uint32) 30))
{
case 3: /* - 63 */
if (walker_len < 8)
{
if (i >= clen)
return -1;
walker |= (data[i++] & 0xff) << (24 - walker_len);
walker_len += 8;
}
walker <<= 2;
match_off = ((uint32) walker) >> ((uint32) 26);
walker <<= 6;
walker_len -= 8;
break;
case 2: /* 64 - 319 */
for (; walker_len < 10; walker_len += 8)
{
if (i >= clen)
return -1;
walker |= (data[i++] & 0xff) << (24 - walker_len);
}
walker <<= 2;
match_off = (((uint32) walker) >> ((uint32) 24)) + 64;
walker <<= 8;
walker_len -= 10;
break;
default: /* 320 - 8191 */
for (; walker_len < 14; walker_len += 8)
{
if (i >= clen)
return -1;
walker |= (data[i++] & 0xff) << (24 - walker_len);
}
match_off = (walker >> 18) + 320;
walker <<= 14;
walker_len -= 14;
break;
}
}
if (walker_len == 0)
{
if (i >= clen)
return -1;
walker = data[i++] << 24;
walker_len = 8;
}
/* decode length of match */
match_len = 0;
if (walker >= 0)
{ /* special case - length of 3 is in bit 0 */
match_len = 3;
walker <<= 1;
walker_len--;
}
else
{
/* this is how it works len of:
4-7: 10 followed by 2 bits of the value
8-15: 110 followed by 3 bits of the value
16-31: 1110 followed by 4 bits of the value
32-63: .... and so forth
64-127:
128-255:
256-511:
512-1023:
1024-2047:
2048-4095:
4096-8191:
i.e. 4097 is encoded as: 111111111110 000000000001
meaning 4096 + 1...
*/
match_bits = big ? 14 : 11; /* 11 or 14 bits of value at most */
do
{
walker <<= 1;
if (--walker_len == 0)
{
if (i >= clen)
return -1;
walker = data[i++] << 24;
walker_len = 8;
}
if (walker >= 0)
break;
if (--match_bits == 0)
{
return -1;
}
}
while (1);
match_len = (big ? 16 : 13) - match_bits;
walker <<= 1;
if (--walker_len < match_len)
{
for (; walker_len < match_len; walker_len += 8)
{
if (i >= clen)
{
return -1;
}
walker |= (data[i++] & 0xff) << (24 - walker_len);
}
}
match_bits = match_len;
match_len =
((walker >> (32 - match_bits)) & (~(-1 << match_bits))) | (1 <<
match_bits);
walker <<= match_bits;
walker_len -= match_bits;
}
if (next_offset + match_len >= RDP_MPPC_DICT_SIZE)
{
return -1;
}
/* memory areas can overlap - meaning we can't use memXXX functions */
k = (next_offset - match_off) & (big ? 65535 : 8191);
do
{
dict[next_offset++] = dict[k++];
}
while (--match_len != 0);
}
while (1);
/* store history offset */
g_mppc_dict.roff = next_offset;
*roff = old_offset;
*rlen = next_offset - old_offset;
return 0;
}

View file

@ -0,0 +1,33 @@
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "../../../../tools/rbuild/project.dtd">
<module name="mstsc" type="win32gui" installbase="system32" installname="mstsc.exe" unicode="no">
<include base="mstsc">.</include>
<define name="_WIN32_IE">0x600</define>
<define name="_WIN32_WINNT">0x501</define>
<library>kernel32</library>
<library>user32</library>
<library>gdi32</library>
<library>comctl32</library>
<library>ws2_32</library>
<compilationunit name="unit.c">
<file>bitmap.c</file>
<file>bsops.c</file>
<file>cache.c</file>
<file>channels.c</file>
<file>connectdialog.c</file>
<file>iso.c</file>
<file>licence.c</file>
<file>mcs.c</file>
<file>mppc.c</file>
<file>orders.c</file>
<file>pstcache.c</file>
<file>rdp5.c</file>
<file>rdp.c</file>
<file>secure.c</file>
<file>ssl_calls.c</file>
<file>tcp.c</file>
<file>uimain.c</file>
<file>win32.c</file>
</compilationunit>
<file>rdc.rc</file>
</module>

View file

@ -0,0 +1,32 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mstsc", "mstsc_vc8_auto.vcproj", "{B6EF8F33-E4EA-495D-9E94-9A6ADBC235ED}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug - ReactOS headers|Win32 = Debug - ReactOS headers|Win32
Debug|Win32 = Debug|Win32
Release - ReactOS headers|Win32 = Release - ReactOS headers|Win32
Release|Win32 = Release|Win32
Speed - ReactOS headers|Win32 = Speed - ReactOS headers|Win32
Speed|Win32 = Speed|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B6EF8F33-E4EA-495D-9E94-9A6ADBC235ED}.Debug - ReactOS headers|Win32.ActiveCfg = Debug - ReactOS headers|Win32
{B6EF8F33-E4EA-495D-9E94-9A6ADBC235ED}.Debug - ReactOS headers|Win32.Build.0 = Debug - ReactOS headers|Win32
{B6EF8F33-E4EA-495D-9E94-9A6ADBC235ED}.Debug|Win32.ActiveCfg = Debug|Win32
{B6EF8F33-E4EA-495D-9E94-9A6ADBC235ED}.Debug|Win32.Build.0 = Debug|Win32
{B6EF8F33-E4EA-495D-9E94-9A6ADBC235ED}.Release - ReactOS headers|Win32.ActiveCfg = Release - ReactOS headers|Win32
{B6EF8F33-E4EA-495D-9E94-9A6ADBC235ED}.Release - ReactOS headers|Win32.Build.0 = Release - ReactOS headers|Win32
{B6EF8F33-E4EA-495D-9E94-9A6ADBC235ED}.Release|Win32.ActiveCfg = Release|Win32
{B6EF8F33-E4EA-495D-9E94-9A6ADBC235ED}.Release|Win32.Build.0 = Release|Win32
{B6EF8F33-E4EA-495D-9E94-9A6ADBC235ED}.Speed - ReactOS headers|Win32.ActiveCfg = Speed - ReactOS headers|Win32
{B6EF8F33-E4EA-495D-9E94-9A6ADBC235ED}.Speed - ReactOS headers|Win32.Build.0 = Speed - ReactOS headers|Win32
{B6EF8F33-E4EA-495D-9E94-9A6ADBC235ED}.Speed|Win32.ActiveCfg = Speed|Win32
{B6EF8F33-E4EA-495D-9E94-9A6ADBC235ED}.Speed|Win32.Build.0 = Speed|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,645 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="mstsc"
ProjectGUID="{B6EF8F33-E4EA-495D-9E94-9A6ADBC235ED}"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="..\..\..\output-i386\base\applications\mstsc\vc8\Debug"
IntermediateDirectory="..\..\..\obj-i386\base\applications\mstsc\vc8\Debug"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
WholeProgramOptimization="false"
AdditionalIncludeDirectories="./;../../../.;../../../include;../../../include;../../../include/dxsdk;../../../include/ndk;../../../include/reactos;../../../include/reactos;../../../include/reactos/libs;..\..\..\obj-i386\include\reactos"
PreprocessorDefinitions=";DBG=1;KDBG=1;STDCALL=__stdcall;_DEBUG;_LIB;_M_IX86;_SEH_ENABLE_TRACE;_WIN32_IE=0x600;_WIN32_WINNT=0x501;_X86_;__REACTOS__;__i386__"
MinimalRebuild="false"
BasicRuntimeChecks="0"
RuntimeLibrary="1"
BufferSecurityCheck="false"
EnableFunctionLevelLinking="false"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="4"
CallingConvention="0"
CompileAs="1"
ForcedIncludeFiles="warning.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
AdditionalIncludeDirectories="./;../../../.;../../../include;../../../include;../../../include/dxsdk;../../../include/ndk;../../../include/reactos;../../../include/reactos;../../../include/reactos/libs;..\..\..\obj-i386\include\reactos"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="kernel32.lib user32.lib gdi32.lib comctl32.lib ws2_32.lib"
OutputFile="$(OutDir)/mstsc.exe"
LinkIncremental="2"
AdditionalLibraryDirectories="..\..\..\output-i386\dll\win32\kernel32\vc8\Debug;..\..\..\output-i386\dll\win32\user32\vc8\Debug;..\..\..\output-i386\dll\win32\gdi32\vc8\Debug;..\..\..\output-i386\dll\win32\comctl32\vc8\Debug;..\..\..\output-i386\dll\win32\ws2_32\vc8\Debug"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)/mstsc.pdb"
SubSystem="2"
LinkTimeCodeGeneration="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
EmbedManifest="false"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\..\..\output-i386\base\applications\mstsc\vc8\Release"
IntermediateDirectory="..\..\..\obj-i386\base\applications\mstsc\vc8\Release"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
FavorSizeOrSpeed="1"
WholeProgramOptimization="false"
AdditionalIncludeDirectories="./;../../../.;../../../include;../../../include;../../../include/dxsdk;../../../include/ndk;../../../include/reactos;../../../include/reactos;../../../include/reactos/libs;..\..\..\obj-i386\include\reactos"
PreprocessorDefinitions=";DBG=1;KDBG=1;STDCALL=__stdcall;_LIB;_M_IX86;_SEH_ENABLE_TRACE;_WIN32_IE=0x600;_WIN32_WINNT=0x501;_X86_;__REACTOS__;__i386__"
StringPooling="true"
MinimalRebuild="false"
BasicRuntimeChecks="0"
BufferSecurityCheck="false"
EnableFunctionLevelLinking="false"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
CallingConvention="0"
CompileAs="1"
ForcedIncludeFiles="warning.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
AdditionalIncludeDirectories="./;../../../.;../../../include;../../../include;../../../include/dxsdk;../../../include/ndk;../../../include/reactos;../../../include/reactos;../../../include/reactos/libs;..\..\..\obj-i386\include\reactos"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="kernel32.lib user32.lib gdi32.lib comctl32.lib ws2_32.lib"
OutputFile="$(OutDir)/mstsc.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="..\..\..\output-i386\dll\win32\kernel32\vc8\Release;..\..\..\output-i386\dll\win32\user32\vc8\Release;..\..\..\output-i386\dll\win32\gdi32\vc8\Release;..\..\..\output-i386\dll\win32\comctl32\vc8\Release;..\..\..\output-i386\dll\win32\ws2_32\vc8\Release"
GenerateDebugInformation="true"
SubSystem="2"
LinkTimeCodeGeneration="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
EmbedManifest="false"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Speed|Win32"
OutputDirectory="..\..\..\output-i386\base\applications\mstsc\vc8\Speed"
IntermediateDirectory="..\..\..\obj-i386\base\applications\mstsc\vc8\Speed"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
WholeProgramOptimization="false"
AdditionalIncludeDirectories="./;../../../.;../../../include;../../../include;../../../include/dxsdk;../../../include/ndk;../../../include/reactos;../../../include/reactos;../../../include/reactos/libs;..\..\..\obj-i386\include\reactos"
PreprocessorDefinitions=";DBG=1;KDBG=1;STDCALL=__stdcall;_LIB;_M_IX86;_SEH_ENABLE_TRACE;_WIN32_IE=0x600;_WIN32_WINNT=0x501;_X86_;__REACTOS__;__i386__"
MinimalRebuild="true"
BasicRuntimeChecks="0"
BufferSecurityCheck="false"
EnableFunctionLevelLinking="false"
UsePrecompiledHeader="0"
WarningLevel="0"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="0"
CallingConvention="0"
CompileAs="1"
ForcedIncludeFiles="warning.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
AdditionalIncludeDirectories="./;../../../.;../../../include;../../../include;../../../include/dxsdk;../../../include/ndk;../../../include/reactos;../../../include/reactos;../../../include/reactos/libs;..\..\..\obj-i386\include\reactos"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="kernel32.lib user32.lib gdi32.lib comctl32.lib ws2_32.lib"
OutputFile="$(OutDir)/mstsc.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="..\..\..\output-i386\dll\win32\kernel32\vc8\Speed;..\..\..\output-i386\dll\win32\user32\vc8\Speed;..\..\..\output-i386\dll\win32\gdi32\vc8\Speed;..\..\..\output-i386\dll\win32\comctl32\vc8\Speed;..\..\..\output-i386\dll\win32\ws2_32\vc8\Speed"
GenerateDebugInformation="false"
SubSystem="2"
LinkTimeCodeGeneration="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
EmbedManifest="false"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug - ReactOS headers|Win32"
OutputDirectory="..\..\..\output-i386\base\applications\mstsc\vc8\Debug - ReactOS headers"
IntermediateDirectory="..\..\..\obj-i386\base\applications\mstsc\vc8\Debug - ReactOS headers"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
WholeProgramOptimization="false"
AdditionalIncludeDirectories="./;../../../.;../../../include;../../../include;../../../include/dxsdk;../../../include/ndk;../../../include/reactos;../../../include/reactos;../../../include/reactos/libs;..\..\..\obj-i386\include\reactos;../../../include/psdk;../../../include/psdk;../../../include/ddk;../../../include/GL"
PreprocessorDefinitions=";DBG=1;KDBG=1;_DEBUG;_LIB;_M_IX86;_SEH_ENABLE_TRACE;_WIN32_IE=0x600;_WIN32_WINNT=0x501;_X86_;__REACTOS__;__i386__"
MinimalRebuild="false"
BasicRuntimeChecks="0"
RuntimeLibrary="1"
BufferSecurityCheck="false"
EnableFunctionLevelLinking="false"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="4"
CallingConvention="0"
CompileAs="1"
ForcedIncludeFiles="warning.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
AdditionalIncludeDirectories="./;../../../.;../../../include;../../../include;../../../include/dxsdk;../../../include/ndk;../../../include/reactos;../../../include/reactos;../../../include/reactos/libs;..\..\..\obj-i386\include\reactos;../../../include/psdk;../../../include/psdk;../../../include/ddk;../../../include/GL"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="kernel32.lib user32.lib gdi32.lib comctl32.lib ws2_32.lib"
OutputFile="$(OutDir)/mstsc.exe"
LinkIncremental="2"
AdditionalLibraryDirectories="..\..\..\output-i386\dll\win32\kernel32\vc8\Debug - ReactOS headers;..\..\..\output-i386\dll\win32\user32\vc8\Debug - ReactOS headers;..\..\..\output-i386\dll\win32\gdi32\vc8\Debug - ReactOS headers;..\..\..\output-i386\dll\win32\comctl32\vc8\Debug - ReactOS headers;..\..\..\output-i386\dll\win32\ws2_32\vc8\Debug - ReactOS headers"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)/mstsc.pdb"
SubSystem="2"
LinkTimeCodeGeneration="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
EmbedManifest="false"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release - ReactOS headers|Win32"
OutputDirectory="..\..\..\output-i386\base\applications\mstsc\vc8\Release - ReactOS headers"
IntermediateDirectory="..\..\..\obj-i386\base\applications\mstsc\vc8\Release - ReactOS headers"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
FavorSizeOrSpeed="1"
WholeProgramOptimization="false"
AdditionalIncludeDirectories="./;../../../.;../../../include;../../../include;../../../include/dxsdk;../../../include/ndk;../../../include/reactos;../../../include/reactos;../../../include/reactos/libs;..\..\..\obj-i386\include\reactos;../../../include/psdk;../../../include/psdk;../../../include/ddk;../../../include/GL"
PreprocessorDefinitions=";DBG=1;KDBG=1;_LIB;_M_IX86;_SEH_ENABLE_TRACE;_WIN32_IE=0x600;_WIN32_WINNT=0x501;_X86_;__REACTOS__;__i386__"
StringPooling="true"
MinimalRebuild="false"
BasicRuntimeChecks="0"
BufferSecurityCheck="false"
EnableFunctionLevelLinking="false"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
CallingConvention="0"
CompileAs="1"
ForcedIncludeFiles="warning.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
AdditionalIncludeDirectories="./;../../../.;../../../include;../../../include;../../../include/dxsdk;../../../include/ndk;../../../include/reactos;../../../include/reactos;../../../include/reactos/libs;..\..\..\obj-i386\include\reactos;../../../include/psdk;../../../include/psdk;../../../include/ddk;../../../include/GL"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="kernel32.lib user32.lib gdi32.lib comctl32.lib ws2_32.lib"
OutputFile="$(OutDir)/mstsc.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="..\..\..\output-i386\dll\win32\kernel32\vc8\Release - ReactOS headers;..\..\..\output-i386\dll\win32\user32\vc8\Release - ReactOS headers;..\..\..\output-i386\dll\win32\gdi32\vc8\Release - ReactOS headers;..\..\..\output-i386\dll\win32\comctl32\vc8\Release - ReactOS headers;..\..\..\output-i386\dll\win32\ws2_32\vc8\Release - ReactOS headers"
GenerateDebugInformation="true"
SubSystem="2"
LinkTimeCodeGeneration="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
EmbedManifest="false"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Speed - ReactOS headers|Win32"
OutputDirectory="..\..\..\output-i386\base\applications\mstsc\vc8\Speed - ReactOS headers"
IntermediateDirectory="..\..\..\obj-i386\base\applications\mstsc\vc8\Speed - ReactOS headers"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
WholeProgramOptimization="false"
AdditionalIncludeDirectories="./;../../../.;../../../include;../../../include;../../../include/dxsdk;../../../include/ndk;../../../include/reactos;../../../include/reactos;../../../include/reactos/libs;..\..\..\obj-i386\include\reactos;../../../include/psdk;../../../include/psdk;../../../include/ddk;../../../include/GL"
PreprocessorDefinitions=";DBG=1;KDBG=1;_LIB;_M_IX86;_SEH_ENABLE_TRACE;_WIN32_IE=0x600;_WIN32_WINNT=0x501;_X86_;__REACTOS__;__i386__"
MinimalRebuild="true"
BasicRuntimeChecks="0"
BufferSecurityCheck="false"
EnableFunctionLevelLinking="false"
UsePrecompiledHeader="0"
WarningLevel="0"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="0"
CallingConvention="0"
CompileAs="1"
ForcedIncludeFiles="warning.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
AdditionalIncludeDirectories="./;../../../.;../../../include;../../../include;../../../include/dxsdk;../../../include/ndk;../../../include/reactos;../../../include/reactos;../../../include/reactos/libs;..\..\..\obj-i386\include\reactos;../../../include/psdk;../../../include/psdk;../../../include/ddk;../../../include/GL"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="kernel32.lib user32.lib gdi32.lib comctl32.lib ws2_32.lib"
OutputFile="$(OutDir)/mstsc.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="..\..\..\output-i386\dll\win32\kernel32\vc8\Speed - ReactOS headers;..\..\..\output-i386\dll\win32\user32\vc8\Speed - ReactOS headers;..\..\..\output-i386\dll\win32\gdi32\vc8\Speed - ReactOS headers;..\..\..\output-i386\dll\win32\comctl32\vc8\Speed - ReactOS headers;..\..\..\output-i386\dll\win32\ws2_32\vc8\Speed - ReactOS headers"
GenerateDebugInformation="false"
SubSystem="2"
LinkTimeCodeGeneration="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
EmbedManifest="false"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;S"
>
<File
RelativePath=".\bitmap.c"
>
</File>
<File
RelativePath=".\bsops.c"
>
</File>
<File
RelativePath=".\cache.c"
>
</File>
<File
RelativePath=".\channels.c"
>
</File>
<File
RelativePath=".\connectdialog.c"
>
</File>
<File
RelativePath=".\iso.c"
>
</File>
<File
RelativePath=".\licence.c"
>
</File>
<File
RelativePath=".\mcs.c"
>
</File>
<File
RelativePath=".\mppc.c"
>
</File>
<File
RelativePath=".\orders.c"
>
</File>
<File
RelativePath=".\pstcache.c"
>
</File>
<File
RelativePath=".\rdp.c"
>
</File>
<File
RelativePath=".\rdp5.c"
>
</File>
<File
RelativePath=".\secure.c"
>
</File>
<File
RelativePath=".\ssl_calls.c"
>
</File>
<File
RelativePath=".\tcp.c"
>
</File>
<File
RelativePath=".\uimain.c"
>
</File>
<File
RelativePath=".\win32.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl"
>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
>
<File
RelativePath=".\rdc.rc"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,368 @@
/*
rdesktop: A Remote Desktop Protocol client.
RDP order processing
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define RDP_ORDER_STANDARD 0x01
#define RDP_ORDER_SECONDARY 0x02
#define RDP_ORDER_BOUNDS 0x04
#define RDP_ORDER_CHANGE 0x08
#define RDP_ORDER_DELTA 0x10
#define RDP_ORDER_LASTBOUNDS 0x20
#define RDP_ORDER_SMALL 0x40
#define RDP_ORDER_TINY 0x80
enum RDP_ORDER_TYPE
{
RDP_ORDER_DESTBLT = 0,
RDP_ORDER_PATBLT = 1,
RDP_ORDER_SCREENBLT = 2,
RDP_ORDER_LINE = 9,
RDP_ORDER_RECT = 10,
RDP_ORDER_DESKSAVE = 11,
RDP_ORDER_MEMBLT = 13,
RDP_ORDER_TRIBLT = 14,
RDP_ORDER_POLYGON = 20,
RDP_ORDER_POLYGON2 = 21,
RDP_ORDER_POLYLINE = 22,
RDP_ORDER_ELLIPSE = 25,
RDP_ORDER_ELLIPSE2 = 26,
RDP_ORDER_TEXT2 = 27
};
enum RDP_SECONDARY_ORDER_TYPE
{
RDP_ORDER_RAW_BMPCACHE = 0,
RDP_ORDER_COLCACHE = 1,
RDP_ORDER_BMPCACHE = 2,
RDP_ORDER_FONTCACHE = 3,
RDP_ORDER_RAW_BMPCACHE2 = 4,
RDP_ORDER_BMPCACHE2 = 5,
RDP_ORDER_BRUSHCACHE = 7
};
typedef struct _DESTBLT_ORDER
{
sint16 x;
sint16 y;
sint16 cx;
sint16 cy;
uint8 opcode;
}
DESTBLT_ORDER;
typedef struct _PATBLT_ORDER
{
sint16 x;
sint16 y;
sint16 cx;
sint16 cy;
uint8 opcode;
uint32 bgcolour;
uint32 fgcolour;
BRUSH brush;
}
PATBLT_ORDER;
typedef struct _SCREENBLT_ORDER
{
sint16 x;
sint16 y;
sint16 cx;
sint16 cy;
uint8 opcode;
sint16 srcx;
sint16 srcy;
}
SCREENBLT_ORDER;
typedef struct _LINE_ORDER
{
uint16 mixmode;
sint16 startx;
sint16 starty;
sint16 endx;
sint16 endy;
uint32 bgcolour;
uint8 opcode;
PEN pen;
}
LINE_ORDER;
typedef struct _RECT_ORDER
{
sint16 x;
sint16 y;
sint16 cx;
sint16 cy;
uint32 colour;
}
RECT_ORDER;
typedef struct _DESKSAVE_ORDER
{
uint32 offset;
sint16 left;
sint16 top;
sint16 right;
sint16 bottom;
uint8 action;
}
DESKSAVE_ORDER;
typedef struct _TRIBLT_ORDER
{
uint8 colour_table;
uint8 cache_id;
sint16 x;
sint16 y;
sint16 cx;
sint16 cy;
uint8 opcode;
sint16 srcx;
sint16 srcy;
uint32 bgcolour;
uint32 fgcolour;
BRUSH brush;
uint16 cache_idx;
uint16 unknown;
}
TRIBLT_ORDER;
typedef struct _MEMBLT_ORDER
{
uint8 colour_table;
uint8 cache_id;
sint16 x;
sint16 y;
sint16 cx;
sint16 cy;
uint8 opcode;
sint16 srcx;
sint16 srcy;
uint16 cache_idx;
}
MEMBLT_ORDER;
#define MAX_DATA 256
typedef struct _POLYGON_ORDER
{
sint16 x;
sint16 y;
uint8 opcode;
uint8 fillmode;
uint32 fgcolour;
uint8 npoints;
uint8 datasize;
uint8 data[MAX_DATA];
}
POLYGON_ORDER;
typedef struct _POLYGON2_ORDER
{
sint16 x;
sint16 y;
uint8 opcode;
uint8 fillmode;
uint32 bgcolour;
uint32 fgcolour;
BRUSH brush;
uint8 npoints;
uint8 datasize;
uint8 data[MAX_DATA];
}
POLYGON2_ORDER;
typedef struct _POLYLINE_ORDER
{
sint16 x;
sint16 y;
uint8 opcode;
uint32 fgcolour;
uint8 lines;
uint8 datasize;
uint8 data[MAX_DATA];
}
POLYLINE_ORDER;
typedef struct _ELLIPSE_ORDER
{
sint16 left;
sint16 top;
sint16 right;
sint16 bottom;
uint8 opcode;
uint8 fillmode;
uint32 fgcolour;
}
ELLIPSE_ORDER;
typedef struct _ELLIPSE2_ORDER
{
sint16 left;
sint16 top;
sint16 right;
sint16 bottom;
uint8 opcode;
uint8 fillmode;
BRUSH brush;
uint32 bgcolour;
uint32 fgcolour;
}
ELLIPSE2_ORDER;
#define MAX_TEXT 256
typedef struct _TEXT2_ORDER
{
uint8 font;
uint8 flags;
uint8 opcode;
uint8 mixmode;
uint32 bgcolour;
uint32 fgcolour;
sint16 clipleft;
sint16 cliptop;
sint16 clipright;
sint16 clipbottom;
sint16 boxleft;
sint16 boxtop;
sint16 boxright;
sint16 boxbottom;
BRUSH brush;
sint16 x;
sint16 y;
uint8 length;
uint8 text[MAX_TEXT];
}
TEXT2_ORDER;
typedef struct _RDP_ORDER_STATE
{
uint8 order_type;
BOUNDS bounds;
DESTBLT_ORDER destblt;
PATBLT_ORDER patblt;
SCREENBLT_ORDER screenblt;
LINE_ORDER line;
RECT_ORDER rect;
DESKSAVE_ORDER desksave;
MEMBLT_ORDER memblt;
TRIBLT_ORDER triblt;
POLYGON_ORDER polygon;
POLYGON2_ORDER polygon2;
POLYLINE_ORDER polyline;
ELLIPSE_ORDER ellipse;
ELLIPSE2_ORDER ellipse2;
TEXT2_ORDER text2;
}
RDP_ORDER_STATE;
typedef struct _RDP_RAW_BMPCACHE_ORDER
{
uint8 cache_id;
uint8 pad1;
uint8 width;
uint8 height;
uint8 bpp;
uint16 bufsize;
uint16 cache_idx;
uint8 *data;
}
RDP_RAW_BMPCACHE_ORDER;
typedef struct _RDP_BMPCACHE_ORDER
{
uint8 cache_id;
uint8 pad1;
uint8 width;
uint8 height;
uint8 bpp;
uint16 bufsize;
uint16 cache_idx;
uint16 pad2;
uint16 size;
uint16 row_size;
uint16 final_size;
uint8 *data;
}
RDP_BMPCACHE_ORDER;
/* RDP_BMPCACHE2_ORDER */
#define ID_MASK 0x0007
#define MODE_MASK 0x0038
#define SQUARE 0x0080
#define PERSIST 0x0100
#define FLAG_51_UNKNOWN 0x0800
#define MODE_SHIFT 3
#define LONG_FORMAT 0x80
#define BUFSIZE_MASK 0x3FFF /* or 0x1FFF? */
#define MAX_GLYPH 32
typedef struct _RDP_FONT_GLYPH
{
uint16 character;
uint16 unknown;
uint16 baseline;
uint16 width;
uint16 height;
uint8 data[MAX_GLYPH];
}
RDP_FONT_GLYPH;
#define MAX_GLYPHS 256
typedef struct _RDP_FONTCACHE_ORDER
{
uint8 font;
uint8 nglyphs;
RDP_FONT_GLYPH glyphs[MAX_GLYPHS];
}
RDP_FONTCACHE_ORDER;
typedef struct _RDP_COLCACHE_ORDER
{
uint8 cache_id;
COLOURMAP map;
}
RDP_COLCACHE_ORDER;

View file

@ -0,0 +1,95 @@
/*
rdesktop: A Remote Desktop Protocol client.
Parsing primitives
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Parser state */
typedef struct stream
{
unsigned char *p;
unsigned char *end;
unsigned char *data;
unsigned int size;
/* Offsets of various headers */
unsigned char *iso_hdr;
unsigned char *mcs_hdr;
unsigned char *sec_hdr;
unsigned char *rdp_hdr;
unsigned char *channel_hdr;
}
*STREAM;
#define s_push_layer(s,h,n) { (s)->h = (s)->p; (s)->p += n; }
#define s_pop_layer(s,h) (s)->p = (s)->h;
#define s_mark_end(s) (s)->end = (s)->p;
#define s_check(s) ((s)->p <= (s)->end)
#define s_check_rem(s,n) ((s)->p + n <= (s)->end)
#define s_check_end(s) ((s)->p == (s)->end)
#if defined(L_ENDIAN) && !defined(NEED_ALIGN)
#define in_uint16_le(s,v) { v = *(uint16 *)((s)->p); (s)->p += 2; }
#define in_uint32_le(s,v) { v = *(uint32 *)((s)->p); (s)->p += 4; }
#define out_uint16_le(s,v) { *(uint16 *)((s)->p) = v; (s)->p += 2; }
#define out_uint32_le(s,v) { *(uint32 *)((s)->p) = v; (s)->p += 4; }
#else
#define in_uint16_le(s,v) { v = *((s)->p++); v += *((s)->p++) << 8; }
#define in_uint32_le(s,v) { in_uint16_le(s,v) \
v += *((s)->p++) << 16; v += *((s)->p++) << 24; }
#define out_uint16_le(s,v) { *((s)->p++) = (v) & 0xff; *((s)->p++) = ((v) >> 8) & 0xff; }
#define out_uint32_le(s,v) { out_uint16_le(s, (v) & 0xffff); out_uint16_le(s, ((v) >> 16) & 0xffff); }
#endif
#if defined(B_ENDIAN) && !defined(NEED_ALIGN)
#define in_uint16_be(s,v) { v = *(uint16 *)((s)->p); (s)->p += 2; }
#define in_uint32_be(s,v) { v = *(uint32 *)((s)->p); (s)->p += 4; }
#define out_uint16_be(s,v) { *(uint16 *)((s)->p) = v; (s)->p += 2; }
#define out_uint32_be(s,v) { *(uint32 *)((s)->p) = v; (s)->p += 4; }
#define B_ENDIAN_PREFERRED
#define in_uint16(s,v) in_uint16_be(s,v)
#define in_uint32(s,v) in_uint32_be(s,v)
#define out_uint16(s,v) out_uint16_be(s,v)
#define out_uint32(s,v) out_uint32_be(s,v)
#else
#define in_uint16_be(s,v) { v = *((s)->p++); next_be(s,v); }
#define in_uint32_be(s,v) { in_uint16_be(s,v); next_be(s,v); next_be(s,v); }
#define out_uint16_be(s,v) { *((s)->p++) = ((v) >> 8) & 0xff; *((s)->p++) = (v) & 0xff; }
#define out_uint32_be(s,v) { out_uint16_be(s, ((v) >> 16) & 0xffff); out_uint16_be(s, (v) & 0xffff); }
#endif
#ifndef B_ENDIAN_PREFERRED
#define in_uint16(s,v) in_uint16_le(s,v)
#define in_uint32(s,v) in_uint32_le(s,v)
#define out_uint16(s,v) out_uint16_le(s,v)
#define out_uint32(s,v) out_uint32_le(s,v)
#endif
#define in_uint8(s,v) v = *((s)->p++);
#define in_uint8p(s,v,n) { v = (s)->p; (s)->p += n; }
#define in_uint8a(s,v,n) { memcpy(v,(s)->p,n); (s)->p += n; }
#define in_uint8s(s,n) (s)->p += n;
#define out_uint8(s,v) *((s)->p++) = v;
#define out_uint8p(s,v,n) { memcpy((s)->p,v,n); (s)->p += n; }
#define out_uint8a(s,v,n) out_uint8p(s,v,n);
#define out_uint8s(s,n) { memset((s)->p,0,n); (s)->p += n; }
#define next_be(s,v) v = ((v) << 8) + *((s)->p++);

View file

@ -0,0 +1,310 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef RDESKTOP_PROTO_H
#define RDESKTOP_PROTO_H
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/* bitmap.c */
BOOL bitmap_decompress(uint8 * output, int width, int height, uint8 * input, int size, int Bpp);
/* cache.c */
void cache_rebuild_bmpcache_linked_list(uint8 id, sint16 * idx, int count);
void cache_bump_bitmap(uint8 id, uint16 idx, int bump);
void cache_evict_bitmap(uint8 id);
RD_HBITMAP cache_get_bitmap(uint8 id, uint16 idx);
void cache_put_bitmap(uint8 id, uint16 idx, RD_HBITMAP bitmap);
void cache_save_state(void);
FONTGLYPH *cache_get_font(uint8 font, uint16 character);
void cache_put_font(uint8 font, uint16 character, uint16 offset, uint16 baseline, uint16 width,
uint16 height, RD_HGLYPH pixmap);
DATABLOB *cache_get_text(uint8 cache_id);
void cache_put_text(uint8 cache_id, void *data, int length);
uint8 *cache_get_desktop(uint32 offset, int cx, int cy, int bytes_per_pixel);
void cache_put_desktop(uint32 offset, int cx, int cy, int scanline, int bytes_per_pixel,
uint8 * data);
RD_HCURSOR cache_get_cursor(uint16 cache_idx);
void cache_put_cursor(uint16 cache_idx, RD_HCURSOR cursor);
/* channels.c */
VCHANNEL *channel_register(char *name, uint32 flags, void (*callback) (STREAM));
STREAM channel_init(VCHANNEL * channel, uint32 length);
void channel_send(STREAM s, VCHANNEL * channel);
void channel_process(STREAM s, uint16 mcs_channel);
/* cliprdr.c */
void cliprdr_send_simple_native_format_announce(uint32 format);
void cliprdr_send_native_format_announce(uint8 * formats_data, uint32 formats_data_length);
void cliprdr_send_data_request(uint32 format);
void cliprdr_send_data(uint8 * data, uint32 length);
void cliprdr_set_mode(const char *optarg);
BOOL cliprdr_init(void);
/* disk.c */
int disk_enum_devices(uint32 * id, char *optarg);
RD_NTSTATUS disk_query_information(RD_NTHANDLE handle, uint32 info_class, STREAM out);
RD_NTSTATUS disk_set_information(RD_NTHANDLE handle, uint32 info_class, STREAM in, STREAM out);
RD_NTSTATUS disk_check_notify(RD_NTHANDLE handle);
RD_NTSTATUS disk_create_notify(RD_NTHANDLE handle, uint32 info_class);
RD_NTSTATUS disk_query_volume_information(RD_NTHANDLE handle, uint32 info_class, STREAM out);
RD_NTSTATUS disk_query_directory(RD_NTHANDLE handle, uint32 info_class, char *pattern, STREAM out);
/* mppc.c */
int mppc_expand(uint8 * data, uint32 clen, uint8 ctype, uint32 * roff, uint32 * rlen);
/* ewmhints.c */
int get_current_workarea(uint32 * x, uint32 * y, uint32 * width, uint32 * height);
void ewmh_init(void);
/* iso.c */
STREAM iso_init(int length);
void iso_send(STREAM s);
STREAM iso_recv(uint8 * rdpver);
BOOL iso_connect(char *server, char *username);
BOOL iso_reconnect(char *server);
void iso_disconnect(void);
void iso_reset_state(void);
/* licence.c */
void licence_process(STREAM s);
/* mcs.c */
STREAM mcs_init(int length);
void mcs_send_to_channel(STREAM s, uint16 channel);
void mcs_send(STREAM s);
STREAM mcs_recv(uint16 * channel, uint8 * rdpver);
BOOL mcs_connect(char *server, STREAM mcs_data, char *username);
BOOL mcs_reconnect(char *server, STREAM mcs_data);
void mcs_disconnect(void);
void mcs_reset_state(void);
/* orders.c */
void process_orders(STREAM s, uint16 num_orders);
void reset_order_state(void);
/* parallel.c */
int parallel_enum_devices(uint32 * id, char *optarg);
/* printer.c */
int printer_enum_devices(uint32 * id, char *optarg);
/* printercache.c */
int printercache_load_blob(char *printer_name, uint8 ** data);
void printercache_process(STREAM s);
/* pstcache.c */
void pstcache_touch_bitmap(uint8 cache_id, uint16 cache_idx, uint32 stamp);
BOOL pstcache_load_bitmap(uint8 cache_id, uint16 cache_idx);
BOOL pstcache_save_bitmap(uint8 cache_id, uint16 cache_idx, uint8 * key, uint8 width,
uint8 height, uint16 length, uint8 * data);
int pstcache_enumerate(uint8 id, HASH_KEY * keylist);
BOOL pstcache_init(uint8 cache_id);
/* rdesktop.c */
int main(int argc, char *argv[]);
void generate_random(uint8 * random);
void *xmalloc(int size);
char *xstrdup(const char *s);
void *xrealloc(void *oldmem, int size);
void xfree(void *mem);
void error(char *format, ...);
void warning(char *format, ...);
void unimpl(char *format, ...);
void hexdump(unsigned char *p, unsigned int len);
char *next_arg(char *src, char needle);
void toupper_str(char *p);
BOOL str_startswith(const char *s, const char *prefix);
BOOL str_handle_lines(const char *input, char **rest, str_handle_lines_t linehandler, void *data);
BOOL subprocess(char *const argv[], str_handle_lines_t linehandler, void *data);
char *l_to_a(long N, int base);
int load_licence(unsigned char **data);
void save_licence(unsigned char *data, int length);
BOOL rd_pstcache_mkdir(void);
int rd_open_file(char *filename);
void rd_close_file(int fd);
int rd_read_file(int fd, void *ptr, int len);
int rd_write_file(int fd, void *ptr, int len);
int rd_lseek_file(int fd, int offset);
BOOL rd_lock_file(int fd, int start, int len);
/* rdp5.c */
void rdp5_process(STREAM s);
/* rdp.c */
void rdp_out_unistr(STREAM s, char *string, int len);
int rdp_in_unistr(STREAM s, char *string, int uni_len);
void rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1,
uint16 param2);
void rdp_send_client_window_status(int status);
void process_colour_pointer_pdu(STREAM s);
void process_cached_pointer_pdu(STREAM s);
void process_system_pointer_pdu(STREAM s);
void process_bitmap_updates(STREAM s);
void process_palette(STREAM s);
void process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason);
void rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason);
BOOL rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason);
BOOL rdp_connect(char *server, uint32 flags, char *domain, char *password, char *command,
char *directory);
BOOL rdp_reconnect(char *server, uint32 flags, char *domain, char *password, char *command,
char *directory, char *cookie);
void rdp_reset_state(void);
void rdp_disconnect(void);
/* rdpdr.c */
int get_device_index(RD_NTHANDLE handle);
void convert_to_unix_filename(char *filename);
BOOL rdpdr_init(void);
void rdpdr_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv, BOOL * timeout);
struct async_iorequest *rdpdr_remove_iorequest(struct async_iorequest *prev,
struct async_iorequest *iorq);
void rdpdr_check_fds(fd_set * rfds, fd_set * wfds, BOOL timed_out);
BOOL rdpdr_abort_io(uint32 fd, uint32 major, RD_NTSTATUS status);
/* rdpsnd.c */
void rdpsnd_send_completion(uint16 tick, uint8 packet_index);
BOOL rdpsnd_init(void);
/* rdpsnd_oss.c */
BOOL wave_out_open(void);
void wave_out_close(void);
BOOL wave_out_format_supported(WAVEFORMATEX * pwfx);
BOOL wave_out_set_format(WAVEFORMATEX * pwfx);
void wave_out_volume(uint16 left, uint16 right);
void wave_out_write(STREAM s, uint16 tick, uint8 index);
void wave_out_play(void);
/* secure.c */
void sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt);
void sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2);
void buf_out_uint32(uint8 * buffer, uint32 value);
void sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 * data,
int datalen);
void sec_decrypt(uint8 * data, int length);
STREAM sec_init(uint32 flags, int maxlen);
void sec_send_to_channel(STREAM s, uint32 flags, uint16 channel);
void sec_send(STREAM s, uint32 flags);
void sec_process_mcs_data(STREAM s);
STREAM sec_recv(uint8 * rdpver);
BOOL sec_connect(char *server, char *username);
BOOL sec_reconnect(char *server);
void sec_disconnect(void);
void sec_reset_state(void);
/* serial.c */
int serial_enum_devices(uint32 * id, char *optarg);
BOOL serial_get_event(RD_NTHANDLE handle, uint32 * result);
BOOL serial_get_timeout(RD_NTHANDLE handle, uint32 length, uint32 * timeout, uint32 * itv_timeout);
/* tcp.c */
STREAM tcp_init(uint32 maxlen);
void tcp_send(STREAM s);
STREAM tcp_recv(STREAM s, uint32 length);
BOOL tcp_connect(char *server);
void tcp_disconnect(void);
char *tcp_get_address(void);
void tcp_reset_state(void);
/* xclip.c */
void ui_clip_format_announce(uint8 * data, uint32 length);
void ui_clip_handle_data(uint8 * data, uint32 length);
void ui_clip_request_failed(void);
void ui_clip_request_data(uint32 format);
void ui_clip_sync(void);
void ui_clip_set_mode(const char *optarg);
void xclip_init(void);
/* xkeymap.c */
BOOL xkeymap_from_locale(const char *locale);
FILE *xkeymap_open(const char *filename);
void xkeymap_init(void);
BOOL handle_special_keys(uint32 keysym, unsigned int state, uint32 ev_time, BOOL pressed);
key_translation xkeymap_translate_key(uint32 keysym, unsigned int keycode, unsigned int state);
void xkeymap_send_keys(uint32 keysym, unsigned int keycode, unsigned int state, uint32 ev_time,
BOOL pressed, uint8 nesting);
uint16 xkeymap_translate_button(unsigned int button);
char *get_ksname(uint32 keysym);
void save_remote_modifiers(uint8 scancode);
void restore_remote_modifiers(uint32 ev_time, uint8 scancode);
void ensure_remote_modifiers(uint32 ev_time, key_translation tr);
unsigned int read_keyboard_state(void);
uint16 ui_get_numlock_state(unsigned int state);
void reset_modifier_keys(void);
void rdp_send_scancode(uint32 time, uint16 flags, uint8 scancode);
/* xwin.c */
BOOL get_key_state(unsigned int state, uint32 keysym);
BOOL ui_init(void);
void ui_deinit(void);
BOOL ui_create_window(void);
void ui_resize_window(void);
void ui_destroy_window(void);
void xwin_toggle_fullscreen(void);
int ui_select(int rdp_socket);
void ui_move_pointer(int x, int y);
RD_HBITMAP ui_create_bitmap(int width, int height, uint8 * data);
void ui_paint_bitmap(int x, int y, int cx, int cy, int width, int height, uint8 * data);
void ui_destroy_bitmap(RD_HBITMAP bmp);
RD_HGLYPH ui_create_glyph(int width, int height, uint8 * data);
void ui_destroy_glyph(RD_HGLYPH glyph);
RD_HCURSOR ui_create_cursor(unsigned int x, unsigned int y, int width, int height, uint8 * andmask,
uint8 * xormask);
void ui_set_cursor(RD_HCURSOR cursor);
void ui_destroy_cursor(RD_HCURSOR cursor);
void ui_set_null_cursor(void);
RD_HCOLOURMAP ui_create_colourmap(COLOURMAP * colours);
void ui_destroy_colourmap(RD_HCOLOURMAP map);
void ui_set_colourmap(RD_HCOLOURMAP map);
void ui_set_clip(int x, int y, int cx, int cy);
void ui_reset_clip(void);
void ui_bell(void);
void ui_destblt(uint8 opcode, int x, int y, int cx, int cy);
void ui_patblt(uint8 opcode, int x, int y, int cx, int cy, BRUSH * brush, int bgcolour,
int fgcolour);
void ui_screenblt(uint8 opcode, int x, int y, int cx, int cy, int srcx, int srcy);
void ui_memblt(uint8 opcode, int x, int y, int cx, int cy, RD_HBITMAP src, int srcx, int srcy);
void ui_triblt(uint8 opcode, int x, int y, int cx, int cy, RD_HBITMAP src, int srcx, int srcy,
BRUSH * brush, int bgcolour, int fgcolour);
void ui_line(uint8 opcode, int startx, int starty, int endx, int endy, PEN * pen);
void ui_rect(int x, int y, int cx, int cy, int colour);
void ui_polygon(uint8 opcode, uint8 fillmode, POINT * point, int npoints, BRUSH * brush,
int bgcolour, int fgcolour);
void ui_polyline(uint8 opcode, POINT * points, int npoints, PEN * pen);
void ui_ellipse(uint8 opcode, uint8 fillmode, int x, int y, int cx, int cy, BRUSH * brush,
int bgcolour, int fgcolour);
void ui_draw_glyph(int mixmode, int x, int y, int cx, int cy, RD_HGLYPH glyph, int srcx, int srcy,
int bgcolour, int fgcolour);
void ui_draw_text(uint8 font, uint8 flags, uint8 opcode, int mixmode, int x, int y, int clipx,
int clipy, int clipcx, int clipcy, int boxx, int boxy, int boxcx, int boxcy,
BRUSH * brush, int bgcolour, int fgcolour, uint8 * text, uint8 length);
void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy);
void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy);
void ui_begin_update(void);
void ui_end_update(void);
void ui_seamless_begin(BOOL hidden);
void ui_seamless_hide_desktop(void);
void ui_seamless_unhide_desktop(void);
void ui_seamless_toggle(void);
void ui_seamless_create_window(unsigned long id, unsigned long group, unsigned long parent,
unsigned long flags);
void ui_seamless_destroy_window(unsigned long id, unsigned long flags);
void ui_seamless_move_window(unsigned long id, int x, int y, int width, int height,
unsigned long flags);
void ui_seamless_restack_window(unsigned long id, unsigned long behind, unsigned long flags);
void ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags);
void ui_seamless_setstate(unsigned long id, unsigned int state, unsigned long flags);
void ui_seamless_syncbegin(unsigned long flags);
void ui_seamless_ack(unsigned int serial);
/* lspci.c */
BOOL lspci_init(void);
/* seamless.c */
BOOL seamless_init(void);
unsigned int seamless_send_sync(void);
unsigned int seamless_send_state(unsigned long id, unsigned int state, unsigned long flags);
unsigned int seamless_send_position(unsigned long id, int x, int y, int width, int height,
unsigned long flags);
void seamless_select_timeout(struct timeval *tv);
unsigned int seamless_send_zchange(unsigned long id, unsigned long below, unsigned long flags);
unsigned int seamless_send_focus(unsigned long id, unsigned long flags);
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif

View file

@ -0,0 +1,200 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Persistent Bitmap Cache routines
Copyright (C) Jeroen Meijer 2004-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
#define MAX_CELL_SIZE 0x1000 /* pixels */
#define IS_PERSISTENT(id) (id < 8 && g_pstcache_fd[id] > 0)
extern int g_server_depth;
extern BOOL g_bitmap_cache;
extern BOOL g_bitmap_cache_persist_enable;
extern BOOL g_bitmap_cache_precache;
int g_pstcache_fd[8];
int g_pstcache_Bpp;
BOOL g_pstcache_enumerated = False;
uint8 zero_key[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
/* Update mru stamp/index for a bitmap */
void
pstcache_touch_bitmap(uint8 cache_id, uint16 cache_idx, uint32 stamp)
{
int fd;
if (!IS_PERSISTENT(cache_id) || cache_idx >= BMPCACHE2_NUM_PSTCELLS)
return;
fd = g_pstcache_fd[cache_id];
rd_lseek_file(fd, 12 + cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
rd_write_file(fd, &stamp, sizeof(stamp));
}
/* Load a bitmap from the persistent cache */
BOOL
pstcache_load_bitmap(uint8 cache_id, uint16 cache_idx)
{
uint8 *celldata;
int fd;
CELLHEADER cellhdr;
HBITMAP bitmap;
if (!g_bitmap_cache_persist_enable)
return False;
if (!IS_PERSISTENT(cache_id) || cache_idx >= BMPCACHE2_NUM_PSTCELLS)
return False;
fd = g_pstcache_fd[cache_id];
rd_lseek_file(fd, cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
rd_read_file(fd, &cellhdr, sizeof(CELLHEADER));
celldata = (uint8 *) xmalloc(cellhdr.length);
rd_read_file(fd, celldata, cellhdr.length);
bitmap = ui_create_bitmap(cellhdr.width, cellhdr.height, celldata);
DEBUG(("Load bitmap from disk: id=%d, idx=%d, bmp=0x%x)\n", cache_id, cache_idx, bitmap));
cache_put_bitmap(cache_id, cache_idx, bitmap);
xfree(celldata);
return True;
}
/* Store a bitmap in the persistent cache */
BOOL
pstcache_save_bitmap(uint8 cache_id, uint16 cache_idx, uint8 * key,
uint8 width, uint8 height, uint16 length, uint8 * data)
{
int fd;
CELLHEADER cellhdr;
if (!IS_PERSISTENT(cache_id) || cache_idx >= BMPCACHE2_NUM_PSTCELLS)
return False;
memcpy(cellhdr.key, key, sizeof(HASH_KEY));
cellhdr.width = width;
cellhdr.height = height;
cellhdr.length = length;
cellhdr.stamp = 0;
fd = g_pstcache_fd[cache_id];
rd_lseek_file(fd, cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
rd_write_file(fd, &cellhdr, sizeof(CELLHEADER));
rd_write_file(fd, data, length);
return True;
}
/* List the bitmap keys from the persistent cache file */
int
pstcache_enumerate(uint8 id, HASH_KEY * keylist)
{
int fd, n;
uint16 idx;
sint16 mru_idx[0xa00];
uint32 mru_stamp[0xa00];
CELLHEADER cellhdr;
if (!(g_bitmap_cache && g_bitmap_cache_persist_enable && IS_PERSISTENT(id)))
return 0;
/* The server disconnects if the bitmap cache content is sent more than once */
if (g_pstcache_enumerated)
return 0;
DEBUG_RDP5(("Persistent bitmap cache enumeration... "));
for (idx = 0; idx < BMPCACHE2_NUM_PSTCELLS; idx++)
{
fd = g_pstcache_fd[id];
rd_lseek_file(fd, idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
if (rd_read_file(fd, &cellhdr, sizeof(CELLHEADER)) <= 0)
break;
if (memcmp(cellhdr.key, zero_key, sizeof(HASH_KEY)) != 0)
{
memcpy(keylist[idx], cellhdr.key, sizeof(HASH_KEY));
/* Pre-cache (not possible for 8 bit colour depth cause it needs a colourmap) */
if (g_bitmap_cache_precache && cellhdr.stamp && g_server_depth > 8)
pstcache_load_bitmap(id, idx);
/* Sort by stamp */
for (n = idx; n > 0 && cellhdr.stamp < mru_stamp[n - 1]; n--)
{
mru_idx[n] = mru_idx[n - 1];
mru_stamp[n] = mru_stamp[n - 1];
}
mru_idx[n] = idx;
mru_stamp[n] = cellhdr.stamp;
}
else
{
break;
}
}
DEBUG_RDP5(("%d cached bitmaps.\n", idx));
cache_rebuild_bmpcache_linked_list(id, mru_idx, idx);
g_pstcache_enumerated = True;
return idx;
}
/* initialise the persistent bitmap cache */
BOOL
pstcache_init(uint8 cache_id)
{
int fd;
char filename[256];
if (g_pstcache_enumerated)
return True;
g_pstcache_fd[cache_id] = 0;
if (!(g_bitmap_cache && g_bitmap_cache_persist_enable))
return False;
if (!rd_pstcache_mkdir())
{
DEBUG(("failed to get/make cache directory!\n"));
return False;
}
g_pstcache_Bpp = (g_server_depth + 7) / 8;
sprintf(filename, "cache/pstcache_%d_%d", cache_id, g_pstcache_Bpp);
DEBUG(("persistent bitmap cache file: %s\n", filename));
fd = rd_open_file(filename);
if (fd == -1)
return False;
if (!rd_lock_file(fd, 0, 0))
{
warning("Persistent bitmap caching is disabled. (The file is already in use)\n");
rd_close_file(fd);
return False;
}
g_pstcache_fd[cache_id] = fd;
return True;
}

View file

@ -0,0 +1,9 @@
#include <windows.h>
#include "resource.h"
#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Remote Desktop Client\0"
#define REACTOS_STR_INTERNAL_NAME "mstsc\0"
#define REACTOS_STR_ORIGINAL_FILENAME "mstsc.exe\0"
//#include <reactos/version.rc>
#include "rsrc.rc"

View file

@ -0,0 +1,126 @@
/*
rdesktop: A Remote Desktop Protocol client.
Master include file
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef _WIN32
#include <winsock2.h> /* winsock2.h first */
#include <windows.h>
#include <time.h>
#else /* WIN32 */
#include <dirent.h>
#include <sys/types.h>
#include <sys/time.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#else /* HAVE_SYS_SELECT_H */
#include <sys/types.h>
#include <unistd.h>
#endif /* HAVE_SYS_SELECT_H */
#endif /* WIN32 */
#include <limits.h> /* PATH_MAX */
#define VERSION "1.4.1"
#ifdef WITH_DEBUG
#define DEBUG(args) printf args;
#else
#define DEBUG(args)
#endif
#ifdef WITH_DEBUG_KBD
#define DEBUG_KBD(args) printf args;
#else
#define DEBUG_KBD(args)
#endif
#ifdef WITH_DEBUG_RDP5
#define DEBUG_RDP5(args) printf args;
#else
#define DEBUG_RDP5(args)
#endif
#ifdef WITH_DEBUG_CLIPBOARD
#define DEBUG_CLIPBOARD(args) printf args;
#else
#define DEBUG_CLIPBOARD(args)
#endif
#ifdef WITH_DEBUG_CHANNEL
#define DEBUG_CHANNEL(args) printf args;
#else
#define DEBUG_CHANNEL(args)
#endif
#define STRNCPY(dst,src,n) { strncpy(dst,src,n-1); dst[n-1] = 0; }
#ifndef MIN
#define MIN(x,y) (((x) < (y)) ? (x) : (y))
#endif
#ifndef MAX
#define MAX(x,y) (((x) > (y)) ? (x) : (y))
#endif
/* timeval macros */
#ifndef timerisset
#define timerisset(tvp)\
((tvp)->tv_sec || (tvp)->tv_usec)
#endif
#ifndef timercmp
#define timercmp(tvp, uvp, cmp)\
((tvp)->tv_sec cmp (uvp)->tv_sec ||\
(tvp)->tv_sec == (uvp)->tv_sec &&\
(tvp)->tv_usec cmp (uvp)->tv_usec)
#endif
#ifndef timerclear
#define timerclear(tvp)\
((tvp)->tv_sec = (tvp)->tv_usec = 0)
#endif
/* If configure does not define the endianess, try
to find it out */
#if !defined(L_ENDIAN) && !defined(B_ENDIAN)
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define L_ENDIAN
#elif __BYTE_ORDER == __BIG_ENDIAN
#define B_ENDIAN
#else
#error Unknown endianness. Edit rdesktop.h.
#endif
#endif /* B_ENDIAN, L_ENDIAN from configure */
/* No need for alignment on x86 and amd64 */
#if !defined(NEED_ALIGN)
#if !(defined(__x86__) || defined(__x86_64__) || \
defined(__AMD64__) || defined(_M_IX86) || \
defined(__i386__))
#define NEED_ALIGN
#endif
#endif
#include "parse.h"
#include "constants.h"
#include "types.h"
#ifndef MAKE_PROTO
#include "proto.h"
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,121 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Protocol services - RDP5 short form PDU processing
Copyright (C) Matthew Chapman 1999-2005
Copyright (C) Erik Forsberg 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
extern uint8 *g_next_packet;
extern RDPCOMP g_mppc_dict;
void
rdp5_process(STREAM s)
{
uint16 length, count, x, y;
uint8 type, ctype;
uint8 *next;
uint32 roff, rlen;
struct stream *ns = &(g_mppc_dict.ns);
struct stream *ts;
#if 0
printf("RDP5 data:\n");
hexdump(s->p, s->end - s->p);
#endif
ui_begin_update();
while (s->p < s->end)
{
in_uint8(s, type);
if (type & RDP5_COMPRESSED)
{
in_uint8(s, ctype);
in_uint16_le(s, length);
type ^= RDP5_COMPRESSED;
}
else
{
ctype = 0;
in_uint16_le(s, length);
}
g_next_packet = next = s->p + length;
if (ctype & RDP_MPPC_COMPRESSED)
{
if (mppc_expand(s->p, length, ctype, &roff, &rlen) == -1)
error("error while decompressing packet\n");
/* allocate memory and copy the uncompressed data into the temporary stream */
ns->data = (uint8 *) xrealloc(ns->data, rlen);
memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
ns->size = rlen;
ns->end = (ns->data + ns->size);
ns->p = ns->data;
ns->rdp_hdr = ns->p;
ts = ns;
}
else
ts = s;
switch (type)
{
case 0: /* update orders */
in_uint16_le(ts, count);
process_orders(ts, count);
break;
case 1: /* update bitmap */
in_uint8s(ts, 2); /* part length */
process_bitmap_updates(ts);
break;
case 2: /* update palette */
in_uint8s(ts, 2); /* uint16 = 2 */
process_palette(ts);
break;
case 3: /* update synchronize */
break;
case 5: /* null pointer */
ui_set_null_cursor();
break;
case 6: /* default pointer */
break;
case 8: /* pointer position */
in_uint16_le(ts, x);
in_uint16_le(ts, y);
if (s_check(ts))
ui_move_pointer(x, y);
break;
case 9: /* color pointer */
process_colour_pointer_pdu(ts);
break;
case 10: /* cached pointer */
process_cached_pointer_pdu(ts);
break;
default:
unimpl("RDP5 opcode %d\n", type);
}
s->p = next;
}
ui_end_update();
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View file

@ -0,0 +1,28 @@
#define IDD_CONNECTDIALOG 101
#define IDD_GENERAL 105
#define IDS_TAB_DISPLAY 106
#define IDD_DISPLAY 107
#define IDC_TAB 1003
#define IDC_SERVERCOMBO 1007
#define IDC_SAVE 1008
#define IDC_SAVEAS 1009
#define IDC_OPEN 1010
#define IDC_GEOSLIDER 1012
#define IDC_BPPCOMBO 1013
#define IDC_LOGONICON 1016
#define IDC_CONNICON 1017
#define IDC_REMICON 1014
#define IDC_COLORSICON 1015
#define IDB_HEADER 1016
#define IDB_SPECT 1017
#define IDC_COLORIMAGE 1018
#define IDS_TAB_GENERAL 1104
#define IDC_STATIC -1
#define IDI_LOGON 2000
#define IDI_CONN 2001
#define IDI_REMOTE 2002
#define IDI_COLORS 2003

View file

@ -0,0 +1,16 @@
#include <windows.h>
#include "resource.h"
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
//1 24 DISCARDABLE "manifest.xml"
IDI_LOGON ICON "res/logon.ico"
IDI_CONN ICON "res/connection.ico"
IDI_REMOTE ICON "res/remote.ico"
IDI_COLORS ICON "res/colors.ico"
IDB_HEADER BITMAP "res/header.bmp"
IDB_SPECT BITMAP "res/spectrum.bmp"
#include "lang/en-US.rc"

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,309 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Protocol services - TCP layer
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _WIN32
#include <unistd.h> /* select read write close */
#include <sys/socket.h> /* socket connect setsockopt */
#include <sys/time.h> /* timeval */
#include <netdb.h> /* gethostbyname */
#include <netinet/in.h> /* sockaddr_in */
#include <netinet/tcp.h> /* TCP_NODELAY */
#include <arpa/inet.h> /* inet_addr */
#include <errno.h> /* errno */
#endif /* _WIN32 */
#include "rdesktop.h"
#ifdef _WIN32
#define socklen_t int
#define TCP_CLOSE(_sck) closesocket(_sck)
#define TCP_STRERROR "tcp error"
#define TCP_SLEEP(_n) Sleep(_n)
#define TCP_BLOCKS (WSAGetLastError() == WSAEWOULDBLOCK)
#else /* _WIN32 */
#define TCP_CLOSE(_sck) close(_sck)
#define TCP_STRERROR strerror(errno)
#define TCP_SLEEP(_n) sleep(_n)
#define TCP_BLOCKS (errno == EWOULDBLOCK)
#endif /* _WIN32 */
#ifndef INADDR_NONE
#define INADDR_NONE ((unsigned long) -1)
#endif
static int sock;
static struct stream in;
static struct stream out;
int g_tcp_port_rdp = TCP_PORT_RDP;
/* Initialise TCP transport data packet */
STREAM
tcp_init(uint32 maxlen)
{
if (maxlen > out.size)
{
out.data = (uint8 *) xrealloc(out.data, maxlen);
out.size = maxlen;
}
out.p = out.data;
out.end = out.data + out.size;
return &out;
}
/* Send TCP transport data packet */
void
tcp_send(STREAM s)
{
int length = s->end - s->data;
int sent, total = 0;
while (total < length)
{
sent = send(sock, s->data + total, length - total, 0);
if (sent <= 0)
{
if (sent == -1 && TCP_BLOCKS)
{
TCP_SLEEP(0);
sent = 0;
}
else
{
error("send: %s\n", TCP_STRERROR);
return;
}
}
total += sent;
}
}
/* Receive a message on the TCP layer */
STREAM
tcp_recv(STREAM s, uint32 length)
{
unsigned int new_length, end_offset, p_offset;
int rcvd = 0;
if (s == NULL)
{
/* read into "new" stream */
if (length > in.size)
{
in.data = (uint8 *) xrealloc(in.data, length);
in.size = length;
}
in.end = in.p = in.data;
s = &in;
}
else
{
/* append to existing stream */
new_length = (s->end - s->data) + length;
if (new_length > s->size)
{
p_offset = s->p - s->data;
end_offset = s->end - s->data;
s->data = (uint8 *) xrealloc(s->data, new_length);
s->size = new_length;
s->p = s->data + p_offset;
s->end = s->data + end_offset;
}
}
while (length > 0)
{
if (!ui_select(sock))
/* User quit */
return NULL;
rcvd = recv(sock, s->end, length, 0);
if (rcvd < 0)
{
if (rcvd == -1 && TCP_BLOCKS)
{
TCP_SLEEP(0);
rcvd = 0;
}
else
{
error("recv: %s\n", TCP_STRERROR);
return NULL;
}
}
else if (rcvd == 0)
{
error("Connection closed\n");
return NULL;
}
s->end += rcvd;
length -= rcvd;
}
return s;
}
/* Establish a connection on the TCP layer */
BOOL
tcp_connect(char *server)
{
int true_value = 1;
#ifdef IPv6
int n;
struct addrinfo hints, *res, *ressave;
char tcp_port_rdp_s[10];
snprintf(tcp_port_rdp_s, 10, "%d", g_tcp_port_rdp);
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if ((n = getaddrinfo(server, tcp_port_rdp_s, &hints, &res)))
{
error("getaddrinfo: %s\n", gai_strerror(n));
return False;
}
ressave = res;
sock = -1;
while (res)
{
sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (!(sock < 0))
{
if (connect(sock, res->ai_addr, res->ai_addrlen) == 0)
break;
TCP_CLOSE(sock);
sock = -1;
}
res = res->ai_next;
}
freeaddrinfo(ressave);
if (sock == -1)
{
error("%s: unable to connect\n", server);
return False;
}
#else /* no IPv6 support */
struct hostent *nslookup;
struct sockaddr_in servaddr;
if ((nslookup = gethostbyname(server)) != NULL)
{
memcpy(&servaddr.sin_addr, nslookup->h_addr, sizeof(servaddr.sin_addr));
}
else if ((servaddr.sin_addr.s_addr = inet_addr(server)) == INADDR_NONE)
{
error("%s: unable to resolve host\n", server);
return False;
}
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
error("socket: %s\n", TCP_STRERROR);
return False;
}
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons((uint16) g_tcp_port_rdp);
if (connect(sock, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) < 0)
{
error("connect: %s\n", TCP_STRERROR);
TCP_CLOSE(sock);
return False;
}
#endif /* IPv6 */
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *) &true_value, sizeof(true_value));
in.size = 4096;
in.data = (uint8 *) xmalloc(in.size);
out.size = 4096;
out.data = (uint8 *) xmalloc(out.size);
return True;
}
/* Disconnect on the TCP layer */
void
tcp_disconnect(void)
{
TCP_CLOSE(sock);
}
char *
tcp_get_address()
{
static char ipaddr[32];
struct sockaddr_in sockaddr;
socklen_t len = sizeof(sockaddr);
if (getsockname(sock, (struct sockaddr *) &sockaddr, &len) == 0)
{
unsigned char *ip = (unsigned char *) &sockaddr.sin_addr;
sprintf(ipaddr, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
}
else
strcpy(ipaddr, "127.0.0.1");
return ipaddr;
}
/* reset the state of the tcp layer */
/* Support for Session Directory */
void
tcp_reset_state(void)
{
sock = -1; /* reset socket */
/* Clear the incoming stream */
if (in.data != NULL)
xfree(in.data);
in.p = NULL;
in.end = NULL;
in.data = NULL;
in.size = 0;
in.iso_hdr = NULL;
in.mcs_hdr = NULL;
in.sec_hdr = NULL;
in.rdp_hdr = NULL;
in.channel_hdr = NULL;
/* Clear the outgoing stream */
if (out.data != NULL)
xfree(out.data);
out.p = NULL;
out.end = NULL;
out.data = NULL;
out.size = 0;
out.iso_hdr = NULL;
out.mcs_hdr = NULL;
out.sec_hdr = NULL;
out.rdp_hdr = NULL;
out.channel_hdr = NULL;
}

View file

@ -0,0 +1,270 @@
/*
rdesktop: A Remote Desktop Protocol client.
Common data types
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
typedef int BOOL;
#ifndef True
#define True (1)
#define False (0)
#endif
typedef unsigned char uint8;
typedef signed char sint8;
typedef unsigned short uint16;
typedef signed short sint16;
typedef unsigned int uint32;
typedef signed int sint32;
typedef void *RD_HBITMAP;
typedef void *RD_HGLYPH;
typedef void *RD_HCOLOURMAP;
typedef void *RD_HCURSOR;
typedef struct _RD_POINT
{
sint16 x, y;
}
RD_POINT;
typedef struct _COLOURENTRY
{
uint8 red;
uint8 green;
uint8 blue;
}
COLOURENTRY;
typedef struct _COLOURMAP
{
uint16 ncolours;
COLOURENTRY *colours;
}
COLOURMAP;
typedef struct _BOUNDS
{
sint16 left;
sint16 top;
sint16 right;
sint16 bottom;
}
BOUNDS;
typedef struct _PEN
{
uint8 style;
uint8 width;
uint32 colour;
}
PEN;
typedef struct _BRUSH
{
uint8 xorigin;
uint8 yorigin;
uint8 style;
uint8 pattern[8];
}
BRUSH;
typedef struct _FONTGLYPH
{
sint16 offset;
sint16 baseline;
uint16 width;
uint16 height;
RD_HBITMAP pixmap;
}
FONTGLYPH;
typedef struct _DATABLOB
{
void *data;
int size;
}
DATABLOB;
typedef struct _key_translation
{
/* For normal scancode translations */
uint8 scancode;
uint16 modifiers;
/* For sequences. If keysym is nonzero, the fields above are not used. */
uint32 seq_keysym; /* Really KeySym */
struct _key_translation *next;
}
key_translation;
typedef struct _VCHANNEL
{
uint16 mcs_id;
char name[8];
uint32 flags;
struct stream in;
void (*process) (STREAM);
}
VCHANNEL;
/* PSTCACHE */
typedef uint8 HASH_KEY[8];
/* Header for an entry in the persistent bitmap cache file */
typedef struct _PSTCACHE_CELLHEADER
{
HASH_KEY key;
uint8 width, height;
uint16 length;
uint32 stamp;
}
CELLHEADER;
#define MAX_CBSIZE 256
/* RDPSND */
typedef struct
{
uint16 wFormatTag;
uint16 nChannels;
uint32 nSamplesPerSec;
uint32 nAvgBytesPerSec;
uint16 nBlockAlign;
uint16 wBitsPerSample;
uint16 cbSize;
uint8 cb[MAX_CBSIZE];
} RD_WAVEFORMATEX;
typedef struct _RDPCOMP
{
uint32 roff;
uint8 hist[RDP_MPPC_DICT_SIZE];
struct stream ns;
}
RDPCOMP;
/* RDPDR */
typedef uint32 RD_NTSTATUS;
typedef uint32 RD_NTHANDLE;
typedef struct _DEVICE_FNS
{
RD_NTSTATUS(*create) (uint32 device, uint32 desired_access, uint32 share_mode,
uint32 create_disposition, uint32 flags_and_attributes, char *filename,
RD_NTHANDLE * handle);
RD_NTSTATUS(*close) (RD_NTHANDLE handle);
RD_NTSTATUS(*read) (RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset,
uint32 * result);
RD_NTSTATUS(*write) (RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset,
uint32 * result);
RD_NTSTATUS(*device_control) (RD_NTHANDLE handle, uint32 request, STREAM in, STREAM out);
}
DEVICE_FNS;
typedef struct rdpdr_device_info
{
uint32 device_type;
RD_NTHANDLE handle;
char name[8];
char *local_path;
void *pdevice_data;
}
RDPDR_DEVICE;
typedef struct rdpdr_serial_device_info
{
int dtr;
int rts;
uint32 control, xonoff, onlimit, offlimit;
uint32 baud_rate,
queue_in_size,
queue_out_size,
wait_mask,
read_interval_timeout,
read_total_timeout_multiplier,
read_total_timeout_constant,
write_total_timeout_multiplier, write_total_timeout_constant, posix_wait_mask;
uint8 stop_bits, parity, word_length;
uint8 chars[6];
struct termios *ptermios, *pold_termios;
int event_txempty, event_cts, event_dsr, event_rlsd, event_pending;
}
SERIAL_DEVICE;
typedef struct rdpdr_parallel_device_info
{
char *driver, *printer;
uint32 queue_in_size,
queue_out_size,
wait_mask,
read_interval_timeout,
read_total_timeout_multiplier,
read_total_timeout_constant,
write_total_timeout_multiplier,
write_total_timeout_constant, posix_wait_mask, bloblen;
uint8 *blob;
}
PARALLEL_DEVICE;
typedef struct rdpdr_printer_info
{
FILE *printer_fp;
char *driver, *printer;
uint32 bloblen;
uint8 *blob;
BOOL default_printer;
}
PRINTER;
typedef struct notify_data
{
time_t modify_time;
time_t status_time;
time_t total_time;
unsigned int num_entries;
}
NOTIFY;
#ifndef PATH_MAX
#define PATH_MAX 256
#endif
#ifndef _WIN32
typedef struct fileinfo
{
uint32 device_id, flags_and_attributes, accessmask;
char path[PATH_MAX];
DIR *pdir;
struct dirent *pdirent;
char pattern[PATH_MAX];
BOOL delete_on_close;
NOTIFY notify;
uint32 info_class;
}
FILEINFO;
#endif
typedef BOOL(*str_handle_lines_t) (const char *line, void *data);

View file

@ -0,0 +1,979 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Main ui file
Copyright (C) Jay Sorg 2006
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
#include "bsops.h"
char g_username[256] = "";
char g_hostname[256] = "";
char g_servername[256] = "";
char g_password[256] = "";
char g_shell[256] = "";
char g_directory[256] = "";
char g_domain[256] = "";
BOOL g_desktop_save = False; /* desktop save order */
BOOL g_polygon_ellipse_orders = False; /* polygon / ellipse orders */
BOOL g_bitmap_compression = True;
uint32 g_rdp5_performanceflags =
RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS;
BOOL g_bitmap_cache_persist_enable = False;
BOOL g_bitmap_cache_precache = True;
BOOL g_bitmap_cache = True;
BOOL g_encryption = True;
int g_server_depth = 8;
BOOL g_use_rdp5 = False;
int g_width = 800;
int g_height = 600;
uint32 g_keylayout = 0x409; /* Defaults to US keyboard layout */
int g_keyboard_type = 0x4; /* Defaults to US keyboard layout */
int g_keyboard_subtype = 0x0; /* Defaults to US keyboard layout */
int g_keyboard_functionkeys = 0xc; /* Defaults to US keyboard layout */
BOOL g_console_session = False;
/* can't be static, hardware file or bsops need these */
int g_tcp_sck = 0;
int pal_entries[256];
/* Session Directory redirection */
BOOL g_redirect = False;
char g_redirect_server[64];
char g_redirect_domain[16];
char g_redirect_password[64];
char g_redirect_username[64];
char g_redirect_cookie[128];
uint32 g_redirect_flags = 0;
extern int g_tcp_port_rdp;
static int g_deactivated = 0;
static uint32 g_ext_disc_reason = 0;
struct bitmap
{
uint8 * data;
uint32 width;
uint32 height;
};
/* in ui specific file eg win32.c, qt.c, df.c, ... */
int
mi_create_window(void);
int
mi_main_loop(void);
void
mi_error(char * msg);
void
mi_warning(char * msg);
void
mi_paint_rect(char * data, int width, int height, int x, int y, int cx, int cy);
void
mi_begin_update(void);
void
mi_end_update(void);
void
mi_fill_rect(int x, int y, int cx, int cy, int colour);
void
mi_screen_copy(int x, int y, int cx, int cy, int srcx, int srcy);
void
mi_set_clip(int x, int y, int cx, int cy);
void
mi_reset_clip(void);
void
mi_line(int x1, int y1, int x2, int y2, int colour);
mi_create_cursor(unsigned int x, unsigned int y,
int width, int height,
unsigned char * andmask, unsigned char * xormask);
void
mi_destroy_cursor(void * cursor);
void
mi_set_cursor(void * cursor);
void
mi_set_null_cursor(void);
int
mi_read_keyboard_state(void);
/*****************************************************************************/
/* put part of the screen from the backing store to the display */
void
ui_invalidate(int x, int y, int cx, int cy)
{
char * data;
if (cx < 1 || cy < 1)
{
return;
}
if (bs_warp_coords(&x, &y, &cx, &cy, 0, 0))
{
cx = (cx + 3) & ~3;
data = (char *) xmalloc(cx * cy * 4);
bs_copy_box(data, x, y, cx, cy, cx * ((g_server_depth + 7) / 8));
mi_paint_rect(data, cx, cy, x, y, cx, cy);
xfree(data);
}
}
/*****************************************************************************/
void
ui_bell(void)
{
}
/*****************************************************************************/
int
ui_select(int in)
{
if (g_tcp_sck == 0)
{
g_tcp_sck = in;
}
return 1;
}
/*****************************************************************************/
void *
ui_create_cursor(uint32 x, uint32 y,
int width, int height,
uint8 * andmask, uint8 * xormask)
{
int i;
int j;
char am[32 * 4];
char xm[32 * 4];
if (width != 32 || height != 32)
{
return 0;
}
memset(am, 0, 32 * 4);
memset(xm, 0, 32 * 4);
for (i = 0; i < 32; i++)
{
for (j = 0; j < 32; j++)
{
if (bs_is_pixel_on(andmask, j, i, 32, 1))
{
bs_set_pixel_on(am, j, 31 - i, 32, 1, 1);
}
if (bs_is_pixel_on(xormask, j, i, 32, 24))
{
bs_set_pixel_on(xm, j, 31 - i, 32, 1, 1);
}
}
}
return (void *) mi_create_cursor(x, y, width, height, am, xm);
}
/*****************************************************************************/
void
ui_destroy_cursor(void * cursor)
{
mi_destroy_cursor(cursor);
}
/*****************************************************************************/
void
ui_set_cursor(void * cursor)
{
mi_set_cursor(cursor);
}
/*****************************************************************************/
void
ui_set_null_cursor(void)
{
mi_set_null_cursor();
}
/*****************************************************************************/
void *
ui_create_glyph(int width, int height, uint8 * data)
{
int i;
int j;
char * glyph_data;
struct bitmap * the_glyph;
glyph_data = (char *) xmalloc(width * height);
memset(glyph_data, 0, width * height);
the_glyph = (struct bitmap *) xmalloc(sizeof(struct bitmap));
memset(the_glyph, 0, sizeof(struct bitmap));
the_glyph->width = width;
the_glyph->height = height;
the_glyph->data = glyph_data;
for (i = 0; i < height; i++)
{
for (j = 0; j < width; j++)
{
if (bs_is_pixel_on(data, j, i, width, 1))
{
bs_set_pixel_on(glyph_data, j, i, width, 8, 255);
}
}
}
return the_glyph;
}
/*****************************************************************************/
void
ui_destroy_glyph(void * glyph)
{
struct bitmap * the_glyph;
the_glyph = glyph;
if (the_glyph != 0)
{
xfree(the_glyph->data);
}
xfree(the_glyph);
}
/*****************************************************************************/
void *
ui_create_bitmap(int width, int height, uint8 * data)
{
struct bitmap * b;
int size;
size = width * height * ((g_server_depth + 7) / 8);
b = (struct bitmap *) xmalloc(sizeof(struct bitmap));
b->data = (uint8 *) xmalloc(size);
memcpy(b->data, data, size);
b->width = width;
b->height = height;
return b;
}
/*****************************************************************************/
void
ui_destroy_bitmap(void * bmp)
{
struct bitmap * b;
b = (struct bitmap *) bmp;
if (b != 0)
{
xfree(b->data);
}
xfree(b);
}
/*****************************************************************************/
void
ui_paint_bitmap(int x, int y, int cx, int cy,
int width, int height, uint8 * data)
{
struct bitmap b;
b.width = width;
b.height = height;
b.data = data;
ui_memblt(12, x, y, cx, cy, &b, 0, 0);
}
/*****************************************************************************/
void
ui_set_clip(int x, int y, int cx, int cy)
{
bs_set_clip(x, y, cx, cy);
mi_set_clip(x, y, cx, cy);
}
/*****************************************************************************/
void
ui_reset_clip(void)
{
bs_reset_clip();
mi_reset_clip();
}
/*****************************************************************************/
void *
ui_create_colourmap(COLOURMAP * colours)
{
int i;
int n;
n = MIN(256, colours->ncolours);
memset(pal_entries, 0, sizeof(pal_entries));
for (i = 0; i < n; i++)
{
pal_entries[i] = (colours->colours[i].red << 16) |
(colours->colours[i].green << 8) |
colours->colours[i].blue;
}
return 0;
}
/*****************************************************************************/
void
ui_set_colourmap(void * map)
{
}
/*****************************************************************************/
static void
draw_glyph(int x, int y, void * glyph, int fgcolor)
{
struct bitmap * b;
b = glyph;
bs_draw_glyph(x, y, b->data, b->width, b->height, fgcolor);
}
/*****************************************************************************/
#define DO_GLYPH(ttext,idx) \
{ \
glyph = cache_get_font(font, ttext[idx]); \
if (!(flags & TEXT2_IMPLICIT_X)) \
{ \
xyoffset = ttext[++idx]; \
if (xyoffset & 0x80) \
{ \
if (flags & TEXT2_VERTICAL) \
{ \
y += ttext[idx + 1] | (ttext[idx + 2] << 8); \
} \
else \
{ \
x += ttext[idx + 1] | (ttext[idx + 2] << 8); \
} \
idx += 2; \
} \
else \
{ \
if (flags & TEXT2_VERTICAL) \
{ \
y += xyoffset; \
} \
else \
{ \
x += xyoffset; \
} \
} \
} \
if (glyph != NULL) \
{ \
draw_glyph(x + glyph->offset, y + glyph->baseline, glyph->pixmap, \
fgcolour); \
if (flags & TEXT2_IMPLICIT_X) \
{ \
x += glyph->width; \
} \
} \
}
/*****************************************************************************/
void
ui_draw_text(uint8 font, uint8 flags, uint8 opcode, int mixmode,
int x, int y,
int clipx, int clipy, int clipcx, int clipcy,
int boxx, int boxy, int boxcx, int boxcy, BRUSH * brush,
int bgcolour, int fgcolour, uint8 * text, uint8 length)
{
int i;
int j;
int xyoffset;
DATABLOB * entry;
FONTGLYPH * glyph;
if (boxx + boxcx > g_width)
{
boxcx = g_width - boxx;
}
if (boxcx > 1)
{
bs_rect(boxx, boxy, boxcx, boxcy, bgcolour, 0xc);
}
else
{
if (mixmode == MIX_OPAQUE)
{
bs_rect(clipx, clipy, clipcx, clipcy, bgcolour, 0xc);
}
}
/* Paint text, character by character */
for (i = 0; i < length;)
{
switch (text[i])
{
case 0xff:
if (i + 2 < length)
{
cache_put_text(text[i + 1], text, text[i + 2]);
}
else
{
error("this shouldn't be happening\n");
exit(1);
}
/* this will move pointer from start to first character after */
/* FF command */
length -= i + 3;
text = &(text[i + 3]);
i = 0;
break;
case 0xfe:
entry = cache_get_text(text[i + 1]);
if (entry != NULL)
{
if ((((uint8 *) (entry->data))[1] == 0) &&
(!(flags & TEXT2_IMPLICIT_X)))
{
if (flags & TEXT2_VERTICAL)
{
y += text[i + 2];
}
else
{
x += text[i + 2];
}
}
for (j = 0; j < entry->size; j++)
{
DO_GLYPH(((uint8 *) (entry->data)), j);
}
}
if (i + 2 < length)
{
i += 3;
}
else
{
i += 2;
}
length -= i;
/* this will move pointer from start to first character after */
/* FE command */
text = &(text[i]);
i = 0;
break;
default:
DO_GLYPH(text, i);
i++;
break;
}
}
if (boxcx > 1)
{
ui_invalidate(boxx, boxy, boxcx, boxcy);
}
else
{
ui_invalidate(clipx, clipy, clipcx, clipcy);
}
}
/*****************************************************************************/
void
ui_line(uint8 opcode, int startx, int starty, int endx, int endy,
PEN * pen)
{
int x;
int y;
int cx;
int cy;
bs_line(opcode, startx, starty, endx, endy, pen->width, pen->style,
pen->colour);
if (pen->style == 0 && pen->width < 2 && opcode == 12)
{
mi_line(startx, starty, endx, endy, pen->colour);
}
else
{
x = MIN(startx, endx);
y = MIN(starty, endy);
cx = (MAX(startx, endx) + 1) - x;
cy = (MAX(starty, endy) + 1) - y;
ui_invalidate(x, y, cx, cy);
}
}
/*****************************************************************************/
void
ui_triblt(uint8 opcode, int x, int y, int cx, int cy,
void * src, int srcx, int srcy,
BRUSH* brush, int bgcolour, int fgcolour)
{
/* not used */
}
/*****************************************************************************/
void
ui_memblt(uint8 opcode, int x, int y, int cx, int cy,
void * src, int srcx, int srcy)
{
struct bitmap* b;
b = (struct bitmap*)src;
bs_memblt(opcode, x, y, cx, cy, b->data, b->width, b->height,
srcx, srcy);
ui_invalidate(x, y, cx, cy);
}
/*****************************************************************************/
void
ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
{
}
/*****************************************************************************/
void
ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
{
}
/*****************************************************************************/
void
ui_rect(int x, int y, int cx, int cy, int colour)
{
bs_rect(x, y, cx, cy, colour, 12);
mi_fill_rect(x, y, cx, cy, colour);
}
/*****************************************************************************/
void
ui_screenblt(uint8 opcode, int x, int y, int cx, int cy,
int srcx, int srcy)
{
bs_screenblt(opcode, x, y, cx, cy, srcx, srcy);
if (opcode == 12)
{
mi_screen_copy(x, y, cx, cy, srcx, srcy);
}
else
{
ui_invalidate(x, y, cx, cy);
}
}
/*****************************************************************************/
void
ui_patblt(uint8 opcode, int x, int y, int cx, int cy,
BRUSH * brush, int bgcolour, int fgcolour)
{
bs_patblt(opcode, x, y, cx, cy, brush->style, brush->pattern,
brush->xorigin, brush->yorigin, bgcolour, fgcolour);
ui_invalidate(x, y, cx, cy);
}
/*****************************************************************************/
void
ui_destblt(uint8 opcode, int x, int y, int cx, int cy)
{
bs_rect(x, y, cx, cy, 0, opcode);
ui_invalidate(x, y, cx, cy);
/* todo */
}
/*****************************************************************************/
void
ui_move_pointer(int x, int y)
{
}
/*****************************************************************************/
uint16
ui_get_numlock_state(uint32 state)
{
return (uint16) state;
}
/*****************************************************************************/
/* get the num, caps, and scroll lock state */
/* scroll lock is 1, num lock is 2 and caps lock is 4 */
/* just returning 0, the hardware specific file is responsable for this */
uint32
read_keyboard_state(void)
{
return (uint32) mi_read_keyboard_state();
}
/*****************************************************************************/
void
ui_set_modifier_state(int code)
{
//error("%8.8x", code);
rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, (uint16) code, 0);
}
/*****************************************************************************/
void
ui_resize_window(void)
{
}
/*****************************************************************************/
void
ui_begin_update(void)
{
mi_begin_update();
}
/*****************************************************************************/
void
ui_end_update(void)
{
mi_end_update();
}
/*****************************************************************************/
void
ui_polygon(uint8 opcode, uint8 fillmode, POINT * point, int npoints,
BRUSH * brush, int bgcolour, int fgcolour)
{
/* not used */
}
/*****************************************************************************/
void
ui_polyline(uint8 opcode, POINT * points, int npoints, PEN * pen)
{
int i, x, y, dx, dy;
if (npoints > 0)
{
x = points[0].x;
y = points[0].y;
for (i = 1; i < npoints; i++)
{
dx = points[i].x;
dy = points[i].y;
ui_line(opcode, x, y, x + dx, y + dy, pen);
x = x + dx;
y = y + dy;
}
}
}
/*****************************************************************************/
void
ui_ellipse(uint8 opcode, uint8 fillmode,
int x, int y, int cx, int cy,
BRUSH * brush, int bgcolour, int fgcolour)
{
/* not used */
}
/*****************************************************************************/
/* get a 32 byte random */
void
generate_random(uint8 * random)
{
int i;
rand();
rand();
for (i = 0; i < 32; i++)
{
random[i] = rand() >> 16; /* higher bits are more random */
}
}
/*****************************************************************************/
void
save_licence(uint8 * data, int length)
{
}
/*****************************************************************************/
int
load_licence(uint8 ** data)
{
return 0;
}
/*****************************************************************************/
void *
xrealloc(void * in, int size)
{
if (size < 1)
{
size = 1;
}
return realloc(in, size);
}
/*****************************************************************************/
void *
xmalloc(int size)
{
if (size < 1)
{
size = 1;
}
return malloc(size);
}
/*****************************************************************************/
void
xfree(void * in)
{
if (in != 0)
{
free(in);
}
}
/*****************************************************************************/
char *
xstrdup(const char * s)
{
int len;
char * p;
if (s == 0)
{
return 0;
}
len = strlen(s);
p = (char *) xmalloc(len + 1);
strcpy(p, s);
return p;
}
/*****************************************************************************/
void
warning(char * format, ...)
{
va_list ap;
char text[512];
char text1[512];
sprintf(text1, "WARNING: ");
va_start(ap, format);
vsprintf(text, format, ap);
va_end(ap);
strcat(text1, text);
mi_warning(text1);
}
/*****************************************************************************/
void
unimpl(char * format, ...)
{
va_list ap;
char text[512];
char text1[512];
sprintf(text1, "UNIMPL: ");
va_start(ap, format);
vsprintf(text, format, ap);
va_end(ap);
strcat(text1, text);
mi_warning(text1);
}
/*****************************************************************************/
void
error(char * format, ...)
{
va_list ap;
char text[512];
char text1[512];
sprintf(text1, "ERROR: ");
va_start(ap, format);
vsprintf(text, format, ap);
va_end(ap);
strcat(text1, text);
mi_error(text1);
}
/*****************************************************************************/
BOOL
rd_pstcache_mkdir(void)
{
return 0;
}
/*****************************************************************************/
int
rd_open_file(char * filename)
{
return 0;
}
/*****************************************************************************/
void
rd_close_file(int fd)
{
return;
}
/*****************************************************************************/
int
rd_read_file(int fd, void * ptr, int len)
{
return 0;
}
/*****************************************************************************/
int
rd_write_file(int fd, void * ptr, int len)
{
return 0;
}
/*****************************************************************************/
int
rd_lseek_file(int fd, int offset)
{
return 0;
}
/*****************************************************************************/
BOOL
rd_lock_file(int fd, int start, int len)
{
return False;
}
/*****************************************************************************/
void
ui_mouse_move(int x, int y)
{
rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_MOVE, (uint16) x, (uint16) y);
}
/*****************************************************************************/
void
ui_mouse_button(int button, int x, int y, int down)
{
uint16 flags;
flags = 0;
if (down)
{
flags |= MOUSE_FLAG_DOWN;
}
switch (button)
{
case 1:
flags |= MOUSE_FLAG_BUTTON1;
break;
case 2:
flags |= MOUSE_FLAG_BUTTON2;
break;
case 3:
flags |= MOUSE_FLAG_BUTTON3;
break;
case 4:
flags |= MOUSE_FLAG_BUTTON4;
break;
case 5:
flags |= MOUSE_FLAG_BUTTON5;
break;
}
rdp_send_input(0, RDP_INPUT_MOUSE, flags, (uint16) x, (uint16) y);
}
/*****************************************************************************/
void
ui_key_down(int key, int ext)
{
rdp_send_input(0, RDP_INPUT_SCANCODE, (uint16) (RDP_KEYPRESS | ext),
(uint16) key, 0);
}
/*****************************************************************************/
void
ui_key_up(int key, int ext)
{
rdp_send_input(0, RDP_INPUT_SCANCODE, (uint16) (RDP_KEYRELEASE | ext),
(uint16) key, 0);
}
/*****************************************************************************/
/* returns boolean, non zero is good */
int
ui_read_wire(void)
{
return rdp_loop(&g_deactivated, &g_ext_disc_reason);
}
/*****************************************************************************/
/* called after the command line parameters are processed */
/* returns boolean, non zero is ok */
int
ui_main(void)
{
uint32 flags;
/* try to connect */
flags = RDP_LOGON_NORMAL;
if (g_password[0] != 0)
{
flags |= RDP_LOGON_AUTO;
}
if (!rdp_connect(g_servername, flags, g_domain, g_password,
g_shell, g_directory))
{
return 0;
}
/* init backingstore */
bs_init(g_width, g_height, g_server_depth);
/* create the window */
if (!mi_create_window())
{
return 0;
}
/* if all ok, enter main loop */
return mi_main_loop();
}
/*****************************************************************************/
/* produce a hex dump */
void
hexdump(uint8 * p, uint32 len)
{
uint8 * line = p;
int i, thisline, offset = 0;
while (offset < (int)len)
{
printf("%04x ", offset);
thisline = len - offset;
if (thisline > 16)
thisline = 16;
for (i = 0; i < thisline; i++)
printf("%02x ", line[i]);
for (; i < 16; i++)
printf(" ");
for (i = 0; i < thisline; i++)
printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
printf("\n");
offset += thisline;
line += thisline;
}
}

View file

@ -0,0 +1,80 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
main ui header
Copyright (C) Jay Sorg 2005-2006
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* in uimain.c */
int
ui_main(void);
void
ui_invalidate(int x, int y, int cx, int cy);
int
ui_read_wire(void);
void
ui_mouse_move(int x, int y);
void
ui_mouse_button(int button, int x, int y, int down);
void
ui_key_down(int key, int ext);
void
ui_key_up(int key, int ext);
void
ui_set_modifier_state(int code);
#define SPLIT_COLOUR15(c, r, g, b) \
{ \
r = ((c >> 7) & 0xf8) | ((c >> 12) & 0x7); \
g = ((c >> 2) & 0xf8) | ((c >> 8) & 0x7); \
b = ((c << 3) & 0xf8) | ((c >> 2) & 0x7); \
}
#define SPLIT_COLOUR16(c, r, g, b) \
{ \
r = ((c >> 8) & 0xf8) | ((c >> 13) & 0x7); \
g = ((c >> 3) & 0xfc) | ((c >> 9) & 0x3); \
b = ((c << 3) & 0xf8) | ((c >> 2) & 0x7); \
}
#define MAKE_COLOUR15(c, r, g, b) \
{ \
c = ( \
(((r & 0xff) >> 3) << 10) | \
(((g & 0xff) >> 3) << 5) | \
(((b & 0xff) >> 3) << 0) \
); \
}
#define MAKE_COLOUR32(c, r, g, b) \
{ \
c = ( \
((r & 0xff) << 16) | \
((g & 0xff) << 8) | \
((b & 0xff) << 0) \
); \
}
#undef UI_MAX
#define UI_MAX(a, b) (((a) > (b)) ? (a) : (b))
#undef UI_MIN
#define UI_MIN(a, b) (((a) < (b)) ? (a) : (b))
/* in connectdialog.c */
BOOL OpenRDPConnectDialog();

File diff suppressed because it is too large Load diff