mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2024-12-04 15:23:32 +08:00
Merge from upstream
This commit is contained in:
commit
7b42422cd3
3
.gitignore
vendored
3
.gitignore
vendored
@ -40,4 +40,5 @@ cunit/test_freerdp
|
||||
client/X11/xfreerdp
|
||||
client/test/freerdp-test
|
||||
client/DirectFB/dfreerdp
|
||||
server/test/freerdp-server-test
|
||||
server/test/tfreerdp-server
|
||||
server/X11/xfreerdp-server
|
||||
|
@ -58,7 +58,8 @@ endif()
|
||||
|
||||
# Compiler-specific flags
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-unused-but-set-variable")
|
||||
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-unused-but-set-variable")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -lncurses")
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2")
|
||||
endif()
|
||||
@ -133,6 +134,7 @@ endif()
|
||||
add_subdirectory(libfreerdp-gdi)
|
||||
add_subdirectory(libfreerdp-rail)
|
||||
add_subdirectory(libfreerdp-cache)
|
||||
add_subdirectory(libfreerdp-common)
|
||||
add_subdirectory(libfreerdp-chanman)
|
||||
add_subdirectory(libfreerdp-core)
|
||||
add_subdirectory(libfreerdp-rfx)
|
||||
|
@ -146,7 +146,7 @@ void df_keyboard_init()
|
||||
keymap[DIKI_SUPER_L - DIKI_UNKNOWN] = VK_APPS;
|
||||
}
|
||||
|
||||
void df_send_mouse_event(rdpInput* input, boolean down, uint32 button, uint16 x, uint16 y)
|
||||
void df_send_mouse_button_event(rdpInput* input, boolean down, uint32 button, uint16 x, uint16 y)
|
||||
{
|
||||
uint16 flags;
|
||||
|
||||
@ -163,6 +163,11 @@ void df_send_mouse_event(rdpInput* input, boolean down, uint32 button, uint16 x,
|
||||
input->MouseEvent(input, flags, x, y);
|
||||
}
|
||||
|
||||
void df_send_mouse_motion_event(rdpInput* input, uint16 x, uint16 y)
|
||||
{
|
||||
input->MouseEvent(input, PTR_FLAGS_MOVE, x, y);
|
||||
}
|
||||
|
||||
void df_send_keyboard_event(rdpInput* input, boolean down, uint8 keycode)
|
||||
{
|
||||
uint16 flags;
|
||||
@ -206,14 +211,15 @@ boolean df_event_process(freerdp* instance, DFBEvent* event)
|
||||
if (pointer_y > (gdi->height - 1))
|
||||
pointer_y = gdi->height - 1;
|
||||
|
||||
df_send_mouse_motion_event(instance->input, pointer_x, pointer_y);
|
||||
break;
|
||||
|
||||
case DIET_BUTTONPRESS:
|
||||
df_send_mouse_event(instance->input, True, input_event->button, pointer_x, pointer_y);
|
||||
df_send_mouse_button_event(instance->input, True, input_event->button, pointer_x, pointer_y);
|
||||
break;
|
||||
|
||||
case DIET_BUTTONRELEASE:
|
||||
df_send_mouse_event(instance->input, False, input_event->button, pointer_x, pointer_y);
|
||||
df_send_mouse_button_event(instance->input, False, input_event->button, pointer_x, pointer_y);
|
||||
break;
|
||||
|
||||
case DIET_KEYPRESS:
|
||||
|
@ -78,7 +78,7 @@ target_link_libraries(xfreerdp freerdp-kbd)
|
||||
target_link_libraries(xfreerdp freerdp-rail)
|
||||
target_link_libraries(xfreerdp freerdp-chanman)
|
||||
target_link_libraries(xfreerdp freerdp-utils)
|
||||
target_link_libraries(xfreerdp ${X11_LIBRARIES})
|
||||
target_link_libraries(xfreerdp ${X11_LIBRARIES} dl)
|
||||
|
||||
install(TARGETS xfreerdp DESTINATION bin)
|
||||
|
||||
|
@ -17,6 +17,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
#include <freerdp/rfx/rfx.h>
|
||||
#include <freerdp/constants.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
|
||||
#include "xf_gdi.h"
|
||||
@ -194,9 +197,9 @@ Pixmap xf_bitmap_new(xfInfo* xfi, int width, int height, int bpp, uint8* data)
|
||||
uint8* cdata;
|
||||
XImage* image;
|
||||
|
||||
bitmap = XCreatePixmap(xfi->display, xfi->window->handle, width, height, xfi->depth);
|
||||
bitmap = XCreatePixmap(xfi->display, xfi->window->handle, width, height, xfi->bpp);
|
||||
|
||||
cdata = gdi_image_convert(data, NULL, width, height, bpp, xfi->bpp, xfi->clrconv);
|
||||
cdata = freerdp_image_convert(data, NULL, width, height, bpp, xfi->bpp, xfi->clrconv);
|
||||
|
||||
image = XCreateImage(xfi->display, xfi->visual, xfi->depth,
|
||||
ZPixmap, 0, (char *) cdata, width, height, xfi->scanline_pad, 0);
|
||||
@ -210,6 +213,25 @@ Pixmap xf_bitmap_new(xfInfo* xfi, int width, int height, int bpp, uint8* data)
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
Pixmap xf_mono_bitmap_new(xfInfo* xfi, int width, int height, uint8* data)
|
||||
{
|
||||
int scanline;
|
||||
XImage* image;
|
||||
Pixmap bitmap;
|
||||
|
||||
scanline = (width + 7) / 8;
|
||||
|
||||
bitmap = XCreatePixmap(xfi->display, xfi->window->handle, width, height, 1);
|
||||
|
||||
image = XCreateImage(xfi->display, xfi->visual, 1,
|
||||
ZPixmap, 0, (char*) data, width, height, 8, scanline);
|
||||
|
||||
XPutImage(xfi->display, bitmap, xfi->gc_mono, image, 0, 0, 0, 0, width, height);
|
||||
XFree(image);
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
void xf_gdi_bitmap_update(rdpUpdate* update, BITMAP_UPDATE* bitmap)
|
||||
{
|
||||
int i;
|
||||
@ -224,7 +246,7 @@ void xf_gdi_bitmap_update(rdpUpdate* update, BITMAP_UPDATE* bitmap)
|
||||
{
|
||||
bmp = &bitmap->bitmaps[i];
|
||||
|
||||
data = gdi_image_convert(bmp->data, NULL, bmp->width, bmp->height, bmp->bpp, xfi->bpp, xfi->clrconv);
|
||||
data = freerdp_image_convert(bmp->data, NULL, bmp->width, bmp->height, bmp->bpp, xfi->bpp, xfi->clrconv);
|
||||
|
||||
image = XCreateImage(xfi->display, xfi->visual, xfi->depth,
|
||||
ZPixmap, 0, (char*) data, bmp->width, bmp->height, xfi->scanline_pad, 0);
|
||||
@ -277,14 +299,80 @@ void xf_gdi_dstblt(rdpUpdate* update, DSTBLT_ORDER* dstblt)
|
||||
if (xfi->drawing == xfi->primary)
|
||||
{
|
||||
XFillRectangle(xfi->display, xfi->window->handle, xfi->gc,
|
||||
dstblt->nLeftRect, dstblt->nTopRect,
|
||||
dstblt->nWidth, dstblt->nHeight);
|
||||
dstblt->nLeftRect, dstblt->nTopRect, dstblt->nWidth, dstblt->nHeight);
|
||||
}
|
||||
}
|
||||
|
||||
void xf_gdi_patblt(rdpUpdate* update, PATBLT_ORDER* patblt)
|
||||
{
|
||||
BRUSH* brush;
|
||||
Pixmap pattern;
|
||||
uint32 foreColor;
|
||||
uint32 backColor;
|
||||
xfInfo* xfi = GET_XFI(update);
|
||||
|
||||
brush = &patblt->brush;
|
||||
xf_set_rop3(xfi, gdi_rop3_code(patblt->bRop));
|
||||
|
||||
foreColor = freerdp_color_convert(patblt->foreColor, xfi->srcBpp, 32, xfi->clrconv);
|
||||
backColor = freerdp_color_convert(patblt->backColor, xfi->srcBpp, 32, xfi->clrconv);
|
||||
|
||||
if (brush->style & CACHED_BRUSH)
|
||||
{
|
||||
printf("cached brush bpp:%d\n", brush->bpp);
|
||||
brush->data = brush_get(xfi->cache->brush, brush->index, &brush->bpp);
|
||||
brush->style = GDI_BS_PATTERN;
|
||||
}
|
||||
|
||||
if (brush->style == GDI_BS_SOLID)
|
||||
{
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
|
||||
XSetForeground(xfi->display, xfi->gc, patblt->foreColor);
|
||||
|
||||
XFillRectangle(xfi->display, xfi->drawing, xfi->gc,
|
||||
patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight);
|
||||
}
|
||||
else if (brush->style == GDI_BS_PATTERN)
|
||||
{
|
||||
if (brush->bpp > 1)
|
||||
{
|
||||
pattern = xf_bitmap_new(xfi, 8, 8, brush->bpp, brush->data);
|
||||
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillTiled);
|
||||
XSetTile(xfi->display, xfi->gc, pattern);
|
||||
XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y);
|
||||
|
||||
XFillRectangle(xfi->display, xfi->drawing, xfi->gc,
|
||||
patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight);
|
||||
|
||||
XSetTile(xfi->display, xfi->gc, xfi->primary);
|
||||
}
|
||||
else
|
||||
{
|
||||
pattern = xf_mono_bitmap_new(xfi, 8, 8, brush->data);
|
||||
|
||||
XSetForeground(xfi->display, xfi->gc, backColor);
|
||||
XSetBackground(xfi->display, xfi->gc, foreColor);
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillOpaqueStippled);
|
||||
XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y);
|
||||
|
||||
XFillRectangle(xfi->display, xfi->drawing, xfi->gc,
|
||||
patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight);
|
||||
|
||||
XSetStipple(xfi->display, xfi->gc_mono, pattern);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("unimplemented brush style:%d\n", brush->style);
|
||||
}
|
||||
|
||||
if (xfi->drawing == xfi->primary)
|
||||
{
|
||||
XSetFunction(xfi->display, xfi->gc, GXcopy);
|
||||
XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, patblt->nLeftRect, patblt->nTopRect,
|
||||
patblt->nWidth, patblt->nHeight, patblt->nLeftRect, patblt->nTopRect);
|
||||
}
|
||||
}
|
||||
|
||||
void xf_gdi_scrblt(rdpUpdate* update, SCRBLT_ORDER* scrblt)
|
||||
@ -318,7 +406,7 @@ void xf_gdi_opaque_rect(rdpUpdate* update, OPAQUE_RECT_ORDER* opaque_rect)
|
||||
uint32 color;
|
||||
xfInfo* xfi = GET_XFI(update);
|
||||
|
||||
color = gdi_color_convert(opaque_rect->color, xfi->srcBpp, xfi->bpp, xfi->clrconv);
|
||||
color = freerdp_color_convert(opaque_rect->color, xfi->srcBpp, xfi->bpp, xfi->clrconv);
|
||||
|
||||
XSetFunction(xfi->display, xfi->gc, GXcopy);
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
|
||||
@ -330,8 +418,7 @@ void xf_gdi_opaque_rect(rdpUpdate* update, OPAQUE_RECT_ORDER* opaque_rect)
|
||||
if (xfi->drawing == xfi->primary)
|
||||
{
|
||||
XFillRectangle(xfi->display, xfi->window->handle, xfi->gc,
|
||||
opaque_rect->nLeftRect, opaque_rect->nTopRect,
|
||||
opaque_rect->nWidth, opaque_rect->nHeight);
|
||||
opaque_rect->nLeftRect, opaque_rect->nTopRect, opaque_rect->nWidth, opaque_rect->nHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@ -342,7 +429,7 @@ void xf_gdi_multi_opaque_rect(rdpUpdate* update, MULTI_OPAQUE_RECT_ORDER* multi_
|
||||
DELTA_RECT* rectangle;
|
||||
xfInfo* xfi = GET_XFI(update);
|
||||
|
||||
color = gdi_color_convert(multi_opaque_rect->color, xfi->srcBpp, xfi->bpp, xfi->clrconv);
|
||||
color = freerdp_color_convert(multi_opaque_rect->color, xfi->srcBpp, xfi->bpp, xfi->clrconv);
|
||||
|
||||
XSetFunction(xfi->display, xfi->gc, GXcopy);
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
|
||||
@ -359,20 +446,61 @@ void xf_gdi_multi_opaque_rect(rdpUpdate* update, MULTI_OPAQUE_RECT_ORDER* multi_
|
||||
if (xfi->drawing == xfi->primary)
|
||||
{
|
||||
XFillRectangle(xfi->display, xfi->window->handle, xfi->gc,
|
||||
rectangle->left, rectangle->top,
|
||||
rectangle->width, rectangle->height);
|
||||
rectangle->left, rectangle->top, rectangle->width, rectangle->height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void xf_gdi_line_to(rdpUpdate* update, LINE_TO_ORDER* line_to)
|
||||
{
|
||||
uint32 color;
|
||||
xfInfo* xfi = GET_XFI(update);
|
||||
|
||||
xf_set_rop2(xfi, line_to->bRop2);
|
||||
color = freerdp_color_convert(line_to->penColor, xfi->srcBpp, 32, xfi->clrconv);
|
||||
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
|
||||
XSetForeground(xfi->display, xfi->gc, color);
|
||||
|
||||
XDrawLine(xfi->display, xfi->drawing, xfi->gc,
|
||||
line_to->nXStart, line_to->nYStart, line_to->nXEnd, line_to->nYEnd);
|
||||
|
||||
if (xfi->drawing == xfi->primary)
|
||||
{
|
||||
XDrawLine(xfi->display, xfi->window->handle, xfi->gc,
|
||||
line_to->nXStart, line_to->nYStart, line_to->nXEnd, line_to->nYEnd);
|
||||
}
|
||||
}
|
||||
|
||||
void xf_gdi_polyline(rdpUpdate* update, POLYLINE_ORDER* polyline)
|
||||
{
|
||||
int i;
|
||||
uint32 color;
|
||||
XPoint* points;
|
||||
xfInfo* xfi = GET_XFI(update);
|
||||
|
||||
xf_set_rop2(xfi, polyline->bRop2);
|
||||
color = freerdp_color_convert(polyline->penColor, xfi->srcBpp, 32, xfi->clrconv);
|
||||
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
|
||||
XSetForeground(xfi->display, xfi->gc, color);
|
||||
|
||||
points = xmalloc(sizeof(XPoint) * polyline->numPoints);
|
||||
|
||||
for (i = 0; i < polyline->numPoints; i++)
|
||||
{
|
||||
points[i].x = polyline->points[i].x;
|
||||
points[i].y = polyline->points[i].y;
|
||||
}
|
||||
|
||||
XDrawLines(xfi->display, xfi->drawing, xfi->gc, points, polyline->numPoints, CoordModePrevious);
|
||||
|
||||
if (xfi->drawing == xfi->primary)
|
||||
{
|
||||
XDrawLines(xfi->display, xfi->window->handle, xfi->gc, points, polyline->numPoints, CoordModePrevious);
|
||||
}
|
||||
|
||||
xfree(points);
|
||||
}
|
||||
|
||||
void xf_gdi_fast_index(rdpUpdate* update, FAST_INDEX_ORDER* fast_index)
|
||||
@ -408,7 +536,10 @@ void xf_gdi_switch_surface(rdpUpdate* update, SWITCH_SURFACE_ORDER* switch_surfa
|
||||
|
||||
void xf_gdi_cache_bitmap_v2(rdpUpdate* update, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2)
|
||||
{
|
||||
xfInfo* xfi = GET_XFI(update);
|
||||
|
||||
bitmap_v2_put(xfi->cache->bitmap_v2, cache_bitmap_v2->cacheId,
|
||||
cache_bitmap_v2->cacheIndex, cache_bitmap_v2->data);
|
||||
}
|
||||
|
||||
void xf_gdi_cache_color_table(rdpUpdate* update, CACHE_COLOR_TABLE_ORDER* cache_color_table)
|
||||
@ -428,12 +559,90 @@ void xf_gdi_cache_glyph_v2(rdpUpdate* update, CACHE_GLYPH_V2_ORDER* cache_glyph_
|
||||
|
||||
void xf_gdi_cache_brush(rdpUpdate* update, CACHE_BRUSH_ORDER* cache_brush)
|
||||
{
|
||||
|
||||
xfInfo* xfi = GET_XFI(update);
|
||||
brush_put(xfi->cache->brush, cache_brush->index, cache_brush->data, cache_brush->bpp);
|
||||
}
|
||||
|
||||
void xf_gdi_surface_bits(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_command)
|
||||
{
|
||||
STREAM* s;
|
||||
XImage* image;
|
||||
int i, tx, ty;
|
||||
RFX_MESSAGE* message;
|
||||
xfInfo* xfi = GET_XFI(update);
|
||||
RFX_CONTEXT* context = (RFX_CONTEXT*) xfi->rfx_context;
|
||||
|
||||
if (surface_bits_command->codecID == CODEC_ID_REMOTEFX)
|
||||
{
|
||||
s = stream_new(0);
|
||||
stream_attach(s, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
|
||||
|
||||
message = rfx_process_message(context, s);
|
||||
|
||||
XSetFunction(xfi->display, xfi->gc, GXcopy);
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
|
||||
|
||||
XSetClipRectangles(xfi->display, xfi->gc,
|
||||
surface_bits_command->destLeft, surface_bits_command->destTop,
|
||||
(XRectangle*) message->rects, message->num_rects, YXBanded);
|
||||
|
||||
/* Draw the tiles to primary surface, each is 64x64. */
|
||||
for (i = 0; i < message->num_tiles; i++)
|
||||
{
|
||||
image = XCreateImage(xfi->display, xfi->visual, 24, ZPixmap, 0,
|
||||
(char*) message->tiles[i]->data, 64, 64, 32, 0);
|
||||
|
||||
tx = message->tiles[i]->x + surface_bits_command->destLeft;
|
||||
ty = message->tiles[i]->y + surface_bits_command->destTop;
|
||||
|
||||
XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0, tx, ty, 64, 64);
|
||||
XFree(image);
|
||||
}
|
||||
|
||||
/* Copy the updated region from backstore to the window. */
|
||||
for (i = 0; i < message->num_rects; i++)
|
||||
{
|
||||
tx = message->rects[i].x + surface_bits_command->destLeft;
|
||||
ty = message->rects[i].y + surface_bits_command->destTop;
|
||||
|
||||
XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc,
|
||||
tx, ty, message->rects[i].width, message->rects[i].height, tx, ty);
|
||||
}
|
||||
|
||||
XSetClipMask(xfi->display, xfi->gc, None);
|
||||
rfx_message_free(context, message);
|
||||
stream_detach(s);
|
||||
stream_free(s);
|
||||
}
|
||||
else if (surface_bits_command->codecID == CODEC_ID_NONE)
|
||||
{
|
||||
XSetFunction(xfi->display, xfi->gc, GXcopy);
|
||||
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
|
||||
|
||||
xfi->bmp_codec_none = (uint8*) xrealloc(xfi->bmp_codec_none,
|
||||
surface_bits_command->width * surface_bits_command->height * 4);
|
||||
|
||||
freerdp_image_invert(surface_bits_command->bitmapData, xfi->bmp_codec_none,
|
||||
surface_bits_command->width, surface_bits_command->height, 32);
|
||||
|
||||
image = XCreateImage(xfi->display, xfi->visual, 24, ZPixmap, 0,
|
||||
(char*) xfi->bmp_codec_none, surface_bits_command->width, surface_bits_command->height, 32, 0);
|
||||
|
||||
XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0,
|
||||
surface_bits_command->destLeft, surface_bits_command->destTop,
|
||||
surface_bits_command->width, surface_bits_command->height);
|
||||
|
||||
XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc,
|
||||
surface_bits_command->destLeft, surface_bits_command->destTop,
|
||||
surface_bits_command->width, surface_bits_command->height,
|
||||
surface_bits_command->destLeft, surface_bits_command->destTop);
|
||||
|
||||
XSetClipMask(xfi->display, xfi->gc, None);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Unsupported codecID %d\n", surface_bits_command->codecID);
|
||||
}
|
||||
}
|
||||
|
||||
void xf_gdi_register_update_callbacks(rdpUpdate* update)
|
||||
|
@ -146,7 +146,7 @@ void xf_rail_SetWindowIcon(rdpRail* rail, rdpWindow* window, rdpIcon* icon)
|
||||
xfi = (xfInfo*) rail->extra;
|
||||
xfw = (xfWindow*) window->extra;
|
||||
|
||||
icon->extra = gdi_icon_convert(icon->entry->bitsColor, NULL, icon->entry->bitsMask,
|
||||
icon->extra = freerdp_icon_convert(icon->entry->bitsColor, NULL, icon->entry->bitsMask,
|
||||
icon->entry->width, icon->entry->height, icon->entry->bpp, rail->clrconv);
|
||||
|
||||
xf_SetWindowIcon(xfi, xfw, icon);
|
||||
|
@ -72,10 +72,7 @@ void xf_SetWindowFullscreen(xfInfo* xfi, xfWindow* window, boolean fullscreen)
|
||||
|
||||
XMoveResizeWindow(xfi->display, window->handle, 0, 0, window->width, window->height);
|
||||
XMapRaised(xfi->display, window->handle);
|
||||
//XGrabPointer(xfi->display, window->handle, True, 0, GrabModeAsync, GrabModeAsync, window->handle, 0L, CurrentTime);
|
||||
//XGrabKeyboard(xfi->display, window->handle, False, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
|
||||
//XSetInputFocus(xfi->display, window->handle, RevertToParent, CurrentTime);
|
||||
window->fullscreen = True;
|
||||
}
|
||||
}
|
||||
@ -218,10 +215,8 @@ xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height)
|
||||
|
||||
if (class_hints != NULL)
|
||||
{
|
||||
if (name != NULL)
|
||||
class_hints->res_name = name;
|
||||
|
||||
class_hints->res_class = "freerdp";
|
||||
class_hints->res_name = "xfreerdp";
|
||||
class_hints->res_class = "xfreerdp";
|
||||
XSetClassHint(xfi->display, window->handle, class_hints);
|
||||
XFree(class_hints);
|
||||
}
|
||||
@ -237,6 +232,8 @@ xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height)
|
||||
XMapWindow(xfi->display, window->handle);
|
||||
}
|
||||
|
||||
XStoreName(xfi->display, window->handle, name);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <locale.h>
|
||||
#include <sys/select.h>
|
||||
#include <termios.h>
|
||||
#include <freerdp/rfx/rfx.h>
|
||||
#include <freerdp/utils/args.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
#include <freerdp/utils/semaphore.h>
|
||||
@ -204,7 +205,9 @@ void xf_toggle_fullscreen(xfInfo* xfi)
|
||||
contents = XCreatePixmap(xfi->display, xfi->window->handle, xfi->width, xfi->height, xfi->depth);
|
||||
XCopyArea(xfi->display, xfi->primary, contents, xfi->gc, 0, 0, xfi->width, xfi->height, 0, 0);
|
||||
|
||||
XDestroyWindow(xfi->display, xfi->window->handle);
|
||||
xfi->fullscreen = (xfi->fullscreen) ? False : True;
|
||||
xf_post_connect(xfi->instance);
|
||||
|
||||
XCopyArea(xfi->display, contents, xfi->primary, xfi->gc, 0, 0, xfi->width, xfi->height, 0, 0);
|
||||
XFreePixmap(xfi->display, contents);
|
||||
@ -298,8 +301,10 @@ boolean xf_pre_connect(freerdp* instance)
|
||||
settings->order_support[NEG_MULTI_DRAWNINEGRID_INDEX] = False;
|
||||
settings->order_support[NEG_LINETO_INDEX] = True;
|
||||
settings->order_support[NEG_POLYLINE_INDEX] = True;
|
||||
settings->order_support[NEG_MEMBLT_INDEX] = True;
|
||||
settings->order_support[NEG_MEMBLT_INDEX] = False;
|
||||
settings->order_support[NEG_MEM3BLT_INDEX] = False;
|
||||
settings->order_support[NEG_MEMBLT_V2_INDEX] = False;
|
||||
settings->order_support[NEG_MEM3BLT_V2_INDEX] = False;
|
||||
settings->order_support[NEG_SAVEBITMAP_INDEX] = True;
|
||||
settings->order_support[NEG_GLYPH_INDEX_INDEX] = True;
|
||||
settings->order_support[NEG_FAST_INDEX_INDEX] = True;
|
||||
@ -356,6 +361,7 @@ boolean xf_pre_connect(freerdp* instance)
|
||||
xfi->decoration = settings->decorations;
|
||||
xfi->remote_app = settings->remote_app;
|
||||
xfi->fullscreen = settings->fullscreen;
|
||||
xfi->fullscreen_toggle = xfi->fullscreen;
|
||||
|
||||
xf_detect_monitors(xfi, settings);
|
||||
|
||||
@ -384,6 +390,9 @@ boolean xf_post_connect(freerdp* instance)
|
||||
{
|
||||
xfi->srcBpp = instance->settings->color_depth;
|
||||
xf_gdi_register_update_callbacks(instance->update);
|
||||
|
||||
if (instance->settings->rfx_codec)
|
||||
xfi->rfx_context = (void*) rfx_context_new();
|
||||
}
|
||||
|
||||
if (xfi->fullscreen)
|
||||
@ -400,7 +409,7 @@ boolean xf_post_connect(freerdp* instance)
|
||||
|
||||
if (xfi->remote_app != True)
|
||||
{
|
||||
xfi->window = xf_CreateDesktopWindow(xfi, "xfreerdp", xfi->width, xfi->height);
|
||||
xfi->window = xf_CreateDesktopWindow(xfi, "FreeRDP", xfi->width, xfi->height);
|
||||
|
||||
xf_SetWindowDecorations(xfi, xfi->window, xfi->decoration);
|
||||
|
||||
@ -428,12 +437,17 @@ boolean xf_post_connect(freerdp* instance)
|
||||
xfi->primary = XCreatePixmap(xfi->display, DefaultRootWindow(xfi->display), xfi->width, xfi->height, xfi->depth);
|
||||
xfi->drawing = xfi->primary;
|
||||
|
||||
xfi->bitmap_mono = XCreatePixmap(xfi->display, xfi->window->handle, 8, 8, 1);
|
||||
xfi->gc_mono = XCreateGC(xfi->display, xfi->bitmap_mono, GCGraphicsExposures, &gcv);
|
||||
|
||||
XSetForeground(xfi->display, xfi->gc, BlackPixelOfScreen(xfi->screen));
|
||||
XFillRectangle(xfi->display, xfi->primary, xfi->gc, 0, 0, xfi->width, xfi->height);
|
||||
|
||||
xfi->image = XCreateImage(xfi->display, xfi->visual, xfi->depth, ZPixmap, 0,
|
||||
(char*) gdi->primary_buffer, gdi->width, gdi->height, xfi->scanline_pad, 0);
|
||||
|
||||
xfi->bmp_codec_none = (uint8*) xmalloc(64 * 64 * 4);
|
||||
|
||||
instance->update->BeginPaint = xf_begin_paint;
|
||||
instance->update->EndPaint = xf_end_paint;
|
||||
instance->update->DesktopResize = xf_desktop_resize;
|
||||
|
@ -57,12 +57,14 @@ struct xf_info
|
||||
int width;
|
||||
int height;
|
||||
int srcBpp;
|
||||
GC gc_mono;
|
||||
Screen* screen;
|
||||
XImage* image;
|
||||
Pixmap primary;
|
||||
Pixmap drawing;
|
||||
Visual* visual;
|
||||
Display* display;
|
||||
Pixmap bitmap_mono;
|
||||
Colormap colormap;
|
||||
int screen_number;
|
||||
int scanline_pad;
|
||||
@ -89,6 +91,8 @@ struct xf_info
|
||||
XSetWindowAttributes attribs;
|
||||
boolean complex_regions;
|
||||
VIRTUAL_SCREEN vscreen;
|
||||
uint8* bmp_codec_none;
|
||||
void* rfx_context;
|
||||
|
||||
Atom _NET_WM_ICON;
|
||||
Atom _MOTIF_WM_HINTS;
|
||||
@ -109,6 +113,7 @@ struct xf_info
|
||||
};
|
||||
|
||||
void xf_toggle_fullscreen(xfInfo* xfi);
|
||||
boolean xf_post_connect(freerdp* instance);
|
||||
|
||||
#ifdef WITH_DEBUG_X11
|
||||
#define DEBUG_X11(fmt, ...) DEBUG_CLASS(X11, fmt, ## __VA_ARGS__)
|
||||
|
@ -23,4 +23,4 @@ add_executable(freerdp-test
|
||||
target_link_libraries(freerdp-test freerdp-core)
|
||||
target_link_libraries(freerdp-test freerdp-gdi)
|
||||
target_link_libraries(freerdp-test freerdp-utils)
|
||||
target_link_libraries(freerdp-test freerdp-chanman)
|
||||
target_link_libraries(freerdp-test freerdp-chanman dl)
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/utils/hexdump.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
#include "libfreerdp-core/bitmap.h"
|
||||
#include <freerdp/common/bitmap.h>
|
||||
|
||||
#include "test_bitmap.h"
|
||||
|
||||
|
@ -1533,88 +1533,88 @@ void test_gdi_LineTo(void)
|
||||
clrconv->invert = 0;
|
||||
clrconv->palette = hPalette;
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_case_1, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_case_1, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_1 = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_case_2, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_case_2, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_2 = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_case_3, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_case_3, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_3 = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_case_4, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_case_4, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_4 = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_case_5, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_case_5, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_5 = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_case_5, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_case_5, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_5 = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_case_6, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_case_6, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_6 = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_case_7, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_case_7, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_7 = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_case_8, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_case_8, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_8 = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_case_9, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_case_9, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_9 = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_case_10, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_case_10, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_10 = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_case_11, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_case_11, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_11 = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_R2_BLACK, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_BLACK, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_R2_BLACK = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_R2_NOTMERGEPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_NOTMERGEPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_R2_NOTMERGEPEN = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_R2_MASKNOTPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_MASKNOTPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_R2_MASKNOTPEN = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_R2_NOTCOPYPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_NOTCOPYPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_R2_NOTCOPYPEN = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_R2_MASKPENNOT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_MASKPENNOT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_R2_MASKPENNOT = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_R2_NOT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_NOT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_R2_NOT = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_R2_XORPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_XORPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_R2_XORPEN = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_R2_NOTMASKPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_NOTMASKPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_R2_NOTMASKPEN = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_R2_MASKPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_MASKPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_R2_MASKPEN = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_R2_NOTXORPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_NOTXORPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_R2_NOTXORPEN = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_R2_NOP, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_NOP, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_R2_NOP = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_R2_MERGENOTPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_MERGENOTPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_R2_MERGENOTPEN = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_R2_COPYPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_COPYPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_R2_COPYPEN = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_R2_MERGEPENNOT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_MERGEPENNOT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_R2_MERGEPENNOT = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_R2_MERGEPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_MERGEPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_R2_MERGEPEN = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) line_to_R2_WHITE, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_WHITE, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_LineTo_R2_WHITE = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
/* Test Case 1: (0,0) -> (15, 15) */
|
||||
@ -1851,13 +1851,13 @@ void test_gdi_Ellipse(void)
|
||||
clrconv->invert = 0;
|
||||
clrconv->palette = hPalette;
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) ellipse_case_1, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) ellipse_case_1, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_Ellipse_1 = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) ellipse_case_2, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) ellipse_case_2, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_Ellipse_2 = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) ellipse_case_3, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) ellipse_case_3, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_Ellipse_3 = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
/* Test Case 1: (0,0) -> (16, 16) */
|
||||
@ -2009,64 +2009,64 @@ void test_gdi_BitBlt_32bpp(void)
|
||||
clrconv->invert = 0;
|
||||
clrconv->palette = hPalette;
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_SRC, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_SRC, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmpSrc = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_DST, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_DST, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmpDst = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_DST, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_DST, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmpDstOriginal = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_PAT, NULL, 8, 8, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_PAT, NULL, 8, 8, 8, bitsPerPixel, clrconv);
|
||||
hBmpPat = gdi_CreateBitmap(8, 8, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_SRCCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_SRCCOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_SPna, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_SPna, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_SPna = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_BLACKNESS, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_BLACKNESS, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_BLACKNESS = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_WHITENESS, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_WHITENESS, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_WHITENESS = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_SRCAND, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCAND, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_SRCAND = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_SRCPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_SRCPAINT = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_SRCINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_SRCINVERT = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_SRCERASE, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCERASE, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_SRCERASE = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_NOTSRCCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_NOTSRCCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_NOTSRCCOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_NOTSRCERASE, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_NOTSRCERASE, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_NOTSRCERASE = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_DSTINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_DSTINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_DSTINVERT = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_MERGECOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_MERGECOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_MERGECOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_MERGEPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_MERGEPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_MERGEPAINT = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_PATCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_PATCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_PATCOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_PATPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_PATPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_PATPAINT = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_PATINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_PATINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_PATINVERT = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc);
|
||||
@ -2263,64 +2263,64 @@ void test_gdi_BitBlt_16bpp(void)
|
||||
clrconv->invert = 0;
|
||||
clrconv->palette = hPalette;
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_SRC, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_SRC, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmpSrc = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_DST, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_DST, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmpDst = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_DST, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_DST, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmpDstOriginal = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_PAT, NULL, 8, 8, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_PAT, NULL, 8, 8, 8, bitsPerPixel, clrconv);
|
||||
hBmpPat = gdi_CreateBitmap(8, 8, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_SRCCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_SRCCOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_SPna, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_SPna, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_SPna = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_BLACKNESS, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_BLACKNESS, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_BLACKNESS = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_WHITENESS, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_WHITENESS, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_WHITENESS = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_SRCAND, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCAND, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_SRCAND = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_SRCPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_SRCPAINT = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_SRCINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_SRCINVERT = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_SRCERASE, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCERASE, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_SRCERASE = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_NOTSRCCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_NOTSRCCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_NOTSRCCOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_NOTSRCERASE, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_NOTSRCERASE, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_NOTSRCERASE = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_DSTINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_DSTINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_DSTINVERT = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_MERGECOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_MERGECOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_MERGECOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_MERGEPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_MERGEPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_MERGEPAINT = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_PATCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_PATCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_PATCOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_PATPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_PATPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_PATPAINT = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_PATINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_PATINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_PATINVERT = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc);
|
||||
@ -2517,64 +2517,64 @@ void test_gdi_BitBlt_8bpp(void)
|
||||
clrconv->invert = 0;
|
||||
clrconv->palette = hPalette;
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_SRC, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_SRC, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmpSrc = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_DST, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_DST, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmpDst = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_DST, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_DST, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmpDstOriginal = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_PAT, NULL, 8, 8, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_PAT, NULL, 8, 8, 8, bitsPerPixel, clrconv);
|
||||
hBmpPat = gdi_CreateBitmap(8, 8, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_SRCCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_SRCCOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_SPna, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_SPna, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_SPna = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_BLACKNESS, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_BLACKNESS, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_BLACKNESS = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_WHITENESS, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_WHITENESS, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_WHITENESS = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_SRCAND, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCAND, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_SRCAND = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_SRCPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_SRCPAINT = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_SRCINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_SRCINVERT = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_SRCERASE, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCERASE, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_SRCERASE = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_NOTSRCCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_NOTSRCCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_NOTSRCCOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_NOTSRCERASE, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_NOTSRCERASE, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_NOTSRCERASE = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_DSTINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_DSTINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_DSTINVERT = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_MERGECOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_MERGECOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_MERGECOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_MERGEPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_MERGEPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_MERGEPAINT = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_PATCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_PATCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_PATCOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_PATPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_PATPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_PATPAINT = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
data = (uint8*) gdi_image_convert((uint8*) bmp_PATINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
data = (uint8*) freerdp_image_convert((uint8*) bmp_PATINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv);
|
||||
hBmp_PATINVERT = gdi_CreateBitmap(16, 16, bitsPerPixel, data);
|
||||
|
||||
gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc);
|
||||
|
@ -195,7 +195,8 @@ void test_bitstream(void)
|
||||
rfx_bitstream_attach(bs, (uint8*) y_data, sizeof(y_data));
|
||||
while (!rfx_bitstream_eos(bs))
|
||||
{
|
||||
b = rfx_bitstream_get_bits(bs, 3);
|
||||
rfx_bitstream_get_bits(bs, 3, b);
|
||||
(void) b;
|
||||
//printf("%u ", b);
|
||||
}
|
||||
xfree(bs);
|
||||
|
@ -650,12 +650,12 @@ void test_mppc(void)
|
||||
rdp.mppc->history_ptr = rdp.mppc->history_buf;
|
||||
|
||||
|
||||
/* store starting time */
|
||||
/* save starting time */
|
||||
gettimeofday(&start_time, NULL);
|
||||
|
||||
/* uncompress data */
|
||||
CU_ASSERT(decompress_rdp_5(&rdp, compressed_rd5, sizeof(compressed_rd5),
|
||||
PACKET_COMPRESSED, &roff, &rlen) == 0);
|
||||
PACKET_COMPRESSED, &roff, &rlen) == True);
|
||||
|
||||
/* get end time */
|
||||
gettimeofday(&end_time, NULL);
|
||||
|
@ -20,34 +20,7 @@
|
||||
#ifndef __BITMAP_H
|
||||
#define __BITMAP_H
|
||||
|
||||
#include <freerdp/utils/stream.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
|
||||
#define REGULAR_BG_RUN 0x00
|
||||
#define MEGA_MEGA_BG_RUN 0xF0
|
||||
#define REGULAR_FG_RUN 0x01
|
||||
#define MEGA_MEGA_FG_RUN 0xF1
|
||||
#define LITE_SET_FG_FG_RUN 0x0C
|
||||
#define MEGA_MEGA_SET_FG_RUN 0xF6
|
||||
#define LITE_DITHERED_RUN 0x0E
|
||||
#define MEGA_MEGA_DITHERED_RUN 0xF8
|
||||
#define REGULAR_COLOR_RUN 0x03
|
||||
#define MEGA_MEGA_COLOR_RUN 0xF3
|
||||
#define REGULAR_FGBG_IMAGE 0x02
|
||||
#define MEGA_MEGA_FGBG_IMAGE 0xF2
|
||||
#define LITE_SET_FG_FGBG_IMAGE 0x0D
|
||||
#define MEGA_MEGA_SET_FGBG_IMAGE 0xF7
|
||||
#define REGULAR_COLOR_IMAGE 0x04
|
||||
#define MEGA_MEGA_COLOR_IMAGE 0xF4
|
||||
#define SPECIAL_FGBG_1 0xF9
|
||||
#define SPECIAL_FGBG_2 0xFA
|
||||
#define SPECIAL_WHITE 0xFD
|
||||
#define SPECIAL_BLACK 0xFE
|
||||
|
||||
#define BLACK_PIXEL 0x000000
|
||||
#define WHITE_PIXEL 0xFFFFFF
|
||||
|
||||
typedef uint32 PIXEL;
|
||||
#include <freerdp/types.h>
|
||||
|
||||
boolean bitmap_decompress(uint8* srcData, uint8* dstData, int width, int height, int size, int srcBpp, int dstBpp);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* GDI Color Conversion Routines
|
||||
* Color Conversion Routines
|
||||
*
|
||||
* Copyright 2010 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
@ -234,14 +234,14 @@ typedef CLRCONV* HCLRCONV;
|
||||
|
||||
#define IBPP(_bpp) (((_bpp + 1)/ 8) % 5)
|
||||
|
||||
typedef uint8* (*p_gdi_image_convert)(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv);
|
||||
typedef uint8* (*p_freerdp_image_convert)(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv);
|
||||
|
||||
FREERDP_API uint32 gdi_color_convert(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv);
|
||||
FREERDP_API uint8* gdi_image_convert(uint8* srcData, uint8 *dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv);
|
||||
FREERDP_API uint8* gdi_glyph_convert(int width, int height, uint8* data);
|
||||
FREERDP_API uint8* gdi_image_invert(uint8* srcData, uint8* dstData, int width, int height, int bpp);
|
||||
FREERDP_API uint8* gdi_icon_convert(uint8* srcData, uint8* dstData, uint8* mask, int width, int height, int bpp, HCLRCONV clrconv);
|
||||
FREERDP_API uint8* gdi_mono_image_convert(uint8* srcData, int width, int height, int srcBpp, int dstBpp, uint32 bgcolor, uint32 fgcolor, HCLRCONV clrconv);
|
||||
FREERDP_API uint32 freerdp_color_convert(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv);
|
||||
FREERDP_API uint8* freerdp_image_convert(uint8* srcData, uint8 *dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv);
|
||||
FREERDP_API uint8* freerdp_glyph_convert(int width, int height, uint8* data);
|
||||
FREERDP_API uint8* freerdp_image_invert(uint8* srcData, uint8* dstData, int width, int height, int bpp);
|
||||
FREERDP_API uint8* freerdp_icon_convert(uint8* srcData, uint8* dstData, uint8* mask, int width, int height, int bpp, HCLRCONV clrconv);
|
||||
FREERDP_API uint8* freerdp_mono_image_convert(uint8* srcData, int width, int height, int srcBpp, int dstBpp, uint32 bgcolor, uint32 fgcolor, HCLRCONV clrconv);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
@ -22,9 +22,9 @@
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/gdi/color.h>
|
||||
#include <freerdp/cache/cache.h>
|
||||
#include <freerdp/utils/debug.h>
|
||||
#include <freerdp/common/color.h>
|
||||
|
||||
/* For more information, see [MS-RDPEGDI] */
|
||||
|
||||
|
@ -39,6 +39,7 @@ typedef void (*psPeerAccepted)(freerdp_listener* instance, freerdp_peer* client)
|
||||
|
||||
struct rdp_freerdp_listener
|
||||
{
|
||||
void* info;
|
||||
void* listener;
|
||||
void* param1;
|
||||
void* param2;
|
||||
|
@ -37,6 +37,7 @@ typedef boolean (*psPeerActivate)(freerdp_peer* client);
|
||||
|
||||
struct rdp_freerdp_peer
|
||||
{
|
||||
void* info;
|
||||
void* peer;
|
||||
void* param1;
|
||||
void* param2;
|
||||
|
@ -24,8 +24,8 @@
|
||||
#include <freerdp/rail.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/update.h>
|
||||
#include <freerdp/gdi/color.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
#include <freerdp/common/color.h>
|
||||
|
||||
typedef struct rdp_rail rdpRail;
|
||||
|
||||
|
@ -42,7 +42,9 @@ enum _RFX_PIXEL_FORMAT
|
||||
RFX_PIXEL_FORMAT_BGR,
|
||||
RFX_PIXEL_FORMAT_RGB,
|
||||
RFX_PIXEL_FORMAT_BGR565_LE,
|
||||
RFX_PIXEL_FORMAT_RGB565_LE
|
||||
RFX_PIXEL_FORMAT_RGB565_LE,
|
||||
RFX_PIXEL_FORMAT_PALETTE4_PLANER,
|
||||
RFX_PIXEL_FORMAT_PALETTE8
|
||||
};
|
||||
typedef enum _RFX_PIXEL_FORMAT RFX_PIXEL_FORMAT;
|
||||
|
||||
@ -96,7 +98,10 @@ struct _RFX_CONTEXT
|
||||
uint32 codec_id;
|
||||
uint32 codec_version;
|
||||
RFX_PIXEL_FORMAT pixel_format;
|
||||
uint8 bytes_per_pixel;
|
||||
uint8 bits_per_pixel;
|
||||
|
||||
/* color palette allocated by the application */
|
||||
const uint8* palette;
|
||||
|
||||
/* temporary data within a frame */
|
||||
uint32 frame_idx;
|
||||
|
@ -58,11 +58,16 @@
|
||||
#define NEG_SCRBLT_INDEX 0x02
|
||||
#define NEG_MEMBLT_INDEX 0x03
|
||||
#define NEG_MEM3BLT_INDEX 0x04
|
||||
#define NEG_ATEXTOUT_INDEX 0x05
|
||||
#define NEG_AEXTTEXTOUT_INDEX 0x06
|
||||
#define NEG_DRAWNINEGRID_INDEX 0x07
|
||||
#define NEG_LINETO_INDEX 0x08
|
||||
#define NEG_MULTI_DRAWNINEGRID_INDEX 0x09
|
||||
#define NEG_OPAQUE_RECT_INDEX 0x0A
|
||||
#define NEG_SAVEBITMAP_INDEX 0x0B
|
||||
#define NEG_WTEXTOUT_INDEX 0x0C
|
||||
#define NEG_MEMBLT_V2_INDEX 0x0D
|
||||
#define NEG_MEM3BLT_V2_INDEX 0x0E
|
||||
#define NEG_MULTIDSTBLT_INDEX 0x0F
|
||||
#define NEG_MULTIPATBLT_INDEX 0x10
|
||||
#define NEG_MULTISCRBLT_INDEX 0x11
|
||||
@ -75,6 +80,9 @@
|
||||
#define NEG_ELLIPSE_SC_INDEX 0x19
|
||||
#define NEG_ELLIPSE_CB_INDEX 0x1A
|
||||
#define NEG_GLYPH_INDEX_INDEX 0x1B
|
||||
#define NEG_GLYPH_WEXTTEXTOUT_INDEX 0x1C
|
||||
#define NEG_GLYPH_WLONGTEXTOUT_INDEX 0x1D
|
||||
#define NEG_GLYPH_WLONGEXTTEXTOUT_INDEX 0x1E
|
||||
|
||||
/* Glyph Support Level */
|
||||
#define GLYPH_SUPPORT_NONE 0x0000
|
||||
@ -197,6 +205,18 @@ struct rdp_settings
|
||||
|
||||
rdpBlob server_random;
|
||||
rdpBlob server_certificate;
|
||||
struct rdp_certificate* server_cert;
|
||||
|
||||
uint8 sign_key[16];
|
||||
uint8 decrypt_key[16];
|
||||
uint8 encrypt_key[16];
|
||||
uint8 decrypt_update_key[16];
|
||||
uint8 encrypt_update_key[16];
|
||||
int rc4_key_len;
|
||||
|
||||
uint8 fips_sign_key[20];
|
||||
uint8 fips_encrypt_key[24];
|
||||
uint8 fips_decrypt_key[24];
|
||||
|
||||
boolean console_audio;
|
||||
boolean console_session;
|
||||
|
@ -530,6 +530,7 @@ struct _CACHE_BITMAP_V2_ORDER
|
||||
uint16 cacheIndex;
|
||||
uint8 bitmapComprHdr[8];
|
||||
uint8* bitmapDataStream;
|
||||
uint8* data;
|
||||
};
|
||||
typedef struct _CACHE_BITMAP_V2_ORDER CACHE_BITMAP_V2_ORDER;
|
||||
|
||||
|
@ -79,7 +79,7 @@ rdpBitmapV2* bitmap_v2_new(rdpSettings* settings)
|
||||
|
||||
bitmap_v2->maxCells = 5;
|
||||
|
||||
settings->bitmap_cache = True;
|
||||
settings->bitmap_cache = False;
|
||||
settings->bitmapCacheV2NumCells = 5;
|
||||
settings->bitmapCacheV2CellInfo[0].numEntries = 600;
|
||||
settings->bitmapCacheV2CellInfo[0].persistent = False;
|
||||
|
30
libfreerdp-common/CMakeLists.txt
Normal file
30
libfreerdp-common/CMakeLists.txt
Normal file
@ -0,0 +1,30 @@
|
||||
# FreeRDP: A Remote Desktop Protocol Client
|
||||
# libfreerdp-common cmake build script
|
||||
#
|
||||
# Copyright 2011 O.S. Systems Software Ltda.
|
||||
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
|
||||
# Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set(FREERDP_COMMON_SRCS
|
||||
bitmap.c
|
||||
color.c)
|
||||
|
||||
add_library(freerdp-common ${FREERDP_COMMON_SRCS})
|
||||
|
||||
set_target_properties(freerdp-common PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib")
|
||||
target_link_libraries(freerdp-common freerdp-utils)
|
||||
|
||||
install(TARGETS freerdp-common DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
@ -17,7 +17,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "bitmap.h"
|
||||
#include <freerdp/utils/stream.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
|
||||
#include <freerdp/common/bitmap.h>
|
||||
|
||||
/*
|
||||
RLE Compressed Bitmap Stream (RLE_BITMAP_STREAM)
|
||||
@ -26,6 +29,158 @@
|
||||
http://msdn.microsoft.com/en-us/library/dd240593%28v=prot.10%29.aspx
|
||||
*/
|
||||
|
||||
#define REGULAR_BG_RUN 0x00
|
||||
#define MEGA_MEGA_BG_RUN 0xF0
|
||||
#define REGULAR_FG_RUN 0x01
|
||||
#define MEGA_MEGA_FG_RUN 0xF1
|
||||
#define LITE_SET_FG_FG_RUN 0x0C
|
||||
#define MEGA_MEGA_SET_FG_RUN 0xF6
|
||||
#define LITE_DITHERED_RUN 0x0E
|
||||
#define MEGA_MEGA_DITHERED_RUN 0xF8
|
||||
#define REGULAR_COLOR_RUN 0x03
|
||||
#define MEGA_MEGA_COLOR_RUN 0xF3
|
||||
#define REGULAR_FGBG_IMAGE 0x02
|
||||
#define MEGA_MEGA_FGBG_IMAGE 0xF2
|
||||
#define LITE_SET_FG_FGBG_IMAGE 0x0D
|
||||
#define MEGA_MEGA_SET_FGBG_IMAGE 0xF7
|
||||
#define REGULAR_COLOR_IMAGE 0x04
|
||||
#define MEGA_MEGA_COLOR_IMAGE 0xF4
|
||||
#define SPECIAL_FGBG_1 0xF9
|
||||
#define SPECIAL_FGBG_2 0xFA
|
||||
#define SPECIAL_WHITE 0xFD
|
||||
#define SPECIAL_BLACK 0xFE
|
||||
|
||||
#define BLACK_PIXEL 0x000000
|
||||
#define WHITE_PIXEL 0xFFFFFF
|
||||
|
||||
typedef uint32 PIXEL;
|
||||
|
||||
static uint8 g_MaskBit0 = 0x01; /* Least significant bit */
|
||||
static uint8 g_MaskBit1 = 0x02;
|
||||
static uint8 g_MaskBit2 = 0x04;
|
||||
static uint8 g_MaskBit3 = 0x08;
|
||||
static uint8 g_MaskBit4 = 0x10;
|
||||
static uint8 g_MaskBit5 = 0x20;
|
||||
static uint8 g_MaskBit6 = 0x40;
|
||||
static uint8 g_MaskBit7 = 0x80; /* Most significant bit */
|
||||
|
||||
static uint8 g_MaskSpecialFgBg1 = 0x03;
|
||||
static uint8 g_MaskSpecialFgBg2 = 0x05;
|
||||
|
||||
static uint8 g_MaskRegularRunLength = 0x1F;
|
||||
static uint8 g_MaskLiteRunLength = 0x0F;
|
||||
|
||||
/**
|
||||
* Reads the supplied order header and extracts the compression
|
||||
* order code ID.
|
||||
*/
|
||||
static uint32 ExtractCodeId(uint8 bOrderHdr)
|
||||
{
|
||||
int code;
|
||||
|
||||
switch (bOrderHdr)
|
||||
{
|
||||
case MEGA_MEGA_BG_RUN:
|
||||
case MEGA_MEGA_FG_RUN:
|
||||
case MEGA_MEGA_SET_FG_RUN:
|
||||
case MEGA_MEGA_DITHERED_RUN:
|
||||
case MEGA_MEGA_COLOR_RUN:
|
||||
case MEGA_MEGA_FGBG_IMAGE:
|
||||
case MEGA_MEGA_SET_FGBG_IMAGE:
|
||||
case MEGA_MEGA_COLOR_IMAGE:
|
||||
case SPECIAL_FGBG_1:
|
||||
case SPECIAL_FGBG_2:
|
||||
case SPECIAL_WHITE:
|
||||
case SPECIAL_BLACK:
|
||||
return bOrderHdr;
|
||||
}
|
||||
code = bOrderHdr >> 5;
|
||||
switch (code)
|
||||
{
|
||||
case REGULAR_BG_RUN:
|
||||
case REGULAR_FG_RUN:
|
||||
case REGULAR_COLOR_RUN:
|
||||
case REGULAR_FGBG_IMAGE:
|
||||
case REGULAR_COLOR_IMAGE:
|
||||
return code;
|
||||
}
|
||||
return bOrderHdr >> 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the run length of a compression order.
|
||||
*/
|
||||
static uint32 ExtractRunLength(uint32 code, uint8* pbOrderHdr, uint32* advance)
|
||||
{
|
||||
uint32 runLength;
|
||||
uint32 ladvance;
|
||||
|
||||
ladvance = 1;
|
||||
runLength = 0;
|
||||
switch (code)
|
||||
{
|
||||
case REGULAR_FGBG_IMAGE:
|
||||
runLength = (*pbOrderHdr) & g_MaskRegularRunLength;
|
||||
if (runLength == 0)
|
||||
{
|
||||
runLength = (*(pbOrderHdr + 1)) + 1;
|
||||
ladvance += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
runLength = runLength * 8;
|
||||
}
|
||||
break;
|
||||
case LITE_SET_FG_FGBG_IMAGE:
|
||||
runLength = (*pbOrderHdr) & g_MaskLiteRunLength;
|
||||
if (runLength == 0)
|
||||
{
|
||||
runLength = (*(pbOrderHdr + 1)) + 1;
|
||||
ladvance += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
runLength = runLength * 8;
|
||||
}
|
||||
break;
|
||||
case REGULAR_BG_RUN:
|
||||
case REGULAR_FG_RUN:
|
||||
case REGULAR_COLOR_RUN:
|
||||
case REGULAR_COLOR_IMAGE:
|
||||
runLength = (*pbOrderHdr) & g_MaskRegularRunLength;
|
||||
if (runLength == 0)
|
||||
{
|
||||
/* An extended (MEGA) run. */
|
||||
runLength = (*(pbOrderHdr + 1)) + 32;
|
||||
ladvance += 1;
|
||||
}
|
||||
break;
|
||||
case LITE_SET_FG_FG_RUN:
|
||||
case LITE_DITHERED_RUN:
|
||||
runLength = (*pbOrderHdr) & g_MaskLiteRunLength;
|
||||
if (runLength == 0)
|
||||
{
|
||||
/* An extended (MEGA) run. */
|
||||
runLength = (*(pbOrderHdr + 1)) + 16;
|
||||
ladvance += 1;
|
||||
}
|
||||
break;
|
||||
case MEGA_MEGA_BG_RUN:
|
||||
case MEGA_MEGA_FG_RUN:
|
||||
case MEGA_MEGA_SET_FG_RUN:
|
||||
case MEGA_MEGA_DITHERED_RUN:
|
||||
case MEGA_MEGA_COLOR_RUN:
|
||||
case MEGA_MEGA_FGBG_IMAGE:
|
||||
case MEGA_MEGA_SET_FGBG_IMAGE:
|
||||
case MEGA_MEGA_COLOR_IMAGE:
|
||||
runLength = ((uint16) pbOrderHdr[1]) | ((uint16) (pbOrderHdr[2] << 8));
|
||||
ladvance += 2;
|
||||
break;
|
||||
}
|
||||
*advance = ladvance;
|
||||
return runLength;
|
||||
}
|
||||
|
||||
#define UNROLL_COUNT 4
|
||||
#define UNROLL(_exp) do { _exp _exp _exp _exp } while (0)
|
||||
|
@ -19,137 +19,6 @@
|
||||
|
||||
/* do not compile the file directly */
|
||||
|
||||
#ifndef __BITMAP_TEMPLATE
|
||||
#define __BITMAP_TEMPLATE
|
||||
|
||||
static uint8 g_MaskBit0 = 0x01; /* Least significant bit */
|
||||
static uint8 g_MaskBit1 = 0x02;
|
||||
static uint8 g_MaskBit2 = 0x04;
|
||||
static uint8 g_MaskBit3 = 0x08;
|
||||
static uint8 g_MaskBit4 = 0x10;
|
||||
static uint8 g_MaskBit5 = 0x20;
|
||||
static uint8 g_MaskBit6 = 0x40;
|
||||
static uint8 g_MaskBit7 = 0x80; /* Most significant bit */
|
||||
|
||||
static uint8 g_MaskSpecialFgBg1 = 0x03;
|
||||
static uint8 g_MaskSpecialFgBg2 = 0x05;
|
||||
|
||||
static uint8 g_MaskRegularRunLength = 0x1F;
|
||||
static uint8 g_MaskLiteRunLength = 0x0F;
|
||||
|
||||
/**
|
||||
* Reads the supplied order header and extracts the compression
|
||||
* order code ID.
|
||||
*/
|
||||
static uint32 ExtractCodeId(uint8 bOrderHdr)
|
||||
{
|
||||
int code;
|
||||
|
||||
switch (bOrderHdr)
|
||||
{
|
||||
case MEGA_MEGA_BG_RUN:
|
||||
case MEGA_MEGA_FG_RUN:
|
||||
case MEGA_MEGA_SET_FG_RUN:
|
||||
case MEGA_MEGA_DITHERED_RUN:
|
||||
case MEGA_MEGA_COLOR_RUN:
|
||||
case MEGA_MEGA_FGBG_IMAGE:
|
||||
case MEGA_MEGA_SET_FGBG_IMAGE:
|
||||
case MEGA_MEGA_COLOR_IMAGE:
|
||||
case SPECIAL_FGBG_1:
|
||||
case SPECIAL_FGBG_2:
|
||||
case SPECIAL_WHITE:
|
||||
case SPECIAL_BLACK:
|
||||
return bOrderHdr;
|
||||
}
|
||||
code = bOrderHdr >> 5;
|
||||
switch (code)
|
||||
{
|
||||
case REGULAR_BG_RUN:
|
||||
case REGULAR_FG_RUN:
|
||||
case REGULAR_COLOR_RUN:
|
||||
case REGULAR_FGBG_IMAGE:
|
||||
case REGULAR_COLOR_IMAGE:
|
||||
return code;
|
||||
}
|
||||
return bOrderHdr >> 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the run length of a compression order.
|
||||
*/
|
||||
static uint32 ExtractRunLength(uint32 code, uint8* pbOrderHdr, uint32* advance)
|
||||
{
|
||||
uint32 runLength;
|
||||
uint32 ladvance;
|
||||
|
||||
ladvance = 1;
|
||||
runLength = 0;
|
||||
switch (code)
|
||||
{
|
||||
case REGULAR_FGBG_IMAGE:
|
||||
runLength = (*pbOrderHdr) & g_MaskRegularRunLength;
|
||||
if (runLength == 0)
|
||||
{
|
||||
runLength = (*(pbOrderHdr + 1)) + 1;
|
||||
ladvance += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
runLength = runLength * 8;
|
||||
}
|
||||
break;
|
||||
case LITE_SET_FG_FGBG_IMAGE:
|
||||
runLength = (*pbOrderHdr) & g_MaskLiteRunLength;
|
||||
if (runLength == 0)
|
||||
{
|
||||
runLength = (*(pbOrderHdr + 1)) + 1;
|
||||
ladvance += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
runLength = runLength * 8;
|
||||
}
|
||||
break;
|
||||
case REGULAR_BG_RUN:
|
||||
case REGULAR_FG_RUN:
|
||||
case REGULAR_COLOR_RUN:
|
||||
case REGULAR_COLOR_IMAGE:
|
||||
runLength = (*pbOrderHdr) & g_MaskRegularRunLength;
|
||||
if (runLength == 0)
|
||||
{
|
||||
/* An extended (MEGA) run. */
|
||||
runLength = (*(pbOrderHdr + 1)) + 32;
|
||||
ladvance += 1;
|
||||
}
|
||||
break;
|
||||
case LITE_SET_FG_FG_RUN:
|
||||
case LITE_DITHERED_RUN:
|
||||
runLength = (*pbOrderHdr) & g_MaskLiteRunLength;
|
||||
if (runLength == 0)
|
||||
{
|
||||
/* An extended (MEGA) run. */
|
||||
runLength = (*(pbOrderHdr + 1)) + 16;
|
||||
ladvance += 1;
|
||||
}
|
||||
break;
|
||||
case MEGA_MEGA_BG_RUN:
|
||||
case MEGA_MEGA_FG_RUN:
|
||||
case MEGA_MEGA_SET_FG_RUN:
|
||||
case MEGA_MEGA_DITHERED_RUN:
|
||||
case MEGA_MEGA_COLOR_RUN:
|
||||
case MEGA_MEGA_FGBG_IMAGE:
|
||||
case MEGA_MEGA_SET_FGBG_IMAGE:
|
||||
case MEGA_MEGA_COLOR_IMAGE:
|
||||
runLength = ((uint16) pbOrderHdr[1]) | ((uint16) (pbOrderHdr[2] << 8));
|
||||
ladvance += 2;
|
||||
break;
|
||||
}
|
||||
*advance = ladvance;
|
||||
return runLength;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Write a foreground/background image to a destination buffer.
|
||||
*/
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* GDI Color Conversion Routines
|
||||
* Color Conversion Routines
|
||||
*
|
||||
* Copyright 2010 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
@ -21,9 +21,9 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/gdi/color.h>
|
||||
#include <freerdp/common/color.h>
|
||||
|
||||
uint32 gdi_color_convert_rgb(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
||||
uint32 freerdp_color_convert_rgb(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
||||
{
|
||||
uint8 red = 0;
|
||||
uint8 green = 0;
|
||||
@ -107,7 +107,7 @@ uint32 gdi_color_convert_rgb(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV c
|
||||
return dstColor;
|
||||
}
|
||||
|
||||
uint32 gdi_color_convert_bgr(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
||||
uint32 freerdp_color_convert_bgr(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
||||
{
|
||||
uint8 red = 0;
|
||||
uint8 green = 0;
|
||||
@ -191,15 +191,15 @@ uint32 gdi_color_convert_bgr(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV c
|
||||
return dstColor;
|
||||
}
|
||||
|
||||
uint32 gdi_color_convert(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
||||
uint32 freerdp_color_convert(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
||||
{
|
||||
if (clrconv->invert)
|
||||
return gdi_color_convert_bgr(srcColor, srcBpp, dstBpp, clrconv);
|
||||
return freerdp_color_convert_bgr(srcColor, srcBpp, dstBpp, clrconv);
|
||||
else
|
||||
return gdi_color_convert_rgb(srcColor, srcBpp, dstBpp, clrconv);
|
||||
return freerdp_color_convert_rgb(srcColor, srcBpp, dstBpp, clrconv);
|
||||
}
|
||||
|
||||
uint8* gdi_image_convert_8bpp(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
||||
uint8* freerdp_image_convert_8bpp(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
||||
{
|
||||
int i;
|
||||
uint8 red;
|
||||
@ -280,7 +280,7 @@ uint8* gdi_image_convert_8bpp(uint8* srcData, uint8* dstData, int width, int hei
|
||||
return srcData;
|
||||
}
|
||||
|
||||
uint8* gdi_image_convert_15bpp(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
||||
uint8* freerdp_image_convert_15bpp(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
||||
{
|
||||
int i;
|
||||
uint8 red;
|
||||
@ -341,10 +341,10 @@ uint8* gdi_image_convert_15bpp(uint8* srcData, uint8* dstData, int width, int he
|
||||
return srcData;
|
||||
}
|
||||
|
||||
uint8* gdi_image_convert_16bpp(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
||||
uint8* freerdp_image_convert_16bpp(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
||||
{
|
||||
if (srcBpp == 15)
|
||||
return gdi_image_convert_15bpp(srcData, dstData, width, height, srcBpp, dstBpp, clrconv);
|
||||
return freerdp_image_convert_15bpp(srcData, dstData, width, height, srcBpp, dstBpp, clrconv);
|
||||
|
||||
if (dstBpp == 16)
|
||||
{
|
||||
@ -434,29 +434,21 @@ uint8* gdi_image_convert_16bpp(uint8* srcData, uint8* dstData, int width, int he
|
||||
return srcData;
|
||||
}
|
||||
|
||||
uint8* gdi_image_convert_24bpp(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
||||
uint8* freerdp_image_convert_24bpp(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
||||
{
|
||||
int i;
|
||||
uint8 red;
|
||||
uint8 green;
|
||||
uint8 blue;
|
||||
uint32 pixel;
|
||||
uint32 *dst32;
|
||||
|
||||
if (dstBpp == 32)
|
||||
{
|
||||
if (dstData == NULL)
|
||||
dstData = (uint8*) malloc(width * height * 4);
|
||||
|
||||
dst32 = (uint32 *) dstData;
|
||||
for (i = width * height; i > 0; i--)
|
||||
{
|
||||
red = *(srcData++);
|
||||
green = *(srcData++);
|
||||
blue = *(srcData++);
|
||||
pixel = BGR24(red, green, blue);
|
||||
*dst32 = pixel;
|
||||
dst32++;
|
||||
*(dstData++) = *(srcData++);
|
||||
*(dstData++) = *(srcData++);
|
||||
*(dstData++) = *(srcData++);
|
||||
*(dstData++) = 0xFF;
|
||||
}
|
||||
return dstData;
|
||||
}
|
||||
@ -464,7 +456,7 @@ uint8* gdi_image_convert_24bpp(uint8* srcData, uint8* dstData, int width, int he
|
||||
return srcData;
|
||||
}
|
||||
|
||||
uint8* gdi_image_convert_32bpp(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
||||
uint8* freerdp_image_convert_32bpp(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
||||
{
|
||||
if (dstBpp == 16)
|
||||
{
|
||||
@ -556,26 +548,26 @@ uint8* gdi_image_convert_32bpp(uint8* srcData, uint8* dstData, int width, int he
|
||||
return srcData;
|
||||
}
|
||||
|
||||
p_gdi_image_convert gdi_image_convert_[5] =
|
||||
p_freerdp_image_convert freerdp_image_convert_[5] =
|
||||
{
|
||||
NULL,
|
||||
gdi_image_convert_8bpp,
|
||||
gdi_image_convert_16bpp,
|
||||
gdi_image_convert_24bpp,
|
||||
gdi_image_convert_32bpp
|
||||
freerdp_image_convert_8bpp,
|
||||
freerdp_image_convert_16bpp,
|
||||
freerdp_image_convert_24bpp,
|
||||
freerdp_image_convert_32bpp
|
||||
};
|
||||
|
||||
uint8* gdi_image_convert(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
||||
uint8* freerdp_image_convert(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
||||
{
|
||||
p_gdi_image_convert _p_gdi_image_convert = gdi_image_convert_[IBPP(srcBpp)];
|
||||
p_freerdp_image_convert _p_freerdp_image_convert = freerdp_image_convert_[IBPP(srcBpp)];
|
||||
|
||||
if (_p_gdi_image_convert != NULL)
|
||||
return _p_gdi_image_convert(srcData, dstData, width, height, srcBpp, dstBpp, clrconv);
|
||||
if (_p_freerdp_image_convert != NULL)
|
||||
return _p_freerdp_image_convert(srcData, dstData, width, height, srcBpp, dstBpp, clrconv);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8* gdi_image_invert(uint8* srcData, uint8* dstData, int width, int height, int bpp)
|
||||
uint8* freerdp_image_invert(uint8* srcData, uint8* dstData, int width, int height, int bpp)
|
||||
{
|
||||
int y;
|
||||
uint8* srcp;
|
||||
@ -600,7 +592,7 @@ uint8* gdi_image_invert(uint8* srcData, uint8* dstData, int width, int height, i
|
||||
return dstData;
|
||||
}
|
||||
|
||||
uint8* gdi_icon_convert(uint8* srcData, uint8* dstData, uint8* mask, int width, int height, int bpp, HCLRCONV clrconv)
|
||||
uint8* freerdp_icon_convert(uint8* srcData, uint8* dstData, uint8* mask, int width, int height, int bpp, HCLRCONV clrconv)
|
||||
{
|
||||
int x, y;
|
||||
int pixel;
|
||||
@ -610,8 +602,8 @@ uint8* gdi_icon_convert(uint8* srcData, uint8* dstData, uint8* mask, int width,
|
||||
uint32* icon;
|
||||
|
||||
pixel = 0;
|
||||
data = gdi_image_invert(srcData, dstData, width, height, bpp);
|
||||
dstData = gdi_image_convert(data, NULL, width, height, bpp, 32, clrconv);
|
||||
data = freerdp_image_invert(srcData, dstData, width, height, bpp);
|
||||
dstData = freerdp_image_convert(data, NULL, width, height, bpp, 32, clrconv);
|
||||
|
||||
free(data);
|
||||
bmask = mask[pixel];
|
||||
@ -642,7 +634,7 @@ uint8* gdi_icon_convert(uint8* srcData, uint8* dstData, uint8* mask, int width,
|
||||
return dstData;
|
||||
}
|
||||
|
||||
uint8* gdi_glyph_convert(int width, int height, uint8* data)
|
||||
uint8* freerdp_glyph_convert(int width, int height, uint8* data)
|
||||
{
|
||||
int x, y;
|
||||
uint8 *srcp;
|
||||
@ -679,7 +671,7 @@ uint8* gdi_glyph_convert(int width, int height, uint8* data)
|
||||
return dstData;
|
||||
}
|
||||
|
||||
uint8* gdi_mono_image_convert(uint8* srcData, int width, int height, int srcBpp, int dstBpp, uint32 bgcolor, uint32 fgcolor, HCLRCONV clrconv)
|
||||
uint8* freerdp_mono_image_convert(uint8* srcData, int width, int height, int srcBpp, int dstBpp, uint32 bgcolor, uint32 fgcolor, HCLRCONV clrconv)
|
||||
{
|
||||
int index;
|
||||
uint16* dst16;
|
@ -24,8 +24,6 @@ include_directories(${ZLIB_INCLUDE_DIRS})
|
||||
set(LIBFREERDP_CORE_SRCS
|
||||
activation.c
|
||||
activation.h
|
||||
bitmap.c
|
||||
bitmap.h
|
||||
ber.c
|
||||
ber.h
|
||||
gcc.c
|
||||
@ -105,5 +103,6 @@ endif()
|
||||
|
||||
target_link_libraries(freerdp-core ${OPENSSL_LIBRARIES})
|
||||
target_link_libraries(freerdp-core freerdp-utils)
|
||||
target_link_libraries(freerdp-core freerdp-common)
|
||||
|
||||
install(TARGETS freerdp-core DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
@ -50,7 +50,8 @@ uint8 CAPSET_TYPE_STRINGS[][32] =
|
||||
"Multifragment Update",
|
||||
"Large Pointer",
|
||||
"Surface Commands",
|
||||
"Bitmap Codecs"
|
||||
"Bitmap Codecs",
|
||||
"Frame Acknowledge"
|
||||
};
|
||||
|
||||
/* CODEC_GUID_REMOTEFX 0x76772F12BD724463AFB3B73C9C6F7886 */
|
||||
@ -900,7 +901,7 @@ void rdp_write_bitmap_cache_host_support_capability_set(STREAM* s, rdpSettings*
|
||||
rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT);
|
||||
}
|
||||
|
||||
void rdp_write_bitmap_cache_cell_info(STREAM* s, uint16 numEntries, boolean persistent)
|
||||
void rdp_write_bitmap_cache_cell_info(STREAM* s, BITMAP_CACHE_V2_CELL_INFO* cellInfo)
|
||||
{
|
||||
uint32 info;
|
||||
|
||||
@ -909,8 +910,7 @@ void rdp_write_bitmap_cache_cell_info(STREAM* s, uint16 numEntries, boolean pers
|
||||
* is used to indicate a persistent bitmap cache.
|
||||
*/
|
||||
|
||||
info = numEntries & persistent;
|
||||
|
||||
info = cellInfo->numEntries || (cellInfo->persistent << 31);
|
||||
stream_write_uint32(s, info);
|
||||
}
|
||||
|
||||
@ -955,12 +955,12 @@ void rdp_write_bitmap_cache_v2_capability_set(STREAM* s, rdpSettings* settings)
|
||||
|
||||
stream_write_uint16(s, cacheFlags); /* cacheFlags (2 bytes) */
|
||||
stream_write_uint8(s, 0); /* pad2 (1 byte) */
|
||||
stream_write_uint8(s, 5); /* numCellCaches (1 byte) */
|
||||
rdp_write_bitmap_cache_cell_info(s, 600, 0); /* bitmapCache0CellInfo (4 bytes) */
|
||||
rdp_write_bitmap_cache_cell_info(s, 600, 0); /* bitmapCache1CellInfo (4 bytes) */
|
||||
rdp_write_bitmap_cache_cell_info(s, 2048, 0); /* bitmapCache2CellInfo (4 bytes) */
|
||||
rdp_write_bitmap_cache_cell_info(s, 4096, 0); /* bitmapCache3CellInfo (4 bytes) */
|
||||
rdp_write_bitmap_cache_cell_info(s, 2048, 0); /* bitmapCache4CellInfo (4 bytes) */
|
||||
stream_write_uint8(s, settings->bitmapCacheV2NumCells); /* numCellCaches (1 byte) */
|
||||
rdp_write_bitmap_cache_cell_info(s, &settings->bitmapCacheV2CellInfo[0]); /* bitmapCache0CellInfo (4 bytes) */
|
||||
rdp_write_bitmap_cache_cell_info(s, &settings->bitmapCacheV2CellInfo[1]); /* bitmapCache1CellInfo (4 bytes) */
|
||||
rdp_write_bitmap_cache_cell_info(s, &settings->bitmapCacheV2CellInfo[2]); /* bitmapCache2CellInfo (4 bytes) */
|
||||
rdp_write_bitmap_cache_cell_info(s, &settings->bitmapCacheV2CellInfo[3]); /* bitmapCache3CellInfo (4 bytes) */
|
||||
rdp_write_bitmap_cache_cell_info(s, &settings->bitmapCacheV2CellInfo[4]); /* bitmapCache4CellInfo (4 bytes) */
|
||||
stream_write_zero(s, 12); /* pad3 (12 bytes) */
|
||||
|
||||
rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V2);
|
||||
@ -975,9 +975,10 @@ void rdp_write_bitmap_cache_v2_capability_set(STREAM* s, rdpSettings* settings)
|
||||
|
||||
void rdp_read_virtual_channel_capability_set(STREAM* s, rdpSettings* settings)
|
||||
{
|
||||
uint32 flags;
|
||||
uint32 VCChunkSize;
|
||||
|
||||
stream_seek_uint32(s); /* flags (4 bytes) */
|
||||
stream_read_uint32(s, flags); /* flags (4 bytes) */
|
||||
stream_read_uint32(s, VCChunkSize); /* VCChunkSize (4 bytes) */
|
||||
|
||||
if (!settings->server_mode)
|
||||
@ -1527,7 +1528,10 @@ boolean rdp_read_capability_sets(STREAM* s, rdpSettings* settings, uint16 number
|
||||
em = bm + length;
|
||||
|
||||
if (stream_get_left(s) < length - 4)
|
||||
{
|
||||
printf("error processing stream\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
@ -1649,7 +1653,7 @@ boolean rdp_read_capability_sets(STREAM* s, rdpSettings* settings, uint16 number
|
||||
}
|
||||
|
||||
if (s->p != em)
|
||||
printf("incorrect offset, type:%d actual:%d expected:%d\n",
|
||||
printf("incorrect offset, type:0x%02X actual:%d expected:%d\n",
|
||||
type, (int) (s->p - bm), (int) (em - bm));
|
||||
|
||||
stream_set_mark(s, em);
|
||||
@ -1668,18 +1672,46 @@ boolean rdp_recv_demand_active(rdpRdp* rdp, STREAM* s)
|
||||
uint16 numberCapabilities;
|
||||
uint16 lengthSourceDescriptor;
|
||||
uint16 lengthCombinedCapabilities;
|
||||
uint32 securityHeader;
|
||||
|
||||
if (!rdp_read_header(rdp, s, &length, &channelId))
|
||||
return False;
|
||||
|
||||
if (rdp->settings->encryption)
|
||||
{
|
||||
stream_read_uint32(s, securityHeader);
|
||||
if (securityHeader & SEC_SECURE_CHECKSUM)
|
||||
{
|
||||
printf("Error: TODO\n");
|
||||
return False;
|
||||
}
|
||||
if (securityHeader & SEC_ENCRYPT)
|
||||
{
|
||||
if (!rdp_decrypt(rdp, s, length - 4))
|
||||
{
|
||||
printf("rdp_decrypt failed\n");
|
||||
return False;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (channelId != MCS_GLOBAL_CHANNEL_ID)
|
||||
{
|
||||
printf("channelId bad\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!rdp_read_share_control_header(s, &pduLength, &pduType, &rdp->settings->pdu_source))
|
||||
{
|
||||
printf("rdp_read_share_control_header failed\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
if (pduType != PDU_TYPE_DEMAND_ACTIVE)
|
||||
{
|
||||
printf("pduType bad\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
stream_read_uint32(s, rdp->settings->share_id); /* shareId (4 bytes) */
|
||||
stream_read_uint16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */
|
||||
@ -1690,7 +1722,10 @@ boolean rdp_recv_demand_active(rdpRdp* rdp, STREAM* s)
|
||||
|
||||
/* capabilitySets */
|
||||
if (!rdp_read_capability_sets(s, rdp->settings, numberCapabilities))
|
||||
{
|
||||
printf("rdp_read_capability_sets failes\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
rdp->update->glyph_v2 = (rdp->settings->glyphSupportLevel > GLYPH_SUPPORT_FULL) ? True : False;
|
||||
|
||||
|
@ -227,15 +227,92 @@ void certificate_free_x509_certificate_chain(rdpX509CertChain* x509_cert_chain)
|
||||
xfree(x509_cert_chain);
|
||||
}
|
||||
|
||||
static boolean certificate_process_server_public_key(rdpCertificate* certificate, STREAM* s, uint32 length)
|
||||
{
|
||||
uint8 magic[4];
|
||||
uint32 keylen;
|
||||
uint32 bitlen;
|
||||
uint32 datalen;
|
||||
uint32 modlen;
|
||||
|
||||
memcpy(magic, s->p, 4);
|
||||
|
||||
if (memcmp(magic, "RSA1", 4) != 0)
|
||||
{
|
||||
printf("gcc_process_server_public_key: magic error\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
stream_seek(s, 4);
|
||||
stream_read_uint32(s, keylen);
|
||||
stream_read_uint32(s, bitlen);
|
||||
stream_read_uint32(s, datalen);
|
||||
memcpy(certificate->cert_info.exponent, s->p, 4);
|
||||
stream_seek(s, 4);
|
||||
modlen = keylen - 8;
|
||||
freerdp_blob_alloc(&(certificate->cert_info.modulus), modlen);
|
||||
memcpy(certificate->cert_info.modulus.data, s->p, modlen);
|
||||
stream_seek(s, keylen);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static boolean certificate_process_server_public_signature(rdpCertificate* certificate, STREAM* s, uint32 length)
|
||||
{
|
||||
stream_seek(s, length);
|
||||
return True;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a Server Proprietary Certificate.\n
|
||||
* @param certificate certificate module
|
||||
* @param s stream
|
||||
*/
|
||||
|
||||
void certificate_read_server_proprietary_certificate(rdpCertificate* certificate, STREAM* s)
|
||||
boolean certificate_read_server_proprietary_certificate(rdpCertificate* certificate, STREAM* s)
|
||||
{
|
||||
DEBUG_CERTIFICATE("Server Proprietary Certificate");
|
||||
uint32 dwSigAlgId;
|
||||
uint32 dwKeyAlgId;
|
||||
uint32 wPublicKeyBlobType;
|
||||
uint32 wPublicKeyBlobLen;
|
||||
uint32 wSignatureBlobType;
|
||||
uint32 wSignatureBlobLen;
|
||||
|
||||
printf("Server Proprietary Certificate\n");
|
||||
|
||||
stream_read_uint32(s, dwSigAlgId);
|
||||
stream_read_uint32(s, dwKeyAlgId);
|
||||
if (!(dwSigAlgId == 1 && dwKeyAlgId == 1))
|
||||
{
|
||||
printf("certificate_read_server_proprietary_certificate: parse error 1\n");
|
||||
return False;
|
||||
}
|
||||
stream_read_uint16(s, wPublicKeyBlobType);
|
||||
if (wPublicKeyBlobType != BB_RSA_KEY_BLOB)
|
||||
{
|
||||
printf("certificate_read_server_proprietary_certificate: parse error 2\n");
|
||||
return False;
|
||||
}
|
||||
stream_read_uint16(s, wPublicKeyBlobLen);
|
||||
if (!certificate_process_server_public_key(certificate, s, wPublicKeyBlobLen))
|
||||
{
|
||||
printf("certificate_read_server_proprietary_certificate: parse error 3\n");
|
||||
return False;
|
||||
}
|
||||
stream_read_uint16(s, wSignatureBlobType);
|
||||
if (wSignatureBlobType != BB_RSA_SIGNATURE_BLOB)
|
||||
{
|
||||
printf("certificate_read_server_proprietary_certificate: parse error 4\n");
|
||||
return False;
|
||||
}
|
||||
stream_read_uint16(s, wSignatureBlobLen);
|
||||
if (!certificate_process_server_public_signature(certificate, s, wSignatureBlobLen))
|
||||
{
|
||||
printf("certificate_read_server_proprietary_certificate: parse error 5\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -244,7 +321,7 @@ void certificate_read_server_proprietary_certificate(rdpCertificate* certificate
|
||||
* @param s stream
|
||||
*/
|
||||
|
||||
void certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, STREAM* s)
|
||||
boolean certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, STREAM* s)
|
||||
{
|
||||
int i;
|
||||
uint32 certLength;
|
||||
@ -280,6 +357,8 @@ void certificate_read_server_x509_certificate_chain(rdpCertificate* certificate,
|
||||
DEBUG_CERTIFICATE("modulus length:%d", certificate->cert_info.modulus.length);
|
||||
}
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -289,7 +368,7 @@ void certificate_read_server_x509_certificate_chain(rdpCertificate* certificate,
|
||||
* @param length certificate length
|
||||
*/
|
||||
|
||||
void certificate_read_server_certificate(rdpCertificate* certificate, uint8* server_cert, int length)
|
||||
boolean certificate_read_server_certificate(rdpCertificate* certificate, uint8* server_cert, int length)
|
||||
{
|
||||
STREAM* s;
|
||||
uint32 dwVersion;
|
||||
@ -300,7 +379,7 @@ void certificate_read_server_certificate(rdpCertificate* certificate, uint8* ser
|
||||
if (length < 1)
|
||||
{
|
||||
printf("null server certificate\n");
|
||||
return;
|
||||
return False;
|
||||
}
|
||||
|
||||
stream_read_uint32(s, dwVersion); /* dwVersion (4 bytes) */
|
||||
@ -319,6 +398,9 @@ void certificate_read_server_certificate(rdpCertificate* certificate, uint8* ser
|
||||
printf("invalid certificate chain version:%d\n", dwVersion & CERT_CHAIN_VERSION_MASK);
|
||||
break;
|
||||
}
|
||||
|
||||
xfree(s);
|
||||
return True;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -327,7 +409,7 @@ void certificate_read_server_certificate(rdpCertificate* certificate, uint8* ser
|
||||
* @return new certificate module
|
||||
*/
|
||||
|
||||
rdpCertificate* certificate_new(rdpRdp* rdp)
|
||||
rdpCertificate* certificate_new(void)
|
||||
{
|
||||
rdpCertificate* certificate;
|
||||
|
||||
@ -335,7 +417,6 @@ rdpCertificate* certificate_new(rdpRdp* rdp)
|
||||
|
||||
if (certificate != NULL)
|
||||
{
|
||||
certificate->rdp = rdp;
|
||||
certificate->x509_cert_chain = NULL;
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,9 @@ typedef struct rdp_certificate rdpCertificate;
|
||||
#define CERT_PERMANENTLY_ISSUED 0x00000000
|
||||
#define CERT_TEMPORARILY_ISSUED 0x80000000
|
||||
|
||||
#define BB_RSA_KEY_BLOB 6
|
||||
#define BB_RSA_SIGNATURE_BLOB 8
|
||||
|
||||
struct rdp_CertBlob
|
||||
{
|
||||
uint32 length;
|
||||
@ -60,7 +63,6 @@ typedef struct rdp_CertInfo rdpCertInfo;
|
||||
|
||||
struct rdp_certificate
|
||||
{
|
||||
struct rdp_rdp* rdp;
|
||||
rdpCertInfo cert_info;
|
||||
rdpX509CertChain* x509_cert_chain;
|
||||
};
|
||||
@ -70,11 +72,11 @@ void certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info);
|
||||
rdpX509CertChain* certificate_new_x509_certificate_chain(uint32 count);
|
||||
void certificate_free_x509_certificate_chain(rdpX509CertChain* x509_cert_chain);
|
||||
|
||||
void certificate_read_server_proprietary_certificate(rdpCertificate* certificate, STREAM* s);
|
||||
void certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, STREAM* s);
|
||||
void certificate_read_server_certificate(rdpCertificate* certificate, uint8* server_cert, int length);
|
||||
boolean certificate_read_server_proprietary_certificate(rdpCertificate* certificate, STREAM* s);
|
||||
boolean certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, STREAM* s);
|
||||
boolean certificate_read_server_certificate(rdpCertificate* certificate, uint8* server_cert, int length);
|
||||
|
||||
rdpCertificate* certificate_new(rdpRdp* rdp);
|
||||
rdpCertificate* certificate_new(void);
|
||||
void certificate_free(rdpCertificate* certificate);
|
||||
|
||||
#ifdef WITH_DEBUG_CERTIFICATE
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "connection.h"
|
||||
#include "info.h"
|
||||
#include "per.h"
|
||||
|
||||
/**
|
||||
* Connection Sequence
|
||||
@ -80,7 +81,7 @@ boolean rdp_client_connect(rdpRdp* rdp)
|
||||
ret = transport_connect_nla(rdp->transport);
|
||||
else if (rdp->nego->selected_protocol & PROTOCOL_TLS)
|
||||
ret = transport_connect_tls(rdp->transport);
|
||||
else if (rdp->nego->selected_protocol & PROTOCOL_RDP)
|
||||
else if (rdp->nego->selected_protocol == PROTOCOL_RDP) /* 0 */
|
||||
ret = transport_connect_rdp(rdp->transport);
|
||||
|
||||
if (!ret)
|
||||
@ -145,11 +146,83 @@ boolean rdp_client_redirect(rdpRdp* rdp)
|
||||
return rdp_client_connect(rdp);
|
||||
}
|
||||
|
||||
static boolean rdp_establish_keys(rdpRdp* rdp)
|
||||
{
|
||||
uint8 client_random[32];
|
||||
uint8 crypt_client_random[256 + 8];
|
||||
uint32 key_len;
|
||||
uint8* mod;
|
||||
uint8* exp;
|
||||
uint32 length;
|
||||
STREAM* s;
|
||||
|
||||
if (rdp->settings->encryption == False)
|
||||
{
|
||||
/* no RDP encryption */
|
||||
return True;
|
||||
}
|
||||
|
||||
/* encrypt client random */
|
||||
memset(crypt_client_random, 0, sizeof(crypt_client_random));
|
||||
memset(client_random, 0x5e, 32);
|
||||
crypto_nonce(client_random, 32);
|
||||
key_len = rdp->settings->server_cert->cert_info.modulus.length;
|
||||
mod = rdp->settings->server_cert->cert_info.modulus.data;
|
||||
exp = rdp->settings->server_cert->cert_info.exponent;
|
||||
crypto_rsa_encrypt(client_random, 32, key_len, mod, exp, crypt_client_random);
|
||||
|
||||
/* send crypt client random to server */
|
||||
length = 7 + 8 + 4 + 4 + key_len + 8;
|
||||
s = transport_send_stream_init(rdp->mcs->transport, length);
|
||||
tpkt_write_header(s, length);
|
||||
tpdu_write_header(s, 2, 0xf0);
|
||||
per_write_choice(s, DomainMCSPDU_SendDataRequest << 2);
|
||||
per_write_integer16(s, rdp->mcs->user_id, MCS_BASE_CHANNEL_ID);
|
||||
per_write_integer16(s, MCS_GLOBAL_CHANNEL_ID, 0);
|
||||
stream_write_uint8(s, 0x70);
|
||||
length = (4 + 4 + key_len + 8) | 0x8000;
|
||||
stream_write_uint16_be(s, length);
|
||||
stream_write_uint32(s, 1); /* SEC_CLIENT_RANDOM */
|
||||
length = key_len + 8;
|
||||
stream_write_uint32(s, length);
|
||||
memcpy(s->p, crypt_client_random, length);
|
||||
stream_seek(s, length);
|
||||
if (transport_write(rdp->mcs->transport, s) < 0)
|
||||
{
|
||||
return False;
|
||||
}
|
||||
|
||||
/* now calculate encrypt / decrypt and upate keys */
|
||||
if (!security_establish_keys(client_random, rdp->settings))
|
||||
{
|
||||
return False;
|
||||
}
|
||||
|
||||
rdp->do_crypt = True;
|
||||
|
||||
if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS)
|
||||
{
|
||||
uint8 fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
|
||||
rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->settings->fips_encrypt_key, fips_ivec);
|
||||
rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->settings->fips_decrypt_key, fips_ivec);
|
||||
|
||||
rdp->fips_hmac = crypto_hmac_new();
|
||||
return True;
|
||||
}
|
||||
|
||||
rdp->rc4_decrypt_key = crypto_rc4_init(rdp->settings->decrypt_key, rdp->settings->rc4_key_len);
|
||||
rdp->rc4_encrypt_key = crypto_rc4_init(rdp->settings->encrypt_key, rdp->settings->rc4_key_len);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean rdp_client_connect_mcs_connect_response(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
if (!mcs_recv_connect_response(rdp->mcs, s))
|
||||
{
|
||||
printf("rdp_client_connect_mcs_connect_response: mcs_recv_connect_response failed\n");
|
||||
return False;
|
||||
|
||||
}
|
||||
if (!mcs_send_erect_domain_request(rdp->mcs))
|
||||
return False;
|
||||
if (!mcs_send_attach_user_request(rdp->mcs))
|
||||
@ -229,6 +302,8 @@ boolean rdp_client_connect_mcs_channel_join_confirm(rdpRdp* rdp, STREAM* s)
|
||||
|
||||
if (rdp->mcs->user_channel_joined && rdp->mcs->global_channel_joined && all_joined)
|
||||
{
|
||||
if (!rdp_establish_keys(rdp))
|
||||
return False;
|
||||
if (!rdp_send_client_info(rdp))
|
||||
return False;
|
||||
rdp->state = CONNECTION_STATE_LICENSE;
|
||||
|
@ -72,6 +72,72 @@ void crypto_rc4_free(CryptoRc4 rc4)
|
||||
xfree(rc4);
|
||||
}
|
||||
|
||||
CryptoDes3 crypto_des3_encrypt_init(uint8 key[24], uint8 ivec[8])
|
||||
{
|
||||
CryptoDes3 des3 = xmalloc(sizeof(*des3));
|
||||
EVP_CIPHER_CTX_init(&des3->des3_ctx);
|
||||
EVP_EncryptInit_ex(&des3->des3_ctx, EVP_des_ede3_cbc(), NULL, key, ivec);
|
||||
EVP_CIPHER_CTX_set_padding(&des3->des3_ctx, 0);
|
||||
return des3;
|
||||
}
|
||||
|
||||
CryptoDes3 crypto_des3_decrypt_init(uint8 key[24], uint8 ivec[8])
|
||||
{
|
||||
CryptoDes3 des3 = xmalloc(sizeof(*des3));
|
||||
EVP_CIPHER_CTX_init(&des3->des3_ctx);
|
||||
EVP_DecryptInit_ex(&des3->des3_ctx, EVP_des_ede3_cbc(), NULL, key, ivec);
|
||||
EVP_CIPHER_CTX_set_padding(&des3->des3_ctx, 0);
|
||||
return des3;
|
||||
}
|
||||
|
||||
void crypto_des3_encrypt(CryptoDes3 des3, uint32 length, uint8 *in_data, uint8 *out_data)
|
||||
{
|
||||
int len;
|
||||
EVP_EncryptUpdate(&des3->des3_ctx, out_data, &len, in_data, length);
|
||||
}
|
||||
|
||||
void crypto_des3_decrypt(CryptoDes3 des3, uint32 length, uint8 *in_data, uint8* out_data)
|
||||
{
|
||||
int len;
|
||||
EVP_DecryptUpdate(&des3->des3_ctx, out_data, &len, in_data, length);
|
||||
if (length != len)
|
||||
abort(); // TODO
|
||||
}
|
||||
|
||||
void crypto_des3_free(CryptoDes3 des3)
|
||||
{
|
||||
EVP_CIPHER_CTX_cleanup(&des3->des3_ctx);
|
||||
xfree(des3);
|
||||
}
|
||||
|
||||
CryptoHmac crypto_hmac_new(void)
|
||||
{
|
||||
CryptoHmac hmac = xmalloc(sizeof(*hmac));
|
||||
HMAC_CTX_init(&hmac->hmac_ctx);
|
||||
return hmac;
|
||||
}
|
||||
|
||||
void crypto_hmac_sha1_init(CryptoHmac hmac, uint8 *data, uint32 length)
|
||||
{
|
||||
HMAC_Init_ex(&hmac->hmac_ctx, data, length, EVP_sha1(), NULL);
|
||||
}
|
||||
|
||||
void crypto_hmac_update(CryptoHmac hmac, uint8 *data, uint32 length)
|
||||
{
|
||||
HMAC_Update(&hmac->hmac_ctx, data, length);
|
||||
}
|
||||
|
||||
void crypto_hmac_final(CryptoHmac hmac, uint8 *out_data, uint32 length)
|
||||
{
|
||||
HMAC_Final(&hmac->hmac_ctx, out_data, &length);
|
||||
}
|
||||
|
||||
void crypto_hmac_free(CryptoHmac hmac)
|
||||
{
|
||||
HMAC_CTX_cleanup(&hmac->hmac_ctx);
|
||||
xfree(hmac);
|
||||
}
|
||||
|
||||
CryptoCert crypto_cert_read(uint8* data, uint32 length)
|
||||
{
|
||||
CryptoCert cert = xmalloc(sizeof(*cert));
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <openssl/rc4.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include <openssl/rand.h>
|
||||
@ -40,7 +41,7 @@
|
||||
#endif
|
||||
|
||||
#define EXPONENT_MAX_SIZE 4
|
||||
#define MODULUS_MAX_SIZE 64
|
||||
#define MODULUS_MAX_SIZE 256
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/utils/blob.h>
|
||||
@ -62,6 +63,16 @@ struct crypto_rc4_struct
|
||||
RC4_KEY rc4_key;
|
||||
};
|
||||
|
||||
struct crypto_des3_struct
|
||||
{
|
||||
EVP_CIPHER_CTX des3_ctx;
|
||||
};
|
||||
|
||||
struct crypto_hmac_struct
|
||||
{
|
||||
HMAC_CTX hmac_ctx;
|
||||
};
|
||||
|
||||
struct crypto_cert_struct
|
||||
{
|
||||
X509 * px509;
|
||||
@ -82,6 +93,20 @@ CryptoRc4 crypto_rc4_init(uint8* key, uint32 length);
|
||||
void crypto_rc4(CryptoRc4 rc4, uint32 length, uint8* in_data, uint8* out_data);
|
||||
void crypto_rc4_free(CryptoRc4 rc4);
|
||||
|
||||
typedef struct crypto_des3_struct* CryptoDes3;
|
||||
CryptoDes3 crypto_des3_encrypt_init(uint8 key[24], uint8 ivec[8]);
|
||||
CryptoDes3 crypto_des3_decrypt_init(uint8 key[24], uint8 ivec[8]);
|
||||
void crypto_des3_encrypt(CryptoDes3 des3, uint32 length, uint8 *in_data, uint8 *out_data);
|
||||
void crypto_des3_decrypt(CryptoDes3 des3, uint32 length, uint8 *in_data, uint8* out_data);
|
||||
void crypto_des3_free(CryptoDes3 des3);
|
||||
|
||||
typedef struct crypto_hmac_struct* CryptoHmac;
|
||||
CryptoHmac crypto_hmac_new(void);
|
||||
void crypto_hmac_sha1_init(CryptoHmac hmac, uint8 *data, uint32 length);
|
||||
void crypto_hmac_update(CryptoHmac hmac, uint8 *data, uint32 length);
|
||||
void crypto_hmac_final(CryptoHmac hmac, uint8 *out_data, uint32 length);
|
||||
void crypto_hmac_free(CryptoHmac hmac);
|
||||
|
||||
typedef struct crypto_cert_struct* CryptoCert;
|
||||
CryptoCert crypto_cert_read(uint8* data, uint32 length);
|
||||
char* cypto_cert_fingerprint(X509* xcert);
|
||||
|
@ -55,6 +55,7 @@ uint16 fastpath_read_header(rdpFastPath* fastpath, STREAM* s)
|
||||
uint8 t;
|
||||
|
||||
stream_read_uint8(s, header);
|
||||
|
||||
if (fastpath != NULL)
|
||||
{
|
||||
fastpath->encryptionFlags = (header & 0xC0) >> 6;
|
||||
@ -94,6 +95,36 @@ INLINE void fastpath_write_update_header(STREAM* s, uint8 updateCode, uint8 frag
|
||||
stream_write_uint8(s, updateHeader);
|
||||
}
|
||||
|
||||
uint16 fastpath_read_header_rdp(rdpFastPath* fastpath, STREAM* s)
|
||||
{
|
||||
uint8 header;
|
||||
uint16 length;
|
||||
uint8 t;
|
||||
uint16 hs;
|
||||
|
||||
hs = 2;
|
||||
stream_read_uint8(s, header);
|
||||
|
||||
if (fastpath != NULL)
|
||||
{
|
||||
fastpath->encryptionFlags = (header & 0xC0) >> 6;
|
||||
fastpath->numberEvents = (header & 0x3C) >> 2;
|
||||
}
|
||||
|
||||
stream_read_uint8(s, length); /* length1 */
|
||||
/* If most significant bit is not set, length2 is not presented. */
|
||||
if ((length & 0x80))
|
||||
{
|
||||
hs++;
|
||||
length &= 0x7F;
|
||||
length <<= 8;
|
||||
stream_read_uint8(s, t);
|
||||
length += t;
|
||||
}
|
||||
|
||||
return length - hs;
|
||||
}
|
||||
|
||||
boolean fastpath_read_security_header(rdpFastPath* fastpath, STREAM* s)
|
||||
{
|
||||
/* TODO: fipsInformation */
|
||||
@ -204,6 +235,12 @@ static void fastpath_recv_update_data(rdpFastPath* fastpath, STREAM* s)
|
||||
uint8 compression;
|
||||
uint8 compressionFlags;
|
||||
STREAM* update_stream;
|
||||
STREAM* comp_stream;
|
||||
rdpRdp *rdp;
|
||||
uint32 roff;
|
||||
uint32 rlen;
|
||||
|
||||
rdp = fastpath->rdp;
|
||||
|
||||
fastpath_read_update_header(s, &updateCode, &fragmentation, &compression);
|
||||
|
||||
@ -214,19 +251,30 @@ static void fastpath_recv_update_data(rdpFastPath* fastpath, STREAM* s)
|
||||
|
||||
stream_read_uint16(s, size);
|
||||
next_pos = stream_get_pos(s) + size;
|
||||
comp_stream = s;
|
||||
|
||||
if (compressionFlags != 0)
|
||||
if (compressionFlags & PACKET_COMPRESSED)
|
||||
{
|
||||
printf("FastPath compression is not yet implemented!\n");
|
||||
stream_seek(s, size);
|
||||
return;
|
||||
if (decompress_rdp(rdp, s->p, size, compressionFlags, &roff, &rlen))
|
||||
{
|
||||
comp_stream = stream_new(0);
|
||||
comp_stream->data = rdp->mppc->history_buf + roff;
|
||||
comp_stream->p = comp_stream->data;
|
||||
comp_stream->size = rlen;
|
||||
size = comp_stream->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("decompress_rdp() failed\n");
|
||||
stream_seek(s, size);
|
||||
}
|
||||
}
|
||||
|
||||
update_stream = NULL;
|
||||
if (fragmentation == FASTPATH_FRAGMENT_SINGLE)
|
||||
{
|
||||
totalSize = size;
|
||||
update_stream = s;
|
||||
update_stream = comp_stream;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -234,7 +282,7 @@ static void fastpath_recv_update_data(rdpFastPath* fastpath, STREAM* s)
|
||||
stream_set_pos(fastpath->updateData, 0);
|
||||
|
||||
stream_check_size(fastpath->updateData, size);
|
||||
stream_copy(fastpath->updateData, s, size);
|
||||
stream_copy(fastpath->updateData, comp_stream, size);
|
||||
|
||||
if (fragmentation == FASTPATH_FRAGMENT_LAST)
|
||||
{
|
||||
@ -248,6 +296,9 @@ static void fastpath_recv_update_data(rdpFastPath* fastpath, STREAM* s)
|
||||
fastpath_recv_update(fastpath, updateCode, totalSize, update_stream);
|
||||
|
||||
stream_set_pos(s, next_pos);
|
||||
|
||||
if (comp_stream != s)
|
||||
xfree(comp_stream);
|
||||
}
|
||||
|
||||
boolean fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s)
|
||||
|
@ -91,6 +91,7 @@ struct rdp_fastpath
|
||||
};
|
||||
|
||||
uint16 fastpath_read_header(rdpFastPath* fastpath, STREAM* s);
|
||||
uint16 fastpath_read_header_rdp(rdpFastPath* fastpath, STREAM* s);
|
||||
boolean fastpath_read_security_header(rdpFastPath* fastpath, STREAM* s);
|
||||
boolean fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s);
|
||||
boolean fastpath_recv_inputs(rdpFastPath* fastpath, STREAM* s);
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <freerdp/utils/print.h>
|
||||
|
||||
#include "gcc.h"
|
||||
#include "certificate.h"
|
||||
|
||||
/**
|
||||
* T.124 GCC is defined in:
|
||||
@ -252,12 +253,16 @@ boolean gcc_read_conference_create_response(STREAM* s, rdpSettings* settings)
|
||||
per_read_choice(s, &choice);
|
||||
|
||||
/* h221NonStandard */
|
||||
per_read_octet_string(s, h221_sc_key, 4, 4); /* h221NonStandard, server-to-client H.221 key, "McDn" */
|
||||
if (!per_read_octet_string(s, h221_sc_key, 4, 4)) /* h221NonStandard, server-to-client H.221 key, "McDn" */
|
||||
return False;
|
||||
|
||||
/* userData (OCTET_STRING) */
|
||||
per_read_length(s, &length);
|
||||
if (!gcc_read_server_data_blocks(s, settings, length))
|
||||
{
|
||||
printf("gcc_read_conference_create_response: gcc_read_server_data_blocks failed\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
@ -359,34 +364,49 @@ boolean gcc_read_server_data_blocks(STREAM* s, rdpSettings *settings, int length
|
||||
uint16 type;
|
||||
uint16 offset = 0;
|
||||
uint16 blockLength;
|
||||
uint8* holdp;
|
||||
|
||||
while (offset < length)
|
||||
{
|
||||
holdp = s->p;
|
||||
|
||||
if (!gcc_read_user_data_header(s, &type, &blockLength))
|
||||
{
|
||||
printf("gcc_read_server_data_blocks: gcc_read_user_data_header failed\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case SC_CORE:
|
||||
if (!gcc_read_server_core_data(s, settings))
|
||||
{
|
||||
printf("gcc_read_server_data_blocks: gcc_read_server_core_data failed\n");
|
||||
return False;
|
||||
}
|
||||
break;
|
||||
|
||||
case SC_SECURITY:
|
||||
if (!gcc_read_server_security_data(s, settings))
|
||||
{
|
||||
printf("gcc_read_server_data_blocks: gcc_read_server_security_data failed\n");
|
||||
return False;
|
||||
}
|
||||
break;
|
||||
|
||||
case SC_NET:
|
||||
if (!gcc_read_server_network_data(s, settings))
|
||||
{
|
||||
printf("gcc_read_server_data_blocks: gcc_read_server_network_data failed\n");
|
||||
return False;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
offset += blockLength;
|
||||
s->p = holdp + blockLength;
|
||||
}
|
||||
|
||||
return True;
|
||||
@ -731,7 +751,7 @@ void gcc_write_client_security_data(STREAM* s, rdpSettings *settings)
|
||||
{
|
||||
gcc_write_user_data_header(s, CS_SECURITY, 12);
|
||||
|
||||
if (settings->encryption > 0)
|
||||
if (settings->encryption)
|
||||
{
|
||||
stream_write_uint32(s, settings->encryption_method); /* encryptionMethods */
|
||||
stream_write_uint32(s, 0); /* extEncryptionMethods */
|
||||
@ -746,17 +766,20 @@ void gcc_write_client_security_data(STREAM* s, rdpSettings *settings)
|
||||
|
||||
boolean gcc_read_server_security_data(STREAM* s, rdpSettings *settings)
|
||||
{
|
||||
uint32 encryptionMethod;
|
||||
uint32 encryptionLevel;
|
||||
uint32 serverRandomLen;
|
||||
uint32 serverCertLen;
|
||||
uint8* data;
|
||||
uint32 len;
|
||||
|
||||
stream_read_uint32(s, encryptionMethod); /* encryptionMethod */
|
||||
stream_read_uint32(s, encryptionLevel); /* encryptionLevel */
|
||||
stream_read_uint32(s, settings->encryption_method); /* encryptionMethod */
|
||||
stream_read_uint32(s, settings->encryption_level); /* encryptionLevel */
|
||||
|
||||
if (encryptionMethod == 0 && encryptionLevel == 0)
|
||||
if (settings->encryption_method == 0 && settings->encryption_level == 0)
|
||||
{
|
||||
/* serverRandom and serverRandom must not be present */
|
||||
settings->encryption = False;
|
||||
settings->encryption_method = ENCRYPTION_METHOD_NONE;
|
||||
settings->encryption_level = ENCRYPTION_LEVEL_NONE;
|
||||
return True;
|
||||
}
|
||||
|
||||
@ -770,6 +793,10 @@ boolean gcc_read_server_security_data(STREAM* s, rdpSettings *settings)
|
||||
memcpy(settings->server_random.data, s->p, serverRandomLen);
|
||||
stream_seek(s, serverRandomLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
return False;
|
||||
}
|
||||
|
||||
if (serverCertLen > 0)
|
||||
{
|
||||
@ -777,6 +804,18 @@ boolean gcc_read_server_security_data(STREAM* s, rdpSettings *settings)
|
||||
freerdp_blob_alloc(&settings->server_certificate, serverCertLen);
|
||||
memcpy(settings->server_certificate.data, s->p, serverCertLen);
|
||||
stream_seek(s, serverCertLen);
|
||||
certificate_free(settings->server_cert);
|
||||
settings->server_cert = certificate_new();
|
||||
data = settings->server_certificate.data;
|
||||
len = settings->server_certificate.length;
|
||||
if (!certificate_read_server_certificate(settings->server_cert, data, len))
|
||||
{
|
||||
return False;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
|
@ -495,7 +495,7 @@ void rdp_write_info_packet(STREAM* s, rdpSettings* settings)
|
||||
flags |= INFO_REMOTECONSOLEAUDIO;
|
||||
|
||||
if (settings->compression)
|
||||
flags |= INFO_COMPRESSION | PACKET_COMPR_TYPE_64K;
|
||||
flags |= INFO_COMPRESSION | INFO_PACKET_COMPR_TYPE_64K;
|
||||
|
||||
domain = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->domain, &length);
|
||||
cbDomain = length;
|
||||
@ -584,11 +584,10 @@ boolean rdp_send_client_info(rdpRdp* rdp)
|
||||
{
|
||||
STREAM* s;
|
||||
|
||||
//rdp->settings->crypt_flags |= SEC_INFO_PKT;
|
||||
rdp->sec_flags |= SEC_INFO_PKT;
|
||||
s = rdp_send_stream_init(rdp);
|
||||
|
||||
rdp_write_security_header(s, SEC_INFO_PKT);
|
||||
rdp_write_info_packet(s, rdp->settings);
|
||||
|
||||
return rdp_send(rdp, s, MCS_GLOBAL_CHANNEL_ID);
|
||||
}
|
||||
|
||||
|
@ -870,7 +870,8 @@ rdpLicense* license_new(rdpRdp* rdp)
|
||||
{
|
||||
license->rdp = rdp;
|
||||
license->state = LICENSE_STATE_AWAIT;
|
||||
license->certificate = certificate_new(rdp);
|
||||
//license->certificate = certificate_new(rdp);
|
||||
license->certificate = certificate_new();
|
||||
license->product_info = license_new_product_info();
|
||||
license->error_info = license_new_binary_blob(BB_ERROR_BLOB);
|
||||
license->key_exchange_list = license_new_binary_blob(BB_KEY_EXCHG_ALG_BLOB);
|
||||
|
@ -517,7 +517,10 @@ boolean mcs_recv_connect_response(rdpMcs* mcs, STREAM* s)
|
||||
ber_read_octet_string(s, &length);
|
||||
|
||||
if (!gcc_read_conference_create_response(s, mcs->transport->settings))
|
||||
{
|
||||
printf("mcs_recv_connect_response: gcc_read_conference_create_response failed\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -22,15 +22,30 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define _MPPC_DEBUG
|
||||
|
||||
#ifdef MPPC_DEBUG
|
||||
#define mprintf(y...) printf(y);
|
||||
#else
|
||||
#define mprintf(y...)
|
||||
#endif
|
||||
|
||||
#define RDP5_HISTORY_BUF_SIZE 65536
|
||||
|
||||
struct rdp_mppc
|
||||
{
|
||||
uint8_t *history_buf;
|
||||
uint8_t *history_ptr;
|
||||
uint8 *history_buf;
|
||||
uint8 *history_buf_end;
|
||||
uint8 *history_ptr;
|
||||
};
|
||||
|
||||
// forward declarations
|
||||
int decompress_rdp_5(rdpRdp *, uint8_t *, int, int, uint32_t *, uint32_t *);
|
||||
int decompress_rdp(rdpRdp *, uint8 *, int, int, uint32 *, uint32 *);
|
||||
int decompress_rdp_4(rdpRdp *, uint8 *, int, int, uint32 *, uint32 *);
|
||||
int decompress_rdp_5(rdpRdp *, uint8 *, int, int, uint32 *, uint32 *);
|
||||
int decompress_rdp_6(rdpRdp *, uint8 *, int, int, uint32 *, uint32 *);
|
||||
int decompress_rdp_61(rdpRdp *, uint8 *, int, int, uint32 *, uint32 *);
|
||||
struct rdp_mppc *mppc_new(rdpRdp *rdp);
|
||||
void mppc_free(rdpRdp *rdp);
|
||||
|
||||
#endif
|
||||
|
@ -364,7 +364,7 @@ void nego_send_negotiation_request(rdpNego* nego)
|
||||
stream_write(s, nego->routing_token->data, nego->routing_token->length);
|
||||
length += nego->routing_token->length;
|
||||
}
|
||||
else
|
||||
else if (nego->cookie != NULL)
|
||||
{
|
||||
int cookie_length = strlen(nego->cookie);
|
||||
stream_write(s, "Cookie: mstshash=", 17);
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "window.h"
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/common/bitmap.h>
|
||||
|
||||
#include "orders.h"
|
||||
|
||||
@ -405,10 +406,10 @@ INLINE void update_read_delta_points(STREAM* s, DELTA_POINT* points, int number,
|
||||
|
||||
memset(points, 0, sizeof(DELTA_POINT) * number);
|
||||
|
||||
for (i = 1; i < number + 1; i++)
|
||||
for (i = 0; i < number; i++)
|
||||
{
|
||||
if ((i - 1) % 4 == 0)
|
||||
flags = zeroBits[(i - 1) / 4];
|
||||
if (i % 4 == 0)
|
||||
flags = zeroBits[i / 4];
|
||||
|
||||
if (~flags & 0x80)
|
||||
update_read_delta(s, &points[i].x);
|
||||
@ -416,17 +417,11 @@ INLINE void update_read_delta_points(STREAM* s, DELTA_POINT* points, int number,
|
||||
if (~flags & 0x40)
|
||||
update_read_delta(s, &points[i].y);
|
||||
|
||||
points[i].x = points[i].x + points[i - 1].x;
|
||||
points[i].y = points[i].y + points[i - 1].y;
|
||||
|
||||
points[i - 1].x += x;
|
||||
points[i - 1].y += y;
|
||||
points[i].x += (i > 0 ? points[i - 1].x : x);
|
||||
points[i].y += (i > 0 ? points[i - 1].y : y);
|
||||
|
||||
flags <<= 2;
|
||||
}
|
||||
|
||||
points[i - 1].x += x;
|
||||
points[i - 1].y += y;
|
||||
}
|
||||
|
||||
INLINE uint16 update_read_glyph_fragments(STREAM* s, GLYPH_FRAGMENT** fragments, boolean delta, uint8 size)
|
||||
@ -1365,6 +1360,9 @@ void update_read_cache_bitmap_order(STREAM* s, CACHE_BITMAP_ORDER* cache_bitmap_
|
||||
|
||||
void update_read_cache_bitmap_v2_order(STREAM* s, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2_order, boolean compressed, uint16 flags)
|
||||
{
|
||||
boolean status;
|
||||
uint16 dstSize;
|
||||
uint8* srcData;
|
||||
uint8 bitsPerPixelId;
|
||||
|
||||
cache_bitmap_v2_order->cacheId = flags & 0x0003;
|
||||
@ -1395,20 +1393,40 @@ void update_read_cache_bitmap_v2_order(STREAM* s, CACHE_BITMAP_V2_ORDER* cache_b
|
||||
|
||||
if (compressed)
|
||||
{
|
||||
if (cache_bitmap_v2_order->flags & CBR2_NO_BITMAP_COMPRESSION_HDR)
|
||||
{
|
||||
stream_seek(s, cache_bitmap_v2_order->bitmapLength); /* bitmapDataStream */
|
||||
}
|
||||
else
|
||||
if (!(cache_bitmap_v2_order->flags & CBR2_NO_BITMAP_COMPRESSION_HDR))
|
||||
{
|
||||
uint8* bitmapComprHdr = (uint8*) &(cache_bitmap_v2_order->bitmapComprHdr);
|
||||
stream_read(s, bitmapComprHdr, 8); /* bitmapComprHdr (8 bytes) */
|
||||
stream_seek(s, cache_bitmap_v2_order->bitmapLength); /* bitmapDataStream */
|
||||
}
|
||||
|
||||
dstSize = cache_bitmap_v2_order->bitmapLength;
|
||||
cache_bitmap_v2_order->data = (uint8*) xmalloc(dstSize);
|
||||
|
||||
stream_get_mark(s, srcData);
|
||||
stream_seek(s, cache_bitmap_v2_order->bitmapLength);
|
||||
|
||||
status = bitmap_decompress(srcData, cache_bitmap_v2_order->data, cache_bitmap_v2_order->bitmapWidth,
|
||||
cache_bitmap_v2_order->bitmapHeight, cache_bitmap_v2_order->bitmapLength,
|
||||
cache_bitmap_v2_order->bitmapBpp, cache_bitmap_v2_order->bitmapBpp);
|
||||
|
||||
if (status != True)
|
||||
printf("bitmap decompression failed, bpp:%d\n", cache_bitmap_v2_order->bitmapBpp);
|
||||
}
|
||||
else
|
||||
{
|
||||
stream_seek(s, cache_bitmap_v2_order->bitmapLength); /* bitmapDataStream */
|
||||
int y;
|
||||
int offset;
|
||||
int scanline;
|
||||
stream_get_mark(s, srcData);
|
||||
dstSize = cache_bitmap_v2_order->bitmapLength;
|
||||
cache_bitmap_v2_order->data = (uint8*) xmalloc(dstSize);
|
||||
scanline = cache_bitmap_v2_order->bitmapWidth * (cache_bitmap_v2_order->bitmapBpp / 8);
|
||||
|
||||
for (y = 0; y < cache_bitmap_v2_order->bitmapHeight; y++)
|
||||
{
|
||||
offset = (cache_bitmap_v2_order->bitmapHeight - y - 1) * scanline;
|
||||
stream_read(s, &cache_bitmap_v2_order->data[offset], scanline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,8 +59,11 @@ static boolean peer_recv_data_pdu(rdpPeer* peer, STREAM* s)
|
||||
uint8 type;
|
||||
uint16 length;
|
||||
uint32 share_id;
|
||||
uint8 compressed_type;
|
||||
uint16 compressed_len;
|
||||
|
||||
if (!rdp_read_share_data_header(s, &length, &type, &share_id))
|
||||
|
||||
if (!rdp_read_share_data_header(s, &length, &type, &share_id, &compressed_type, &compressed_len))
|
||||
return False;
|
||||
|
||||
switch (type)
|
||||
@ -154,15 +157,20 @@ static boolean peer_recv_fastpath_pdu(rdpPeer* peer, STREAM* s)
|
||||
{
|
||||
uint16 length;
|
||||
|
||||
length = fastpath_read_header(peer->rdp->fastpath, s);
|
||||
if (length == 0 || length > stream_get_size(s))
|
||||
length = fastpath_read_header_rdp(peer->rdp->fastpath, s);
|
||||
if (length == 0 || length > stream_get_left(s))
|
||||
{
|
||||
printf("incorrect FastPath PDU header length %d\n", length);
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!fastpath_read_security_header(peer->rdp->fastpath, s))
|
||||
return False;
|
||||
if (peer->rdp->fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED)
|
||||
{
|
||||
rdp_decrypt(peer->rdp, s, length);
|
||||
}
|
||||
|
||||
//if (!fastpath_read_security_header(peer->rdp->fastpath, s))
|
||||
// return False;
|
||||
|
||||
return fastpath_recv_inputs(peer->rdp->fastpath, s);
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* RDP Core
|
||||
@ -113,7 +114,8 @@ void rdp_write_share_control_header(STREAM* s, uint16 length, uint16 type, uint1
|
||||
stream_write_uint16(s, channel_id); /* pduSource */
|
||||
}
|
||||
|
||||
boolean rdp_read_share_data_header(STREAM* s, uint16* length, uint8* type, uint32* share_id)
|
||||
boolean rdp_read_share_data_header(STREAM* s, uint16* length, uint8* type, uint32* share_id,
|
||||
uint8 *compressed_type, uint16 *compressed_len)
|
||||
{
|
||||
if (stream_get_left(s) < 12)
|
||||
return False;
|
||||
@ -124,8 +126,17 @@ boolean rdp_read_share_data_header(STREAM* s, uint16* length, uint8* type, uint3
|
||||
stream_seek_uint8(s); /* streamId (1 byte) */
|
||||
stream_read_uint16(s, *length); /* uncompressedLength (2 bytes) */
|
||||
stream_read_uint8(s, *type); /* pduType2, Data PDU Type (1 byte) */
|
||||
stream_seek_uint8(s); /* compressedType (1 byte) */
|
||||
stream_seek_uint16(s); /* compressedLength (2 bytes) */
|
||||
if (*type & 0x80)
|
||||
{
|
||||
stream_read_uint8(s, *compressed_type); /* compressedType (1 byte) */
|
||||
stream_read_uint16(s, *compressed_len); /* compressedLength (2 bytes) */
|
||||
}
|
||||
else
|
||||
{
|
||||
stream_seek(s, 3);
|
||||
*compressed_type = 0;
|
||||
*compressed_len = 0;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
@ -146,6 +157,22 @@ void rdp_write_share_data_header(STREAM* s, uint16 length, uint8 type, uint32 sh
|
||||
stream_write_uint16(s, 0); /* compressedLength (2 bytes) */
|
||||
}
|
||||
|
||||
static int rdp_security_stream_init(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
if (rdp->do_crypt)
|
||||
{
|
||||
stream_seek(s, 12);
|
||||
if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS)
|
||||
stream_seek(s, 4);
|
||||
rdp->sec_flags |= SEC_ENCRYPT;
|
||||
}
|
||||
else if (rdp->sec_flags != 0)
|
||||
{
|
||||
stream_seek(s, 4);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize an RDP packet stream.\n
|
||||
* @param rdp rdp module
|
||||
@ -155,8 +182,11 @@ void rdp_write_share_data_header(STREAM* s, uint16 length, uint8 type, uint32 sh
|
||||
STREAM* rdp_send_stream_init(rdpRdp* rdp)
|
||||
{
|
||||
STREAM* s;
|
||||
|
||||
s = transport_send_stream_init(rdp->transport, 2048);
|
||||
stream_seek(s, RDP_PACKET_HEADER_LENGTH);
|
||||
rdp_security_stream_init(rdp, s);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -165,6 +195,7 @@ STREAM* rdp_pdu_init(rdpRdp* rdp)
|
||||
STREAM* s;
|
||||
s = transport_send_stream_init(rdp->transport, 2048);
|
||||
stream_seek(s, RDP_PACKET_HEADER_LENGTH);
|
||||
rdp_security_stream_init(rdp, s);
|
||||
stream_seek(s, RDP_SHARE_CONTROL_HEADER_LENGTH);
|
||||
return s;
|
||||
}
|
||||
@ -174,6 +205,7 @@ STREAM* rdp_data_pdu_init(rdpRdp* rdp)
|
||||
STREAM* s;
|
||||
s = transport_send_stream_init(rdp->transport, 2048);
|
||||
stream_seek(s, RDP_PACKET_HEADER_LENGTH);
|
||||
rdp_security_stream_init(rdp, s);
|
||||
stream_seek(s, RDP_SHARE_CONTROL_HEADER_LENGTH);
|
||||
stream_seek(s, RDP_SHARE_DATA_HEADER_LENGTH);
|
||||
return s;
|
||||
@ -217,9 +249,20 @@ boolean rdp_read_header(rdpRdp* rdp, STREAM* s, uint16* length, uint16* channel_
|
||||
void rdp_write_header(rdpRdp* rdp, STREAM* s, uint16 length, uint16 channel_id)
|
||||
{
|
||||
enum DomainMCSPDU MCSPDU;
|
||||
int body_length;
|
||||
|
||||
MCSPDU = (rdp->settings->server_mode) ? DomainMCSPDU_SendDataIndication : DomainMCSPDU_SendDataRequest;
|
||||
|
||||
if (rdp->sec_flags & SEC_ENCRYPT && rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS) {
|
||||
int pad;
|
||||
|
||||
body_length = length - RDP_PACKET_HEADER_LENGTH - 16;
|
||||
pad = 8 - (body_length % 8);
|
||||
if (pad != 8)
|
||||
length += pad;
|
||||
//printf("rdp_write_header: %d %d (%d)\n", length, body_length, pad);
|
||||
}
|
||||
|
||||
mcs_write_domain_mcspdu_header(s, MCSPDU, length, 0);
|
||||
per_write_integer16(s, rdp->mcs->user_id, MCS_BASE_CHANNEL_ID); /* initiator */
|
||||
per_write_integer16(s, channel_id, 0); /* channelId */
|
||||
@ -229,6 +272,73 @@ void rdp_write_header(rdpRdp* rdp, STREAM* s, uint16 length, uint16 channel_id)
|
||||
stream_write_uint16_be(s, length); /* userData (OCTET_STRING) */
|
||||
}
|
||||
|
||||
static uint32 rdp_security_stream_out(rdpRdp* rdp, STREAM* s, int length)
|
||||
{
|
||||
uint32 ml;
|
||||
uint8* mk;
|
||||
uint8* data;
|
||||
uint32 sec_flags;
|
||||
uint32 pad = 0;
|
||||
|
||||
sec_flags = rdp->sec_flags;
|
||||
if (sec_flags != 0)
|
||||
{
|
||||
rdp_write_security_header(s, sec_flags);
|
||||
if (sec_flags & SEC_ENCRYPT)
|
||||
{
|
||||
if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS)
|
||||
{
|
||||
data = s->p + 12;
|
||||
|
||||
length = length - (data - s->data);
|
||||
stream_write_uint16(s, 0x10); /* length */
|
||||
stream_write_uint8(s, 0x1); /* TSFIPS_VERSION 1*/
|
||||
/* handle padding */
|
||||
pad = 8 - (length % 8);
|
||||
if (pad == 8)
|
||||
pad = 0;
|
||||
if (pad)
|
||||
memset(data+length, 0, pad);
|
||||
stream_write_uint8(s, pad);
|
||||
|
||||
// printf("FIPS padding %d, length %d\n", pad, length);
|
||||
|
||||
security_hmac_signature(data, length, s->p, rdp);
|
||||
stream_seek(s, 8);
|
||||
security_fips_encrypt(data, length + pad, rdp);
|
||||
}
|
||||
else
|
||||
{
|
||||
data = s->p + 8;
|
||||
length = length - (data - s->data);
|
||||
|
||||
mk = rdp->settings->sign_key;
|
||||
ml = rdp->settings->rc4_key_len;
|
||||
security_mac_signature(mk, ml, data, length, s->p);
|
||||
stream_seek(s, 8);
|
||||
security_encrypt(s->p, length, rdp);
|
||||
}
|
||||
}
|
||||
rdp->sec_flags = 0;
|
||||
}
|
||||
return pad;
|
||||
}
|
||||
|
||||
static uint32 rdp_get_sec_bytes(rdpRdp* rdp)
|
||||
{
|
||||
uint32 sec_bytes;
|
||||
|
||||
if (rdp->sec_flags & SEC_ENCRYPT) {
|
||||
sec_bytes = 12;
|
||||
if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS)
|
||||
sec_bytes += 4;
|
||||
} else if (rdp->sec_flags != 0)
|
||||
sec_bytes = 4;
|
||||
else
|
||||
sec_bytes = 0;
|
||||
return sec_bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an RDP packet.\n
|
||||
* @param rdp RDP module
|
||||
@ -239,12 +349,21 @@ void rdp_write_header(rdpRdp* rdp, STREAM* s, uint16 length, uint16 channel_id)
|
||||
boolean rdp_send(rdpRdp* rdp, STREAM* s, uint16 channel_id)
|
||||
{
|
||||
uint16 length;
|
||||
uint32 sec_bytes;
|
||||
uint8* sec_hold;
|
||||
|
||||
length = stream_get_length(s);
|
||||
stream_set_pos(s, 0);
|
||||
|
||||
rdp_write_header(rdp, s, length, channel_id);
|
||||
|
||||
sec_bytes = rdp_get_sec_bytes(rdp);
|
||||
sec_hold = s->p;
|
||||
stream_seek(s, sec_bytes);
|
||||
|
||||
s->p = sec_hold;
|
||||
length += rdp_security_stream_out(rdp, s, length);
|
||||
|
||||
stream_set_pos(s, length);
|
||||
if (transport_write(rdp->transport, s) < 0)
|
||||
return False;
|
||||
@ -255,13 +374,23 @@ boolean rdp_send(rdpRdp* rdp, STREAM* s, uint16 channel_id)
|
||||
boolean rdp_send_pdu(rdpRdp* rdp, STREAM* s, uint16 type, uint16 channel_id)
|
||||
{
|
||||
uint16 length;
|
||||
uint32 sec_bytes;
|
||||
uint8* sec_hold;
|
||||
|
||||
length = stream_get_length(s);
|
||||
stream_set_pos(s, 0);
|
||||
|
||||
rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID);
|
||||
|
||||
sec_bytes = rdp_get_sec_bytes(rdp);
|
||||
sec_hold = s->p;
|
||||
stream_seek(s, sec_bytes);
|
||||
|
||||
rdp_write_share_control_header(s, length, type, channel_id);
|
||||
|
||||
s->p = sec_hold;
|
||||
length += rdp_security_stream_out(rdp, s, length);
|
||||
|
||||
stream_set_pos(s, length);
|
||||
if (transport_write(rdp->transport, s) < 0)
|
||||
return False;
|
||||
@ -272,16 +401,26 @@ boolean rdp_send_pdu(rdpRdp* rdp, STREAM* s, uint16 type, uint16 channel_id)
|
||||
boolean rdp_send_data_pdu(rdpRdp* rdp, STREAM* s, uint8 type, uint16 channel_id)
|
||||
{
|
||||
uint16 length;
|
||||
uint32 sec_bytes;
|
||||
uint8* sec_hold;
|
||||
|
||||
length = stream_get_length(s);
|
||||
stream_set_pos(s, 0);
|
||||
|
||||
rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID);
|
||||
|
||||
sec_bytes = rdp_get_sec_bytes(rdp);
|
||||
sec_hold = s->p;
|
||||
stream_seek(s, sec_bytes);
|
||||
|
||||
rdp_write_share_control_header(s, length, PDU_TYPE_DATA, channel_id);
|
||||
rdp_write_share_data_header(s, length, type, rdp->settings->share_id);
|
||||
|
||||
//printf("send %s Data PDU (0x%02X), length:%d\n", DATA_PDU_TYPE_STRINGS[type], type, length);
|
||||
|
||||
s->p = sec_hold;
|
||||
length += rdp_security_stream_out(rdp, s, length);
|
||||
|
||||
stream_set_pos(s, length);
|
||||
if (transport_write(rdp->transport, s) < 0)
|
||||
return False;
|
||||
@ -304,8 +443,10 @@ void rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s)
|
||||
uint8 type;
|
||||
uint16 length;
|
||||
uint32 share_id;
|
||||
uint8 compressed_type;
|
||||
uint16 compressed_len;
|
||||
|
||||
rdp_read_share_data_header(s, &length, &type, &share_id);
|
||||
rdp_read_share_data_header(s, &length, &type, &share_id, &compressed_type, &compressed_len);
|
||||
|
||||
#ifdef WITH_DEBUG_RDP
|
||||
if (type != DATA_PDU_TYPE_UPDATE)
|
||||
@ -425,6 +566,55 @@ boolean rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, STREAM* s)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt an RDP packet.\n
|
||||
* @param rdp RDP module
|
||||
* @param s stream
|
||||
* @param length int
|
||||
*/
|
||||
|
||||
boolean rdp_decrypt(rdpRdp* rdp, STREAM* s, int length)
|
||||
{
|
||||
int cryptlen;
|
||||
|
||||
if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS)
|
||||
{
|
||||
uint16 len;
|
||||
uint8 version, pad;
|
||||
uint8 *sig;
|
||||
|
||||
stream_read_uint16(s, len); // 0x10
|
||||
stream_read_uint8(s, version); // 0x1
|
||||
stream_read_uint8(s, pad);
|
||||
|
||||
sig = s->p;
|
||||
stream_seek(s, 8); /* signature */
|
||||
|
||||
cryptlen = length - 12;
|
||||
|
||||
if (!security_fips_decrypt(s->p, cryptlen, rdp))
|
||||
{
|
||||
printf("FATAL: cannot decrypt\n");
|
||||
return False; // TODO
|
||||
}
|
||||
|
||||
if (!security_fips_check_signature(s->p, cryptlen-pad, sig, rdp))
|
||||
{
|
||||
printf("FATAL: invalid packet signature\n");
|
||||
return False; // TODO
|
||||
}
|
||||
|
||||
// is this what needs adjusting?
|
||||
s->size -= pad;
|
||||
return True;
|
||||
}
|
||||
|
||||
stream_seek(s, 8); /* signature */
|
||||
cryptlen = length - 8;
|
||||
security_decrypt(s->p, cryptlen, rdp);
|
||||
return True;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an RDP packet.\n
|
||||
* @param rdp RDP module
|
||||
@ -437,6 +627,7 @@ static boolean rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
|
||||
uint16 pduType;
|
||||
uint16 pduLength;
|
||||
uint16 channelId;
|
||||
uint32 securityHeader;
|
||||
|
||||
if (!rdp_read_header(rdp, s, &length, &channelId))
|
||||
{
|
||||
@ -444,6 +635,24 @@ static boolean rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
|
||||
return False;
|
||||
}
|
||||
|
||||
if (rdp->settings->encryption)
|
||||
{
|
||||
stream_read_uint32(s, securityHeader);
|
||||
if (securityHeader & SEC_SECURE_CHECKSUM)
|
||||
{
|
||||
printf("Error: TODO\n");
|
||||
return False;
|
||||
}
|
||||
if (securityHeader & SEC_ENCRYPT)
|
||||
{
|
||||
if (!rdp_decrypt(rdp, s, length - 4))
|
||||
{
|
||||
printf("rdp_decrypt failed\n");
|
||||
return False;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (channelId != MCS_GLOBAL_CHANNEL_ID)
|
||||
{
|
||||
vchan_process(rdp->vchan, s, channelId);
|
||||
@ -480,15 +689,18 @@ static boolean rdp_recv_fastpath_pdu(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
uint16 length;
|
||||
|
||||
length = fastpath_read_header(rdp->fastpath, s);
|
||||
if (length == 0 || length > stream_get_size(s))
|
||||
length = fastpath_read_header_rdp(rdp->fastpath, s);
|
||||
|
||||
if (length == 0 || length > stream_get_left(s))
|
||||
{
|
||||
printf("incorrect FastPath PDU header length %d\n", length);
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!fastpath_read_security_header(rdp->fastpath, s))
|
||||
return False;
|
||||
if (rdp->fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED)
|
||||
{
|
||||
rdp_decrypt(rdp, s, length);
|
||||
}
|
||||
|
||||
return fastpath_recv_updates(rdp->fastpath, s);
|
||||
}
|
||||
@ -544,7 +756,10 @@ static int rdp_recv_callback(rdpTransport* transport, STREAM* s, void* extra)
|
||||
|
||||
case CONNECTION_STATE_CAPABILITY:
|
||||
if (!rdp_client_connect_demand_active(rdp, s))
|
||||
{
|
||||
printf("rdp_client_connect_demand_active failed\n");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_ACTIVE:
|
||||
@ -605,6 +820,7 @@ rdpRdp* rdp_new(freerdp* instance)
|
||||
rdp->mcs = mcs_new(rdp->transport);
|
||||
rdp->vchan = vchan_new(instance);
|
||||
rdp->redirection = redirection_new();
|
||||
rdp->mppc = mppc_new(rdp);
|
||||
}
|
||||
|
||||
return rdp;
|
||||
@ -629,6 +845,7 @@ void rdp_free(rdpRdp* rdp)
|
||||
mcs_free(rdp->mcs);
|
||||
vchan_free(rdp->vchan);
|
||||
redirection_free(rdp->redirection);
|
||||
mppc_free(rdp);
|
||||
xfree(rdp);
|
||||
}
|
||||
}
|
||||
|
@ -127,7 +127,16 @@ struct rdp_rdp
|
||||
struct rdp_settings* settings;
|
||||
struct rdp_transport* transport;
|
||||
struct rdp_vchan* vchan;
|
||||
struct rdp_mppc* mppc;
|
||||
struct rdp_mppc* mppc;
|
||||
struct crypto_rc4_struct* rc4_decrypt_key;
|
||||
int decrypt_use_count;
|
||||
struct crypto_rc4_struct* rc4_encrypt_key;
|
||||
int encrypt_use_count;
|
||||
struct crypto_des3_struct* fips_encrypt;
|
||||
struct crypto_des3_struct* fips_decrypt;
|
||||
struct crypto_hmac_struct* fips_hmac;
|
||||
uint32 sec_flags;
|
||||
boolean do_crypt;
|
||||
};
|
||||
|
||||
void rdp_read_security_header(STREAM* s, uint16* flags);
|
||||
@ -136,7 +145,9 @@ void rdp_write_security_header(STREAM* s, uint16 flags);
|
||||
boolean rdp_read_share_control_header(STREAM* s, uint16* length, uint16* type, uint16* channel_id);
|
||||
void rdp_write_share_control_header(STREAM* s, uint16 length, uint16 type, uint16 channel_id);
|
||||
|
||||
boolean rdp_read_share_data_header(STREAM* s, uint16* length, uint8* type, uint32* share_id);
|
||||
boolean rdp_read_share_data_header(STREAM* s, uint16* length, uint8* type, uint32* share_id,
|
||||
uint8 *compressed_type, uint16 *compressed_len);
|
||||
|
||||
void rdp_write_share_data_header(STREAM* s, uint16 length, uint8 type, uint32 share_id);
|
||||
|
||||
STREAM* rdp_send_stream_init(rdpRdp* rdp);
|
||||
@ -169,4 +180,6 @@ void rdp_free(rdpRdp* rdp);
|
||||
#define DEBUG_RDP(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
boolean rdp_decrypt(rdpRdp* rdp, STREAM* s, int length);
|
||||
|
||||
#endif /* __RDP_H */
|
||||
|
@ -40,6 +40,79 @@ static uint8 pad2[48] =
|
||||
"\x5C\x5C\x5C\x5C\x5C\x5C\x5C\x5C"
|
||||
};
|
||||
|
||||
static uint8
|
||||
fips_reverse_table[256] = {
|
||||
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
|
||||
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
|
||||
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
|
||||
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
|
||||
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
|
||||
0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
|
||||
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
|
||||
0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
|
||||
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
|
||||
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
|
||||
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
|
||||
0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
|
||||
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
|
||||
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
|
||||
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
|
||||
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
|
||||
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
|
||||
0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
|
||||
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
|
||||
0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
|
||||
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
|
||||
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
|
||||
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
|
||||
0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
|
||||
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
|
||||
0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
|
||||
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
|
||||
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
|
||||
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
|
||||
0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
|
||||
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
|
||||
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
|
||||
};
|
||||
|
||||
static uint8
|
||||
fips_oddparity_table[256] = {
|
||||
0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x07, 0x07,
|
||||
0x08, 0x08, 0x0b, 0x0b, 0x0d, 0x0d, 0x0e, 0x0e,
|
||||
0x10, 0x10, 0x13, 0x13, 0x15, 0x15, 0x16, 0x16,
|
||||
0x19, 0x19, 0x1a, 0x1a, 0x1c, 0x1c, 0x1f, 0x1f,
|
||||
0x20, 0x20, 0x23, 0x23, 0x25, 0x25, 0x26, 0x26,
|
||||
0x29, 0x29, 0x2a, 0x2a, 0x2c, 0x2c, 0x2f, 0x2f,
|
||||
0x31, 0x31, 0x32, 0x32, 0x34, 0x34, 0x37, 0x37,
|
||||
0x38, 0x38, 0x3b, 0x3b, 0x3d, 0x3d, 0x3e, 0x3e,
|
||||
0x40, 0x40, 0x43, 0x43, 0x45, 0x45, 0x46, 0x46,
|
||||
0x49, 0x49, 0x4a, 0x4a, 0x4c, 0x4c, 0x4f, 0x4f,
|
||||
0x51, 0x51, 0x52, 0x52, 0x54, 0x54, 0x57, 0x57,
|
||||
0x58, 0x58, 0x5b, 0x5b, 0x5d, 0x5d, 0x5e, 0x5e,
|
||||
0x61, 0x61, 0x62, 0x62, 0x64, 0x64, 0x67, 0x67,
|
||||
0x68, 0x68, 0x6b, 0x6b, 0x6d, 0x6d, 0x6e, 0x6e,
|
||||
0x70, 0x70, 0x73, 0x73, 0x75, 0x75, 0x76, 0x76,
|
||||
0x79, 0x79, 0x7a, 0x7a, 0x7c, 0x7c, 0x7f, 0x7f,
|
||||
0x80, 0x80, 0x83, 0x83, 0x85, 0x85, 0x86, 0x86,
|
||||
0x89, 0x89, 0x8a, 0x8a, 0x8c, 0x8c, 0x8f, 0x8f,
|
||||
0x91, 0x91, 0x92, 0x92, 0x94, 0x94, 0x97, 0x97,
|
||||
0x98, 0x98, 0x9b, 0x9b, 0x9d, 0x9d, 0x9e, 0x9e,
|
||||
0xa1, 0xa1, 0xa2, 0xa2, 0xa4, 0xa4, 0xa7, 0xa7,
|
||||
0xa8, 0xa8, 0xab, 0xab, 0xad, 0xad, 0xae, 0xae,
|
||||
0xb0, 0xb0, 0xb3, 0xb3, 0xb5, 0xb5, 0xb6, 0xb6,
|
||||
0xb9, 0xb9, 0xba, 0xba, 0xbc, 0xbc, 0xbf, 0xbf,
|
||||
0xc1, 0xc1, 0xc2, 0xc2, 0xc4, 0xc4, 0xc7, 0xc7,
|
||||
0xc8, 0xc8, 0xcb, 0xcb, 0xcd, 0xcd, 0xce, 0xce,
|
||||
0xd0, 0xd0, 0xd3, 0xd3, 0xd5, 0xd5, 0xd6, 0xd6,
|
||||
0xd9, 0xd9, 0xda, 0xda, 0xdc, 0xdc, 0xdf, 0xdf,
|
||||
0xe0, 0xe0, 0xe3, 0xe3, 0xe5, 0xe5, 0xe6, 0xe6,
|
||||
0xe9, 0xe9, 0xea, 0xea, 0xec, 0xec, 0xef, 0xef,
|
||||
0xf1, 0xf1, 0xf2, 0xf2, 0xf4, 0xf4, 0xf7, 0xf7,
|
||||
0xf8, 0xf8, 0xfb, 0xfb, 0xfd, 0xfd, 0xfe, 0xfe,
|
||||
};
|
||||
|
||||
|
||||
static void security_salted_hash(uint8* salt, uint8* input, int length, uint8* salt1, uint8* salt2, uint8* output)
|
||||
{
|
||||
CryptoMd5 md5;
|
||||
@ -97,19 +170,23 @@ void security_mac_salt_key(uint8* session_key_blob, uint8* client_random, uint8*
|
||||
memcpy(output, session_key_blob, 16);
|
||||
}
|
||||
|
||||
void security_licensing_encryption_key(uint8* session_key_blob, uint8* client_random, uint8* server_random, uint8* output)
|
||||
void security_md5_16_32_32(uint8* in0, uint8* in1, uint8* in2, uint8* output)
|
||||
{
|
||||
CryptoMd5 md5;
|
||||
|
||||
/* LicensingEncryptionKey = MD5(Second128Bits(SessionKeyBlob) + ClientRandom + ServerRandom)) */
|
||||
|
||||
md5 = crypto_md5_init();
|
||||
crypto_md5_update(md5, &session_key_blob[16], 16); /* Second128Bits(SessionKeyBlob) */
|
||||
crypto_md5_update(md5, client_random, 32); /* ClientRandom */
|
||||
crypto_md5_update(md5, server_random, 32); /* ServerRandom */
|
||||
crypto_md5_update(md5, in0, 16);
|
||||
crypto_md5_update(md5, in1, 32);
|
||||
crypto_md5_update(md5, in2, 32);
|
||||
crypto_md5_final(md5, output);
|
||||
}
|
||||
|
||||
void security_licensing_encryption_key(uint8* session_key_blob, uint8* client_random, uint8* server_random, uint8* output)
|
||||
{
|
||||
/* LicensingEncryptionKey = MD5(Second128Bits(SessionKeyBlob) + ClientRandom + ServerRandom)) */
|
||||
security_md5_16_32_32(&session_key_blob[16], client_random, server_random, output);
|
||||
}
|
||||
|
||||
void security_uint32_le(uint8* output, uint32 value)
|
||||
{
|
||||
output[0] = (value) & 0xFF;
|
||||
@ -172,3 +249,227 @@ void security_mac_signature(uint8* mac_key, int mac_key_length, uint8* data, uin
|
||||
|
||||
memcpy(output, md5_digest, 8);
|
||||
}
|
||||
|
||||
static void security_A(uint8* master_secret, uint8* client_random, uint8* server_random, uint8* output)
|
||||
{
|
||||
security_premaster_hash("A", 1, master_secret, client_random, server_random, &output[0]);
|
||||
security_premaster_hash("BB", 2, master_secret, client_random, server_random, &output[16]);
|
||||
security_premaster_hash("CCC", 3, master_secret, client_random, server_random, &output[32]);
|
||||
}
|
||||
|
||||
static void security_X(uint8* master_secret, uint8* client_random, uint8* server_random, uint8* output)
|
||||
{
|
||||
security_premaster_hash("X", 1, master_secret, client_random, server_random, &output[0]);
|
||||
security_premaster_hash("YY", 2, master_secret, client_random, server_random, &output[16]);
|
||||
security_premaster_hash("ZZZ", 3, master_secret, client_random, server_random, &output[32]);
|
||||
}
|
||||
|
||||
static void
|
||||
fips_expand_key_bits(uint8 *in, uint8 *out)
|
||||
{
|
||||
uint8 buf[21], c;
|
||||
int i, b, p, r;
|
||||
|
||||
// reverse every byte in the key
|
||||
for (i = 0; i < 21; i++)
|
||||
buf[i] = fips_reverse_table[in[i]];
|
||||
|
||||
// insert a zero-bit after every 7th bit
|
||||
for (i = 0, b = 0; i < 24; i++, b += 7)
|
||||
{
|
||||
p = b/8;
|
||||
r = b%8;
|
||||
if (r == 0)
|
||||
{
|
||||
out[i] = buf[p] & 0xfe;
|
||||
}
|
||||
else
|
||||
{
|
||||
// c is accumulator
|
||||
c = buf[p] << r;
|
||||
c |= buf[p+1] >> (8-r);
|
||||
out[i] = c & 0xfe;
|
||||
}
|
||||
}
|
||||
|
||||
// reverse every byte
|
||||
// alter lsb so the byte has odd parity
|
||||
for (i = 0; i < 24; i++)
|
||||
out[i] = fips_oddparity_table[fips_reverse_table[out[i]]];
|
||||
}
|
||||
|
||||
|
||||
boolean security_establish_keys(uint8* client_random, rdpSettings* settings)
|
||||
{
|
||||
uint8 pre_master_secret[48];
|
||||
uint8 master_secret[48];
|
||||
uint8 session_key_blob[48];
|
||||
uint8* server_random;
|
||||
uint8 salt40[] = { 0xD1, 0x26, 0x9E };
|
||||
|
||||
server_random = settings->server_random.data;
|
||||
|
||||
if (settings->encryption_method == ENCRYPTION_METHOD_FIPS)
|
||||
{
|
||||
CryptoSha1 sha1;
|
||||
uint8 client_encrypt_key_t[21], client_decrypt_key_t[21];
|
||||
|
||||
printf("FIPS Compliant encryption level.\n");
|
||||
|
||||
sha1 = crypto_sha1_init();
|
||||
crypto_sha1_update(sha1, client_random + 16, 16);
|
||||
crypto_sha1_update(sha1, server_random + 16, 16);
|
||||
crypto_sha1_final(sha1, client_encrypt_key_t);
|
||||
|
||||
client_encrypt_key_t[20] = client_encrypt_key_t[0];
|
||||
fips_expand_key_bits(client_encrypt_key_t, settings->fips_encrypt_key);
|
||||
|
||||
sha1 = crypto_sha1_init();
|
||||
crypto_sha1_update(sha1, client_random, 16);
|
||||
crypto_sha1_update(sha1, server_random, 16);
|
||||
crypto_sha1_final(sha1, client_decrypt_key_t);
|
||||
|
||||
client_decrypt_key_t[20] = client_decrypt_key_t[0];
|
||||
fips_expand_key_bits(client_decrypt_key_t, settings->fips_decrypt_key);
|
||||
|
||||
sha1 = crypto_sha1_init();
|
||||
crypto_sha1_update(sha1, client_decrypt_key_t, 20);
|
||||
crypto_sha1_update(sha1, client_encrypt_key_t, 20);
|
||||
crypto_sha1_final(sha1, settings->fips_sign_key);
|
||||
}
|
||||
|
||||
memcpy(pre_master_secret, client_random, 24);
|
||||
memcpy(pre_master_secret + 24, server_random, 24);
|
||||
|
||||
security_A(pre_master_secret, client_random, server_random, master_secret);
|
||||
security_X(master_secret, client_random, server_random, session_key_blob);
|
||||
|
||||
memcpy(settings->sign_key, session_key_blob, 16);
|
||||
|
||||
security_md5_16_32_32(&session_key_blob[16], client_random, server_random, settings->decrypt_key);
|
||||
security_md5_16_32_32(&session_key_blob[32], client_random, server_random, settings->encrypt_key);
|
||||
|
||||
if (settings->encryption_method == 1) /* 40 and 56 bit */
|
||||
{
|
||||
memcpy(settings->sign_key, salt40, 3); /* TODO 56 bit */
|
||||
memcpy(settings->decrypt_key, salt40, 3); /* TODO 56 bit */
|
||||
memcpy(settings->encrypt_key, salt40, 3); /* TODO 56 bit */
|
||||
settings->rc4_key_len = 8;
|
||||
}
|
||||
else if (settings->encryption_method == 2) /* 128 bit */
|
||||
{
|
||||
settings->rc4_key_len = 16;
|
||||
}
|
||||
|
||||
memcpy(settings->decrypt_update_key, settings->decrypt_key, 16);
|
||||
memcpy(settings->encrypt_update_key, settings->encrypt_key, 16);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean security_key_update(uint8* key, uint8* update_key, int key_len)
|
||||
{
|
||||
uint8 sha1h[20];
|
||||
CryptoMd5 md5;
|
||||
CryptoSha1 sha1;
|
||||
CryptoRc4 rc4;
|
||||
uint8 salt40[] = { 0xD1, 0x26, 0x9E };
|
||||
|
||||
sha1 = crypto_sha1_init();
|
||||
crypto_sha1_update(sha1, update_key, key_len);
|
||||
crypto_sha1_update(sha1, pad1, sizeof(pad1));
|
||||
crypto_sha1_update(sha1, key, key_len);
|
||||
crypto_sha1_final(sha1, sha1h);
|
||||
|
||||
md5 = crypto_md5_init();
|
||||
crypto_md5_update(md5, update_key, key_len);
|
||||
crypto_md5_update(md5, pad2, sizeof(pad2));
|
||||
crypto_md5_update(md5, sha1h, 20);
|
||||
crypto_md5_final(md5, key);
|
||||
|
||||
rc4 = crypto_rc4_init(key, key_len);
|
||||
crypto_rc4(rc4, key_len, key, key);
|
||||
crypto_rc4_free(rc4);
|
||||
|
||||
if (key_len == 8)
|
||||
memcpy(key, salt40, 3); /* TODO 56 bit */
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean security_encrypt(uint8* data, int length, rdpRdp* rdp)
|
||||
{
|
||||
if (rdp->encrypt_use_count >= 4096)
|
||||
{
|
||||
security_key_update(rdp->settings->encrypt_key, rdp->settings->encrypt_update_key, rdp->settings->rc4_key_len);
|
||||
crypto_rc4_free(rdp->rc4_encrypt_key);
|
||||
rdp->rc4_encrypt_key = crypto_rc4_init(rdp->settings->encrypt_key, rdp->settings->rc4_key_len);
|
||||
rdp->encrypt_use_count = 0;
|
||||
}
|
||||
crypto_rc4(rdp->rc4_encrypt_key, length, data, data);
|
||||
rdp->encrypt_use_count += 1;
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean security_decrypt(uint8* data, int length, rdpRdp* rdp)
|
||||
{
|
||||
if (rdp->decrypt_use_count >= 4096)
|
||||
{
|
||||
security_key_update(rdp->settings->decrypt_key, rdp->settings->decrypt_update_key, rdp->settings->rc4_key_len);
|
||||
crypto_rc4_free(rdp->rc4_decrypt_key);
|
||||
rdp->rc4_decrypt_key = crypto_rc4_init(rdp->settings->decrypt_key, rdp->settings->rc4_key_len);
|
||||
rdp->decrypt_use_count = 0;
|
||||
}
|
||||
crypto_rc4(rdp->rc4_decrypt_key, length, data, data);
|
||||
rdp->decrypt_use_count += 1;
|
||||
return True;
|
||||
}
|
||||
|
||||
void security_hmac_signature(uint8* data, int length, uint8* output, rdpRdp* rdp)
|
||||
{
|
||||
uint8 buf[20];
|
||||
uint8 use_count_le[4];
|
||||
|
||||
security_uint32_le(use_count_le, rdp->encrypt_use_count);
|
||||
|
||||
crypto_hmac_sha1_init(rdp->fips_hmac, rdp->settings->fips_sign_key, 20);
|
||||
crypto_hmac_update(rdp->fips_hmac, data, length);
|
||||
crypto_hmac_update(rdp->fips_hmac, use_count_le, 4);
|
||||
crypto_hmac_final(rdp->fips_hmac, buf, 20);
|
||||
|
||||
memmove(output, buf, 8);
|
||||
}
|
||||
|
||||
boolean security_fips_encrypt(uint8* data, int length, rdpRdp* rdp)
|
||||
{
|
||||
crypto_des3_encrypt(rdp->fips_encrypt, length, data, data);
|
||||
rdp->encrypt_use_count++;
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean security_fips_decrypt(uint8* data, int length, rdpRdp* rdp)
|
||||
{
|
||||
crypto_des3_decrypt(rdp->fips_decrypt, length, data, data);
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean security_fips_check_signature(uint8* data, int length, uint8* sig, rdpRdp* rdp)
|
||||
{
|
||||
uint8 buf[20];
|
||||
uint8 use_count_le[4];
|
||||
|
||||
security_uint32_le(use_count_le, rdp->decrypt_use_count);
|
||||
|
||||
crypto_hmac_sha1_init(rdp->fips_hmac, rdp->settings->fips_sign_key, 20);
|
||||
crypto_hmac_update(rdp->fips_hmac, data, length);
|
||||
crypto_hmac_update(rdp->fips_hmac, use_count_le, 4);
|
||||
crypto_hmac_final(rdp->fips_hmac, buf, 20);
|
||||
|
||||
rdp->decrypt_use_count++;
|
||||
|
||||
if (memcmp(sig, buf, 8))
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
@ -33,5 +33,14 @@ void security_licensing_encryption_key(uint8* session_key_blob, uint8* client_ra
|
||||
void security_mac_data(uint8* mac_salt_key, uint8* data, uint32 length, uint8* output);
|
||||
|
||||
void security_mac_signature(uint8* mac_key, int mac_key_length, uint8* data, uint32 length, uint8* output);
|
||||
boolean security_establish_keys(uint8* client_random, rdpSettings* settings);
|
||||
|
||||
boolean security_encrypt(uint8* data, int length, rdpRdp* rdp);
|
||||
boolean security_decrypt(uint8* data, int length, rdpRdp* rdp);
|
||||
|
||||
void security_hmac_signature(uint8* data, int length, uint8* output, rdpRdp* rdp);
|
||||
boolean security_fips_encrypt(uint8* data, int length, rdpRdp* rdp);
|
||||
boolean security_fips_decrypt(uint8* data, int length, rdpRdp* rdp);
|
||||
boolean security_fips_check_signature(uint8* data, int length, uint8* sig, rdpRdp* rdp);
|
||||
|
||||
#endif /* __SECURITY_H */
|
||||
|
@ -100,7 +100,7 @@ rdpSettings* settings_new()
|
||||
settings->frame_marker = False;
|
||||
settings->bitmap_cache_v3 = False;
|
||||
|
||||
settings->bitmap_cache = True;
|
||||
settings->bitmap_cache = False;
|
||||
settings->persistent_bitmap_cache = False;
|
||||
|
||||
settings->glyphSupportLevel = GLYPH_SUPPORT_NONE;
|
||||
@ -169,6 +169,8 @@ void settings_free(rdpSettings* settings)
|
||||
xfree(settings->client_dir);
|
||||
xfree(settings->cert_file);
|
||||
xfree(settings->privatekey_file);
|
||||
freerdp_blob_free(&(settings->server_certificate));
|
||||
certificate_free(settings->server_cert);
|
||||
xfree(settings);
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#else
|
||||
#define close(_fd) closesocket(_fd)
|
||||
#endif
|
||||
@ -165,6 +166,11 @@ int tcp_read(rdpTcp* tcp, uint8* data, int length)
|
||||
perror("recv");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("tcp_read: length %d\n", status);
|
||||
//freerdp_hexdump(data, status);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -175,6 +181,9 @@ int tcp_write(rdpTcp* tcp, uint8* data, int length)
|
||||
|
||||
status = send(tcp->sockfd, data, length, MSG_NOSIGNAL);
|
||||
|
||||
//printf("tcp_write: length %d\n", status);
|
||||
//freerdp_hexdump(data, status);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
|
@ -18,8 +18,8 @@
|
||||
*/
|
||||
|
||||
#include "update.h"
|
||||
#include "bitmap.h"
|
||||
#include "surface.h"
|
||||
#include <freerdp/common/bitmap.h>
|
||||
|
||||
uint8 UPDATE_TYPE_STRINGS[][32] =
|
||||
{
|
||||
@ -29,6 +29,17 @@ uint8 UPDATE_TYPE_STRINGS[][32] =
|
||||
"Synchronize"
|
||||
};
|
||||
|
||||
void update_free_bitmap(BITMAP_UPDATE* bitmap_update)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < bitmap_update->number; i++)
|
||||
{
|
||||
xfree(bitmap_update->bitmaps[i].data);
|
||||
}
|
||||
xfree(bitmap_update->bitmaps);
|
||||
}
|
||||
|
||||
void update_recv_orders(rdpUpdate* update, STREAM* s)
|
||||
{
|
||||
uint16 numberOrders;
|
||||
@ -110,6 +121,7 @@ void update_read_bitmap(rdpUpdate* update, STREAM* s, BITMAP_UPDATE* bitmap_upda
|
||||
{
|
||||
int i;
|
||||
|
||||
update_free_bitmap(bitmap_update);
|
||||
stream_read_uint16(s, bitmap_update->number); /* numberRectangles (2 bytes) */
|
||||
|
||||
bitmap_update->bitmaps = (BITMAP_DATA*) xzalloc(sizeof(BITMAP_DATA) * bitmap_update->number);
|
||||
@ -294,13 +306,15 @@ void update_recv(rdpUpdate* update, STREAM* s)
|
||||
uint16 length;
|
||||
uint16 source;
|
||||
uint32 shareId;
|
||||
uint8 compressed_type;
|
||||
uint16 compressed_len;
|
||||
|
||||
rdp_read_share_control_header(s, &length, &pduType, &source);
|
||||
|
||||
if (pduType != PDU_TYPE_DATA)
|
||||
return;
|
||||
|
||||
rdp_read_share_data_header(s, &length, &type, &shareId);
|
||||
rdp_read_share_data_header(s, &length, &type, &shareId, &compressed_type, &compressed_len);
|
||||
|
||||
if (type == DATA_PDU_TYPE_UPDATE)
|
||||
update_recv(update, s);
|
||||
@ -394,6 +408,8 @@ rdpUpdate* update_new(rdpRdp* rdp)
|
||||
|
||||
void update_free(rdpUpdate* update)
|
||||
{
|
||||
update_free_bitmap(&update->bitmap_update);
|
||||
|
||||
if (update != NULL)
|
||||
{
|
||||
xfree(update);
|
||||
|
@ -37,6 +37,7 @@
|
||||
|
||||
rdpUpdate* update_new(rdpRdp* rdp);
|
||||
void update_free(rdpUpdate* update);
|
||||
void update_free_bitmap(BITMAP_UPDATE* bitmap_update);
|
||||
void update_reset_state(rdpUpdate* update);
|
||||
|
||||
void update_read_bitmap(rdpUpdate* update, STREAM* s, BITMAP_UPDATE* bitmap_update);
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
#include <freerdp/gdi/color.h>
|
||||
#include <freerdp/common/color.h>
|
||||
|
||||
#include <freerdp/gdi/pen.h>
|
||||
#include <freerdp/gdi/bitmap.h>
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
#include <freerdp/gdi/color.h>
|
||||
#include <freerdp/common/color.h>
|
||||
|
||||
#include <freerdp/gdi/pen.h>
|
||||
#include <freerdp/gdi/bitmap.h>
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
#include <freerdp/gdi/color.h>
|
||||
#include <freerdp/common/color.h>
|
||||
|
||||
#include <freerdp/gdi/pen.h>
|
||||
#include <freerdp/gdi/bitmap.h>
|
||||
|
@ -18,7 +18,6 @@
|
||||
# limitations under the License.
|
||||
|
||||
set(FREERDP_GDI_SRCS
|
||||
color.c
|
||||
8bpp.c
|
||||
16bpp.c
|
||||
32bpp.c
|
||||
@ -37,6 +36,7 @@ set(FREERDP_GDI_SRCS
|
||||
add_library(freerdp-gdi ${FREERDP_GDI_SRCS})
|
||||
|
||||
target_link_libraries(freerdp-gdi freerdp-cache)
|
||||
target_link_libraries(freerdp-gdi freerdp-common)
|
||||
target_link_libraries(freerdp-gdi freerdp-rfx)
|
||||
|
||||
set_target_properties(freerdp-gdi PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib")
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
#include <freerdp/gdi/color.h>
|
||||
#include <freerdp/common/color.h>
|
||||
|
||||
#include <freerdp/gdi/32bpp.h>
|
||||
#include <freerdp/gdi/16bpp.h>
|
||||
|
@ -23,8 +23,8 @@
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/constants.h>
|
||||
#include <freerdp/gdi/color.h>
|
||||
#include <freerdp/utils/bitmap.h>
|
||||
#include <freerdp/common/color.h>
|
||||
#include <freerdp/rfx/rfx.h>
|
||||
|
||||
#include <freerdp/gdi/dc.h>
|
||||
@ -396,7 +396,7 @@ HGDI_BITMAP gdi_create_bitmap(GDI* gdi, int width, int height, int bpp, uint8* d
|
||||
uint8* bmpData;
|
||||
HGDI_BITMAP bitmap;
|
||||
|
||||
bmpData = gdi_image_convert(data, NULL, width, height, gdi->srcBpp, bpp, gdi->clrconv);
|
||||
bmpData = freerdp_image_convert(data, NULL, width, height, gdi->srcBpp, bpp, gdi->clrconv);
|
||||
bitmap = gdi_CreateBitmap(width, height, gdi->dstBpp, bmpData);
|
||||
|
||||
return bitmap;
|
||||
@ -506,7 +506,7 @@ void gdi_patblt(rdpUpdate* update, PATBLT_ORDER* patblt)
|
||||
uint32 color;
|
||||
originalBrush = gdi->drawing->hdc->brush;
|
||||
|
||||
color = gdi_color_convert(patblt->foreColor, gdi->srcBpp, 32, gdi->clrconv);
|
||||
color = freerdp_color_convert(patblt->foreColor, gdi->srcBpp, 32, gdi->clrconv);
|
||||
gdi->drawing->hdc->brush = gdi_CreateSolidBrush(color);
|
||||
|
||||
gdi_PatBlt(gdi->drawing->hdc, patblt->nLeftRect, patblt->nTopRect,
|
||||
@ -521,11 +521,11 @@ void gdi_patblt(rdpUpdate* update, PATBLT_ORDER* patblt)
|
||||
|
||||
if (brush->bpp > 1)
|
||||
{
|
||||
data = gdi_image_convert(brush->data, NULL, 8, 8, gdi->srcBpp, gdi->dstBpp, gdi->clrconv);
|
||||
data = freerdp_image_convert(brush->data, NULL, 8, 8, gdi->srcBpp, gdi->dstBpp, gdi->clrconv);
|
||||
}
|
||||
else
|
||||
{
|
||||
data = gdi_mono_image_convert(brush->data, 8, 8, gdi->srcBpp, gdi->dstBpp,
|
||||
data = freerdp_mono_image_convert(brush->data, 8, 8, gdi->srcBpp, gdi->dstBpp,
|
||||
patblt->backColor, patblt->foreColor, gdi->clrconv);
|
||||
}
|
||||
|
||||
@ -565,7 +565,7 @@ void gdi_opaque_rect(rdpUpdate* update, OPAQUE_RECT_ORDER* opaque_rect)
|
||||
gdi_CRgnToRect(opaque_rect->nLeftRect, opaque_rect->nTopRect,
|
||||
opaque_rect->nWidth, opaque_rect->nHeight, &rect);
|
||||
|
||||
brush_color = gdi_color_convert(opaque_rect->color, gdi->srcBpp, 32, gdi->clrconv);
|
||||
brush_color = freerdp_color_convert(opaque_rect->color, gdi->srcBpp, 32, gdi->clrconv);
|
||||
|
||||
hBrush = gdi_CreateSolidBrush(brush_color);
|
||||
gdi_FillRect(gdi->drawing->hdc, &rect, hBrush);
|
||||
@ -589,7 +589,7 @@ void gdi_multi_opaque_rect(rdpUpdate* update, MULTI_OPAQUE_RECT_ORDER* multi_opa
|
||||
gdi_CRgnToRect(rectangle->left, rectangle->top,
|
||||
rectangle->width, rectangle->height, &rect);
|
||||
|
||||
brush_color = gdi_color_convert(multi_opaque_rect->color, gdi->srcBpp, 32, gdi->clrconv);
|
||||
brush_color = freerdp_color_convert(multi_opaque_rect->color, gdi->srcBpp, 32, gdi->clrconv);
|
||||
|
||||
hBrush = gdi_CreateSolidBrush(brush_color);
|
||||
gdi_FillRect(gdi->drawing->hdc, &rect, hBrush);
|
||||
@ -604,7 +604,7 @@ void gdi_line_to(rdpUpdate* update, LINE_TO_ORDER* line_to)
|
||||
HGDI_PEN hPen;
|
||||
GDI *gdi = GET_GDI(update);
|
||||
|
||||
color = gdi_color_convert(line_to->penColor, gdi->srcBpp, 32, gdi->clrconv);
|
||||
color = freerdp_color_convert(line_to->penColor, gdi->srcBpp, 32, gdi->clrconv);
|
||||
hPen = gdi_CreatePen(line_to->penStyle, line_to->penWidth, (GDI_COLOR) color);
|
||||
gdi_SelectObject(gdi->drawing->hdc, (HGDIOBJECT) hPen);
|
||||
gdi_SetROP2(gdi->drawing->hdc, line_to->bRop2);
|
||||
@ -623,16 +623,18 @@ void gdi_polyline(rdpUpdate* update, POLYLINE_ORDER* polyline)
|
||||
DELTA_POINT* points;
|
||||
GDI *gdi = GET_GDI(update);
|
||||
|
||||
color = gdi_color_convert(polyline->penColor, gdi->srcBpp, 32, gdi->clrconv);
|
||||
color = freerdp_color_convert(polyline->penColor, gdi->srcBpp, 32, gdi->clrconv);
|
||||
hPen = gdi_CreatePen(0, 1, (GDI_COLOR) color);
|
||||
gdi_SelectObject(gdi->drawing->hdc, (HGDIOBJECT) hPen);
|
||||
gdi_SetROP2(gdi->drawing->hdc, polyline->bRop2);
|
||||
|
||||
gdi_MoveToEx(gdi->drawing->hdc, polyline->xStart, polyline->yStart, NULL);
|
||||
|
||||
points = polyline->points;
|
||||
for (i = 0; i < polyline->numPoints; i++)
|
||||
{
|
||||
gdi_LineTo(gdi->drawing->hdc, points[i].x, points[i].y);
|
||||
gdi_MoveToEx(gdi->drawing->hdc, points[i].x, points[i].y, NULL);
|
||||
gdi_LineTo(gdi->drawing->hdc, points[i + 1].x, points[i + 1].y);
|
||||
}
|
||||
|
||||
gdi_DeleteObject((HGDIOBJECT) hPen);
|
||||
@ -643,7 +645,7 @@ void gdi_fast_index(rdpUpdate* update, FAST_INDEX_ORDER* fast_index)
|
||||
uint32 color;
|
||||
GDI* gdi = GET_GDI(update);
|
||||
|
||||
color = gdi_color_convert(fast_index->foreColor, gdi->srcBpp, 32, gdi->clrconv);
|
||||
color = freerdp_color_convert(fast_index->foreColor, gdi->srcBpp, 32, gdi->clrconv);
|
||||
gdi->textColor = gdi_SetTextColor(gdi->drawing->hdc, color);
|
||||
|
||||
|
||||
@ -708,7 +710,7 @@ void gdi_cache_glyph(rdpUpdate* update, CACHE_GLYPH_ORDER* cache_glyph)
|
||||
gdi_bmp->hdc->bytesPerPixel = 1;
|
||||
gdi_bmp->hdc->bitsPerPixel = 1;
|
||||
|
||||
extra = gdi_glyph_convert(glyph->cx, glyph->cy, glyph->aj);
|
||||
extra = freerdp_glyph_convert(glyph->cx, glyph->cy, glyph->aj);
|
||||
gdi_bmp->bitmap = gdi_CreateBitmap(glyph->cx, glyph->cy, 1, extra);
|
||||
gdi_bmp->bitmap->bytesPerPixel = 1;
|
||||
gdi_bmp->bitmap->bitsPerPixel = 1;
|
||||
@ -737,7 +739,7 @@ void gdi_cache_glyph_v2(rdpUpdate* update, CACHE_GLYPH_V2_ORDER* cache_glyph_v2)
|
||||
gdi_bmp->hdc->bytesPerPixel = 1;
|
||||
gdi_bmp->hdc->bitsPerPixel = 1;
|
||||
|
||||
extra = gdi_glyph_convert(glyph->cx, glyph->cy, glyph->aj);
|
||||
extra = freerdp_glyph_convert(glyph->cx, glyph->cy, glyph->aj);
|
||||
gdi_bmp->bitmap = gdi_CreateBitmap(glyph->cx, glyph->cy, 1, extra);
|
||||
gdi_bmp->bitmap->bytesPerPixel = 1;
|
||||
gdi_bmp->bitmap->bitsPerPixel = 1;
|
||||
@ -786,70 +788,31 @@ void gdi_surface_bits(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_comm
|
||||
|
||||
DEBUG_GDI("num_rects %d num_tiles %d", message->num_rects, message->num_tiles);
|
||||
|
||||
if (message->num_rects > 1) /* RDVH */
|
||||
/* blit each tile */
|
||||
for (i = 0; i < message->num_tiles; i++)
|
||||
{
|
||||
/* blit each tile */
|
||||
for (i = 0; i < message->num_tiles; i++)
|
||||
{
|
||||
tx = message->tiles[i]->x + surface_bits_command->destLeft;
|
||||
ty = message->tiles[i]->y + surface_bits_command->destTop;
|
||||
tx = message->tiles[i]->x + surface_bits_command->destLeft;
|
||||
ty = message->tiles[i]->y + surface_bits_command->destTop;
|
||||
|
||||
gdi_image_convert(message->tiles[i]->data, gdi->tile->bitmap->data, 64, 64, 32, 32, gdi->clrconv);
|
||||
freerdp_image_convert(message->tiles[i]->data, gdi->tile->bitmap->data, 64, 64, 32, 32, gdi->clrconv);
|
||||
|
||||
#ifdef DUMP_REMOTEFX_TILES
|
||||
sprintf(tile_bitmap, "/tmp/rfx/tile_%d.bmp", tilenum++);
|
||||
freerdp_bitmap_write(tile_bitmap, gdi->tile->bitmap->data, 64, 64, 32);
|
||||
sprintf(tile_bitmap, "/tmp/rfx/tile_%d.bmp", tilenum++);
|
||||
freerdp_bitmap_write(tile_bitmap, gdi->tile->bitmap->data, 64, 64, 32);
|
||||
#endif
|
||||
|
||||
for (j = 0; j < message->num_rects; j++)
|
||||
{
|
||||
gdi_SetClipRgn(gdi->primary->hdc,
|
||||
surface_bits_command->destLeft + message->rects[j].x,
|
||||
surface_bits_command->destTop + message->rects[j].y,
|
||||
message->rects[j].width, message->rects[j].height);
|
||||
|
||||
gdi_BitBlt(gdi->primary->hdc, tx, ty, 64, 64, gdi->tile->hdc, 0, 0, GDI_SRCCOPY);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < message->num_rects; i++)
|
||||
for (j = 0; j < message->num_rects; j++)
|
||||
{
|
||||
gdi_InvalidateRegion(gdi->primary->hdc,
|
||||
surface_bits_command->destLeft + message->rects[i].x,
|
||||
surface_bits_command->destTop + message->rects[i].y,
|
||||
message->rects[i].width, message->rects[i].height);
|
||||
}
|
||||
}
|
||||
else if (message->num_rects == 1) /* RDSH */
|
||||
{
|
||||
gdi_SetClipRgn(gdi->primary->hdc,
|
||||
surface_bits_command->destLeft + message->rects[0].x,
|
||||
surface_bits_command->destTop + message->rects[0].y,
|
||||
message->rects[0].width, message->rects[0].height);
|
||||
|
||||
/* blit each tile */
|
||||
for (i = 0; i < message->num_tiles; i++)
|
||||
{
|
||||
tx = message->tiles[i]->x + surface_bits_command->destLeft;
|
||||
ty = message->tiles[i]->y + surface_bits_command->destTop;
|
||||
|
||||
gdi_image_convert(message->tiles[i]->data, gdi->tile->bitmap->data, 64, 64, 32, 32, gdi->clrconv);
|
||||
|
||||
#ifdef DUMP_REMOTEFX_TILES
|
||||
sprintf(tile_bitmap, "/tmp/rfx/tile_%d.bmp", tilenum++);
|
||||
freerdp_bitmap_write(tile_bitmap, gdi->tile->bitmap->data, 64, 64, 32);
|
||||
#endif
|
||||
gdi_SetClipRgn(gdi->primary->hdc,
|
||||
surface_bits_command->destLeft + message->rects[j].x,
|
||||
surface_bits_command->destTop + message->rects[j].y,
|
||||
message->rects[j].width, message->rects[j].height);
|
||||
|
||||
gdi_BitBlt(gdi->primary->hdc, tx, ty, 64, 64, gdi->tile->hdc, 0, 0, GDI_SRCCOPY);
|
||||
|
||||
}
|
||||
|
||||
gdi_InvalidateRegion(gdi->primary->hdc,
|
||||
surface_bits_command->destLeft + message->rects[0].x,
|
||||
surface_bits_command->destTop + message->rects[0].y,
|
||||
message->rects[0].width, message->rects[0].height);
|
||||
}
|
||||
|
||||
gdi_SetNullClipRgn(gdi->primary->hdc);
|
||||
rfx_message_free(context, message);
|
||||
|
||||
stream_detach(s);
|
||||
@ -867,7 +830,7 @@ void gdi_surface_bits(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_comm
|
||||
|
||||
if (surface_bits_command->bpp != 32)
|
||||
{
|
||||
gdi_image_convert(surface_bits_command->bitmapData, gdi->image->bitmap->data,
|
||||
freerdp_image_convert(surface_bits_command->bitmapData, gdi->image->bitmap->data,
|
||||
gdi->image->bitmap->width, gdi->image->bitmap->height,
|
||||
gdi->image->bitmap->bitsPerPixel, 32, gdi->clrconv);
|
||||
|
||||
@ -875,7 +838,7 @@ void gdi_surface_bits(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_comm
|
||||
surface_bits_command->bitmapData = gdi->image->bitmap->data;
|
||||
}
|
||||
|
||||
gdi_image_invert(surface_bits_command->bitmapData, gdi->image->bitmap->data,
|
||||
freerdp_image_invert(surface_bits_command->bitmapData, gdi->image->bitmap->data,
|
||||
gdi->image->bitmap->width, gdi->image->bitmap->height, 32);
|
||||
|
||||
gdi_BitBlt(gdi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop,
|
||||
|
@ -18,7 +18,6 @@
|
||||
# limitations under the License.
|
||||
|
||||
set(LIBFREERDP_RFX_SRCS
|
||||
rfx_bitstream.c
|
||||
rfx_bitstream.h
|
||||
rfx_constants.h
|
||||
rfx_decode.c
|
||||
|
@ -183,18 +183,24 @@ void rfx_context_set_pixel_format(RFX_CONTEXT* context, RFX_PIXEL_FORMAT pixel_f
|
||||
{
|
||||
case RFX_PIXEL_FORMAT_BGRA:
|
||||
case RFX_PIXEL_FORMAT_RGBA:
|
||||
context->bytes_per_pixel = 4;
|
||||
context->bits_per_pixel = 32;
|
||||
break;
|
||||
case RFX_PIXEL_FORMAT_BGR:
|
||||
case RFX_PIXEL_FORMAT_RGB:
|
||||
context->bytes_per_pixel = 3;
|
||||
context->bits_per_pixel = 24;
|
||||
break;
|
||||
case RFX_PIXEL_FORMAT_BGR565_LE:
|
||||
case RFX_PIXEL_FORMAT_RGB565_LE:
|
||||
context->bytes_per_pixel = 2;
|
||||
context->bits_per_pixel = 16;
|
||||
break;
|
||||
case RFX_PIXEL_FORMAT_PALETTE4_PLANER:
|
||||
context->bits_per_pixel = 4;
|
||||
break;
|
||||
case RFX_PIXEL_FORMAT_PALETTE8:
|
||||
context->bits_per_pixel = 8;
|
||||
break;
|
||||
default:
|
||||
context->bytes_per_pixel = 0;
|
||||
context->bits_per_pixel = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -802,7 +808,7 @@ static void rfx_compose_message_tileset(RFX_CONTEXT* context, STREAM* data_out,
|
||||
for (xIdx = 0; xIdx < numTilesX; xIdx++)
|
||||
{
|
||||
rfx_compose_message_tile(context, data_out,
|
||||
image_data + yIdx * 64 * rowstride + xIdx * 64 * context->bytes_per_pixel,
|
||||
image_data + yIdx * 64 * rowstride + xIdx * 8 * context->bits_per_pixel,
|
||||
xIdx < numTilesX - 1 ? 64 : width - xIdx * 64,
|
||||
yIdx < numTilesY - 1 ? 64 : height - yIdx * 64,
|
||||
rowstride, quantVals, quantIdxY, quantIdxCb, quantIdxCr, xIdx, yIdx);
|
||||
|
@ -1,86 +0,0 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol client.
|
||||
* RemoteFX Codec Library - Bit Stream
|
||||
*
|
||||
* Copyright 2011 Vic Lee
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
|
||||
#include "rfx_bitstream.h"
|
||||
|
||||
void rfx_bitstream_attach(RFX_BITSTREAM* bs, uint8* buffer, int nbytes)
|
||||
{
|
||||
bs->buffer = buffer;
|
||||
bs->nbytes = nbytes;
|
||||
bs->byte_pos = 0;
|
||||
bs->bits_left = 8;
|
||||
}
|
||||
|
||||
uint16 rfx_bitstream_get_bits(RFX_BITSTREAM* bs, int nbits)
|
||||
{
|
||||
int b;
|
||||
uint16 n = 0;
|
||||
|
||||
while (bs->byte_pos < bs->nbytes && nbits > 0)
|
||||
{
|
||||
b = nbits;
|
||||
|
||||
if (b > bs->bits_left)
|
||||
b = bs->bits_left;
|
||||
|
||||
if (n)
|
||||
n <<= b;
|
||||
|
||||
n |= (bs->buffer[bs->byte_pos] >> (bs->bits_left - b)) & ((1 << b) - 1);
|
||||
bs->bits_left -= b;
|
||||
nbits -= b;
|
||||
|
||||
if (bs->bits_left == 0)
|
||||
{
|
||||
bs->bits_left = 8;
|
||||
bs->byte_pos++;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void rfx_bitstream_put_bits(RFX_BITSTREAM* bs, uint16 bits, int nbits)
|
||||
{
|
||||
int b;
|
||||
|
||||
while (bs->byte_pos < bs->nbytes && nbits > 0)
|
||||
{
|
||||
b = nbits;
|
||||
|
||||
if (b > bs->bits_left)
|
||||
b = bs->bits_left;
|
||||
|
||||
bs->buffer[bs->byte_pos] &= ~(((1 << b) - 1) << (bs->bits_left - b));
|
||||
bs->buffer[bs->byte_pos] |= ((bits >> (nbits - b)) & ((1 << b) - 1)) << (bs->bits_left - b);
|
||||
bs->bits_left -= b;
|
||||
nbits -= b;
|
||||
|
||||
if (bs->bits_left == 0)
|
||||
{
|
||||
bs->bits_left = 8;
|
||||
bs->byte_pos++;
|
||||
}
|
||||
}
|
||||
}
|
@ -31,9 +31,53 @@ struct _RFX_BITSTREAM
|
||||
};
|
||||
typedef struct _RFX_BITSTREAM RFX_BITSTREAM;
|
||||
|
||||
void rfx_bitstream_attach(RFX_BITSTREAM* bs, uint8* buffer, int nbytes);
|
||||
uint16 rfx_bitstream_get_bits(RFX_BITSTREAM* bs, int nbits);
|
||||
void rfx_bitstream_put_bits(RFX_BITSTREAM* bs, uint16 bits, int nbits);
|
||||
#define rfx_bitstream_attach(bs, _buffer, _nbytes) do { \
|
||||
bs->buffer = (uint8*) (_buffer); \
|
||||
bs->nbytes = (_nbytes); \
|
||||
bs->byte_pos = 0; \
|
||||
bs->bits_left = 8; } while (0)
|
||||
|
||||
#define rfx_bitstream_get_bits(bs, _nbits, _r) do { \
|
||||
int nbits = _nbits; \
|
||||
int b; \
|
||||
uint16 n = 0; \
|
||||
while (bs->byte_pos < bs->nbytes && nbits > 0) \
|
||||
{ \
|
||||
b = nbits; \
|
||||
if (b > bs->bits_left) \
|
||||
b = bs->bits_left; \
|
||||
if (n) \
|
||||
n <<= b; \
|
||||
n |= (bs->buffer[bs->byte_pos] >> (bs->bits_left - b)) & ((1 << b) - 1); \
|
||||
bs->bits_left -= b; \
|
||||
nbits -= b; \
|
||||
if (bs->bits_left == 0) \
|
||||
{ \
|
||||
bs->bits_left = 8; \
|
||||
bs->byte_pos++; \
|
||||
} \
|
||||
} \
|
||||
_r = n; } while (0)
|
||||
|
||||
#define rfx_bitstream_put_bits(bs, _bits, _nbits) do { \
|
||||
uint16 bits = (_bits); \
|
||||
int nbits = (_nbits); \
|
||||
int b; \
|
||||
while (bs->byte_pos < bs->nbytes && nbits > 0) \
|
||||
{ \
|
||||
b = nbits; \
|
||||
if (b > bs->bits_left) \
|
||||
b = bs->bits_left; \
|
||||
bs->buffer[bs->byte_pos] &= ~(((1 << b) - 1) << (bs->bits_left - b)); \
|
||||
bs->buffer[bs->byte_pos] |= ((bits >> (nbits - b)) & ((1 << b) - 1)) << (bs->bits_left - b); \
|
||||
bs->bits_left -= b; \
|
||||
nbits -= b; \
|
||||
if (bs->bits_left == 0) \
|
||||
{ \
|
||||
bs->bits_left = 8; \
|
||||
bs->byte_pos++; \
|
||||
} \
|
||||
} } while (0)
|
||||
|
||||
#define rfx_bitstream_eos(_bs) ((_bs)->byte_pos >= (_bs)->nbytes)
|
||||
#define rfx_bitstream_left(_bs) ((_bs)->byte_pos >= (_bs)->nbytes ? 0 : ((_bs)->nbytes - (_bs)->byte_pos - 1) * 8 + (_bs)->bits_left)
|
||||
|
@ -31,7 +31,7 @@
|
||||
#define MINMAX(_v,_l,_h) ((_v) < (_l) ? (_l) : ((_v) > (_h) ? (_h) : (_v)))
|
||||
|
||||
static void rfx_encode_format_rgb(const uint8* rgb_data, int width, int height, int rowstride,
|
||||
RFX_PIXEL_FORMAT pixel_format, sint16* r_buf, sint16* g_buf, sint16* b_buf)
|
||||
RFX_PIXEL_FORMAT pixel_format, const uint8* palette, sint16* r_buf, sint16* g_buf, sint16* b_buf)
|
||||
{
|
||||
int x, y;
|
||||
int x_exceed;
|
||||
@ -100,6 +100,40 @@ static void rfx_encode_format_rgb(const uint8* rgb_data, int width, int height,
|
||||
src += 2;
|
||||
}
|
||||
break;
|
||||
case RFX_PIXEL_FORMAT_PALETTE4_PLANER:
|
||||
if (!palette)
|
||||
break;
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
int shift;
|
||||
uint8 idx;
|
||||
|
||||
shift = (7 - (x % 8));
|
||||
idx = ((*src) >> shift) & 1;
|
||||
idx |= (((*(src + 1)) >> shift) & 1) << 1;
|
||||
idx |= (((*(src + 2)) >> shift) & 1) << 2;
|
||||
idx |= (((*(src + 3)) >> shift) & 1) << 3;
|
||||
idx *= 3;
|
||||
*r_buf++ = (sint16) palette[idx];
|
||||
*g_buf++ = (sint16) palette[idx + 1];
|
||||
*b_buf++ = (sint16) palette[idx + 2];
|
||||
if (shift == 0)
|
||||
src += 4;
|
||||
}
|
||||
break;
|
||||
case RFX_PIXEL_FORMAT_PALETTE8:
|
||||
if (!palette)
|
||||
break;
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
int idx = (*src) * 3;
|
||||
|
||||
*r_buf++ = (sint16) palette[idx];
|
||||
*g_buf++ = (sint16) palette[idx + 1];
|
||||
*b_buf++ = (sint16) palette[idx + 2];
|
||||
src++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -211,7 +245,7 @@ void rfx_encode_rgb(RFX_CONTEXT* context, const uint8* rgb_data, int width, int
|
||||
|
||||
PROFILER_ENTER(context->priv->prof_rfx_encode_format_rgb);
|
||||
rfx_encode_format_rgb(rgb_data, width, height, rowstride,
|
||||
context->pixel_format, y_r_buffer, cb_g_buffer, cr_b_buffer);
|
||||
context->pixel_format, context->palette, y_r_buffer, cb_g_buffer, cr_b_buffer);
|
||||
PROFILER_EXIT(context->priv->prof_rfx_encode_format_rgb);
|
||||
|
||||
PROFILER_ENTER(context->priv->prof_rfx_encode_rgb_to_ycbcr);
|
||||
|
@ -39,7 +39,7 @@
|
||||
#define DQ_GR (3) /* decrease in kp after zero symbol in GR mode */
|
||||
|
||||
/* Gets (returns) the next nBits from the bitstream */
|
||||
#define GetBits(nBits) rfx_bitstream_get_bits(bs, nBits)
|
||||
#define GetBits(nBits, r) rfx_bitstream_get_bits(bs, nBits, r)
|
||||
|
||||
/* From current output pointer, write "value", check and update buffer_size */
|
||||
#define WriteValue(value) \
|
||||
@ -99,13 +99,22 @@ static uint16 rfx_rlgr_get_gr_code(RFX_BITSTREAM* bs, int* krp, int* kr)
|
||||
{
|
||||
int vk;
|
||||
uint16 mag;
|
||||
uint16 r;
|
||||
|
||||
/* chew up/count leading 1s and escape 0 */
|
||||
for (vk = 0; GetBits(1) == 1;)
|
||||
vk++;
|
||||
vk = 0;
|
||||
do
|
||||
{
|
||||
GetBits(1, r);
|
||||
if (r == 1)
|
||||
vk++;
|
||||
else
|
||||
break;
|
||||
} while (1);
|
||||
|
||||
/* get next *kr bits, and combine with leading 1s */
|
||||
mag = (vk << *kr) | GetBits(*kr);
|
||||
GetBits(*kr, mag);
|
||||
mag |= (vk << *kr);
|
||||
|
||||
/* adjust krp and kr based on vk */
|
||||
if (!vk)
|
||||
@ -127,11 +136,12 @@ int rfx_rlgr_decode(RLGR_MODE mode, const uint8* data, int data_size, sint16* bu
|
||||
int kp;
|
||||
int kr;
|
||||
int krp;
|
||||
uint16 r;
|
||||
sint16* dst;
|
||||
RFX_BITSTREAM* bs;
|
||||
|
||||
bs = xnew(RFX_BITSTREAM);
|
||||
rfx_bitstream_attach(bs, (uint8*) data, data_size);
|
||||
rfx_bitstream_attach(bs, data, data_size);
|
||||
dst = buffer;
|
||||
|
||||
/* initialize the parameters */
|
||||
@ -149,19 +159,22 @@ int rfx_rlgr_decode(RLGR_MODE mode, const uint8* data, int data_size, sint16* bu
|
||||
uint32 sign;
|
||||
|
||||
/* RL MODE */
|
||||
while (!rfx_bitstream_eos(bs) && GetBits(1) == 0)
|
||||
while (!rfx_bitstream_eos(bs))
|
||||
{
|
||||
GetBits(1, r);
|
||||
if (r)
|
||||
break;
|
||||
/* we have an RL escape "0", which translates to a run (1<<k) of zeros */
|
||||
WriteZeroes(1 << k);
|
||||
UpdateParam(kp, UP_GR, k); /* raise k and kp up because of zero run */
|
||||
}
|
||||
|
||||
/* next k bits will contain remaining run or zeros */
|
||||
run = GetBits(k);
|
||||
GetBits(k, run);
|
||||
WriteZeroes(run);
|
||||
|
||||
/* get nonzero value, starting with sign bit and then GRCode for magnitude -1 */
|
||||
sign = GetBits(1);
|
||||
GetBits(1, sign);
|
||||
|
||||
/* magnitude - 1 was coded (because it was nonzero) */
|
||||
mag = (int) GetGRCode(&krp, &kr) + 1;
|
||||
@ -203,7 +216,7 @@ int rfx_rlgr_decode(RLGR_MODE mode, const uint8* data, int data_size, sint16* bu
|
||||
GetMinBits(mag, nIdx);
|
||||
|
||||
/* decode val1 is first term's (2 * mag - sign) value */
|
||||
val1 = GetBits(nIdx);
|
||||
GetBits(nIdx, val1);
|
||||
|
||||
/* val2 is second term's (2 * mag - sign) value */
|
||||
val2 = mag - val1;
|
||||
@ -245,7 +258,7 @@ int rfx_rlgr_decode(RLGR_MODE mode, const uint8* data, int data_size, sint16* bu
|
||||
}
|
||||
|
||||
/* Emit bitPattern to the output bitstream */
|
||||
#define OutputBits(numBits, bitPattern) rfx_bitstream_put_bits(bs, bitPattern, numBits);
|
||||
#define OutputBits(numBits, bitPattern) rfx_bitstream_put_bits(bs, bitPattern, numBits)
|
||||
|
||||
/* Emit a bit (0 or 1), count number of times, to the output bitstream */
|
||||
#define OutputBit(count, bit) \
|
||||
|
@ -367,6 +367,9 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
|
||||
settings->rdp_security = True;
|
||||
settings->tls_security = False;
|
||||
settings->nla_security = False;
|
||||
settings->encryption = True;
|
||||
settings->encryption_method = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS;
|
||||
settings->encryption_level = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;
|
||||
}
|
||||
else if (strncmp("tls", argv[index], 1) == 0) /* TLS */
|
||||
{
|
||||
|
@ -24,4 +24,10 @@ if(NOT WIN32)
|
||||
# Build Test Server
|
||||
add_subdirectory(test)
|
||||
|
||||
# Build X11 Server
|
||||
find_suggested_package(X11)
|
||||
if(X11_FOUND)
|
||||
add_subdirectory(X11)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
38
server/X11/CMakeLists.txt
Normal file
38
server/X11/CMakeLists.txt
Normal file
@ -0,0 +1,38 @@
|
||||
# FreeRDP: A Remote Desktop Protocol Client
|
||||
# FreeRDP X11 Server cmake build script
|
||||
#
|
||||
# Copyright 2011 O.S. Systems Software Ltda.
|
||||
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
|
||||
# Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
include_directories(${X11_INCLUDE_DIRS})
|
||||
|
||||
add_executable(xfreerdp-server
|
||||
xf_peer.c
|
||||
xf_encode.c
|
||||
xfreerdp.c)
|
||||
|
||||
find_suggested_package(Xext)
|
||||
if(XEXT_FOUND)
|
||||
add_definitions(-DWITH_XEXT)
|
||||
include_directories(${XEXT_INCLUDE_DIRS})
|
||||
target_link_libraries(xfreerdp-server ${XEXT_LIBRARIES})
|
||||
endif()
|
||||
|
||||
target_link_libraries(xfreerdp-server freerdp-core)
|
||||
target_link_libraries(xfreerdp-server freerdp-common)
|
||||
target_link_libraries(xfreerdp-server freerdp-utils)
|
||||
target_link_libraries(xfreerdp-server freerdp-rfx)
|
||||
target_link_libraries(xfreerdp-server ${X11_LIBRARIES})
|
BIN
server/X11/rfx_test.pcap
Normal file
BIN
server/X11/rfx_test.pcap
Normal file
Binary file not shown.
17
server/X11/server.crt
Normal file
17
server/X11/server.crt
Normal file
@ -0,0 +1,17 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICyzCCAbOgAwIBAgIJANbqtAWwlQZuMA0GCSqGSIb3DQEBBQUAMBIxEDAOBgNV
|
||||
BAMTB0ZyZWVSRFAwHhcNMDkxMDI5MDA0MTQ5WhcNMDkxMTI4MDA0MTQ5WjASMRAw
|
||||
DgYDVQQDEwdGcmVlUkRQMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
|
||||
q7mxFgRbS2FYJZX7BzpNd4T/n4nEVDBY6YaObLjGpaB1TptzXTcmfDrDslTGwcEY
|
||||
hTFAC4ZvY6yOURExqbph4LSgvkoa6J722RjVPfshGa4mlh2SXvTiaV26VPPxddGb
|
||||
o6fbs2u029lbtBlpIVbhx5RN9vstNkll26oSZ6wfEdBNHQJLd2SU4ItWHj8zjz1f
|
||||
eGxjgChHihUlwcBYKDJsKFkzHZmLrMgB37KsGlXi/WV+eEsjgvz4yP7I3TL8+GsN
|
||||
MjV8fRGVEKTbKSmgunO67d5u+IaqUQb0Ad1ha1jzDQ+a6hdymrulJSIhoOVfKkwi
|
||||
ptTe43FgwxVRIygJP9HjHQIDAQABoyQwIjATBgNVHSUEDDAKBggrBgEFBQcDATAL
|
||||
BgNVHQ8EBAMCBDAwDQYJKoZIhvcNAQEFBQADggEBAIOdEDhOX2kbl02znltd9hCr
|
||||
nV4kRPKm979RKwBNkrEuwYSlcsjAHg5MZ5itH3wFOUo2s5pjt7/vMOAg+6rOBbIa
|
||||
nqr22/gKBtOmuaJLG1yjxDC2vfez7f3B26pKgxa/krM8oxiFdT9n8QbdxdkN7/D9
|
||||
3RLU/aCfgrMzXxRus7eq3kR00jnSs6ggnAfE1E9gric3vFgr1wCzdcriRXmXDfUb
|
||||
hRq+4VG+ZWk16TwCofV5GVU39XWCv5HNO2swAdjkNXgI5e3tQbV3wWLZLqqYzBco
|
||||
iWulAXtoCGmE81+u1Ms7hLLzpXitLZSGPu1r+sDdkKPLCmOvkAaljDQ4nBz7fIA=
|
||||
-----END CERTIFICATE-----
|
27
server/X11/server.key
Normal file
27
server/X11/server.key
Normal file
@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEAq7mxFgRbS2FYJZX7BzpNd4T/n4nEVDBY6YaObLjGpaB1Tptz
|
||||
XTcmfDrDslTGwcEYhTFAC4ZvY6yOURExqbph4LSgvkoa6J722RjVPfshGa4mlh2S
|
||||
XvTiaV26VPPxddGbo6fbs2u029lbtBlpIVbhx5RN9vstNkll26oSZ6wfEdBNHQJL
|
||||
d2SU4ItWHj8zjz1feGxjgChHihUlwcBYKDJsKFkzHZmLrMgB37KsGlXi/WV+eEsj
|
||||
gvz4yP7I3TL8+GsNMjV8fRGVEKTbKSmgunO67d5u+IaqUQb0Ad1ha1jzDQ+a6hdy
|
||||
mrulJSIhoOVfKkwiptTe43FgwxVRIygJP9HjHQIDAQABAoIBAAVv5K54xtc1JtBR
|
||||
1lfdPbSqDlnjx8aOnVIPg5TnqMp3sR8jBt0NsPc/+RA9ZOmfjoIxFAEJaZ9zSDJC
|
||||
5BqmnxC5R1mfCQkSd2haQ+4pdFvWyrv4Bblh8YU6hXrJGn0LfO0KlIcywtAvKpsi
|
||||
LtTyZkWmaW2HeF/+pO32jYygw38R1wd8Tl6GwjOXwTF6lFACJXOT4YAzcfp3FKSB
|
||||
AiKBIGuMzozoSND7KPFNRrhGhNumJpdS5A8Fb8D2c/ZMv6Cq5IbwOgTfKun+Bz+s
|
||||
mFbnzeb1uWRqQbsVXOBBW/zHfuG3SU5qeZsaAyuu4DTy+LE1oAHF9uhBSHuT5C6i
|
||||
vCJ8A8ECgYEA1iaOmiEJYBrs25iAc4SjCKqhY0mwR3wtu3I06vmgUoML5fhPMv36
|
||||
SvYQIqDyNw3p7TE6mZtw9+G+kK3PqhuJhogwSwg0a6o51RdKnhXH3/68oNWtKCLC
|
||||
1AmR8q/Gd3FwAR3b49CuOIZ9uOiJrc/ejzKdFEJTDR1/TX1frWfZznECgYEAzUiz
|
||||
XxFf7YrGel7JgmfRD2eZRYngOoteFlg5Tee42UjeAY2Pt2aiDLk+2TqQEdI9+Xg7
|
||||
LcFdBqcSNd8bh33xSzgNthIkX+lTDzx0SmKGfyxfFBJcY8nzsLvvnNt3YeuMeaJQ
|
||||
CPszwoZ0jcD46jTCjbrKhaLyEWmUkDp1O71NTW0CgYAXKF49Xpsz8FVyvcAOPeaf
|
||||
dkwzf3F3mX8ciRId4taqdY9g1AREgGCDoK5IAF2RBIkqZCtxFvUVaS0BWjpdq9Ko
|
||||
YKvQQVfh2KueVoF0LOjLWTGutsydzXyCD3Lf6pAstHCnPkJcFWHxrOGFkGfrCtKH
|
||||
a7K+0RlIDsuIZqllCBjukQKBgA31+MTpYJW+D1t5IMkumEgs6n6RLt+sZLyuSU9k
|
||||
B+03CGogn3qAj1rAKmcJlYywuKhDpfqpoNL3/8QMJUokpYlRCZWtTC39pzltCheY
|
||||
9b6mXNz3lrLupBUL4vLO9iKBq28GO90wgEelbz3ItuTuq6CJ6IYIG+BVRtY8M4bZ
|
||||
i+1NAoGANXZjYnJYDnh8Je9SDxDSc5byzK7ddkQoId64RCIfNHqNKH63P81vjgnH
|
||||
YBIPtagY75ZVVNxujCF7m8Rety+d8tEFwfQKDin2EVI7PD2rOJra385/izp7HuBR
|
||||
vqxvLzG9Xv3cNOU2l7PttVw4Pa2i5E37atKi3V3Zp2kMW+KaKPQ=
|
||||
-----END RSA PRIVATE KEY-----
|
27
server/X11/xf_encode.c
Normal file
27
server/X11/xf_encode.c
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* X11 RemoteFX Encoder
|
||||
*
|
||||
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "xf_encode.h"
|
||||
|
||||
XImage* xf_snapshot(xfInfo* xfi, int x, int y, int width, int height)
|
||||
{
|
||||
XImage* image;
|
||||
image = XGetImage(xfi->display, RootWindow(xfi->display, xfi->number), x, y, width, height, AllPlanes, ZPixmap);
|
||||
return image;
|
||||
}
|
27
server/X11/xf_encode.h
Normal file
27
server/X11/xf_encode.h
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* X11 RemoteFX Encoder
|
||||
*
|
||||
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __XF_ENCODE_H
|
||||
#define __XF_ENCODE_H
|
||||
|
||||
#include "xfreerdp.h"
|
||||
|
||||
XImage* xf_snapshot(xfInfo* xfi, int x, int y, int width, int height);
|
||||
|
||||
#endif /* __XF_ENCODE_H */
|
372
server/X11/xf_peer.c
Normal file
372
server/X11/xf_peer.c
Normal file
@ -0,0 +1,372 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* X11 Peer
|
||||
*
|
||||
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <freerdp/utils/sleep.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
#include <freerdp/utils/thread.h>
|
||||
#include <freerdp/common/color.h>
|
||||
|
||||
extern char* xf_pcap_file;
|
||||
|
||||
#include "xf_encode.h"
|
||||
|
||||
#include "xf_peer.h"
|
||||
|
||||
void xf_peer_init(freerdp_peer* client)
|
||||
{
|
||||
xfPeer* info;
|
||||
|
||||
info = xnew(xfPeer);
|
||||
|
||||
info->context = rfx_context_new();
|
||||
info->context->mode = RLGR3;
|
||||
info->context->width = client->settings->width;
|
||||
info->context->height = client->settings->height;
|
||||
rfx_context_set_pixel_format(info->context, RFX_PIXEL_FORMAT_RGB);
|
||||
|
||||
info->s = stream_new(65536);
|
||||
|
||||
client->param1 = info;
|
||||
}
|
||||
|
||||
void xf_peer_uninit(freerdp_peer* client)
|
||||
{
|
||||
xfPeer* info = (xfPeer*) client->param1;
|
||||
|
||||
if (info)
|
||||
{
|
||||
stream_free(info->s);
|
||||
rfx_context_free(info->context);
|
||||
xfree(info);
|
||||
}
|
||||
}
|
||||
|
||||
STREAM* xf_peer_stream_init(xfPeer* info)
|
||||
{
|
||||
stream_clear(info->s);
|
||||
stream_set_pos(info->s, 0);
|
||||
return info->s;
|
||||
}
|
||||
|
||||
void xf_peer_live_rfx(freerdp_peer* client)
|
||||
{
|
||||
int x, y;
|
||||
STREAM* s;
|
||||
int width;
|
||||
int height;
|
||||
int wrects;
|
||||
int hrects;
|
||||
int nrects;
|
||||
uint8* data;
|
||||
xfInfo* xfi;
|
||||
xfPeer* xfp;
|
||||
XImage* image;
|
||||
RFX_RECT* rects;
|
||||
uint32 seconds;
|
||||
uint32 useconds;
|
||||
rdpUpdate* update;
|
||||
SURFACE_BITS_COMMAND* cmd;
|
||||
|
||||
seconds = 1;
|
||||
useconds = 0;
|
||||
update = client->update;
|
||||
xfi = (xfInfo*) client->info;
|
||||
xfp = (xfPeer*) client->param1;
|
||||
cmd = &update->surface_bits_command;
|
||||
|
||||
wrects = 16;
|
||||
hrects = 12;
|
||||
|
||||
nrects = wrects * hrects;
|
||||
rects = xmalloc(sizeof(RFX_RECT) * nrects);
|
||||
|
||||
for (y = 0; y < hrects; y++)
|
||||
{
|
||||
for (x = 0; x < wrects; x++)
|
||||
{
|
||||
rects[(y * wrects) + x].x = x * 64;
|
||||
rects[(y * wrects) + x].y = y * 64;
|
||||
rects[(y * wrects) + x].width = 64;
|
||||
rects[(y * wrects) + x].height = 64;
|
||||
}
|
||||
}
|
||||
|
||||
width = wrects * 64;
|
||||
height = hrects * 64;
|
||||
|
||||
data = (uint8*) xmalloc(width * height * 3);
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (seconds > 0)
|
||||
freerdp_sleep(seconds);
|
||||
|
||||
if (useconds > 0)
|
||||
freerdp_usleep(useconds);
|
||||
|
||||
s = xf_peer_stream_init(xfp);
|
||||
|
||||
image = xf_snapshot(xfi, 0, 0, width, height);
|
||||
freerdp_image_convert((uint8*) image->data, data, width, height, 32, 24, xfi->clrconv);
|
||||
rfx_compose_message(xfp->context, s, rects, nrects, data, width, height, 64 * wrects * 3);
|
||||
|
||||
cmd->destLeft = 0;
|
||||
cmd->destTop = 0;
|
||||
cmd->destRight = width;
|
||||
cmd->destBottom = height;
|
||||
cmd->bpp = 32;
|
||||
cmd->codecID = client->settings->rfx_codec_id;
|
||||
cmd->width = width;
|
||||
cmd->height = height;
|
||||
cmd->bitmapDataLength = stream_get_length(s);
|
||||
cmd->bitmapData = stream_get_head(s);
|
||||
update->SurfaceBits(update, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
void xf_peer_dump_rfx(freerdp_peer* client)
|
||||
{
|
||||
STREAM* s;
|
||||
uint32 seconds;
|
||||
uint32 useconds;
|
||||
rdpUpdate* update;
|
||||
rdpPcap* pcap_rfx;
|
||||
pcap_record record;
|
||||
|
||||
s = stream_new(512);
|
||||
update = client->update;
|
||||
client->update->pcap_rfx = pcap_open(xf_pcap_file, False);
|
||||
pcap_rfx = client->update->pcap_rfx;
|
||||
|
||||
seconds = useconds = 0;
|
||||
|
||||
while (pcap_has_next_record(pcap_rfx))
|
||||
{
|
||||
pcap_get_next_record_header(pcap_rfx, &record);
|
||||
|
||||
s->data = xrealloc(s->data, record.length);
|
||||
record.data = s->data;
|
||||
s->size = record.length;
|
||||
|
||||
pcap_get_next_record_content(pcap_rfx, &record);
|
||||
s->p = s->data + s->size;
|
||||
|
||||
seconds = record.header.ts_sec - seconds;
|
||||
useconds = record.header.ts_usec - useconds;
|
||||
|
||||
if (seconds > 0)
|
||||
freerdp_sleep(seconds);
|
||||
|
||||
if (useconds > 0)
|
||||
freerdp_usleep(useconds);
|
||||
|
||||
update->SurfaceCommand(update, s);
|
||||
}
|
||||
}
|
||||
|
||||
boolean xf_peer_post_connect(freerdp_peer* client)
|
||||
{
|
||||
/**
|
||||
* This callback is called when the entire connection sequence is done, i.e. we've received the
|
||||
* Font List PDU from the client and sent out the Font Map PDU.
|
||||
* The server may start sending graphics output and receiving keyboard/mouse input after this
|
||||
* callback returns.
|
||||
*/
|
||||
printf("Client %s is activated", client->settings->hostname);
|
||||
if (client->settings->autologon)
|
||||
{
|
||||
printf(" and wants to login automatically as %s\\%s",
|
||||
client->settings->domain ? client->settings->domain : "",
|
||||
client->settings->username);
|
||||
|
||||
/* A real server may perform OS login here if NLA is not executed previously. */
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("Client requested desktop: %dx%dx%d\n",
|
||||
client->settings->width, client->settings->height, client->settings->color_depth);
|
||||
|
||||
/* A real server should tag the peer as activated here and start sending updates in mainloop. */
|
||||
xf_peer_init(client);
|
||||
|
||||
/* Return False here would stop the execution of the peer mainloop. */
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean xf_peer_activate(freerdp_peer* client)
|
||||
{
|
||||
xfPeer* xfp = (xfPeer*) client->param1;
|
||||
|
||||
rfx_context_reset(xfp->context);
|
||||
xfp->activated = True;
|
||||
|
||||
if (xf_pcap_file != NULL)
|
||||
{
|
||||
client->update->dump_rfx = True;
|
||||
xf_peer_dump_rfx(client);
|
||||
}
|
||||
else
|
||||
{
|
||||
xf_peer_live_rfx(client);
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
void xf_peer_synchronize_event(rdpInput* input, uint32 flags)
|
||||
{
|
||||
printf("Client sent a synchronize event (flags:0x%X)\n", flags);
|
||||
}
|
||||
|
||||
void xf_peer_keyboard_event(rdpInput* input, uint16 flags, uint16 code)
|
||||
{
|
||||
freerdp_peer* client = (freerdp_peer*) input->param1;
|
||||
rdpUpdate* update = client->update;
|
||||
xfPeer* xfp = (xfPeer*) client->param1;
|
||||
|
||||
printf("Client sent a keyboard event (flags:0x%X code:0x%X)\n", flags, code);
|
||||
|
||||
if ((flags & 0x4000) && code == 0x1F) /* 's' key */
|
||||
{
|
||||
if (client->settings->width != 800)
|
||||
{
|
||||
client->settings->width = 800;
|
||||
client->settings->height = 600;
|
||||
}
|
||||
else
|
||||
{
|
||||
client->settings->width = 640;
|
||||
client->settings->height = 480;
|
||||
}
|
||||
update->DesktopResize(update);
|
||||
xfp->activated = False;
|
||||
}
|
||||
}
|
||||
|
||||
void xf_peer_unicode_keyboard_event(rdpInput* input, uint16 code)
|
||||
{
|
||||
printf("Client sent a unicode keyboard event (code:0x%X)\n", code);
|
||||
}
|
||||
|
||||
void xf_peer_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
|
||||
{
|
||||
printf("Client sent a mouse event (flags:0x%X pos:%d,%d)\n", flags, x, y);
|
||||
}
|
||||
|
||||
void xf_peer_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
|
||||
{
|
||||
printf("Client sent an extended mouse event (flags:0x%X pos:%d,%d)\n", flags, x, y);
|
||||
}
|
||||
|
||||
void* xf_peer_main_loop(void* arg)
|
||||
{
|
||||
int i;
|
||||
int fds;
|
||||
int max_fds;
|
||||
int rcount;
|
||||
void* rfds[32];
|
||||
fd_set rfds_set;
|
||||
freerdp_peer* client = (freerdp_peer*) arg;
|
||||
|
||||
memset(rfds, 0, sizeof(rfds));
|
||||
|
||||
printf("We've got a client %s\n", client->settings->hostname);
|
||||
|
||||
/* Initialize the real server settings here */
|
||||
client->settings->cert_file = xstrdup("server.crt");
|
||||
client->settings->privatekey_file = xstrdup("server.key");
|
||||
client->settings->nla_security = False;
|
||||
client->settings->rfx_codec = True;
|
||||
|
||||
client->PostConnect = xf_peer_post_connect;
|
||||
client->Activate = xf_peer_activate;
|
||||
|
||||
client->input->param1 = client;
|
||||
client->input->SynchronizeEvent = xf_peer_synchronize_event;
|
||||
client->input->KeyboardEvent = xf_peer_keyboard_event;
|
||||
client->input->UnicodeKeyboardEvent = xf_peer_unicode_keyboard_event;
|
||||
client->input->MouseEvent = xf_peer_mouse_event;
|
||||
client->input->ExtendedMouseEvent = xf_peer_extended_mouse_event;
|
||||
|
||||
client->Initialize(client);
|
||||
|
||||
while (1)
|
||||
{
|
||||
rcount = 0;
|
||||
|
||||
if (client->GetFileDescriptor(client, rfds, &rcount) != True)
|
||||
{
|
||||
printf("Failed to get FreeRDP file descriptor\n");
|
||||
break;
|
||||
}
|
||||
|
||||
max_fds = 0;
|
||||
FD_ZERO(&rfds_set);
|
||||
|
||||
for (i = 0; i < rcount; i++)
|
||||
{
|
||||
fds = (int)(long)(rfds[i]);
|
||||
|
||||
if (fds > max_fds)
|
||||
max_fds = fds;
|
||||
|
||||
FD_SET(fds, &rfds_set);
|
||||
}
|
||||
|
||||
if (max_fds == 0)
|
||||
break;
|
||||
|
||||
if (select(max_fds + 1, &rfds_set, NULL, NULL, NULL) == -1)
|
||||
{
|
||||
/* these are not really errors */
|
||||
if (!((errno == EAGAIN) ||
|
||||
(errno == EWOULDBLOCK) ||
|
||||
(errno == EINPROGRESS) ||
|
||||
(errno == EINTR))) /* signal occurred */
|
||||
{
|
||||
printf("select failed\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (client->CheckFileDescriptor(client) != True)
|
||||
break;
|
||||
}
|
||||
|
||||
printf("Client %s disconnected.\n", client->settings->hostname);
|
||||
|
||||
client->Disconnect(client);
|
||||
xf_peer_uninit(client);
|
||||
freerdp_peer_free(client);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void xf_peer_accepted(freerdp_listener* instance, freerdp_peer* client)
|
||||
{
|
||||
pthread_t th;
|
||||
|
||||
client->info = instance->info;
|
||||
pthread_create(&th, 0, xf_peer_main_loop, client);
|
||||
pthread_detach(th);
|
||||
}
|
37
server/X11/xf_peer.h
Normal file
37
server/X11/xf_peer.h
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* X11 Peer
|
||||
*
|
||||
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __XF_PEER_H
|
||||
#define __XF_PEER_H
|
||||
|
||||
#include <freerdp/rfx/rfx.h>
|
||||
#include <freerdp/listener.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
|
||||
struct xf_peer_info
|
||||
{
|
||||
STREAM* s;
|
||||
boolean activated;
|
||||
RFX_CONTEXT* context;
|
||||
};
|
||||
typedef struct xf_peer_info xfPeer;
|
||||
|
||||
void xf_peer_accepted(freerdp_listener* instance, freerdp_peer* client);
|
||||
|
||||
#endif /* __XF_PEER_H */
|
192
server/X11/xfreerdp.c
Normal file
192
server/X11/xfreerdp.c
Normal file
@ -0,0 +1,192 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* FreeRDP X11 Server
|
||||
*
|
||||
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <sys/select.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
|
||||
#include "xf_peer.h"
|
||||
#include "xfreerdp.h"
|
||||
|
||||
char* xf_pcap_file = NULL;
|
||||
|
||||
xfInfo* xf_info_init()
|
||||
{
|
||||
int i;
|
||||
xfInfo* xfi;
|
||||
int pf_count;
|
||||
int vi_count;
|
||||
XVisualInfo* vi;
|
||||
XVisualInfo* vis;
|
||||
XVisualInfo template;
|
||||
XPixmapFormatValues* pf;
|
||||
XPixmapFormatValues* pfs;
|
||||
|
||||
xfi = xnew(xfInfo);
|
||||
|
||||
xfi->display = XOpenDisplay(NULL);
|
||||
|
||||
if (xfi->display == NULL)
|
||||
printf("failed to open display: %s\n", XDisplayName(NULL));
|
||||
|
||||
xfi->number = DefaultScreen(xfi->display);
|
||||
xfi->screen = ScreenOfDisplay(xfi->display, xfi->number);
|
||||
xfi->depth = DefaultDepthOfScreen(xfi->screen);
|
||||
xfi->width = WidthOfScreen(xfi->screen);
|
||||
xfi->height = HeightOfScreen(xfi->screen);
|
||||
|
||||
pfs = XListPixmapFormats(xfi->display, &pf_count);
|
||||
|
||||
if (pfs == NULL)
|
||||
{
|
||||
printf("XListPixmapFormats failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i = 0; i < pf_count; i++)
|
||||
{
|
||||
pf = pfs + i;
|
||||
|
||||
if (pf->depth == xfi->depth)
|
||||
{
|
||||
xfi->bpp = pf->bits_per_pixel;
|
||||
xfi->scanline_pad = pf->scanline_pad;
|
||||
break;
|
||||
}
|
||||
}
|
||||
XFree(pfs);
|
||||
|
||||
memset(&template, 0, sizeof(template));
|
||||
template.class = TrueColor;
|
||||
template.screen = xfi->number;
|
||||
|
||||
vis = XGetVisualInfo(xfi->display, VisualClassMask | VisualScreenMask, &template, &vi_count);
|
||||
|
||||
if (vis == NULL)
|
||||
{
|
||||
printf("XGetVisualInfo failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i = 0; i < vi_count; i++)
|
||||
{
|
||||
vi = vis + i;
|
||||
|
||||
if (vi->depth == xfi->depth)
|
||||
{
|
||||
xfi->visual = vi->visual;
|
||||
break;
|
||||
}
|
||||
}
|
||||
XFree(vis);
|
||||
|
||||
xfi->clrconv = (HCLRCONV) xnew(HCLRCONV);
|
||||
xfi->clrconv->invert = 1;
|
||||
xfi->clrconv->alpha = 1;
|
||||
|
||||
return xfi;
|
||||
}
|
||||
|
||||
void xf_server_main_loop(freerdp_listener* instance)
|
||||
{
|
||||
int i;
|
||||
int fds;
|
||||
int max_fds;
|
||||
int rcount;
|
||||
void* rfds[32];
|
||||
fd_set rfds_set;
|
||||
|
||||
memset(rfds, 0, sizeof(rfds));
|
||||
|
||||
while (1)
|
||||
{
|
||||
rcount = 0;
|
||||
|
||||
if (instance->GetFileDescriptor(instance, rfds, &rcount) != True)
|
||||
{
|
||||
printf("Failed to get FreeRDP file descriptor\n");
|
||||
break;
|
||||
}
|
||||
|
||||
max_fds = 0;
|
||||
FD_ZERO(&rfds_set);
|
||||
|
||||
for (i = 0; i < rcount; i++)
|
||||
{
|
||||
fds = (int)(long)(rfds[i]);
|
||||
|
||||
if (fds > max_fds)
|
||||
max_fds = fds;
|
||||
|
||||
FD_SET(fds, &rfds_set);
|
||||
}
|
||||
|
||||
if (max_fds == 0)
|
||||
break;
|
||||
|
||||
if (select(max_fds + 1, &rfds_set, NULL, NULL, NULL) == -1)
|
||||
{
|
||||
/* these are not really errors */
|
||||
if (!((errno == EAGAIN) ||
|
||||
(errno == EWOULDBLOCK) ||
|
||||
(errno == EINPROGRESS) ||
|
||||
(errno == EINTR))) /* signal occurred */
|
||||
{
|
||||
printf("select failed\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (instance->CheckFileDescriptor(instance) != True)
|
||||
{
|
||||
printf("Failed to check FreeRDP file descriptor\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
instance->Close(instance);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
freerdp_listener* instance;
|
||||
|
||||
/* ignore SIGPIPE, otherwise an SSL_write failure could crash the server */
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
instance = freerdp_listener_new();
|
||||
instance->info = (void*) xf_info_init();
|
||||
instance->PeerAccepted = xf_peer_accepted;
|
||||
|
||||
if (argc > 1)
|
||||
xf_pcap_file = argv[1];
|
||||
|
||||
/* Open the server socket and start listening. */
|
||||
if (instance->Open(instance, NULL, 3389))
|
||||
{
|
||||
/* Entering the server main loop. In a real server the listener can be run in its own thread. */
|
||||
xf_server_main_loop(instance);
|
||||
}
|
||||
|
||||
freerdp_listener_free(instance);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
46
server/X11/xfreerdp.h
Normal file
46
server/X11/xfreerdp.h
Normal file
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* FreeRDP X11 Server
|
||||
*
|
||||
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __XFREERDP_H
|
||||
#define __XFREERDP_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <freerdp/common/color.h>
|
||||
|
||||
struct xf_info
|
||||
{
|
||||
int bpp;
|
||||
int depth;
|
||||
int width;
|
||||
int height;
|
||||
int number;
|
||||
XImage* image;
|
||||
Screen* screen;
|
||||
Visual* visual;
|
||||
Display* display;
|
||||
int scanline_pad;
|
||||
HCLRCONV clrconv;
|
||||
};
|
||||
typedef struct xf_info xfInfo;
|
||||
|
||||
#endif /* __XFREERDP_H */
|
@ -17,9 +17,9 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
add_executable(freerdp-server-test
|
||||
freerdp_server.c)
|
||||
add_executable(tfreerdp-server
|
||||
tfreerdp.c)
|
||||
|
||||
target_link_libraries(freerdp-server-test freerdp-core)
|
||||
target_link_libraries(freerdp-server-test freerdp-utils)
|
||||
target_link_libraries(freerdp-server-test freerdp-rfx)
|
||||
target_link_libraries(tfreerdp-server freerdp-core)
|
||||
target_link_libraries(tfreerdp-server freerdp-utils)
|
||||
target_link_libraries(tfreerdp-server freerdp-rfx)
|
||||
|
Binary file not shown.
@ -24,6 +24,7 @@
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
#include <freerdp/constants.h>
|
||||
#include <freerdp/utils/sleep.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
@ -238,7 +239,7 @@ static void test_peer_draw_icon(freerdp_peer* client, int x, int y)
|
||||
info->icon_y = y;
|
||||
}
|
||||
|
||||
void test_peer_dump_rfx(freerdp_peer* client)
|
||||
void tf_peer_dump_rfx(freerdp_peer* client)
|
||||
{
|
||||
STREAM* s;
|
||||
uint32 seconds;
|
||||
@ -278,7 +279,7 @@ void test_peer_dump_rfx(freerdp_peer* client)
|
||||
}
|
||||
}
|
||||
|
||||
boolean test_peer_post_connect(freerdp_peer* client)
|
||||
boolean tf_peer_post_connect(freerdp_peer* client)
|
||||
{
|
||||
/**
|
||||
* This callback is called when the entire connection sequence is done, i.e. we've received the
|
||||
@ -308,7 +309,7 @@ boolean test_peer_post_connect(freerdp_peer* client)
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean test_peer_activate(freerdp_peer* client)
|
||||
boolean tf_peer_activate(freerdp_peer* client)
|
||||
{
|
||||
testPeerInfo* info = (testPeerInfo*)client->param1;
|
||||
|
||||
@ -318,7 +319,7 @@ boolean test_peer_activate(freerdp_peer* client)
|
||||
if (test_pcap_file != NULL)
|
||||
{
|
||||
client->update->dump_rfx = True;
|
||||
test_peer_dump_rfx(client);
|
||||
tf_peer_dump_rfx(client);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -328,12 +329,12 @@ boolean test_peer_activate(freerdp_peer* client)
|
||||
return True;
|
||||
}
|
||||
|
||||
void test_peer_synchronize_event(rdpInput* input, uint32 flags)
|
||||
void tf_peer_synchronize_event(rdpInput* input, uint32 flags)
|
||||
{
|
||||
printf("Client sent a synchronize event (flags:0x%X)\n", flags);
|
||||
}
|
||||
|
||||
void test_peer_keyboard_event(rdpInput* input, uint16 flags, uint16 code)
|
||||
void tf_peer_keyboard_event(rdpInput* input, uint16 flags, uint16 code)
|
||||
{
|
||||
freerdp_peer* client = (freerdp_peer*) input->param1;
|
||||
rdpUpdate* update = client->update;
|
||||
@ -358,19 +359,19 @@ void test_peer_keyboard_event(rdpInput* input, uint16 flags, uint16 code)
|
||||
}
|
||||
}
|
||||
|
||||
void test_peer_unicode_keyboard_event(rdpInput* input, uint16 code)
|
||||
void tf_peer_unicode_keyboard_event(rdpInput* input, uint16 code)
|
||||
{
|
||||
printf("Client sent a unicode keyboard event (code:0x%X)\n", code);
|
||||
}
|
||||
|
||||
void test_peer_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
|
||||
void tf_peer_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
|
||||
{
|
||||
printf("Client sent a mouse event (flags:0x%X pos:%d,%d)\n", flags, x, y);
|
||||
|
||||
test_peer_draw_icon(input->param1, x + 10, y);
|
||||
}
|
||||
|
||||
void test_peer_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
|
||||
void tf_peer_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
|
||||
{
|
||||
printf("Client sent an extended mouse event (flags:0x%X pos:%d,%d)\n", flags, x, y);
|
||||
}
|
||||
@ -395,15 +396,15 @@ static void* test_peer_mainloop(void* arg)
|
||||
client->settings->nla_security = False;
|
||||
client->settings->rfx_codec = True;
|
||||
|
||||
client->PostConnect = test_peer_post_connect;
|
||||
client->Activate = test_peer_activate;
|
||||
client->PostConnect = tf_peer_post_connect;
|
||||
client->Activate = tf_peer_activate;
|
||||
|
||||
client->input->param1 = client;
|
||||
client->input->SynchronizeEvent = test_peer_synchronize_event;
|
||||
client->input->KeyboardEvent = test_peer_keyboard_event;
|
||||
client->input->UnicodeKeyboardEvent = test_peer_unicode_keyboard_event;
|
||||
client->input->MouseEvent = test_peer_mouse_event;
|
||||
client->input->ExtendedMouseEvent = test_peer_extended_mouse_event;
|
||||
client->input->SynchronizeEvent = tf_peer_synchronize_event;
|
||||
client->input->KeyboardEvent = tf_peer_keyboard_event;
|
||||
client->input->UnicodeKeyboardEvent = tf_peer_unicode_keyboard_event;
|
||||
client->input->MouseEvent = tf_peer_mouse_event;
|
||||
client->input->ExtendedMouseEvent = tf_peer_extended_mouse_event;
|
||||
|
||||
client->Initialize(client);
|
||||
|
Loading…
Reference in New Issue
Block a user