This commit is contained in:
C-o-r-E 2013-02-15 19:52:51 -05:00
commit 26989e0cd2
117 changed files with 6245 additions and 1249 deletions

View File

@ -208,6 +208,7 @@ if(NOT ANDROID)
endif()
if(UNIX OR CYGWIN)
check_include_files(sys/eventfd.h HAVE_EVENTFD_H)
set(X11_FEATURE_TYPE "RECOMMENDED")
else()
set(X11_FEATURE_TYPE "DISABLED")

View File

@ -46,11 +46,11 @@ foreach(STATIC_ENTRY ${CHANNEL_STATIC_CLIENT_ENTRIES})
set(CLIENT_STATIC_ENTRY_IMPORTS "${CLIENT_STATIC_ENTRY_IMPORTS}\n${${STATIC_ENTRY}_IMPORTS}")
set(CLIENT_STATIC_ENTRY_TABLES "${CLIENT_STATIC_ENTRY_TABLES}\nconst STATIC_ENTRY CLIENT_${STATIC_ENTRY}_TABLE[] =\n{")
set(CLIENT_STATIC_ENTRY_TABLES "${CLIENT_STATIC_ENTRY_TABLES}\n${${STATIC_ENTRY}_TABLE}")
set(CLIENT_STATIC_ENTRY_TABLES "${CLIENT_STATIC_ENTRY_TABLES}\n\t{ \"\", NULL }\n};")
set(CLIENT_STATIC_ENTRY_TABLES "${CLIENT_STATIC_ENTRY_TABLES}\n\t{ NULL, NULL }\n};")
set(CLIENT_STATIC_ENTRY_TABLES_LIST "${CLIENT_STATIC_ENTRY_TABLES_LIST}\n\t{ \"${STATIC_ENTRY}\", CLIENT_${STATIC_ENTRY}_TABLE },")
endforeach()
set(CLIENT_STATIC_ENTRY_TABLES_LIST "${CLIENT_STATIC_ENTRY_TABLES_LIST}\n\t{ \"\", NULL }\n};")
set(CLIENT_STATIC_ENTRY_TABLES_LIST "${CLIENT_STATIC_ENTRY_TABLES_LIST}\n\t{ NULL, NULL }\n};")
set(CLIENT_STATIC_ADDIN_TABLE "const STATIC_ADDIN_TABLE CLIENT_STATIC_ADDIN_TABLE[] =\n{")
foreach(STATIC_MODULE ${CHANNEL_STATIC_CLIENT_MODULES})

View File

@ -358,7 +358,9 @@ void* freerdp_channels_load_static_addin_entry(LPCSTR pszName, LPSTR pszSubsyste
}
}
else
{
return (void*) CLIENT_STATIC_ADDIN_TABLE[i].entry;
}
}
}
@ -1275,6 +1277,32 @@ BOOL freerdp_channels_get_fds(rdpChannels* channels, freerdp* instance, void** r
return TRUE;
}
HANDLE freerdp_channels_get_event_handle(freerdp* instance)
{
HANDLE event = NULL;
rdpChannels* channels;
channels = instance->context->channels;
event = channels->signal;
return event;
}
int freerdp_channels_process_pending_messages(freerdp* instance)
{
rdpChannels* channels;
channels = instance->context->channels;
if (WaitForSingleObject(channels->signal, 0) == WAIT_OBJECT_0)
{
ResetEvent(channels->signal);
freerdp_channels_process_sync(channels, instance);
}
return TRUE;
}
/**
* called only from main thread
*/

View File

@ -469,6 +469,24 @@ static void drive_process_irp_query_volume_information(DRIVE_DEVICE* disk, IRP*
irp->Complete(irp);
}
/* http://msdn.microsoft.com/en-us/library/cc241518.aspx */
static void drive_process_irp_silent_ignore(DRIVE_DEVICE* disk, IRP* irp)
{
UINT32 FsInformationClass;
UINT32 pad;
STREAM* output = irp->output;
char* volumeLabel;
int length;
int status;
stream_read_UINT32(irp->input, FsInformationClass);
DEBUG_SVC("FsInformationClass %d in drive_process_irp_silent_ignore", FsInformationClass);
stream_write_UINT32(output, 0); /* Length */
irp->Complete(irp);
}
static void drive_process_irp_query_directory(DRIVE_DEVICE* disk, IRP* irp)
{
char* path = NULL;
@ -568,6 +586,11 @@ static void drive_process_irp(DRIVE_DEVICE* disk, IRP* irp)
drive_process_irp_query_volume_information(disk, irp);
break;
case IRP_MJ_LOCK_CONTROL :
DEBUG_WARN("MajorFunction IRP_MJ_LOCK_CONTROL silent ignored");
drive_process_irp_silent_ignore(disk, irp);
break;
case IRP_MJ_DIRECTORY_CONTROL:
drive_process_irp_directory_control(disk, irp);
break;

View File

@ -336,17 +336,18 @@ static void serial_process_irp_list(SERIAL_DEVICE* serial)
static void* serial_thread_func(void* arg)
{
DWORD status;
SERIAL_DEVICE* serial = (SERIAL_DEVICE*)arg;
while (1)
{
freerdp_thread_wait(serial->thread);
freerdp_thread_wait_timeout(serial->thread, 500);
serial->nfds = 1;
FD_ZERO(&serial->read_fds);
FD_ZERO(&serial->write_fds);
serial->tv.tv_sec = 20;
serial->tv.tv_sec = 1;
serial->tv.tv_usec = 0;
serial->select_timeout = 0;
@ -356,10 +357,12 @@ static void* serial_thread_func(void* arg)
freerdp_thread_reset(serial->thread);
serial_process_irp_list(serial);
if (WaitForSingleObject(serial->in_event, 0) == WAIT_OBJECT_0)
status = WaitForSingleObject(serial->in_event, 0);
if ((status == WAIT_OBJECT_0) || (status == WAIT_TIMEOUT))
{
if (serial_check_fds(serial))
ResetEvent(serial->in_event);
if (serial_check_fds(serial))
ResetEvent(serial->in_event);
}
}
@ -370,7 +373,7 @@ static void* serial_thread_func(void* arg)
static void serial_irp_request(DEVICE* device, IRP* irp)
{
SERIAL_DEVICE* serial = (SERIAL_DEVICE*)device;
SERIAL_DEVICE* serial = (SERIAL_DEVICE*) device;
freerdp_thread_lock(serial->thread);
list_enqueue(serial->irp_list, irp);
@ -536,14 +539,14 @@ static void serial_handle_async_irp(SERIAL_DEVICE* serial, IRP* irp)
serial_get_timeouts(serial, irp, &timeout, &itv_timeout);
/* Check if io request timeout is smaller than current (but not 0). */
if (timeout && (serial->select_timeout == 0 || timeout < serial->select_timeout))
if (timeout && ((serial->select_timeout == 0) || (timeout < serial->select_timeout)))
{
serial->select_timeout = timeout;
serial->tv.tv_sec = serial->select_timeout / 1000;
serial->tv.tv_usec = (serial->select_timeout % 1000) * 1000;
serial->timeout_id = tty->id;
}
if (itv_timeout && (serial->select_timeout == 0 || itv_timeout < serial->select_timeout))
if (itv_timeout && ((serial->select_timeout == 0) || (itv_timeout < serial->select_timeout)))
{
serial->select_timeout = itv_timeout;
serial->tv.tv_sec = serial->select_timeout / 1000;
@ -572,7 +575,7 @@ static void __serial_check_fds(SERIAL_DEVICE* serial)
UINT32 result = 0;
BOOL irp_completed = FALSE;
memset(&serial->tv, 0, sizeof(struct timeval));
ZeroMemory(&serial->tv, sizeof(struct timeval));
tty = serial->tty;
/* scan every pending */
@ -683,6 +686,7 @@ static BOOL serial_check_fds(SERIAL_DEVICE* serial)
case 0:
if (serial->select_timeout)
{
__serial_check_fds(serial);
serial_abort_single_io(serial, serial->timeout_id, SERIAL_ABORT_IO_NONE, STATUS_TIMEOUT);
serial_abort_single_io(serial, serial->timeout_id, SERIAL_ABORT_IO_READ, STATUS_TIMEOUT);
serial_abort_single_io(serial, serial->timeout_id, SERIAL_ABORT_IO_WRITE, STATUS_TIMEOUT);

View File

@ -64,11 +64,12 @@
#define CRTSCTS 0
#endif
/* FIONREAD should really do the same thing as TIOCINQ, where it is
* not available */
/* FIONREAD should really do the same thing as TIOCINQ, where it is not available */
#if !defined(TIOCINQ) && defined(FIONREAD)
#define TIOCINQ FIONREAD
#endif
#if !defined(TIOCOUTQ) && defined(FIONWRITE)
#define TIOCOUTQ FIONWRITE
#endif
@ -371,9 +372,9 @@ UINT32 serial_tty_control(SERIAL_TTY* tty, UINT32 IoControlCode, STREAM* input,
BOOL serial_tty_read(SERIAL_TTY* tty, BYTE* buffer, UINT32* Length)
{
ssize_t r;
long timeout = 90;
struct termios *ptermios;
ssize_t r;
DEBUG_SVC("in");
ptermios = tty->ptermios;
@ -407,8 +408,10 @@ BOOL serial_tty_read(SERIAL_TTY* tty, BYTE* buffer, UINT32* Length)
tcsetattr(tty->fd, TCSANOW, ptermios);
memset(buffer, 0, *Length);
ZeroMemory(buffer, *Length);
r = read(tty->fd, buffer, *Length);
if (r < 0)
return FALSE;
@ -420,20 +423,24 @@ BOOL serial_tty_read(SERIAL_TTY* tty, BYTE* buffer, UINT32* Length)
BOOL serial_tty_write(SERIAL_TTY* tty, BYTE* buffer, UINT32 Length)
{
ssize_t r;
ssize_t status;
UINT32 event_txempty = Length;
DEBUG_SVC("in");
while (Length > 0)
{
r = write(tty->fd, buffer, Length);
if (r < 0)
return FALSE;
status = write(tty->fd, buffer, Length);
Length -= r;
buffer += r;
if (status < 0)
{
return FALSE;
}
Length -= status;
buffer += status;
}
tty->event_txempty = event_txempty;
return TRUE;
@ -454,6 +461,7 @@ void serial_tty_free(SERIAL_TTY* tty)
{
if (tty->pold_termios)
tcsetattr(tty->fd, TCSANOW, tty->pold_termios);
close(tty->fd);
}
@ -462,7 +470,6 @@ void serial_tty_free(SERIAL_TTY* tty)
free(tty);
}
SERIAL_TTY* serial_tty_new(const char* path, UINT32 id)
{
SERIAL_TTY* tty;
@ -567,6 +574,7 @@ BOOL serial_tty_get_event(SERIAL_TTY* tty, UINT32* result)
if (bytes > tty->event_rlsd)
{
tty->event_rlsd = bytes;
if (tty->wait_mask & SERIAL_EV_RLSD)
{
DEBUG_SVC("SERIAL_EV_RLSD");
@ -582,6 +590,7 @@ BOOL serial_tty_get_event(SERIAL_TTY* tty, UINT32* result)
*result |= SERIAL_EV_RXFLAG;
ret = TRUE;
}
if ((tty->wait_mask & SERIAL_EV_RXCHAR))
{
DEBUG_SVC("SERIAL_EV_RXCHAR bytes %d", bytes);
@ -598,8 +607,7 @@ BOOL serial_tty_get_event(SERIAL_TTY* tty, UINT32* result)
#ifdef TIOCOUTQ
ioctl(tty->fd, TIOCOUTQ, &bytes);
if ((bytes == 0)
&& (tty->event_txempty > 0) && (tty->wait_mask & SERIAL_EV_TXEMPTY))
if ((bytes == 0) && (tty->event_txempty > 0) && (tty->wait_mask & SERIAL_EV_TXEMPTY))
{
DEBUG_SVC("SERIAL_EV_TXEMPTY");
*result |= SERIAL_EV_TXEMPTY;
@ -640,14 +648,16 @@ BOOL serial_tty_get_event(SERIAL_TTY* tty, UINT32* result)
static BOOL tty_get_termios(SERIAL_TTY* tty)
{
speed_t speed;
struct termios *ptermios;
struct termios* ptermios;
ptermios = tty->ptermios;
DEBUG_SVC("tcgetattr? %d", tcgetattr(tty->fd, ptermios) >= 0);
if (tcgetattr(tty->fd, ptermios) < 0)
return FALSE;
speed = cfgetispeed(ptermios);
switch (speed)
{
#ifdef B75
@ -773,6 +783,7 @@ static BOOL tty_get_termios(SERIAL_TTY* tty)
}
tty->xonoff = SERIAL_DSR_SENSITIVITY;
if (ptermios->c_iflag & IXON)
tty->xonoff |= SERIAL_XON_HANDSHAKE;
@ -898,11 +909,13 @@ static void tty_set_termios(SERIAL_TTY* tty)
#endif
ptermios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE | CRTSCTS);
switch (tty->stop_bits)
{
case SERIAL_STOP_BITS_2:
ptermios->c_cflag |= CSTOPB;
break;
default:
ptermios->c_cflag &= ~CSTOPB;
break;
@ -913,9 +926,11 @@ static void tty_set_termios(SERIAL_TTY* tty)
case SERIAL_EVEN_PARITY:
ptermios->c_cflag |= PARENB;
break;
case SERIAL_ODD_PARITY:
ptermios->c_cflag |= PARENB | PARODD;
break;
case SERIAL_NO_PARITY:
ptermios->c_cflag &= ~(PARENB | PARODD);
break;
@ -980,16 +995,16 @@ static void tty_set_termios(SERIAL_TTY* tty)
static UINT32 tty_write_data(SERIAL_TTY* tty, BYTE* data, int len)
{
ssize_t r;
ssize_t status;
DEBUG_SVC("in");
r = write(tty->fd, data, len);
status = write(tty->fd, data, len);
if (r < 0)
if (status < 0)
return tty_get_error_status();
tty->event_txempty = r;
tty->event_txempty = status;
return STATUS_SUCCESS;
}

View File

@ -32,9 +32,18 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
MODULE freerdp
MODULES freerdp-utils)
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${FFMPEG_LIBRARIES})
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
if(APPLE)
# For this to work on apple, we need to add some frameworks
FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation )
FIND_LIBRARY(COREVIDEO_LIBRARY CoreVideo )
FIND_LIBRARY(COREVIDEODECODE_LIBRARY VideoDecodeAcceleration )
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${FFMPEG_LIBRARIES} ${COREFOUNDATION_LIBRARY} ${COREVIDEO_LIBRARY} ${COREVIDEODECODE_LIBRARY} )
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
else()
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${FFMPEG_LIBRARIES})
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
endif()
if(NOT STATIC_CHANNELS)
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})

View File

@ -12,12 +12,12 @@
<uses-permission android:name="com.android.vending.BILLING" />
<supports-screens android:anyDensity="true" android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" />
<application android:name=".application.GlobalApp"
<application android:name="com.freerdp.afreerdp.application.GlobalApp"
android:label="aFreeRDP"
android:icon="@drawable/icon_launcher_freerdp" >
<!-- Main activity -->
<activity android:name=".presentation.HomeActivity"
<activity android:name="com.freerdp.afreerdp.presentation.HomeActivity"
android:label="@string/app_title"
android:theme="@style/Theme.Main"
android:alwaysRetainTaskState="true"
@ -34,7 +34,7 @@
android:excludeFromRecents="true" android:finishOnTaskLaunch="true" />
<!-- Session request handler activity - used for search and internally to start sessions -->
<activity android:name=".services.SessionRequestHandlerActivity"
<activity android:name="com.freerdp.afreerdp.services.SessionRequestHandlerActivity"
android:theme="@android:style/Theme.NoDisplay"
android:noHistory="true"
android:excludeFromRecents="true">
@ -46,7 +46,7 @@
</activity>
<!-- Activity to create shortcuts -->
<activity android:name=".presentation.ShortcutsActivity"
<activity android:name="com.freerdp.afreerdp.presentation.ShortcutsActivity"
android:theme="@style/Theme.Main"
android:label="@string/title_create_shortcut">
<intent-filter>
@ -59,8 +59,8 @@
<!-- It is recommended that you use an activity-alias to provide the "CREATE_SHORTCUT" -->
<!-- intent-filter. This gives you a way to set the text (and optionally the -->
<!-- icon) that will be seen in the launcher's create-shortcut user interface. -->
<activity-alias android:name=".presentation.CreateShortcuts"
android:targetActivity=".presentation.ShortcutsActivity"
<activity-alias android:name="com.freerdp.afreerdp.presentation.CreateShortcuts"
android:targetActivity="com.freerdp.afreerdp.presentation.ShortcutsActivity"
android:label="@string/title_create_shortcut">
<!-- This intent-filter allows your shortcuts to be created in the launcher. -->
<intent-filter>
@ -69,35 +69,35 @@
</intent-filter>
</activity-alias>
<activity android:name=".presentation.BookmarkActivity"
<activity android:name="com.freerdp.afreerdp.presentation.BookmarkActivity"
android:label="@string/title_bookmark_settings"
android:theme="@style/Theme.Settings">
</activity>
<activity android:name=".presentation.ApplicationSettingsActivity"
<activity android:name="com.freerdp.afreerdp.presentation.ApplicationSettingsActivity"
android:label="@string/title_application_settings"
android:theme="@style/Theme.Settings"
android:windowSoftInputMode="stateHidden">
</activity>
<activity android:name=".presentation.SessionActivity"
<activity android:name="com.freerdp.afreerdp.presentation.SessionActivity"
android:theme="@android:style/Theme.Black.NoTitleBar"
android:configChanges="orientation|keyboardHidden|keyboard"
android:windowSoftInputMode="adjustResize">
</activity>
<activity android:name=".presentation.AboutActivity"
<activity android:name="com.freerdp.afreerdp.presentation.AboutActivity"
android:label="@string/title_about"
android:theme="@style/Theme.Main">
</activity>
<activity android:name=".presentation.HelpActivity"
<activity android:name="com.freerdp.afreerdp.presentation.HelpActivity"
android:label="@string/title_help"
android:theme="@style/Theme.Main">
</activity>
<provider android:name=".services.FreeRDPSuggestionProvider"
<provider android:name="com.freerdp.afreerdp.services.FreeRDPSuggestionProvider"
android:authorities="com.freerdp.afreerdp.services.freerdpsuggestionprovider"
>
</provider>
<receiver android:name=".application.NetworkStateReceiver" android:enabled="true">
<receiver android:name="com.freerdp.afreerdp.application.NetworkStateReceiver" android:enabled="true">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>

View File

@ -21,6 +21,7 @@ public class BookmarkBase implements Parcelable, Cloneable
public static final int TYPE_MANUAL = 1;
public static final int TYPE_QUICKCONNECT = 2;
public static final int TYPE_PLACEHOLDER = 3;
public static final int TYPE_CUSTOM_BASE = 1000;
// performance flags
public static class PerformanceFlags implements Parcelable

View File

@ -18,13 +18,14 @@ import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.util.Log;
public abstract class BookmarkBaseGateway
{
private final static String TAG = "BookmarkBaseGateway";
private BookmarkDB bookmarkDB;
private SQLiteOpenHelper bookmarkDB;
protected abstract BookmarkBase createBookmark();
protected abstract String getBookmarkTableName();
@ -32,7 +33,7 @@ public abstract class BookmarkBaseGateway
protected abstract void addBookmarkSpecificColumns(BookmarkBase bookmark, ContentValues columns);
protected abstract void readBookmarkSpecificColumns(BookmarkBase bookmark, Cursor cursor);
public BookmarkBaseGateway(BookmarkDB bookmarkDB)
public BookmarkBaseGateway(SQLiteOpenHelper bookmarkDB)
{
this.bookmarkDB = bookmarkDB;
}

View File

@ -84,7 +84,7 @@ public class FreeRDPSuggestionProvider extends ContentProvider {
row[1] = bookmark.getLabel();
row[2] = bookmark.<ManualBookmark>get().getHostname();
row[3] = ConnectionReference.getManualBookmarkReference(bookmark.getId());
row[4] = "android.resource://com.freerdp.afreerdp/" + R.drawable.icon_star_on;
row[4] = "android.resource://" + getContext().getPackageName() + "/" + R.drawable.icon_star_on;
resultCursor.addRow(row);
}
}
@ -97,7 +97,7 @@ public class FreeRDPSuggestionProvider extends ContentProvider {
row[1] = bookmark.getLabel();
row[2] = bookmark.getLabel();
row[3] = ConnectionReference.getHostnameReference(bookmark.getLabel());
row[4] = "android.resource://com.freerdp.afreerdp/" + R.drawable.icon_star_off;
row[4] = "android.resource://" + getContext().getPackageName() + "/" + R.drawable.icon_star_off;
resultCursor.addRow(row);
}
}

View File

@ -13,13 +13,14 @@ import java.util.ArrayList;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteOpenHelper;
import com.freerdp.afreerdp.domain.BookmarkBase;
import com.freerdp.afreerdp.domain.ManualBookmark;
public class ManualBookmarkGateway extends BookmarkBaseGateway {
public ManualBookmarkGateway(BookmarkDB bookmarkDB) {
public ManualBookmarkGateway(SQLiteOpenHelper bookmarkDB) {
super(bookmarkDB);
}

View File

@ -18,15 +18,16 @@ import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class QuickConnectHistoryGateway {
private final static String TAG = "QuickConnectHistoryGateway";
private HistoryDB historyDB;
private SQLiteOpenHelper historyDB;
public QuickConnectHistoryGateway(HistoryDB historyDB)
public QuickConnectHistoryGateway(SQLiteOpenHelper historyDB)
{
this.historyDB = historyDB;
}

View File

@ -358,7 +358,7 @@ static BOOL xf_event_KeyRelease(xfInfo* xfi, XEvent* event, BOOL app)
if (XPending(xfi->display))
{
memset(&next_event, 0, sizeof(next_event));
ZeroMemory(&next_event, sizeof(next_event));
XPeekEvent(xfi->display, &next_event);
if (next_event.type == KeyPress)

View File

@ -33,6 +33,16 @@
#include "xf_gdi.h"
static UINT8 GDI_BS_HACHTED_PATTERNS[] =
{
0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, /* HS_HORIZONTAL */
0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, /* HS_VERTICAL */
0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F, /* HS_FDIAGONAL */
0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE, /* HS_BDIAGONAL */
0xF7, 0xF7, 0xF7, 0x00, 0xF7, 0xF7, 0xF7, 0xF7, /* HS_CROSS */
0x7E, 0xBD, 0xDB, 0xE7, 0xE7, 0xDB, 0xBD, 0x7E /* HS_DIACROSS */
};
static const BYTE xf_rop2_table[] =
{
0,
@ -253,34 +263,15 @@ Pixmap xf_mono_bitmap_new(xfInfo* xfi, int width, int height, BYTE* data)
return bitmap;
}
Pixmap xf_glyph_new(xfInfo* xfi, int width, int height, BYTE* data)
{
int scanline;
Pixmap bitmap;
XImage* image;
scanline = (width + 7) / 8;
bitmap = XCreatePixmap(xfi->display, xfi->drawable, width, height, 1);
image = XCreateImage(xfi->display, xfi->visual, 1,
ZPixmap, 0, (char*) data, width, height, 8, scanline);
image->byte_order = MSBFirst;
image->bitmap_bit_order = MSBFirst;
XInitImage(image);
XPutImage(xfi->display, bitmap, xfi->gc_mono, image, 0, 0, 0, 0, width, height);
XFree(image);
return bitmap;
}
void xf_gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
xfi->clrconv->palette->count = palette->number;
xfi->clrconv->palette->entries = palette->entries;
WaitForSingleObject(xfi->mutex, INFINITE);
CopyMemory(xfi->clrconv->palette, palette, sizeof(rdpPalette));
ReleaseMutex(xfi->mutex);
}
void xf_gdi_set_bounds(rdpContext* context, rdpBounds* bounds)
@ -288,6 +279,8 @@ void xf_gdi_set_bounds(rdpContext* context, rdpBounds* bounds)
XRectangle clip;
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
if (bounds != NULL)
{
clip.x = bounds->left;
@ -300,12 +293,16 @@ void xf_gdi_set_bounds(rdpContext* context, rdpBounds* bounds)
{
XSetClipMask(xfi->display, xfi->gc, None);
}
ReleaseMutex(xfi->mutex);
}
void xf_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_set_rop3(xfi, gdi_rop3_code(dstblt->bRop));
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
@ -323,7 +320,10 @@ void xf_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt)
gdi_InvalidateRegion(xfi->hdc, dstblt->nLeftRect, dstblt->nTopRect, dstblt->nWidth, dstblt->nHeight);
}
XSetFunction(xfi->display, xfi->gc, GXcopy);
ReleaseMutex(xfi->mutex);
}
void xf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
@ -335,11 +335,13 @@ void xf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
brush = &patblt->brush;
xf_set_rop3(xfi, gdi_rop3_code(patblt->bRop));
foreColor = freerdp_color_convert_rgb(patblt->foreColor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
backColor = freerdp_color_convert_rgb(patblt->backColor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
foreColor = freerdp_color_convert_var(patblt->foreColor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
backColor = freerdp_color_convert_var(patblt->backColor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
if (brush->style == GDI_BS_SOLID)
{
@ -349,6 +351,21 @@ void xf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
XFillRectangle(xfi->display, xfi->drawing, xfi->gc,
patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight);
}
else if (brush->style == GDI_BS_HATCHED)
{
pattern = xf_mono_bitmap_new(xfi, 8, 8, GDI_BS_HACHTED_PATTERNS + 8 * brush->hatch);
XSetForeground(xfi->display, xfi->gc, backColor);
XSetBackground(xfi->display, xfi->gc, foreColor);
XSetFillStyle(xfi->display, xfi->gc, FillOpaqueStippled);
XSetStipple(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);
XFreePixmap(xfi->display, pattern);
}
else if (brush->style == GDI_BS_PATTERN)
{
if (brush->bpp > 1)
@ -401,12 +418,16 @@ void xf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
}
XSetFunction(xfi->display, xfi->gc, GXcopy);
ReleaseMutex(xfi->mutex);
}
void xf_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_set_rop3(xfi, gdi_rop3_code(scrblt->bRop));
XCopyArea(xfi->display, xfi->primary, xfi->drawing, xfi->gc, scrblt->nXSrc, scrblt->nYSrc,
@ -435,6 +456,8 @@ void xf_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt)
}
XSetFunction(xfi->display, xfi->gc, GXcopy);
ReleaseMutex(xfi->mutex);
}
void xf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect)
@ -443,6 +466,8 @@ void xf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect)
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
color = freerdp_color_convert_var(opaque_rect->color, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
XSetFunction(xfi->display, xfi->gc, GXcopy);
@ -464,6 +489,8 @@ void xf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect)
gdi_InvalidateRegion(xfi->hdc, opaque_rect->nLeftRect, opaque_rect->nTopRect,
opaque_rect->nWidth, opaque_rect->nHeight);
}
ReleaseMutex(xfi->mutex);
}
void xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect)
@ -474,6 +501,8 @@ void xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* mult
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
color = freerdp_color_convert_var(multi_opaque_rect->color, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
XSetFunction(xfi->display, xfi->gc, GXcopy);
@ -499,6 +528,8 @@ void xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* mult
gdi_InvalidateRegion(xfi->hdc, rectangle->left, rectangle->top, rectangle->width, rectangle->height);
}
}
ReleaseMutex(xfi->mutex);
}
void xf_gdi_draw_nine_grid(rdpContext* context, DRAW_NINE_GRID_ORDER* draw_nine_grid)
@ -512,8 +543,10 @@ void xf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to)
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_set_rop2(xfi, line_to->bRop2);
color = freerdp_color_convert_rgb(line_to->penColor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
color = freerdp_color_convert_var(line_to->penColor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
XSetForeground(xfi->display, xfi->gc, color);
@ -545,6 +578,8 @@ void xf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to)
}
XSetFunction(xfi->display, xfi->gc, GXcopy);
ReleaseMutex(xfi->mutex);
}
void xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline)
@ -560,6 +595,8 @@ void xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline)
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_set_rop2(xfi, polyline->bRop2);
color = freerdp_color_convert_var(polyline->penColor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
@ -608,6 +645,8 @@ void xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline)
XSetFunction(xfi->display, xfi->gc, GXcopy);
free(points);
ReleaseMutex(xfi->mutex);
}
void xf_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
@ -615,6 +654,8 @@ void xf_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
xfBitmap* bitmap;
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
bitmap = (xfBitmap*) memblt->bitmap;
xf_set_rop3(xfi, gdi_rop3_code(memblt->bRop));
@ -635,6 +676,8 @@ void xf_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
}
XSetFunction(xfi->display, xfi->gc, GXcopy);
ReleaseMutex(xfi->mutex);
}
void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
@ -647,11 +690,13 @@ void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
brush = &mem3blt->brush;
bitmap = (xfBitmap*) mem3blt->bitmap;
xf_set_rop3(xfi, gdi_rop3_code(mem3blt->bRop));
foreColor = freerdp_color_convert_rgb(mem3blt->foreColor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
backColor = freerdp_color_convert_rgb(mem3blt->backColor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
foreColor = freerdp_color_convert_var(mem3blt->foreColor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
backColor = freerdp_color_convert_var(mem3blt->backColor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
if (brush->style == GDI_BS_PATTERN)
{
@ -710,6 +755,8 @@ void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
XFreePixmap(xfi->display, pattern);
XSetFunction(xfi->display, xfi->gc, GXcopy);
ReleaseMutex(xfi->mutex);
}
void xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
@ -719,6 +766,8 @@ void xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
UINT32 brush_color;
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_set_rop2(xfi, polygon_sc->bRop2);
brush_color = freerdp_color_convert_var(polygon_sc->brushColor, ((xfContext*)context)->settings->ColorDepth, xfi->bpp, xfi->clrconv);
@ -763,6 +812,8 @@ void xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
XSetFunction(xfi->display, xfi->gc, GXcopy);
free(points);
ReleaseMutex(xfi->mutex);
}
void xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
@ -775,10 +826,12 @@ void xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
UINT32 backColor;
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
brush = &(polygon_cb->brush);
xf_set_rop2(xfi, polygon_cb->bRop2);
foreColor = freerdp_color_convert_rgb(polygon_cb->foreColor, ((xfContext*) context)->settings->ColorDepth, xfi->bpp, xfi->clrconv);
backColor = freerdp_color_convert_rgb(polygon_cb->backColor, ((xfContext*) context)->settings->ColorDepth, xfi->bpp, xfi->clrconv);
foreColor = freerdp_color_convert_var(polygon_cb->foreColor, ((xfContext*) context)->settings->ColorDepth, xfi->bpp, xfi->clrconv);
backColor = freerdp_color_convert_var(polygon_cb->backColor, ((xfContext*) context)->settings->ColorDepth, xfi->bpp, xfi->clrconv);
npoints = polygon_cb->numPoints + 1;
points = malloc(sizeof(XPoint) * npoints);
@ -866,6 +919,8 @@ void xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
XSetFunction(xfi->display, xfi->gc, GXcopy);
free(points);
ReleaseMutex(xfi->mutex);
}
void xf_gdi_ellipse_sc(rdpContext* context, ELLIPSE_SC_ORDER* ellipse_sc)
@ -885,6 +940,9 @@ void xf_gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surf
xfi = ((xfContext*) context)->xfi;
settings = xfi->instance->settings;
WaitForSingleObject(xfi->mutex, INFINITE);
switch (surface_frame_marker->frameAction)
{
case SURFACECMD_FRAMEACTION_BEGIN:
@ -915,6 +973,8 @@ void xf_gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surf
}
break;
}
ReleaseMutex(xfi->mutex);
}
static void xf_gdi_surface_update_frame(xfInfo* xfi, UINT16 tx, UINT16 ty, UINT16 width, UINT16 height)
@ -960,6 +1020,8 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
RFX_CONTEXT* rfx_context = (RFX_CONTEXT*) xfi->rfx_context;
NSC_CONTEXT* nsc_context = (NSC_CONTEXT*) xfi->nsc_context;
WaitForSingleObject(xfi->mutex, INFINITE);
if (surface_bits_command->codecID == RDP_CODEC_ID_REMOTEFX)
{
message = rfx_process_message(rfx_context,
@ -1001,6 +1063,7 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
{
nsc_process_message(nsc_context, surface_bits_command->bpp, surface_bits_command->width, surface_bits_command->height,
surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
XSetFunction(xfi->display, xfi->gc, GXcopy);
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
@ -1030,7 +1093,7 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
/* Validate that the data received is large enough */
if( surface_bits_command->width * surface_bits_command->height * surface_bits_command->bpp / 8 <= surface_bits_command->bitmapDataLength )
if ((surface_bits_command->width * surface_bits_command->height * surface_bits_command->bpp / 8) <= (surface_bits_command->bitmapDataLength))
{
xfi->bmp_codec_none = (BYTE*) realloc(xfi->bmp_codec_none,
surface_bits_command->width * surface_bits_command->height * 4);
@ -1051,7 +1114,9 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
surface_bits_command->width, surface_bits_command->height);
XSetClipMask(xfi->display, xfi->gc, None);
} else {
}
else
{
printf("Invalid bitmap size - data is %d bytes for %dx%d\n update", surface_bits_command->bitmapDataLength, surface_bits_command->width, surface_bits_command->height);
}
}
@ -1059,6 +1124,8 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
{
printf("Unsupported codecID %d\n", surface_bits_command->codecID);
}
ReleaseMutex(xfi->mutex);
}
void xf_gdi_register_update_callbacks(rdpUpdate* update)

View File

@ -46,6 +46,8 @@ void xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
XSetFunction(xfi->display, xfi->gc, GXcopy);
pixmap = XCreatePixmap(xfi->display, xfi->drawable, bitmap->width, bitmap->height, xfi->depth);
@ -75,14 +77,20 @@ void xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
}
((xfBitmap*) bitmap)->pixmap = pixmap;
ReleaseMutex(xfi->mutex);
}
void xf_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
if (((xfBitmap*) bitmap)->pixmap != 0)
XFreePixmap(xfi->display, ((xfBitmap*) bitmap)->pixmap);
ReleaseMutex(xfi->mutex);
}
void xf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
@ -94,6 +102,8 @@ void xf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
width = bitmap->right - bitmap->left + 1;
height = bitmap->bottom - bitmap->top + 1;
WaitForSingleObject(xfi->mutex, INFINITE);
XSetFunction(xfi->display, xfi->gc, GXcopy);
image = XCreateImage(xfi->display, xfi->visual, xfi->depth,
@ -111,6 +121,8 @@ void xf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
}
gdi_InvalidateRegion(xfi->hdc, bitmap->left, bitmap->top, width, height);
ReleaseMutex(xfi->mutex);
}
void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
@ -118,13 +130,15 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
BOOL compressed, int codec_id)
{
UINT16 size;
RFX_MESSAGE* msg;
BYTE* src;
BYTE* dst;
int yindex;
int xindex;
xfInfo* xfi;
BOOL status;
RFX_MESSAGE* msg;
xfi = ((xfContext*) context)->xfi;
size = width * height * (bpp + 7) / 8;
@ -138,10 +152,11 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
case RDP_CODEC_ID_NSCODEC:
printf("xf_Bitmap_Decompress: nsc not done\n");
break;
case RDP_CODEC_ID_REMOTEFX:
xfi = ((xfContext*)context)->xfi;
rfx_context_set_pixel_format(xfi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
msg = rfx_process_message(xfi->rfx_context, data, length);
if (msg == NULL)
{
printf("xf_Bitmap_Decompress: rfx Decompression Failed\n");
@ -163,12 +178,14 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
rfx_message_free(xfi->rfx_context, msg);
}
break;
case RDP_CODEC_ID_JPEG:
if (!jpeg_decompress(data, bitmap->data, width, height, length, bpp))
{
printf("xf_Bitmap_Decompress: jpeg Decompression Failed\n");
}
break;
default:
if (compressed)
{
@ -195,10 +212,14 @@ void xf_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, BOOL primary)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
if (primary)
xfi->drawing = xfi->primary;
else
xfi->drawing = ((xfBitmap*) bitmap)->pixmap;
ReleaseMutex(xfi->mutex);
}
/* Pointer Class */
@ -209,7 +230,9 @@ void xf_Pointer_New(rdpContext* context, rdpPointer* pointer)
XcursorImage ci;
xfInfo* xfi = ((xfContext*) context)->xfi;
memset(&ci, 0, sizeof(ci));
WaitForSingleObject(xfi->mutex, INFINITE);
ZeroMemory(&ci, sizeof(ci));
ci.version = XCURSOR_IMAGE_VERSION;
ci.size = sizeof(ci);
ci.width = pointer->width;
@ -229,6 +252,8 @@ void xf_Pointer_New(rdpContext* context, rdpPointer* pointer)
((xfPointer*) pointer)->cursor = XcursorImageLoadCursor(xfi->display, &ci);
free(ci.pixels);
ReleaseMutex(xfi->mutex);
#endif
}
@ -237,8 +262,12 @@ void xf_Pointer_Free(rdpContext* context, rdpPointer* pointer)
#ifdef WITH_XCURSOR
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
if (((xfPointer*) pointer)->cursor != 0)
XFreeCursor(xfi->display, ((xfPointer*) pointer)->cursor);
ReleaseMutex(xfi->mutex);
#endif
}
@ -247,10 +276,14 @@ void xf_Pointer_Set(rdpContext* context, rdpPointer* pointer)
#ifdef WITH_XCURSOR
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
/* in RemoteApp mode, window can be null if none has had focus */
if (xfi->window != NULL)
XDefineCursor(xfi->display, xfi->window->handle, ((xfPointer*) pointer)->cursor);
ReleaseMutex(xfi->mutex);
#endif
}
@ -260,11 +293,13 @@ void xf_Pointer_SetNull(rdpContext* context)
xfInfo* xfi = ((xfContext*) context)->xfi;
static Cursor nullcursor = None;
WaitForSingleObject(xfi->mutex, INFINITE);
if (nullcursor == None)
{
XcursorImage ci;
XcursorPixel xp = 0;
memset(&ci, 0, sizeof(ci));
ZeroMemory(&ci, sizeof(ci));
ci.version = XCURSOR_IMAGE_VERSION;
ci.size = sizeof(ci);
ci.width = ci.height = 1;
@ -275,6 +310,8 @@ void xf_Pointer_SetNull(rdpContext* context)
if (xfi->window != NULL && nullcursor != None)
XDefineCursor(xfi->display, xfi->window->handle, nullcursor);
ReleaseMutex(xfi->mutex);
#endif
}
@ -283,8 +320,12 @@ void xf_Pointer_SetDefault(rdpContext* context)
#ifdef WITH_XCURSOR
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
if (xfi->window != NULL)
XUndefineCursor(xfi->display, xfi->window->handle);
ReleaseMutex(xfi->mutex);
#endif
}
@ -300,6 +341,8 @@ void xf_Glyph_New(rdpContext* context, rdpGlyph* glyph)
xf_glyph = (xfGlyph*) glyph;
xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
scanline = (glyph->cx + 7) / 8;
xf_glyph->pixmap = XCreatePixmap(xfi->display, xfi->drawing, glyph->cx, glyph->cy, 1);
@ -313,14 +356,20 @@ void xf_Glyph_New(rdpContext* context, rdpGlyph* glyph)
XInitImage(image);
XPutImage(xfi->display, xf_glyph->pixmap, xfi->gc_mono, image, 0, 0, 0, 0, glyph->cx, glyph->cy);
XFree(image);
ReleaseMutex(xfi->mutex);
}
void xf_Glyph_Free(rdpContext* context, rdpGlyph* glyph)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
if (((xfGlyph*) glyph)->pixmap != 0)
XFreePixmap(xfi->display, ((xfGlyph*) glyph)->pixmap);
ReleaseMutex(xfi->mutex);
}
void xf_Glyph_Draw(rdpContext* context, rdpGlyph* glyph, int x, int y)
@ -330,10 +379,14 @@ void xf_Glyph_Draw(rdpContext* context, rdpGlyph* glyph, int x, int y)
xf_glyph = (xfGlyph*) glyph;
WaitForSingleObject(xfi->mutex, INFINITE);
XSetStipple(xfi->display, xfi->gc, xf_glyph->pixmap);
XSetTSOrigin(xfi->display, xfi->gc, x, y);
XFillRectangle(xfi->display, xfi->drawing, xfi->gc, x, y, glyph->cx, glyph->cy);
XSetStipple(xfi->display, xfi->gc, xfi->bitmap_mono);
ReleaseMutex(xfi->mutex);
}
void xf_Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int height, UINT32 bgcolor, UINT32 fgcolor)
@ -349,6 +402,8 @@ void xf_Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int height
freerdp_color_convert_var_bgr(fgcolor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv):
freerdp_color_convert_var_rgb(fgcolor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
WaitForSingleObject(xfi->mutex, INFINITE);
XSetFunction(xfi->display, xfi->gc, GXcopy);
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
XSetForeground(xfi->display, xfi->gc, fgcolor);
@ -357,12 +412,16 @@ void xf_Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int height
XSetForeground(xfi->display, xfi->gc, bgcolor);
XSetBackground(xfi->display, xfi->gc, fgcolor);
XSetFillStyle(xfi->display, xfi->gc, FillStippled);
ReleaseMutex(xfi->mutex);
}
void xf_Glyph_EndDraw(rdpContext* context, int x, int y, int width, int height, UINT32 bgcolor, UINT32 fgcolor)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
WaitForSingleObject(xfi->mutex, INFINITE);
if (xfi->drawing == xfi->primary)
{
if (xfi->remote_app != TRUE)
@ -372,6 +431,8 @@ void xf_Glyph_EndDraw(rdpContext* context, int x, int y, int width, int height,
gdi_InvalidateRegion(xfi->hdc, x, y, width, height);
}
ReleaseMutex(xfi->mutex);
}
/* Graphics Module */

View File

@ -873,6 +873,8 @@ void xf_UpdateWindowArea(xfInfo* xfi, xfWindow* window, int x, int y, int width,
height = (wnd->visibleOffsetY + wnd->windowHeight - 1) - ay;
}
WaitForSingleObject(xfi->mutex, INFINITE);
if (xfi->sw_gdi)
{
XPutImage(xfi->display, xfi->primary, window->gc, xfi->image,
@ -883,6 +885,8 @@ void xf_UpdateWindowArea(xfInfo* xfi, xfWindow* window, int x, int y, int width,
ax, ay, width, height, x, y);
XFlush(xfi->display);
ReleaseMutex(xfi->mutex);
}
BOOL xf_IsWindowBorder(xfInfo* xfi, xfWindow* xfw, int x, int y)

View File

@ -127,8 +127,12 @@ void xf_sw_end_paint(rdpContext* context)
w = gdi->primary->hdc->hwnd->invalid->w;
h = gdi->primary->hdc->hwnd->invalid->h;
WaitForSingleObject(xfi->mutex, INFINITE);
XPutImage(xfi->display, xfi->primary, xfi->gc, xfi->image, x, y, x, y, w, h);
XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, w, h, x, y);
ReleaseMutex(xfi->mutex);
}
else
{
@ -142,6 +146,8 @@ void xf_sw_end_paint(rdpContext* context)
ninvalid = gdi->primary->hdc->hwnd->ninvalid;
cinvalid = gdi->primary->hdc->hwnd->cinvalid;
WaitForSingleObject(xfi->mutex, INFINITE);
for (i = 0; i < ninvalid; i++)
{
x = cinvalid[i].x;
@ -154,6 +160,8 @@ void xf_sw_end_paint(rdpContext* context)
}
XFlush(xfi->display);
ReleaseMutex(xfi->mutex);
}
}
else
@ -166,7 +174,11 @@ void xf_sw_end_paint(rdpContext* context)
w = gdi->primary->hdc->hwnd->invalid->w;
h = gdi->primary->hdc->hwnd->invalid->h;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_rail_paint(xfi, context->rail, x, y, x + w - 1, y + h - 1);
ReleaseMutex(xfi->mutex);
}
}
@ -178,6 +190,8 @@ void xf_sw_desktop_resize(rdpContext* context)
xfi = ((xfContext*) context)->xfi;
settings = xfi->instance->settings;
WaitForSingleObject(xfi->mutex, INFINITE);
if (xfi->fullscreen != TRUE)
{
rdpGdi* gdi = context->gdi;
@ -191,12 +205,15 @@ void xf_sw_desktop_resize(rdpContext* context)
(char*) gdi->primary_buffer, gdi->width, gdi->height, xfi->scanline_pad, 0);
}
}
ReleaseMutex(xfi->mutex);
}
void xf_hw_begin_paint(rdpContext* context)
{
xfInfo* xfi;
xfi = ((xfContext*) context)->xfi;
xfi->hdc->hwnd->invalid->null = 1;
xfi->hdc->hwnd->ninvalid = 0;
}
@ -219,7 +236,11 @@ void xf_hw_end_paint(rdpContext* context)
w = xfi->hdc->hwnd->invalid->w;
h = xfi->hdc->hwnd->invalid->h;
WaitForSingleObject(xfi->mutex, INFINITE);
xf_rail_paint(xfi, context->rail, x, y, x + w - 1, y + h - 1);
ReleaseMutex(xfi->mutex);
}
}
@ -232,6 +253,8 @@ void xf_hw_desktop_resize(rdpContext* context)
xfi = ((xfContext*) context)->xfi;
settings = xfi->instance->settings;
WaitForSingleObject(xfi->mutex, INFINITE);
if (xfi->fullscreen != TRUE)
{
xfi->width = settings->DesktopWidth;
@ -258,9 +281,10 @@ void xf_hw_desktop_resize(rdpContext* context)
XSetFunction(xfi->display, xfi->gc, GXcopy);
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
XSetForeground(xfi->display, xfi->gc, 0);
XFillRectangle(xfi->display, xfi->drawable, xfi->gc,
0, 0, xfi->width, xfi->height);
XFillRectangle(xfi->display, xfi->drawable, xfi->gc, 0, 0, xfi->width, xfi->height);
}
ReleaseMutex(xfi->mutex);
}
BOOL xf_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount)
@ -275,19 +299,35 @@ BOOL xf_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* w
BOOL xf_process_x_events(freerdp* instance)
{
BOOL status;
XEvent xevent;
int pending_status;
xfInfo* xfi = ((xfContext*) instance->context)->xfi;
while (XPending(xfi->display))
{
memset(&xevent, 0, sizeof(xevent));
XNextEvent(xfi->display, &xevent);
status = TRUE;
pending_status = TRUE;
if (xf_event_process(instance, &xevent) != TRUE)
return FALSE;
while (pending_status)
{
WaitForSingleObject(xfi->mutex, INFINITE);
pending_status = XPending(xfi->display);
ReleaseMutex(xfi->mutex);
if (pending_status)
{
ZeroMemory(&xevent, sizeof(xevent));
XNextEvent(xfi->display, &xevent);
status = xf_event_process(instance, &xevent);
if (!status)
return status;
}
}
return TRUE;
return status;
}
void xf_create_window(xfInfo* xfi)
@ -296,7 +336,7 @@ void xf_create_window(xfInfo* xfi)
char* win_title;
int width, height;
memset(&xevent, 0x00, sizeof(xevent));
ZeroMemory(&xevent, sizeof(xevent));
width = xfi->width;
height = xfi->height;
@ -384,7 +424,7 @@ BOOL xf_get_pixmap_info(xfInfo* xfi)
}
XFree(pfs);
memset(&template, 0, sizeof(template));
ZeroMemory(&template, sizeof(template));
template.class = TrueColor;
template.screen = xfi->screen_number;
@ -553,12 +593,12 @@ BOOL xf_pre_connect(freerdp* instance)
if (settings->AuthenticationOnly)
{
/* Check --authonly has a username and password. */
if (settings->Username == NULL )
if (settings->Username == NULL)
{
fprintf(stderr, "--authonly, but no -u username. Please provide one.\n");
exit(1);
}
if (settings->Password == NULL )
if (settings->Password == NULL)
{
fprintf(stderr, "--authonly, but no -p password. Please provide one.\n");
exit(1);
@ -568,6 +608,9 @@ BOOL xf_pre_connect(freerdp* instance)
return TRUE;
}
if (!XInitThreads())
printf("warning: XInitThreads() failure\n");
xfi->display = XOpenDisplay(NULL);
if (xfi->display == NULL)
@ -750,7 +793,7 @@ BOOL xf_post_connect(freerdp* instance)
xf_create_window(xfi);
memset(&gcv, 0, sizeof(gcv));
ZeroMemory(&gcv, sizeof(gcv));
xfi->modifier_map = XGetModifierMapping(xfi->display);
xfi->gc = XCreateGC(xfi->display, xfi->drawable, GCGraphicsExposures, &gcv);
@ -966,11 +1009,11 @@ void xf_window_free(xfInfo* xfi)
if (context != NULL)
{
cache_free(context->cache);
context->cache = NULL;
cache_free(context->cache);
context->cache = NULL;
rail_free(context->rail);
context->rail = NULL;
rail_free(context->rail);
context->rail = NULL;
}
if (xfi->rfx_context)
@ -1005,12 +1048,96 @@ void xf_free(xfInfo* xfi)
free(xfi);
}
void* xf_update_thread(void* arg)
{
wMessage message;
wMessageQueue* queue;
freerdp* instance = (freerdp*) arg;
queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
while (MessageQueue_Wait(queue))
{
if (MessageQueue_Peek(queue, &message, TRUE))
{
if (!freerdp_message_queue_process_message(instance, FREERDP_UPDATE_MESSAGE_QUEUE, &message))
break;
}
}
return NULL;
}
void* xf_input_thread(void* arg)
{
int status;
xfInfo* xfi;
HANDLE event;
XEvent xevent;
freerdp* instance = (freerdp*) arg;
xfi = ((xfContext*) instance->context)->xfi;
event = CreateFileDescriptorEvent(NULL, TRUE, FALSE, xfi->xfds);
while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0)
{
WaitForSingleObject(xfi->mutex, INFINITE);
status = XPending(xfi->display);
ReleaseMutex(xfi->mutex);
if (status)
{
ZeroMemory(&xevent, sizeof(xevent));
WaitForSingleObject(xfi->mutex, INFINITE);
XNextEvent(xfi->display, &xevent);
status = xf_event_process(instance, &xevent);
ReleaseMutex(xfi->mutex);
if (!status)
break;
}
}
printf("Closed from X\n");
xfi->disconnect = TRUE;
return NULL;
}
void* xf_channels_thread(void* arg)
{
int status;
xfInfo* xfi;
HANDLE event;
rdpChannels* channels;
freerdp* instance = (freerdp*) arg;
xfi = ((xfContext*) instance->context)->xfi;
channels = instance->context->channels;
event = freerdp_channels_get_event_handle(instance);
while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0)
{
status = freerdp_channels_process_pending_messages(instance);
xf_process_channel_event(channels, instance);
}
return NULL;
}
/** Main loop for the rdp connection.
* It will be run from the thread's entry point (thread_func()).
* It initiates the connection, and will continue to run until the session ends,
* processing events as they are received.
* @param instance - pointer to the rdp_freerdp structure that contains the session's settings
* @return A code from the enum XF_EXIT_CODE (0 if successfull)
* @return A code from the enum XF_EXIT_CODE (0 if successful)
*/
int xfreerdp_run(freerdp* instance)
{
@ -1021,19 +1148,30 @@ int xfreerdp_run(freerdp* instance)
int rcount;
int wcount;
int ret = 0;
BOOL status;
void* rfds[32];
void* wfds[32];
fd_set rfds_set;
fd_set wfds_set;
int fd_input_event;
HANDLE input_event;
int select_status;
BOOL async_update;
BOOL async_input;
BOOL async_channels;
HANDLE update_thread;
HANDLE input_thread;
HANDLE channels_thread;
rdpChannels* channels;
rdpSettings* settings;
struct timeval timeout;
memset(rfds, 0, sizeof(rfds));
memset(wfds, 0, sizeof(wfds));
memset(&timeout, 0, sizeof(struct timeval));
ZeroMemory(rfds, sizeof(rfds));
ZeroMemory(wfds, sizeof(wfds));
ZeroMemory(&timeout, sizeof(struct timeval));
status = freerdp_connect(instance);
BOOL status = freerdp_connect(instance);
/* Connection succeeded. --authonly ? */
if (instance->settings->AuthenticationOnly)
{
@ -1050,6 +1188,32 @@ int xfreerdp_run(freerdp* instance)
xfi = ((xfContext*) instance->context)->xfi;
channels = instance->context->channels;
settings = instance->context->settings;
async_update = settings->AsyncUpdate;
async_input = settings->AsyncInput;
xfi->mutex = CreateMutex(NULL, FALSE, NULL);
if (async_update)
{
update_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_update_thread, instance, 0, NULL);
}
if (async_input)
{
input_event = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE);
fd_input_event = GetEventFileDescriptor(input_event);
input_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_input_thread, instance, 0, NULL);
}
async_channels = FALSE;
if (async_channels)
{
channels_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_channels_thread, instance, 0, NULL);
}
while (!xfi->disconnect && !freerdp_shall_disconnect(instance))
{
@ -1062,17 +1226,29 @@ int xfreerdp_run(freerdp* instance)
ret = XF_EXIT_CONN_FAILED;
break;
}
if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != TRUE)
if (!async_channels)
{
printf("Failed to get channel manager file descriptor\n");
ret = XF_EXIT_CONN_FAILED;
break;
if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
printf("Failed to get channel manager file descriptor\n");
ret = XF_EXIT_CONN_FAILED;
break;
}
}
if (xf_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
if (!async_input)
{
printf("Failed to get xfreerdp file descriptor\n");
ret = XF_EXIT_CONN_FAILED;
break;
if (xf_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
printf("Failed to get xfreerdp file descriptor\n");
ret = XF_EXIT_CONN_FAILED;
break;
}
}
else
{
rfds[rcount++] = (void*) (long) fd_input_event;
}
max_fds = 0;
@ -1104,10 +1280,8 @@ int xfreerdp_run(freerdp* instance)
else if (select_status == -1)
{
/* these are not really errors */
if (!((errno == EAGAIN) ||
(errno == EWOULDBLOCK) ||
(errno == EINPROGRESS) ||
(errno == EINTR))) /* signal occurred */
if (!((errno == EAGAIN) || (errno == EWOULDBLOCK) ||
(errno == EINPROGRESS) || (errno == EINTR))) /* signal occurred */
{
printf("xfreerdp_run: select failed\n");
break;
@ -1119,40 +1293,69 @@ int xfreerdp_run(freerdp* instance)
printf("Failed to check FreeRDP file descriptor\n");
break;
}
if (xf_process_x_events(instance) != TRUE)
if (!async_channels)
{
printf("Closed from X\n");
break;
if (freerdp_channels_check_fds(channels, instance) != TRUE)
{
printf("Failed to check channel manager file descriptor\n");
break;
}
xf_process_channel_event(channels, instance);
}
if (freerdp_channels_check_fds(channels, instance) != TRUE)
if (!async_input)
{
printf("Failed to check channel manager file descriptor\n");
break;
if (xf_process_x_events(instance) != TRUE)
{
printf("Closed from X\n");
break;
}
}
else
{
freerdp_message_queue_process_pending_messages(instance, FREERDP_INPUT_MESSAGE_QUEUE);
}
xf_process_channel_event(channels, instance);
}
FILE *fin = fopen("/tmp/tsmf.tid", "rt");
if(fin)
if (async_update)
{
wMessageQueue* update_queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
MessageQueue_PostQuit(update_queue, 0);
WaitForSingleObject(update_thread, INFINITE);
CloseHandle(update_thread);
}
FILE* fin = fopen("/tmp/tsmf.tid", "rt");
if (fin)
{
FILE* fin1;
int thid = 0;
int timeout;
fscanf(fin, "%d", &thid);
fclose(fin);
pthread_kill((pthread_t) (size_t) thid, SIGUSR1);
FILE *fin1 = fopen("/tmp/tsmf.tid", "rt");
int timeout = 5;
fin1 = fopen("/tmp/tsmf.tid", "rt");
timeout = 5;
while (fin1)
{
fclose(fin1);
sleep(1);
timeout--;
if (timeout <= 0)
{
unlink("/tmp/tsmf.tid");
pthread_kill((pthread_t) (size_t) thid, SIGKILL);
break;
}
fin1 = fopen("/tmp/tsmf.tid", "rt");
}
}

View File

@ -114,6 +114,7 @@ struct xf_info
BOOL disconnect;
HCLRCONV clrconv;
Window parent_window;
HANDLE mutex;
HGDI_DC hdc;
BOOL sw_gdi;

View File

@ -109,6 +109,8 @@ COMMAND_LINE_ARGUMENT_A args[] =
{ "glyph-cache", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "glyph cache" },
{ "codec-cache", COMMAND_LINE_VALUE_REQUIRED, "<rfx|nsc|jpeg>", NULL, NULL, -1, NULL, "bitmap codec cache" },
{ "fast-path", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "fast-path input/output" },
{ "async-input", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "asynchronous input" },
{ "async-update", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "asynchronous update" },
{ "version", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_VERSION, NULL, NULL, NULL, -1, NULL, "print version" },
{ "help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "?", "print help" },
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
@ -1305,6 +1307,14 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
settings->FastPathInput = arg->Value ? TRUE : FALSE;
settings->FastPathOutput = arg->Value ? TRUE : FALSE;
}
CommandLineSwitchCase(arg, "async-input")
{
settings->AsyncInput = arg->Value ? TRUE : FALSE;
}
CommandLineSwitchCase(arg, "async-update")
{
settings->AsyncUpdate = arg->Value ? TRUE : FALSE;
}
CommandLineSwitchDefault(arg)
{

View File

@ -269,6 +269,11 @@ int freerdp_client_old_command_line_pre_filter(void* context, int index, int arg
index++;
i++;
}
} else {
if (settings->instance)
{
freerdp_client_old_process_plugin(settings, args);
}
}
return (index - old_index);
@ -341,6 +346,9 @@ int freerdp_detect_old_command_line_syntax(int argc, char** argv, int* count)
detect_status = 1;
}
if (settings->ServerHostname)
free(settings->ServerHostname);
free(settings);
return detect_status;

View File

@ -28,7 +28,7 @@
#cmakedefine HAVE_SYS_MODEM_H
#cmakedefine HAVE_SYS_FILIO_H
#cmakedefine HAVE_SYS_STRTIO_H
#cmakedefine HAVE_EVENTFD_H
#cmakedefine HAVE_TM_GMTOFF

View File

@ -316,8 +316,8 @@ void test_license(void)
STREAM _s, *s;
s = &_s;
memcpy(license->client_random, client_random, sizeof(client_random));
memcpy(license->premaster_secret, premaster_secret, sizeof(premaster_secret));
memcpy(license->ClientRandom, client_random, sizeof(client_random));
memcpy(license->PremasterSecret, premaster_secret, sizeof(premaster_secret));
s->data = server_license_request;
s->p = s->data + LICENSE_PREAMBLE_LENGTH;
@ -327,31 +327,31 @@ void test_license(void)
printf("\n");
printf("client random:\n");
winpr_HexDump(license->client_random, 32);
winpr_HexDump(license->ClientRandom, 32);
printf("\n");
printf("server random:\n");
winpr_HexDump(license->server_random, 32);
winpr_HexDump(license->ServerRandom, 32);
printf("\n");
printf("premaster secret:\n");
winpr_HexDump(license->premaster_secret, 48);
winpr_HexDump(license->PremasterSecret, 48);
printf("\n");
printf("master secret:\n");
winpr_HexDump(license->master_secret, 48);
winpr_HexDump(license->MasterSecret, 48);
printf("\n");
printf("session key blob:\n");
winpr_HexDump(license->session_key_blob, 48);
winpr_HexDump(license->SessionKeyBlob, 48);
printf("\n");
printf("licensing encryption key:\n");
winpr_HexDump(license->licensing_encryption_key, 16);
winpr_HexDump(license->LicensingEncryptionKey, 16);
printf("\n");
printf("mac salt key:\n");
winpr_HexDump(license->mac_salt_key, 16);
winpr_HexDump(license->MacSaltKey, 16);
printf("\n");
printf("modulus:\n");
@ -364,8 +364,8 @@ void test_license(void)
printf("\n");
printf("encrypted premaster secret:\n");
winpr_HexDump(license->encrypted_premaster_secret->data,
license->encrypted_premaster_secret->length);
winpr_HexDump(license->EncryptedPremasterSecret->data,
license->EncryptedPremasterSecret->length);
printf("\n");
#endif
@ -422,9 +422,9 @@ void test_license_generate_keys(void)
STREAM _s, *s;
s = &_s;
memcpy(license->client_random, client_random, sizeof(client_random));
memcpy(license->server_random, test_server_random, sizeof(test_server_random));
memcpy(license->premaster_secret, premaster_secret, sizeof(premaster_secret));
memcpy(license->ClientRandom, client_random, sizeof(client_random));
memcpy(license->ServerRandom, test_server_random, sizeof(test_server_random));
memcpy(license->PremasterSecret, premaster_secret, sizeof(premaster_secret));
memcpy(license->certificate->cert_info.exponent, test_exponent, sizeof(test_exponent));
memcpy(license->certificate->cert_info.Modulus, test_modulus, sizeof(test_modulus));
license->certificate->cert_info.ModulusLength = sizeof(test_modulus);
@ -432,23 +432,23 @@ void test_license_generate_keys(void)
license_generate_keys(license);
license_encrypt_premaster_secret(license);
s->data = license->master_secret;
s->data = license->MasterSecret;
s->p = s->data + sizeof(test_master_secret);
ASSERT_STREAM(s, test_master_secret, sizeof(test_master_secret));
s->data = license->session_key_blob;
s->data = license->SessionKeyBlob;
s->p = s->data + sizeof(test_session_key_blob);
ASSERT_STREAM(s, test_session_key_blob, sizeof(test_session_key_blob));
s->data = license->mac_salt_key;
s->data = license->MacSaltKey;
s->p = s->data + sizeof(test_mac_salt_key);
ASSERT_STREAM(s, test_mac_salt_key, sizeof(test_mac_salt_key));
s->data = license->licensing_encryption_key;
s->data = license->LicensingEncryptionKey;
s->p = s->data + sizeof(test_licensing_encryption_key);
ASSERT_STREAM(s, test_licensing_encryption_key, sizeof(test_licensing_encryption_key));
s->data = license->encrypted_premaster_secret->data;
s->data = license->EncryptedPremasterSecret->data;
s->p = s->data + sizeof(test_encrypted_premaster_secret);
ASSERT_STREAM(s, test_encrypted_premaster_secret, sizeof(test_encrypted_premaster_secret));
}
@ -458,12 +458,12 @@ void test_license_encrypt_premaster_secret(void)
STREAM _s, *s;
s = &_s;
memcpy(license->premaster_secret, premaster_secret, sizeof(premaster_secret));
memcpy(license->PremasterSecret, premaster_secret, sizeof(premaster_secret));
memcpy(license->certificate->cert_info.exponent, test_exponent, sizeof(test_exponent));
memcpy(license->certificate->cert_info.Modulus, test_modulus, sizeof(test_modulus));
license->certificate->cert_info.ModulusLength = sizeof(test_modulus);
s->data = license->encrypted_premaster_secret->data;
s->data = license->EncryptedPremasterSecret->data;
s->p = s->data + sizeof(test_encrypted_premaster_secret);
ASSERT_STREAM(s, test_encrypted_premaster_secret, sizeof(test_encrypted_premaster_secret));
}
@ -479,20 +479,20 @@ void test_license_decrypt_platform_challenge(void)
STREAM _s, *s;
s = &_s;
memcpy(license->licensing_encryption_key, test_licensing_encryption_key,
memcpy(license->LicensingEncryptionKey, test_licensing_encryption_key,
sizeof(test_licensing_encryption_key));
license->encrypted_platform_challenge->data =
license->EncryptedPlatformChallenge->data =
(BYTE*) malloc(sizeof(test_encrypted_platform_challenge));
license->encrypted_platform_challenge->length =
license->EncryptedPlatformChallenge->length =
sizeof(test_encrypted_platform_challenge);
memcpy(license->encrypted_platform_challenge->data, test_encrypted_platform_challenge,
memcpy(license->EncryptedPlatformChallenge->data, test_encrypted_platform_challenge,
sizeof(test_encrypted_platform_challenge));
license_decrypt_platform_challenge(license);
s->data = license->platform_challenge->data;
s->data = license->PlatformChallenge->data;
s->p = s->data + sizeof(test_platform_challenge);
ASSERT_STREAM(s, test_platform_challenge, sizeof(test_platform_challenge));

View File

@ -170,7 +170,7 @@ typedef void (*pSwitchSurface)(rdpContext* context, SWITCH_SURFACE_ORDER* switch
typedef void (*pCreateNineGridBitmap)(rdpContext* context, CREATE_NINE_GRID_BITMAP_ORDER* create_nine_grid_bitmap);
typedef void (*pFrameMarker)(rdpContext* context, FRAME_MARKER_ORDER* frame_marker);
typedef void (*pStreamBitmapFirst)(rdpContext* context, STREAM_BITMAP_FIRST_ORDER* stream_bitmap_first);
typedef void (*pStreamBitmapNext)(rdpContext* context, STREAM_BITMAP_FIRST_ORDER* stream_bitmap_next);
typedef void (*pStreamBitmapNext)(rdpContext* context, STREAM_BITMAP_NEXT_ORDER* stream_bitmap_next);
typedef void (*pDrawGdiPlusFirst)(rdpContext* context, DRAW_GDIPLUS_FIRST_ORDER* draw_gdiplus_first);
typedef void (*pDrawGdiPlusNext)(rdpContext* context, DRAW_GDIPLUS_NEXT_ORDER* draw_gdiplus_next);
typedef void (*pDrawGdiPlusEnd)(rdpContext* context, DRAW_GDIPLUS_END_ORDER* draw_gdiplus_end);
@ -204,7 +204,7 @@ struct rdp_altsec_update
CREATE_NINE_GRID_BITMAP_ORDER create_nine_grid_bitmap;
FRAME_MARKER_ORDER frame_marker;
STREAM_BITMAP_FIRST_ORDER stream_bitmap_first;
STREAM_BITMAP_FIRST_ORDER stream_bitmap_next;
STREAM_BITMAP_NEXT_ORDER stream_bitmap_next;
DRAW_GDIPLUS_CACHE_FIRST_ORDER draw_gdiplus_cache_first;
DRAW_GDIPLUS_CACHE_NEXT_ORDER draw_gdiplus_cache_next;
DRAW_GDIPLUS_CACHE_END_ORDER draw_gdiplus_cache_end;

View File

@ -48,6 +48,9 @@ FREERDP_API BOOL freerdp_channels_check_fds(rdpChannels* channels, freerdp* inst
FREERDP_API RDP_EVENT* freerdp_channels_pop_event(rdpChannels* channels);
FREERDP_API void freerdp_channels_close(rdpChannels* channels, freerdp* instance);
FREERDP_API HANDLE freerdp_channels_get_event_handle(freerdp* instance);
FREERDP_API int freerdp_channels_process_pending_messages(freerdp* instance);
#ifdef __cplusplus
}
#endif

View File

@ -40,7 +40,6 @@
#endif
#define EXPONENT_MAX_SIZE 4
#define MODULUS_MAX_SIZE 256
#include <freerdp/api.h>
#include <freerdp/freerdp.h>

View File

@ -40,6 +40,7 @@ typedef struct rdp_freerdp_peer freerdp_peer;
#include <freerdp/input.h>
#include <freerdp/update.h>
#include <freerdp/message.h>
#ifdef __cplusplus
extern "C" {
@ -82,6 +83,7 @@ struct rdp_context
List of arguments given to the program at launch time.
Used to keep this data available and used later on, typically just before connection initialization.
@see freerdp_parse_args() */
UINT32 paddingB[32 - 18]; /* 18 */
rdpRdp* rdp; /**< (offset 32)
@ -96,7 +98,10 @@ struct rdp_context
rdpCache* cache; /* 35 */
rdpChannels* channels; /* 36 */
rdpGraphics* graphics; /* 37 */
UINT32 paddingC[64 - 38]; /* 38 */
rdpInput* input; /* 38 */
rdpUpdate* update; /* 39 */
rdpSettings* settings; /* 40 */
UINT32 paddingC[64 - 41]; /* 41 */
};
/** Defines the options for a given instance of RDP connection.
@ -114,7 +119,8 @@ struct rdp_freerdp
When using this capability, client application should ALWAYS declare their structure with the
rdpContext field first, and any additional content following it.
Can be allocated by a call to freerdp_context_new().
Must be dealocated by a call to freerdp_context_free() before deallocating the current instance. */
Must be deallocated by a call to freerdp_context_free() before deallocating the current instance. */
UINT32 paddingA[16 - 1]; /* 1 */
rdpInput* input; /* (offset 16)
@ -191,6 +197,11 @@ FREERDP_API BOOL freerdp_disconnect(freerdp* instance);
FREERDP_API BOOL freerdp_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount);
FREERDP_API BOOL freerdp_check_fds(freerdp* instance);
FREERDP_API wMessageQueue* freerdp_get_message_queue(freerdp* instance, DWORD id);
FREERDP_API HANDLE freerdp_get_message_queue_event_handle(freerdp* instance, DWORD id);
FREERDP_API int freerdp_message_queue_process_message(freerdp* instance, DWORD id, wMessage* message);
FREERDP_API int freerdp_message_queue_process_pending_messages(freerdp* instance, DWORD id);
FREERDP_API UINT32 freerdp_error_info(freerdp* instance);
FREERDP_API void freerdp_get_version(int* major, int* minor, int* revision);

View File

@ -25,6 +25,7 @@
FREERDP_API HGDI_BRUSH gdi_CreateSolidBrush(GDI_COLOR crColor);
FREERDP_API HGDI_BRUSH gdi_CreatePatternBrush(HGDI_BITMAP hbmp);
FREERDP_API HGDI_BRUSH gdi_CreateHatchBrush(HGDI_BITMAP hbmp);
FREERDP_API int gdi_PatBlt(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop);
typedef int (*p_PatBlt)(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop);

View File

@ -69,19 +69,26 @@
#define GDI_DPa 0x00A000C9 /* D = D & P */
#define GDI_PDxn 0x00A50065 /* D = D ^ ~P */
#define GDI_DPon 0x000500A9
#define GDI_DPna 0x000A0329
#define GDI_Pn 0x000F0001
#define GDI_PDna 0x00500325
#define GDI_DPan 0x005F00E9
#define GDI_DSan 0x007700E6
#define GDI_DSxn 0x00990066
#define GDI_DPa 0x00A000C9
#define GDI_D 0x00AA0029
#define GDI_DPno 0x00AF0229
#define GDI_SDno 0x00DD0228
#define GDI_PDno 0x00F50225
#define GDI_DPo 0x00FA0089
#define GDI_DSxn 0x00990066 /* D = ~(D ^ S) */
#define GDI_PSDnox 0x002D060A /* D = P ^ (S | ~D) */
#define GDI_PDSona 0x00100C85 /* D = P & ~(D | S) */
#define GDI_DSPDxox 0x00740646 /* D = D ^ (S | ( P ^ D)) */
#define GDI_DPSDonox 0x005B18A9 /* D = D ^ (P | ~(S | D)) */
#define GDI_SPDSxax 0x00AC0744 /* D = S ^ (P & (D ^ S)) */
#define GDI_DPon 0x000500A9 /* D = ~(D | P) */
#define GDI_DPna 0x000A0329 /* D = D & ~P */
#define GDI_Pn 0x000F0001 /* D = ~P */
#define GDI_PDna 0x00500325 /* D = P &~D */
#define GDI_DPan 0x005F00E9 /* D = ~(D & P) */
#define GDI_DSan 0x007700E6 /* D = ~(D & S) */
#define GDI_DSxn 0x00990066 /* D = ~(D ^ S) */
#define GDI_DPa 0x00A000C9 /* D = D & P */
#define GDI_D 0x00AA0029 /* D = D */
#define GDI_DPno 0x00AF0229 /* D = D | ~P */
#define GDI_SDno 0x00DD0228 /* D = S | ~D */
#define GDI_PDno 0x00F50225 /* D = P | ~D */
#define GDI_DPo 0x00FA0089 /* D = D | P */
/* Brush Styles */
#define GDI_BS_SOLID 0x00

View File

@ -26,6 +26,9 @@ typedef struct rdp_input rdpInput;
#include <freerdp/freerdp.h>
#include <freerdp/scancode.h>
#include <winpr/crt.h>
#include <winpr/collections.h>
/* keyboard Flags */
#define KBD_FLAGS_EXTENDED 0x0100
#define KBD_FLAGS_DOWN 0x4000
@ -54,6 +57,11 @@ typedef struct rdp_input rdpInput;
#define RDP_CLIENT_INPUT_PDU_HEADER_LENGTH 4
/* defined inside libfreerdp-core */
typedef struct rdp_input_proxy rdpInputProxy;
/* Input Interface */
typedef void (*pSynchronizeEvent)(rdpInput* input, UINT32 flags);
typedef void (*pKeyboardEvent)(rdpInput* input, UINT16 flags, UINT16 code);
typedef void (*pUnicodeKeyboardEvent)(rdpInput* input, UINT16 flags, UINT16 code);
@ -72,6 +80,12 @@ struct rdp_input
pMouseEvent MouseEvent; /* 19 */
pExtendedMouseEvent ExtendedMouseEvent; /* 20 */
UINT32 paddingB[32 - 21]; /* 21 */
/* Internal */
BOOL asynchronous;
rdpInputProxy* proxy;
wMessageQueue* queue;
};
#ifdef __cplusplus

238
include/freerdp/message.h Normal file
View File

@ -0,0 +1,238 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Asynchronous Message Interface
*
* Copyright 2012 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 FREERDP_CORE_MESSAGE_H
#define FREERDP_CORE_MESSAGE_H
#define GetMessageType(_id) (_id & 0xFF)
#define GetMessageClass(_id) ((_id >> 16) & 0xFF)
#define MakeMessageId(_class, _type) \
(((_class ##_Class) << 16) | (_class ## _ ## _type))
/**
* Update Message Queue
*/
#define FREERDP_UPDATE_MESSAGE_QUEUE 1
#define Update_Base 0
/* Update */
#define Update_Class (Update_Base + 1)
#define Update_BeginPaint 1
#define Update_EndPaint 2
#define Update_SetBounds 3
#define Update_Synchronize 4
#define Update_DesktopResize 5
#define Update_BitmapUpdate 6
#define Update_Palette 7
#define Update_PlaySound 8
#define Update_RefreshRect 9
#define Update_SuppressOutput 10
#define Update_SurfaceCommand 11
#define Update_SurfaceBits 12
#define Update_SurfaceFrameMarker 13
#define Update_SurfaceFrameAcknowledge 14
#define FREERDP_UPDATE_BEGIN_PAINT MakeMessageId(Update, BeginPaint)
#define FREERDP_UPDATE_ END_PAINT MakeMessageId(Update, EndPaint)
#define FREERDP_UPDATE_SET_BOUNDS MakeMessageId(Update, SetBounds)
#define FREERDP_UPDATE_SYNCHRONIZE MakeMessageId(Update, Synchronize)
#define FREERDP_UPDATE_DESKTOP_RESIZE MakeMessageId(Update, DesktopResize)
#define FREERDP_UPDATE_BITMAP_UPDATE MakeMessageId(Update, BitmapUpdate)
#define FREERDP_UPDATE_PALETTE MakeMessageId(Update, Palette)
#define FREERDP_UPDATE_PLAY_SOUND MakeMessageId(Update, PlaySound)
#define FREERDP_UPDATE_REFRESH_RECT MakeMessageId(Update, RefreshRect)
#define FREERDP_UPDATE_SUPPRESS_OUTPUT MakeMessageId(Update, SuppressOutput)
#define FREERDP_UPDATE_SURFACE_COMMAND MakeMessageId(Update, SurfaceCommand)
#define FREERDP_UPDATE_SURFACE_BITS MakeMessageId(Update, SurfaceBits)
#define FREERDP_UPDATE_SURFACE_FRAME_MARKER MakeMessageId(Update, SurfaceFrameMarker)
#define FREERDP_UPDATE_SURFACE_FRAME_ACKNOWLEDGE MakeMessageId(Update, SurfaceFrameAcknowledge)
/* Primary Update */
#define PrimaryUpdate_Class (Update_Base + 2)
#define PrimaryUpdate_DstBlt 1
#define PrimaryUpdate_PatBlt 2
#define PrimaryUpdate_ScrBlt 3
#define PrimaryUpdate_OpaqueRect 4
#define PrimaryUpdate_DrawNineGrid 5
#define PrimaryUpdate_MultiDstBlt 6
#define PrimaryUpdate_MultiPatBlt 7
#define PrimaryUpdate_MultiScrBlt 8
#define PrimaryUpdate_MultiOpaqueRect 9
#define PrimaryUpdate_MultiDrawNineGrid 10
#define PrimaryUpdate_LineTo 11
#define PrimaryUpdate_Polyline 12
#define PrimaryUpdate_MemBlt 13
#define PrimaryUpdate_Mem3Blt 14
#define PrimaryUpdate_SaveBitmap 15
#define PrimaryUpdate_GlyphIndex 16
#define PrimaryUpdate_FastIndex 17
#define PrimaryUpdate_FastGlyph 18
#define PrimaryUpdate_PolygonSC 19
#define PrimaryUpdate_PolygonCB 20
#define PrimaryUpdate_EllipseSC 21
#define PrimaryUpdate_EllipseCB 22
#define FREERDP_PRIMARY_UPDATE_DSTBLT MakeMessageId(PrimaryUpdate, DstBlt)
#define FREERDP_PRIMARY_UPDATE_PATBLT MakeMessageId(PrimaryUpdate, PatBlt)
#define FREERDP_PRIMARY_UPDATE_SCRBLT MakeMessageId(PrimaryUpdate, ScrBlt)
#define FREERDP_PRIMARY_UPDATE_OPAQUE_RECT MakeMessageId(PrimaryUpdate, OpaqueRect)
#define FREERDP_PRIMARY_UPDATE_DRAW_NINE_GRID MakeMessageId(PrimaryUpdate, DrawNineGrid)
#define FREERDP_PRIMARY_UPDATE_MULTI_DSTBLT MakeMessageId(PrimaryUpdate, MultiDstBlt)
#define FREERDP_PRIMARY_UPDATE_MULTI_PATBLT MakeMessageId(PrimaryUpdate, MultiPatBlt)
#define FREERDP_PRIMARY_UPDATE_MULTI_SCRBLT MakeMessageId(PrimaryUpdate, MultiScrBlt)
#define FREERDP_PRIMARY_UPDATE_MULTI_OPAQUE_RECT MakeMessageId(PrimaryUpdate, MultiOpaqueRect)
#define FREERDP_PRIMARY_UPDATE_MULTI_DRAW_NINE_GRID MakeMessageId(PrimaryUpdate, MultiDrawNineGrid)
#define FREERDP_PRIMARY_UPDATE_LINE_TO MakeMessageId(PrimaryUpdate, LineTo)
#define FREERDP_PRIMARY_UPDATE_POLYLINE MakeMessageId(PrimaryUpdate, Polyline)
#define FREERDP_PRIMARY_UPDATE_MEMBLT MakeMessageId(PrimaryUpdate, MemBlt)
#define FREERDP_PRIMARY_UPDATE_MEM3BLT MakeMessageId(PrimaryUpdate, Mem3Blt)
#define FREERDP_PRIMARY_UPDATE_SAVE_BITMAP MakeMessageId(PrimaryUpdate, SaveBitmap)
#define FREERDP_PRIMARY_UPDATE_GLYPH_INDEX MakeMessageId(PrimaryUpdate, GlyphIndex)
#define FREERDP_PRIMARY_UPDATE_FAST_INDEX MakeMessageId(PrimaryUpdate, FastIndex)
#define FREERDP_PRIMARY_UPDATE_FAST_GLYPH MakeMessageId(PrimaryUpdate, FastGlyph)
#define FREERDP_PRIMARY_UPDATE_POLYGON_SC MakeMessageId(PrimaryUpdate, PolygonSC)
#define FREERDP_PRIMARY_UPDATE_POLYGON_CB MakeMessageId(PrimaryUpdate, PolygonCB)
#define FREERDP_PRIMARY_UPDATE_ELLIPSE_SC MakeMessageId(PrimaryUpdate, EllipseSC)
#define FREERDP_PRIMARY_UPDATE_ELLIPSE_CB MakeMessageId(PrimaryUpdate, EllipseCB)
/* Secondary Update */
#define SecondaryUpdate_Class (Update_Base + 3)
#define SecondaryUpdate_CacheBitmap 1
#define SecondaryUpdate_CacheBitmapV2 2
#define SecondaryUpdate_CacheBitmapV3 3
#define SecondaryUpdate_CacheColorTable 4
#define SecondaryUpdate_CacheGlyph 5
#define SecondaryUpdate_CacheGlyphV2 6
#define SecondaryUpdate_CacheBrush 7
#define FREERDP_SECONDARY_UPDATE_CACHE_BITMAP MakeMessageId(SecondaryUpdate, CacheBitmap)
#define FREERDP_SECONDARY_UPDATE_CACHE_BITMAP_V2 MakeMessageId(SecondaryUpdate, CacheBitmapV2)
#define FREERDP_SECONDARY_UPDATE_CACHE_BITMAP_V3 MakeMessageId(SecondaryUpdate, CacheBitmapV3)
#define FREERDP_SECONDARY_UPDATE_CACHE_COLOR_TABLE MakeMessageId(SecondaryUpdate, CacheColorTable)
#define FREERDP_SECONDARY_UPDATE_CACHE_GLYPH MakeMessageId(SecondaryUpdate, CacheGlyph)
#define FREERDP_SECONDARY_UPDATE_CACHE_GLYPH_V2 MakeMessageId(SecondaryUpdate, CacheGlyphV2)
#define FREERDP_SECONDARY_UPDATE_CACHE_BRUSH MakeMessageId(SecondaryUpdate, CacheBrush)
/* Alternate Secondary Update */
#define AltSecUpdate_Class (Update_Base + 4)
#define AltSecUpdate_CreateOffscreenBitmap 1
#define AltSecUpdate_SwitchSurface 2
#define AltSecUpdate_CreateNineGridBitmap 3
#define AltSecUpdate_FrameMarker 4
#define AltSecUpdate_StreamBitmapFirst 5
#define AltSecUpdate_StreamBitmapNext 6
#define AltSecUpdate_DrawGdiPlusFirst 7
#define AltSecUpdate_DrawGdiPlusNext 8
#define AltSecUpdate_DrawGdiPlusEnd 9
#define AltSecUpdate_DrawGdiPlusCacheFirst 10
#define AltSecUpdate_DrawGdiPlusCacheNext 11
#define AltSecUpdate_DrawGdiPlusCacheEnd 12
#define FREERDP_ALTSEC_UPDATE_CREATE_OFFSCREEN_BITMAP MakeMessageId(AltSecUpdate, CreateOffscreenBitmap)
#define FREERDP_ALTSEC_UPDATE_SWITCH_SURFACE MakeMessageId(AltSecUpdate, SwitchSurface)
#define FREERDP_ALTSEC_UPDATE_CREATE_NINE_GRID_BITMAP MakeMessageId(AltSecUpdate, CreateNineGridBitmap)
#define FREERDP_ALTSEC_UPDATE_FRAME_MARKER MakeMessageId(AltSecUpdate, FrameMarker)
#define FREERDP_ALTSEC_UPDATE_STREAM_BITMAP_FIRST MakeMessageId(AltSecUpdate, StreamBitmapFirst)
#define FREERDP_ALTSEC_UPDATE_STREAM_BITMAP_NEXT MakeMessageId(AltSecUpdate, StreamBitmapNext)
#define FREERDP_ALTSEC_UPDATE_DRAW_GDI_PLUS_FIRST MakeMessageId(AltSecUpdate, DrawGdiPlusFirst)
#define FREERDP_ALTSEC_UPDATE_DRAW_GDI_PLUS_NEXT MakeMessageId(AltSecUpdate, DrawGdiPlusNext)
#define FREERDP_ALTSEC_UPDATE_DRAW_GDI_PLUS_END MakeMessageId(AltSecUpdate, DrawGdiPlusEnd)
#define FREERDP_ALTSEC_UPDATE_DRAW_GDI_PLUS_CACHE_FIRST MakeMessageId(AltSecUpdate, DrawGdiPlusCacheFirst)
#define FREERDP_ALTSEC_UPDATE_DRAW_GDI_PLUS_CACHE_NEXT MakeMessageId(AltSecUpdate, DrawGdiPlusCacheNext)
#define FREERDP_ALTSEC_UPDATE_DRAW_GDI_PLUS_CACHE_END MakeMessageId(AltSecUpdate, DrawGdiPlusCacheEnd)
/* Window Update */
#define WindowUpdate_Class (Update_Base + 5)
#define WindowUpdate_WindowCreate 1
#define WindowUpdate_WindowUpdate 2
#define WindowUpdate_WindowIcon 3
#define WindowUpdate_WindowCachedIcon 4
#define WindowUpdate_WindowDelete 5
#define WindowUpdate_NotifyIconCreate 6
#define WindowUpdate_NotifyIconUpdate 7
#define WindowUpdate_NotifyIconDelete 8
#define WindowUpdate_MonitoredDesktop 9
#define WindowUpdate_NonMonitoredDesktop 10
#define FREERDP_WINDOW_UPDATE_WINDOW_CREATE MakeMessageId(WindowUpdate, WindowCreate)
#define FREERDP_WINDOW_UPDATE_WINDOW_UPDATE MakeMessageId(WindowUpdate, WindowUpdate)
#define FREERDP_WINDOW_UPDATE_WINDOW_ICON MakeMessageId(WindowUpdate, WindowIcon)
#define FREERDP_WINDOW_UPDATE_WINDOW_CACHED_ICON MakeMessageId(WindowUpdate, WindowCachedIcon)
#define FREERDP_WINDOW_UPDATE_WINDOW_DELETE MakeMessageId(WindowUpdate, WindowDelete)
#define FREERDP_WINDOW_UPDATE_NOTIFY_ICON_CREATE MakeMessageId(WindowUpdate, NotifyIconCreate)
#define FREERDP_WINDOW_UPDATE_NOTIFY_ICON_UPDATE MakeMessageId(WindowUpdate, NotifyIconUpdate)
#define FREERDP_WINDOW_UPDATE_NOTIFY_ICON_DELETE MakeMessageId(WindowUpdate, NotifyIconDelete)
#define FREERDP_WINDOW_UPDATE_MONITORED_DESKTOP MakeMessageId(WindowUpdate, MonitoredDesktop)
#define FREERDP_WINDOW_UPDATE_NON_MONITORED_DESKTOP MakeMessageId(WindowUpdate, NonMonitoredDesktop)
/* Pointer Update */
#define PointerUpdate_Class (Update_Base + 6)
#define PointerUpdate_PointerPosition 1
#define PointerUpdate_PointerSystem 2
#define PointerUpdate_PointerColor 3
#define PointerUpdate_PointerNew 4
#define PointerUpdate_PointerCached 5
#define FREERDP_POINTER_UPDATE_ POINTER_POSITION MakeMessageId(PointerUpdate, PointerPosition)
#define FREERDP_POINTER_UPDATE_POINTER_SYSTEM MakeMessageId(PointerUpdate, PointerSystem)
#define FREERDP_POINTER_UPDATE_POINTER_COLOR MakeMessageId(PointerUpdate, PointerColor)
#define FREERDP_POINTER_UPDATE_POINTER_NEW MakeMessageId(PointerUpdate, PointerNew)
#define FREERDP_POINTER_UPDATE_POINTER_CACHED MakeMessageId(PointerUpdate, PointerCached)
/**
* Input Message Queue
*/
#define FREERDP_INPUT_MESSAGE_QUEUE 2
#define Input_Base 16
/* Input */
#define Input_Class (Input_Base + 1)
#define Input_SynchronizeEvent 1
#define Input_KeyboardEvent 2
#define Input_UnicodeKeyboardEvent 3
#define Input_MouseEvent 4
#define Input_ExtendedMouseEvent 5
#define FREERDP_INPUT_SYNCHRONIZE_EVENT MakeMessageId(Input, SynchronizeEvent)
#define FREERDP_INPUT_KEYBOARD_EVENT MakeMessageId(Input, KeyboardEvent)
#define FREERDP_INPUT_UNICODE_KEYBOARD_EVENT MakeMessageId(Input, UnicodeKeyboardEvent)
#define FREERDP_INPUT_MOUSE_EVENT MakeMessageId(Input, MouseEvent)
#define FREERDP_INPUT_EXTENDED_MOUSE_EVENT MakeMessageId(Input, ExtendedMouseEvent)
#endif /* FREERDP_CORE_MESSAGE_H */

View File

@ -22,6 +22,30 @@
#include <freerdp/types.h>
struct _GLYPH_DATA
{
UINT32 cacheIndex;
INT32 x;
INT32 y;
UINT32 cx;
UINT32 cy;
UINT32 cb;
BYTE* aj;
};
typedef struct _GLYPH_DATA GLYPH_DATA;
struct _GLYPH_DATA_V2
{
UINT32 cacheIndex;
INT32 x;
INT32 y;
UINT32 cx;
UINT32 cy;
UINT32 cb;
BYTE* aj;
};
typedef struct _GLYPH_DATA_V2 GLYPH_DATA_V2;
#define BACKMODE_TRANSPARENT 0x0001
#define BACKMODE_OPAQUE 0x0002
@ -357,7 +381,7 @@ struct _FAST_GLYPH_ORDER
INT32 y;
UINT32 cbData;
BYTE data[256];
void* glyph_data;
GLYPH_DATA_V2 glyphData;
};
typedef struct _FAST_GLYPH_ORDER FAST_GLYPH_ORDER;

View File

@ -21,6 +21,7 @@
#define FREERDP_UPDATE_SECONDARY_H
#include <freerdp/types.h>
#include <freerdp/primary.h>
#define GLYPH_FRAGMENT_NOP 0x00
#define GLYPH_FRAGMENT_USE 0xFE
@ -127,49 +128,25 @@ struct _CACHE_COLOR_TABLE_ORDER
{
UINT32 cacheIndex;
UINT32 numberColors;
UINT32* colorTable;
UINT32 colorTable[256];
};
typedef struct _CACHE_COLOR_TABLE_ORDER CACHE_COLOR_TABLE_ORDER;
struct _GLYPH_DATA
{
UINT32 cacheIndex;
INT32 x;
INT32 y;
UINT32 cx;
UINT32 cy;
UINT32 cb;
BYTE* aj;
};
typedef struct _GLYPH_DATA GLYPH_DATA;
struct _CACHE_GLYPH_ORDER
{
UINT32 cacheId;
UINT32 cGlyphs;
GLYPH_DATA* glyphData[255];
GLYPH_DATA glyphData[256];
BYTE* unicodeCharacters;
};
typedef struct _CACHE_GLYPH_ORDER CACHE_GLYPH_ORDER;
struct _GLYPH_DATA_V2
{
UINT32 cacheIndex;
INT32 x;
INT32 y;
UINT32 cx;
UINT32 cy;
UINT32 cb;
BYTE* aj;
};
typedef struct _GLYPH_DATA_V2 GLYPH_DATA_V2;
struct _CACHE_GLYPH_V2_ORDER
{
UINT32 cacheId;
UINT32 flags;
UINT32 cGlyphs;
GLYPH_DATA_V2* glyphData[255];
GLYPH_DATA_V2 glyphData[256];
BYTE* unicodeCharacters;
};
typedef struct _CACHE_GLYPH_V2_ORDER CACHE_GLYPH_V2_ORDER;
@ -182,7 +159,7 @@ struct _CACHE_BRUSH_ORDER
UINT32 cy;
UINT32 style;
UINT32 length;
BYTE* data;
BYTE data[256];
};
typedef struct _CACHE_BRUSH_ORDER CACHE_BRUSH_ORDER;

View File

@ -676,7 +676,9 @@ struct rdp_settings
ALIGN64 BOOL MouseMotion; /* 1541 */
ALIGN64 char* WindowTitle; /* 1542 */
ALIGN64 UINT64 ParentWindowId; /* 1543 */
UINT64 padding1600[1600 - 1544]; /* 1544 */
ALIGN64 BOOL AsyncInput; /* 1544 */
ALIGN64 BOOL AsyncUpdate; /* 1545 */
UINT64 padding1600[1600 - 1546]; /* 1546 */
/* Miscellaneous */
ALIGN64 BOOL SoftwareGdi; /* 1601 */

View File

@ -90,7 +90,7 @@ typedef struct _PALETTE_UPDATE PALETTE_UPDATE;
struct rdp_palette
{
UINT32 count;
PALETTE_ENTRY* entries;
PALETTE_ENTRY entries[256];
};
typedef struct rdp_palette rdpPalette;
@ -134,6 +134,9 @@ enum SURFCMD_FRAMEACTION
SURFACECMD_FRAMEACTION_END = 0x0001
};
/* defined inside libfreerdp-core */
typedef struct rdp_update_proxy rdpUpdateProxy;
/* Update Interface */
typedef void (*pBeginPaint)(rdpContext* context);
@ -191,6 +194,7 @@ struct rdp_update
BOOL dump_rfx;
BOOL play_rfx;
rdpPcap* pcap_rfx;
BOOL initialState;
BITMAP_UPDATE bitmap_update;
PALETTE_UPDATE palette_update;
@ -199,8 +203,9 @@ struct rdp_update
SURFACE_BITS_COMMAND surface_bits_command;
SURFACE_FRAME_MARKER surface_frame_marker;
HANDLE thread;
wQueue* queue;
BOOL asynchronous;
rdpUpdateProxy* proxy;
wMessageQueue* queue;
};
#endif /* FREERDP_UPDATE_H */

View File

@ -75,8 +75,16 @@ void update_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
void update_gdi_cache_brush(rdpContext* context, CACHE_BRUSH_ORDER* cache_brush)
{
int length;
void* data = NULL;
rdpCache* cache = context->cache;
brush_cache_put(cache->brush, cache_brush->index, cache_brush->data, cache_brush->bpp);
length = cache_brush->bpp * 64 / 8;
data = malloc(length);
CopyMemory(data, cache_brush->data, length);
brush_cache_put(cache->brush, cache_brush->index, data, cache_brush->bpp);
}
void* brush_cache_get(rdpBrushCache* brush, UINT32 index, UINT32* bpp)

View File

@ -173,6 +173,7 @@ void update_gdi_glyph_index(rdpContext* context, GLYPH_INDEX_ORDER* glyph_index)
rdpGlyphCache* glyph_cache;
glyph_cache = context->cache->glyph;
update_process_glyph_fragments(context, glyph_index->data, glyph_index->cbData,
glyph_index->cacheId, glyph_index->ulCharInc, glyph_index->flAccel,
glyph_index->backColor, glyph_index->foreColor, glyph_index->x, glyph_index->y,
@ -184,8 +185,9 @@ void update_gdi_glyph_index(rdpContext* context, GLYPH_INDEX_ORDER* glyph_index)
void update_gdi_fast_index(rdpContext* context, FAST_INDEX_ORDER* fast_index)
{
INT32 opLeft, opTop, opRight, opBottom;
INT32 x, y;
INT32 opLeft, opTop;
INT32 opRight, opBottom;
rdpGlyphCache* glyph_cache;
glyph_cache = context->cache->glyph;
@ -234,12 +236,13 @@ void update_gdi_fast_index(rdpContext* context, FAST_INDEX_ORDER* fast_index)
void update_gdi_fast_glyph(rdpContext* context, FAST_GLYPH_ORDER* fast_glyph)
{
INT32 opLeft, opTop, opRight, opBottom;
INT32 x, y;
GLYPH_DATA_V2* glyph_data;
rdpGlyph* glyph;
rdpCache* cache = context->cache;
BYTE text_data[2];
INT32 opLeft, opTop;
INT32 opRight, opBottom;
GLYPH_DATA_V2* glyph_data;
rdpCache* cache = context->cache;
opLeft = fast_glyph->opLeft;
opTop = fast_glyph->opTop;
@ -274,21 +277,21 @@ void update_gdi_fast_glyph(rdpContext* context, FAST_GLYPH_ORDER* fast_glyph)
if (y == -32768)
y = fast_glyph->bkTop;
if (fast_glyph->glyph_data != NULL)
if (fast_glyph->cbData > 1)
{
/* got option font that needs to go into cache */
glyph_data = (GLYPH_DATA_V2*) (fast_glyph->glyph_data);
glyph_data = &fast_glyph->glyphData;
glyph = Glyph_Alloc(context);
glyph->x = glyph_data->x;
glyph->y = glyph_data->y;
glyph->cx = glyph_data->cx;
glyph->cy = glyph_data->cy;
glyph->aj = glyph_data->aj;
glyph->cb = glyph_data->cb;
glyph->aj = glyph_data->aj;
Glyph_New(context, glyph);
glyph_cache_put(cache->glyph, fast_glyph->cacheId, fast_glyph->data[0], glyph);
free(fast_glyph->glyph_data);
fast_glyph->glyph_data = NULL;
}
text_data[0] = fast_glyph->data[0];
@ -312,7 +315,7 @@ void update_gdi_cache_glyph(rdpContext* context, CACHE_GLYPH_ORDER* cache_glyph)
for (i = 0; i < (int) cache_glyph->cGlyphs; i++)
{
glyph_data = cache_glyph->glyphData[i];
glyph_data = &cache_glyph->glyphData[i];
glyph = Glyph_Alloc(context);
@ -320,14 +323,11 @@ void update_gdi_cache_glyph(rdpContext* context, CACHE_GLYPH_ORDER* cache_glyph)
glyph->y = glyph_data->y;
glyph->cx = glyph_data->cx;
glyph->cy = glyph_data->cy;
glyph->aj = glyph_data->aj;
glyph->cb = glyph_data->cb;
glyph->aj = glyph_data->aj;
Glyph_New(context, glyph);
glyph_cache_put(cache->glyph, cache_glyph->cacheId, glyph_data->cacheIndex, glyph);
cache_glyph->glyphData[i] = NULL;
free(glyph_data);
}
}
@ -340,7 +340,7 @@ void update_gdi_cache_glyph_v2(rdpContext* context, CACHE_GLYPH_V2_ORDER* cache_
for (i = 0; i < (int) cache_glyph_v2->cGlyphs; i++)
{
glyph_data = cache_glyph_v2->glyphData[i];
glyph_data = &cache_glyph_v2->glyphData[i];
glyph = Glyph_Alloc(context);
@ -348,14 +348,11 @@ void update_gdi_cache_glyph_v2(rdpContext* context, CACHE_GLYPH_V2_ORDER* cache_
glyph->y = glyph_data->y;
glyph->cx = glyph_data->cx;
glyph->cy = glyph_data->cy;
glyph->aj = glyph_data->aj;
glyph->cb = glyph_data->cb;
glyph->aj = glyph_data->aj;
Glyph_New(context, glyph);
glyph_cache_put(cache->glyph, cache_glyph_v2->cacheId, glyph_data->cacheIndex, glyph);
cache_glyph_v2->glyphData[i] = NULL;
free(glyph_data);
}
}

View File

@ -25,14 +25,17 @@
#include <winpr/crt.h>
#include <freerdp/utils/stream.h>
#include <freerdp/cache/palette.h>
void update_gdi_cache_color_table(rdpContext* context, CACHE_COLOR_TABLE_ORDER* cache_color_table)
{
UINT32* colorTable;
rdpCache* cache = context->cache;
palette_cache_put(cache->palette, cache_color_table->cacheIndex, (void*) cache_color_table->colorTable);
colorTable = (UINT32*) malloc(sizeof(UINT32) * 256);
CopyMemory(colorTable, cache_color_table->colorTable, sizeof(UINT32) * 256);
palette_cache_put(cache->palette, cache_color_table->cacheIndex, (void*) colorTable);
}
void* palette_cache_get(rdpPaletteCache* palette_cache, UINT32 index)
@ -98,4 +101,3 @@ void palette_cache_free(rdpPaletteCache* palette_cache)
free(palette_cache);
}
}

View File

@ -48,6 +48,7 @@ void update_pointer_system(rdpContext* context, POINTER_SYSTEM_UPDATE* pointer_s
default:
printf("Unknown system pointer type (0x%08X)\n", pointer_system->type);
break;
}
}
@ -92,8 +93,20 @@ void update_pointer_new(rdpContext* context, POINTER_NEW_UPDATE* pointer_new)
pointer->height = pointer_new->colorPtrAttr.height;
pointer->lengthAndMask = pointer_new->colorPtrAttr.lengthAndMask;
pointer->lengthXorMask = pointer_new->colorPtrAttr.lengthXorMask;
pointer->xorMaskData = pointer_new->colorPtrAttr.xorMaskData;
pointer->andMaskData = pointer_new->colorPtrAttr.andMaskData;
pointer->andMaskData = pointer->xorMaskData = NULL;
if (pointer->lengthAndMask)
{
pointer->andMaskData = (BYTE*) malloc(pointer->lengthAndMask);
CopyMemory(pointer->andMaskData, pointer_new->colorPtrAttr.andMaskData, pointer->lengthAndMask);
}
if (pointer->lengthXorMask)
{
pointer->xorMaskData = (BYTE*) malloc(pointer->lengthXorMask);
CopyMemory(pointer->xorMaskData, pointer_new->colorPtrAttr.xorMaskData, pointer->lengthXorMask);
}
pointer->New(context, pointer);
pointer_cache_put(cache->pointer, pointer_new->colorPtrAttr.cacheIndex, pointer);

View File

@ -342,6 +342,17 @@ UINT32 freerdp_color_convert_var(UINT32 srcColor, int srcBpp, int dstBpp, HCLRCO
UINT32 freerdp_color_convert_var_rgb(UINT32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv)
{
if (srcBpp == 8)
{
BYTE alpha = 0xFF;
UINT32 dstColor = 0;
PALETTE_ENTRY* entry = &clrconv->palette->entries[srcColor & 0xFF];
freerdp_color_make_bgr(&dstColor, dstBpp, &entry->red, &entry->green, &entry->blue, &alpha, clrconv);
return dstColor;
}
if (srcBpp > 16)
return freerdp_color_convert_bgr_rgb(srcColor, srcBpp, dstBpp, clrconv);
else
@ -350,6 +361,17 @@ UINT32 freerdp_color_convert_var_rgb(UINT32 srcColor, int srcBpp, int dstBpp, HC
UINT32 freerdp_color_convert_var_bgr(UINT32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv)
{
if (srcBpp == 8)
{
BYTE alpha = 0xFF;
UINT32 dstColor = 0;
PALETTE_ENTRY* entry = &clrconv->palette->entries[srcColor & 0xFF];
freerdp_color_make_rgb(&dstColor, dstBpp, &entry->red, &entry->green, &entry->blue, &alpha, clrconv);
return dstColor;
}
if (srcBpp > 16)
return freerdp_color_convert_bgr(srcColor, srcBpp, dstBpp, clrconv);
else
@ -751,7 +773,7 @@ BYTE* freerdp_image_convert(BYTE* srcData, BYTE* dstData, int width, int height,
return 0;
}
void freerdp_bitmap_flip(BYTE * src, BYTE * dst, int scanLineSz, int height)
void freerdp_bitmap_flip(BYTE * src, BYTE * dst, int scanLineSz, int height)
{
int i;

View File

@ -324,17 +324,22 @@ int rfx_tile_pool_return(RFX_CONTEXT* context, RFX_TILE* tile)
return 0;
}
static void rfx_process_message_sync(RFX_CONTEXT* context, STREAM* s)
static BOOL rfx_process_message_sync(RFX_CONTEXT* context, STREAM* s)
{
UINT32 magic;
/* RFX_SYNC */
if (stream_get_left(s) < 6)
{
DEBUG_WARN("RfxSync packet too small");
return FALSE;
}
stream_read_UINT32(s, magic); /* magic (4 bytes), 0xCACCACCA */
if (magic != WF_MAGIC)
{
DEBUG_WARN("invalid magic number 0x%X", magic);
return;
return FALSE;
}
stream_read_UINT16(s, context->version); /* version (2 bytes), WF_VERSION_1_0 (0x0100) */
@ -342,22 +347,34 @@ static void rfx_process_message_sync(RFX_CONTEXT* context, STREAM* s)
if (context->version != WF_VERSION_1_0)
{
DEBUG_WARN("unknown version number 0x%X", context->version);
return;
return FALSE;
}
DEBUG_RFX("version 0x%X", context->version);
return TRUE;
}
static void rfx_process_message_codec_versions(RFX_CONTEXT* context, STREAM* s)
static BOOL rfx_process_message_codec_versions(RFX_CONTEXT* context, STREAM* s)
{
BYTE numCodecs;
if (stream_get_left(s) < 1)
{
DEBUG_WARN("RfxCodecVersion packet too small");
return FALSE;
}
stream_read_BYTE(s, numCodecs); /* numCodecs (1 byte), must be set to 0x01 */
if (numCodecs != 1)
{
DEBUG_WARN("numCodecs: %d, expected:1", numCodecs);
return;
return FALSE;
}
if (stream_get_left(s) < 2 * numCodecs)
{
DEBUG_WARN("RfxCodecVersion packet too small for numCodecs=%d", numCodecs);
return FALSE;
}
/* RFX_CODEC_VERSIONT */
@ -365,13 +382,20 @@ static void rfx_process_message_codec_versions(RFX_CONTEXT* context, STREAM* s)
stream_read_BYTE(s, context->codec_version); /* version (2 bytes) */
DEBUG_RFX("id %d version 0x%X.", context->codec_id, context->codec_version);
return TRUE;
}
static void rfx_process_message_channels(RFX_CONTEXT* context, STREAM* s)
static BOOL rfx_process_message_channels(RFX_CONTEXT* context, STREAM* s)
{
BYTE channelId;
BYTE numChannels;
if (stream_get_left(s) < 1)
{
DEBUG_WARN("RfxMessageChannels packet too small");
return FALSE;
}
stream_read_BYTE(s, numChannels); /* numChannels (1 byte), must bet set to 0x01 */
/* In RDVH sessions, numChannels will represent the number of virtual monitors
@ -380,7 +404,13 @@ static void rfx_process_message_channels(RFX_CONTEXT* context, STREAM* s)
if (numChannels < 1)
{
DEBUG_WARN("numChannels:%d, expected:1", numChannels);
return;
return TRUE;
}
if (stream_get_left(s) < numChannels * 5)
{
DEBUG_WARN("RfxMessageChannels packet too small for numChannels=%d", numChannels);
return FALSE;
}
/* RFX_CHANNELT */
@ -393,14 +423,21 @@ static void rfx_process_message_channels(RFX_CONTEXT* context, STREAM* s)
DEBUG_RFX("numChannels %d id %d, %dx%d.",
numChannels, channelId, context->width, context->height);
return TRUE;
}
static void rfx_process_message_context(RFX_CONTEXT* context, STREAM* s)
static BOOL rfx_process_message_context(RFX_CONTEXT* context, STREAM* s)
{
BYTE ctxId;
UINT16 tileSize;
UINT16 properties;
if (stream_get_left(s) < 5)
{
DEBUG_WARN("RfxMessageContext packet too small");
return FALSE;
}
stream_read_BYTE(s, ctxId); /* ctxId (1 byte), must be set to 0x00 */
stream_read_UINT16(s, tileSize); /* tileSize (2 bytes), must be set to CT_TILE_64x64 (0x0040) */
stream_read_UINT16(s, properties); /* properties (2 bytes) */
@ -431,17 +468,24 @@ static void rfx_process_message_context(RFX_CONTEXT* context, STREAM* s)
DEBUG_WARN("unknown RLGR algorithm.");
break;
}
return TRUE;
}
static void rfx_process_message_frame_begin(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s)
static BOOL rfx_process_message_frame_begin(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s)
{
UINT32 frameIdx;
UINT16 numRegions;
if (stream_get_left(s) < 6)
{
DEBUG_WARN("RfxMessageFrameBegin packet too small");
return FALSE;
}
stream_read_UINT32(s, frameIdx); /* frameIdx (4 bytes), if codec is in video mode, must be ignored */
stream_read_UINT16(s, numRegions); /* numRegions (2 bytes) */
DEBUG_RFX("RFX_FRAME_BEGIN: frameIdx:%d numRegions:%d", frameIdx, numRegions);
return TRUE;
}
static void rfx_process_message_frame_end(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s)
@ -449,17 +493,29 @@ static void rfx_process_message_frame_end(RFX_CONTEXT* context, RFX_MESSAGE* mes
DEBUG_RFX("RFX_FRAME_END");
}
static void rfx_process_message_region(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s)
static BOOL rfx_process_message_region(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s)
{
int i;
if (stream_get_left(s) < 3)
{
DEBUG_WARN("RfxMessageRegion packet too small");
return FALSE;
}
stream_seek_BYTE(s); /* regionFlags (1 byte) */
stream_read_UINT16(s, message->num_rects); /* numRects (2 bytes) */
if (message->num_rects < 1)
{
DEBUG_WARN("no rects.");
return;
return TRUE;
}
if (stream_get_left(s) < 8 * message->num_rects)
{
DEBUG_WARN("RfxMessageRegion packet too small for num_rects=%d", message->num_rects);
return FALSE;
}
if (message->rects != NULL)
@ -479,9 +535,10 @@ static void rfx_process_message_region(RFX_CONTEXT* context, RFX_MESSAGE* messag
DEBUG_RFX("rect %d (%d %d %d %d).",
i, message->rects[i].x, message->rects[i].y, message->rects[i].width, message->rects[i].height);
}
return TRUE;
}
static void rfx_process_message_tile(RFX_CONTEXT* context, RFX_TILE* tile, STREAM* s)
static BOOL rfx_process_message_tile(RFX_CONTEXT* context, RFX_TILE* tile, STREAM* s)
{
BYTE quantIdxY;
BYTE quantIdxCb;
@ -489,6 +546,12 @@ static void rfx_process_message_tile(RFX_CONTEXT* context, RFX_TILE* tile, STREA
UINT16 xIdx, yIdx;
UINT16 YLen, CbLen, CrLen;
if (stream_get_left(s) < 13)
{
DEBUG_WARN("RfxMessageTile packet too small");
return FALSE;
}
/* RFX_TILE */
stream_read_BYTE(s, quantIdxY); /* quantIdxY (1 byte) */
stream_read_BYTE(s, quantIdxCb); /* quantIdxCb (1 byte) */
@ -505,7 +568,7 @@ static void rfx_process_message_tile(RFX_CONTEXT* context, RFX_TILE* tile, STREA
tile->x = xIdx * 64;
tile->y = yIdx * 64;
rfx_decode_rgb(context, s,
return rfx_decode_rgb(context, s,
YLen, context->quants + (quantIdxY * 10),
CbLen, context->quants + (quantIdxCb * 10),
CrLen, context->quants + (quantIdxCr * 10),
@ -526,7 +589,7 @@ void CALLBACK rfx_process_message_tile_work_callback(PTP_CALLBACK_INSTANCE insta
rfx_process_message_tile(param->context, param->tile, &(param->s));
}
static void rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s)
static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s)
{
int i;
int pos;
@ -539,12 +602,18 @@ static void rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa
PTP_WORK* work_objects = NULL;
RFX_TILE_WORK_PARAM* params = NULL;
if (stream_get_left(s) < 14)
{
DEBUG_WARN("RfxMessageTileSet packet too small");
return FALSE;
}
stream_read_UINT16(s, subtype); /* subtype (2 bytes) must be set to CBT_TILESET (0xCAC2) */
if (subtype != CBT_TILESET)
{
DEBUG_WARN("invalid subtype, expected CBT_TILESET.");
return;
return FALSE;
}
stream_seek_UINT16(s); /* idx (2 bytes), must be set to 0x0000 */
@ -556,7 +625,7 @@ static void rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa
if (context->num_quants < 1)
{
DEBUG_WARN("no quantization value.");
return;
return TRUE;
}
stream_read_UINT16(s, message->num_tiles); /* numTiles (2 bytes) */
@ -564,7 +633,7 @@ static void rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa
if (message->num_tiles < 1)
{
DEBUG_WARN("no tiles.");
return;
return TRUE;
}
stream_read_UINT32(s, tilesDataSize); /* tilesDataSize (4 bytes) */
@ -576,6 +645,12 @@ static void rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa
quants = context->quants;
/* quantVals */
if (stream_get_left(s) < context->num_quants * 5)
{
DEBUG_WARN("RfxMessageTileSet packet too small for num_quants=%d", context->num_quants);
return FALSE;
}
for (i = 0; i < context->num_quants; i++)
{
/* RFX_CODEC_QUANT */
@ -616,9 +691,21 @@ static void rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa
for (i = 0; i < message->num_tiles; i++)
{
/* RFX_TILE */
if (stream_get_left(s) < 6)
{
DEBUG_WARN("RfxMessageTileSet packet too small to read tile %d/%d", i, message->num_tiles);
return FALSE;
}
stream_read_UINT16(s, blockType); /* blockType (2 bytes), must be set to CBT_TILE (0xCAC3) */
stream_read_UINT32(s, blockLen); /* blockLen (4 bytes) */
if (stream_get_left(s) < blockLen - 6)
{
DEBUG_WARN("RfxMessageTileSet not enough bytes to read tile %d/%d with blocklen=%d", i, message->num_tiles, blockLen);
return FALSE;
}
pos = stream_get_pos(s) - 6 + blockLen;
if (blockType != CBT_TILE)
@ -656,6 +743,7 @@ static void rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa
free(work_objects);
free(params);
}
return TRUE;
}
RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length)
@ -686,6 +774,13 @@ RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length
break;
}
if (stream_get_left(s) < blockLen - 6)
{
DEBUG_WARN("rfx_process_message: packet too small for blocklen=%d", blockLen);
break;
}
pos = stream_get_pos(s) - 6 + blockLen;
if (blockType >= WBT_CONTEXT && blockType <= WBT_EXTENSION)
@ -693,7 +788,11 @@ RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length
/* RFX_CODEC_CHANNELT */
/* codecId (1 byte) must be set to 0x01 */
/* channelId (1 byte) must be set to 0x00 */
stream_seek(s, 2);
if (!stream_skip(s, 2))
{
DEBUG_WARN("rfx_process_message: unable to skip RFX_CODEC_CHANNELT");
break;
}
}
switch (blockType)

View File

@ -142,7 +142,7 @@ void CALLBACK rfx_decode_component_work_callback(PTP_CALLBACK_INSTANCE instance,
}
/* stride is bytes between rows in the output buffer. */
void rfx_decode_rgb(RFX_CONTEXT* context, STREAM* data_in,
BOOL rfx_decode_rgb(RFX_CONTEXT* context, STREAM* data_in,
int y_size, const UINT32* y_quants,
int cb_size, const UINT32* cb_quants,
int cr_size, const UINT32* cr_quants, BYTE* rgb_buffer, int stride)
@ -202,6 +202,11 @@ void rfx_decode_rgb(RFX_CONTEXT* context, STREAM* data_in,
else
#endif
{
if (stream_get_left(data_in) < y_size+cb_size+cr_size)
{
DEBUG_WARN("rfx_decode_rgb: packet too small for y_size+cb_size+cr_size");
return FALSE;
}
rfx_decode_component(context, y_quants, stream_get_tail(data_in), y_size, pSrcDst[0]); /* YData */
stream_seek(data_in, y_size);
@ -225,4 +230,5 @@ void rfx_decode_rgb(RFX_CONTEXT* context, STREAM* data_in,
BufferPool_Return(context->priv->BufferPool, pSrcDst[0]);
BufferPool_Return(context->priv->BufferPool, pSrcDst[1]);
BufferPool_Return(context->priv->BufferPool, pSrcDst[2]);
return TRUE;
}

View File

@ -23,7 +23,7 @@
#include <freerdp/codec/rfx.h>
/* stride is bytes between rows in the output buffer. */
void rfx_decode_rgb(RFX_CONTEXT* context, STREAM* data_in,
BOOL rfx_decode_rgb(RFX_CONTEXT* context, STREAM* data_in,
int y_size, const UINT32 * y_quants,
int cb_size, const UINT32 * cb_quants,
int cr_size, const UINT32 * cr_quants, BYTE* rgb_buffer,

View File

@ -155,7 +155,7 @@ rfx_dwt_2d_decode_block_horiz_sse2(INT16* l, INT16* h, INT16* dst, int subband_w
for (y = 0; y < subband_width; y++)
{
/* Even coefficients */
for (n = 0; n < subband_width; n+=8)
for (n = 0; n < subband_width; n += 8)
{
/* dst[2n] = l[n] - ((h[n-1] + h[n] + 1) >> 1); */
@ -163,6 +163,7 @@ rfx_dwt_2d_decode_block_horiz_sse2(INT16* l, INT16* h, INT16* dst, int subband_w
h_n = _mm_load_si128((__m128i*) h_ptr);
h_n_m = _mm_loadu_si128((__m128i*) (h_ptr - 1));
if (n == 0)
{
first = _mm_extract_epi16(h_n_m, 1);
@ -177,14 +178,15 @@ rfx_dwt_2d_decode_block_horiz_sse2(INT16* l, INT16* h, INT16* dst, int subband_w
_mm_store_si128((__m128i*) l_ptr, dst_n);
l_ptr+=8;
h_ptr+=8;
l_ptr += 8;
h_ptr += 8;
}
l_ptr -= subband_width;
h_ptr -= subband_width;
/* Odd coefficients */
for (n = 0; n < subband_width; n+=8)
for (n = 0; n < subband_width; n += 8)
{
/* dst[2n + 1] = (h[n] << 1) + ((dst[2n] + dst[2n + 2]) >> 1); */
@ -194,6 +196,7 @@ rfx_dwt_2d_decode_block_horiz_sse2(INT16* l, INT16* h, INT16* dst, int subband_w
dst_n = _mm_load_si128((__m128i*) (l_ptr));
dst_n_p = _mm_loadu_si128((__m128i*) (l_ptr + 1));
if (n == subband_width - 8)
{
last = _mm_extract_epi16(dst_n_p, 6);
@ -211,9 +214,9 @@ rfx_dwt_2d_decode_block_horiz_sse2(INT16* l, INT16* h, INT16* dst, int subband_w
_mm_store_si128((__m128i*) dst_ptr, dst1);
_mm_store_si128((__m128i*) (dst_ptr + 8), dst2);
l_ptr+=8;
h_ptr+=8;
dst_ptr+=16;
l_ptr += 8;
h_ptr += 8;
dst_ptr += 16;
}
}
}

View File

@ -215,11 +215,15 @@ ADDIN_ARGV* freerdp_static_channel_collection_find(rdpSettings* settings, const
void freerdp_static_channel_collection_free(rdpSettings* settings)
{
int index;
int i, j;
for (index = 0; index < settings->StaticChannelCount; index++)
for (i = 0; i < settings->StaticChannelCount; i++)
{
free(settings->StaticChannelArray[index]);
for (j = 0; j < settings->StaticChannelArray[i]->argc; j++)
free(settings->StaticChannelArray[i]->argv[j]);
free(settings->StaticChannelArray[i]->argv);
free(settings->StaticChannelArray[i]);
}
free(settings->StaticChannelArray);

View File

@ -101,6 +101,8 @@ set(${MODULE_PREFIX}_SRCS
transport.h
update.c
update.h
message.c
message.h
channel.c
channel.h
window.c

View File

@ -248,14 +248,14 @@ BOOL rdp_recv_server_font_map_pdu(rdpRdp* rdp, STREAM* s)
BOOL rdp_recv_client_font_map_pdu(rdpRdp* rdp, STREAM* s)
{
if(stream_get_left(s) < 8)
return FALSE;
rdp->finalize_sc_pdus |= FINALIZE_SC_FONT_MAP_PDU;
stream_seek_UINT16(s); /* numberEntries (2 bytes) */
stream_seek_UINT16(s); /* totalNumEntries (2 bytes) */
stream_seek_UINT16(s); /* mapFlags (2 bytes) */
stream_seek_UINT16(s); /* entrySize (2 bytes) */
if(stream_get_left(s) >= 8)
{
stream_seek_UINT16(s); /* numberEntries (2 bytes) */
stream_seek_UINT16(s); /* totalNumEntries (2 bytes) */
stream_seek_UINT16(s); /* mapFlags (2 bytes) */
stream_seek_UINT16(s); /* entrySize (2 bytes) */
}
return TRUE;
}

View File

@ -212,8 +212,9 @@ BOOL rdp_read_bitmap_capability_set(STREAM* s, UINT16 length, rdpSettings* setti
UINT16 desktopResizeFlag;
UINT16 preferredBitsPerPixel;
if(length < 28)
if (length < 28)
return FALSE;
stream_read_UINT16(s, preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */
stream_seek_UINT16(s); /* receive1BitPerPixel (2 bytes) */
stream_seek_UINT16(s); /* receive4BitsPerPixel (2 bytes) */
@ -228,7 +229,7 @@ BOOL rdp_read_bitmap_capability_set(STREAM* s, UINT16 length, rdpSettings* setti
stream_seek_UINT16(s); /* multipleRectangleSupport (2 bytes) */
stream_seek_UINT16(s); /* pad2OctetsB (2 bytes) */
if (!settings->ServerMode && preferredBitsPerPixel != settings->ColorDepth)
if (!settings->ServerMode && (preferredBitsPerPixel != settings->ColorDepth))
{
/* The client must respect the actual color depth used by the server */
settings->ColorDepth = preferredBitsPerPixel;
@ -243,6 +244,7 @@ BOOL rdp_read_bitmap_capability_set(STREAM* s, UINT16 length, rdpSettings* setti
settings->DesktopWidth = desktopWidth;
settings->DesktopHeight = desktopHeight;
}
return TRUE;
}
@ -1546,8 +1548,9 @@ BOOL rdp_read_bitmap_codecs_capability_set(STREAM* s, UINT16 length, rdpSettings
UINT16 codecPropertiesLength;
UINT16 remainingLength;
if(length < 5)
if (length < 5)
return FALSE;
stream_read_BYTE(s, bitmapCodecCount); /* bitmapCodecCount (1 byte) */
remainingLength = length - 5;
@ -1560,8 +1563,9 @@ BOOL rdp_read_bitmap_codecs_capability_set(STREAM* s, UINT16 length, rdpSettings
while (bitmapCodecCount > 0)
{
if(remainingLength < 19)
if (remainingLength < 19)
return FALSE;
if (settings->ServerMode && strncmp((char*) stream_get_tail(s), CODEC_GUID_REMOTEFX, 16) == 0)
{
stream_seek(s, 16); /* codecGUID (16 bytes) */
@ -1582,7 +1586,8 @@ BOOL rdp_read_bitmap_codecs_capability_set(STREAM* s, UINT16 length, rdpSettings
stream_read_UINT16(s, codecPropertiesLength); /* codecPropertiesLength (2 bytes) */
remainingLength -= 19;
if(remainingLength < codecPropertiesLength)
if (remainingLength < codecPropertiesLength)
return FALSE;
stream_seek(s, codecPropertiesLength); /* codecProperties */

View File

@ -558,20 +558,20 @@ BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate,
* @param length certificate length
*/
BOOL certificate_read_server_certificate(rdpCertificate* certificate, BYTE* server_cert, int length)
int certificate_read_server_certificate(rdpCertificate* certificate, BYTE* server_cert, int length)
{
STREAM* s;
UINT32 dwVersion;
BOOL ret = TRUE;
int status = 1;
if (length < 1)
{
DEBUG_CERTIFICATE("null server certificate\n");
return FALSE;
return 0;
}
if (length < 4)
return FALSE;
return -1;
s = stream_new(0);
stream_attach(s, server_cert, length);
@ -581,20 +581,22 @@ BOOL certificate_read_server_certificate(rdpCertificate* certificate, BYTE* serv
switch (dwVersion & CERT_CHAIN_VERSION_MASK)
{
case CERT_CHAIN_VERSION_1:
ret = certificate_read_server_proprietary_certificate(certificate, s);
status = certificate_read_server_proprietary_certificate(certificate, s);
break;
case CERT_CHAIN_VERSION_2:
ret = certificate_read_server_x509_certificate_chain(certificate, s);
status = certificate_read_server_x509_certificate_chain(certificate, s);
break;
default:
printf("invalid certificate chain version:%d\n", dwVersion & CERT_CHAIN_VERSION_MASK);
status = -1;
break;
}
free(s);
return ret;
return status;
}
rdpRsaKey* key_new(const char* keyfile)

View File

@ -49,7 +49,7 @@ void certificate_free_x509_certificate_chain(rdpX509CertChain* x509_cert_chain);
BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate, STREAM* s);
BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, STREAM* s);
BOOL certificate_read_server_certificate(rdpCertificate* certificate, BYTE* server_cert, int length);
int certificate_read_server_certificate(rdpCertificate* certificate, BYTE* server_cert, int length);
rdpCertificate* certificate_new();
void certificate_free(rdpCertificate* certificate);

View File

@ -32,16 +32,16 @@
enum CONNECTION_STATE
{
CONNECTION_STATE_INITIAL = 0,
CONNECTION_STATE_NEGO,
CONNECTION_STATE_MCS_CONNECT,
CONNECTION_STATE_MCS_ERECT_DOMAIN,
CONNECTION_STATE_MCS_ATTACH_USER,
CONNECTION_STATE_MCS_CHANNEL_JOIN,
CONNECTION_STATE_ESTABLISH_KEYS,
CONNECTION_STATE_LICENSE,
CONNECTION_STATE_CAPABILITY,
CONNECTION_STATE_FINALIZATION,
CONNECTION_STATE_ACTIVE
CONNECTION_STATE_NEGO = 1,
CONNECTION_STATE_MCS_CONNECT = 2,
CONNECTION_STATE_MCS_ERECT_DOMAIN = 3,
CONNECTION_STATE_MCS_ATTACH_USER = 4,
CONNECTION_STATE_MCS_CHANNEL_JOIN = 5,
CONNECTION_STATE_ESTABLISH_KEYS = 6,
CONNECTION_STATE_LICENSE = 7,
CONNECTION_STATE_CAPABILITY = 8,
CONNECTION_STATE_FINALIZATION = 9,
CONNECTION_STATE_ACTIVE = 10
};
BOOL rdp_client_connect(rdpRdp* rdp);

View File

@ -276,7 +276,7 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s
return status;
}
static BOOL fastpath_recv_update_data(rdpFastPath* fastpath, STREAM* s)
static int fastpath_recv_update_data(rdpFastPath* fastpath, STREAM* s)
{
int status;
UINT16 size;

View File

@ -105,8 +105,8 @@ struct rdp_fastpath
UINT16 fastpath_header_length(STREAM* s);
UINT16 fastpath_read_header(rdpFastPath* fastpath, STREAM* s);
BOOL fastpath_read_header_rdp(rdpFastPath* fastpath, STREAM* s, UINT16 *length);
BOOL fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s);
BOOL fastpath_recv_inputs(rdpFastPath* fastpath, STREAM* s);
int fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s);
int fastpath_recv_inputs(rdpFastPath* fastpath, STREAM* s);
STREAM* fastpath_input_pdu_init(rdpFastPath* fastpath, BYTE eventFlags, BYTE eventCode);
BOOL fastpath_send_input_pdu(rdpFastPath* fastpath, STREAM* s);

View File

@ -28,6 +28,7 @@
#include "transport.h"
#include "connection.h"
#include "extension.h"
#include "message.h"
#include <winpr/crt.h>
@ -35,7 +36,7 @@
#include <freerdp/error.h>
#include <freerdp/locale/keyboard.h>
/* connectErrorCode is 'extern' in errorcodes.h. See comment there.*/
/* connectErrorCode is 'extern' in error.h. See comment there.*/
/** Creates a new connection based on the settings found in the "instance" parameter
* It will use the callbacks registered on the structure to process the pre/post connect operations
@ -74,7 +75,7 @@ BOOL freerdp_connect(freerdp* instance)
if (status != TRUE)
{
if(!connectErrorCode)
if (!connectErrorCode)
{
connectErrorCode = PREECONNECTERROR;
}
@ -102,6 +103,7 @@ BOOL freerdp_connect(freerdp* instance)
extension_post_connect(rdp->extension);
IFCALLRET(instance->PostConnect, status, instance);
update_post_connect(instance->update);
if (status != TRUE)
{
@ -183,6 +185,73 @@ BOOL freerdp_check_fds(freerdp* instance)
return TRUE;
}
wMessageQueue* freerdp_get_message_queue(freerdp* instance, DWORD id)
{
wMessageQueue* queue = NULL;
switch (id)
{
case FREERDP_UPDATE_MESSAGE_QUEUE:
queue = instance->update->queue;
break;
case FREERDP_INPUT_MESSAGE_QUEUE:
queue = instance->input->queue;
break;
}
return queue;
}
HANDLE freerdp_get_message_queue_event_handle(freerdp* instance, DWORD id)
{
HANDLE event = NULL;
wMessageQueue* queue = NULL;
queue = freerdp_get_message_queue(instance, id);
if (queue)
event = MessageQueue_Event(queue);
return event;
}
int freerdp_message_queue_process_message(freerdp* instance, DWORD id, wMessage* message)
{
int status = -1;
switch (id)
{
case FREERDP_UPDATE_MESSAGE_QUEUE:
status = update_message_queue_process_message(instance->update, message);
break;
case FREERDP_INPUT_MESSAGE_QUEUE:
status = input_message_queue_process_message(instance->input, message);
break;
}
return status;
}
int freerdp_message_queue_process_pending_messages(freerdp* instance, DWORD id)
{
int status = -1;
switch (id)
{
case FREERDP_UPDATE_MESSAGE_QUEUE:
status = update_message_queue_process_pending_messages(instance->update);
break;
case FREERDP_INPUT_MESSAGE_QUEUE:
status = input_message_queue_process_pending_messages(instance->input);
break;
}
return status;
}
static int freerdp_send_channel_data(freerdp* instance, int channel_id, BYTE* data, int size)
{
return rdp_send_channel_data(instance->context->rdp, channel_id, data, size);
@ -241,6 +310,10 @@ void freerdp_context_new(freerdp* instance)
instance->context->instance = instance;
instance->context->rdp = rdp;
instance->context->input = instance->input;
instance->context->update = instance->update;
instance->context->settings = instance->settings;
instance->update->context = instance->context;
instance->update->pointer->context = instance->context;
instance->update->primary->context = instance->context;
@ -289,10 +362,10 @@ freerdp* freerdp_new()
freerdp* instance;
instance = (freerdp*) malloc(sizeof(freerdp));
ZeroMemory(instance, sizeof(freerdp));
if (instance != NULL)
if (instance)
{
ZeroMemory(instance, sizeof(freerdp));
instance->context_size = sizeof(rdpContext);
instance->SendChannelData = freerdp_send_channel_data;
}

View File

@ -157,10 +157,27 @@ const RPC_FAULT_CODE RPC_FAULT_CODES[] =
const RPC_FAULT_CODE RPC_TSG_FAULT_CODES[] =
{
DEFINE_RPC_FAULT_CODE(ERROR_SUCCESS)
DEFINE_RPC_FAULT_CODE(ERROR_ACCESS_DENIED)
DEFINE_RPC_FAULT_CODE(RPC_S_OK)
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_ARG)
DEFINE_RPC_FAULT_CODE(RPC_S_OUT_OF_MEMORY)
DEFINE_RPC_FAULT_CODE(RPC_S_OUT_OF_THREADS)
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_LEVEL)
DEFINE_RPC_FAULT_CODE(RPC_S_BUFFER_TOO_SMALL)
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_SECURITY_DESC)
DEFINE_RPC_FAULT_CODE(RPC_S_ACCESS_DENIED)
DEFINE_RPC_FAULT_CODE(RPC_S_SERVER_OUT_OF_MEMORY)
DEFINE_RPC_FAULT_CODE(RPC_S_ASYNC_CALL_PENDING)
DEFINE_RPC_FAULT_CODE(RPC_S_UNKNOWN_PRINCIPAL)
DEFINE_RPC_FAULT_CODE(RPC_S_TIMEOUT)
DEFINE_RPC_FAULT_CODE(RPC_X_NO_MEMORY)
DEFINE_RPC_FAULT_CODE(RPC_X_INVALID_BOUND)
DEFINE_RPC_FAULT_CODE(RPC_X_INVALID_TAG)
DEFINE_RPC_FAULT_CODE(RPC_X_ENUM_VALUE_TOO_LARGE)
DEFINE_RPC_FAULT_CODE(RPC_X_SS_CONTEXT_MISMATCH)
DEFINE_RPC_FAULT_CODE(RPC_X_INVALID_BUFFER)
DEFINE_RPC_FAULT_CODE(RPC_X_PIPE_APP_MEMORY)
DEFINE_RPC_FAULT_CODE(RPC_X_INVALID_PIPE_OPERATION)
DEFINE_RPC_FAULT_CODE(ERROR_ONLY_IF_CONNECTED)
DEFINE_RPC_FAULT_CODE(ERROR_INVALID_PARAMETER)
DEFINE_RPC_FAULT_CODE(ERROR_GRACEFUL_DISCONNECT)
DEFINE_RPC_FAULT_CODE(ERROR_OPERATION_ABORTED)
DEFINE_RPC_FAULT_CODE(ERROR_BAD_ARGUMENTS)
@ -311,7 +328,7 @@ int rpc_recv_fault_pdu(rpcconn_hdr_t* header)
}
}
for (index = 0; RPC_FAULT_CODES[index].name != NULL; index++)
for (index = 0; RPC_TSG_FAULT_CODES[index].name != NULL; index++)
{
if (RPC_TSG_FAULT_CODES[index].code == code)
{

View File

@ -320,8 +320,7 @@ BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg)
SwitchValue = *((UINT32*) &buffer[offset + 4]); /* SwitchValue */
offset += 8;
if ((SwitchValue != TSG_CAPABILITY_TYPE_NAP) ||
(tsgCaps->capabilityType != TSG_CAPABILITY_TYPE_NAP))
if ((SwitchValue != TSG_CAPABILITY_TYPE_NAP) || (tsgCaps->capabilityType != TSG_CAPABILITY_TYPE_NAP))
{
printf("Unexpected CapabilityType: 0x%08X, Expected TSG_CAPABILITY_TYPE_NAP\n",
tsgCaps->capabilityType);
@ -573,8 +572,7 @@ BOOL TsProxyAuthorizeTunnelReadResponse(rdpTsg* tsg)
packet->packetId = *((UINT32*) &buffer[offset]); /* PacketId */
SwitchValue = *((UINT32*) &buffer[offset + 4]); /* SwitchValue */
if ((packet->packetId != TSG_PACKET_TYPE_RESPONSE) ||
(SwitchValue != TSG_PACKET_TYPE_RESPONSE))
if ((packet->packetId != TSG_PACKET_TYPE_RESPONSE) || (SwitchValue != TSG_PACKET_TYPE_RESPONSE))
{
printf("Unexpected PacketId: 0x%08X, Expected TSG_PACKET_TYPE_RESPONSE\n", packet->packetId);
return FALSE;
@ -696,7 +694,114 @@ BOOL TsProxyMakeTunnelCallWriteRequest(rdpTsg* tsg, PTUNNEL_CONTEXT_HANDLE_NOSER
BOOL TsProxyMakeTunnelCallReadResponse(rdpTsg* tsg)
{
/* ??? */
RPC_PDU* pdu;
BYTE* buffer;
UINT32 length;
UINT32 offset;
UINT32 Pointer;
UINT32 MaxCount;
UINT32 ActualCount;
UINT32 SwitchValue;
PTSG_PACKET packet;
rdpRpc* rpc = tsg->rpc;
PTSG_PACKET_MSG_RESPONSE packetMsgResponse;
PTSG_PACKET_STRING_MESSAGE packetStringMessage = NULL;
PTSG_PACKET_REAUTH_MESSAGE packetReauthMessage = NULL;
/* This is an asynchronous response */
return TRUE;
pdu = rpc_recv_dequeue_pdu(rpc);
if (!pdu)
return FALSE;
length = Stream_Length(pdu->s);
buffer = Stream_Buffer(pdu->s);
if (!(pdu->Flags & RPC_PDU_FLAG_STUB))
buffer = &buffer[24];
packet = (PTSG_PACKET) malloc(sizeof(TSG_PACKET));
ZeroMemory(packet, sizeof(TSG_PACKET));
offset = 4;
packet->packetId = *((UINT32*) &buffer[offset]); /* PacketId */
SwitchValue = *((UINT32*) &buffer[offset + 4]); /* SwitchValue */
if ((packet->packetId != TSG_PACKET_TYPE_MESSAGE_PACKET) || (SwitchValue != TSG_PACKET_TYPE_MESSAGE_PACKET))
{
printf("Unexpected PacketId: 0x%08X, Expected TSG_PACKET_TYPE_MESSAGE_PACKET\n", packet->packetId);
return FALSE;
}
packetMsgResponse = (PTSG_PACKET_MSG_RESPONSE) malloc(sizeof(TSG_PACKET_MSG_RESPONSE));
ZeroMemory(packetMsgResponse, sizeof(TSG_PACKET_MSG_RESPONSE));
packet->tsgPacket.packetMsgResponse = packetMsgResponse;
Pointer = *((UINT32*) &buffer[offset + 8]); /* PacketMsgResponsePtr */
packetMsgResponse->msgID = *((UINT32*) &buffer[offset + 12]); /* MsgId */
packetMsgResponse->msgType = *((UINT32*) &buffer[offset + 16]); /* MsgType */
packetMsgResponse->isMsgPresent = *((INT32*) &buffer[offset + 20]); /* IsMsgPresent */
SwitchValue = *((UINT32*) &buffer[offset + 24]); /* SwitchValue */
switch (SwitchValue)
{
case TSG_ASYNC_MESSAGE_CONSENT_MESSAGE:
packetStringMessage = (PTSG_PACKET_STRING_MESSAGE) malloc(sizeof(TSG_PACKET_STRING_MESSAGE));
ZeroMemory(packetStringMessage, sizeof(TSG_PACKET_STRING_MESSAGE));
packetMsgResponse->messagePacket.consentMessage = packetStringMessage;
Pointer = *((UINT32*) &buffer[offset + 28]); /* ConsentMessagePtr */
packetStringMessage->isDisplayMandatory = *((INT32*) &buffer[offset + 32]); /* IsDisplayMandatory */
packetStringMessage->isConsentMandatory = *((INT32*) &buffer[offset + 36]); /* IsConsentMandatory */
packetStringMessage->msgBytes = *((UINT32*) &buffer[offset + 40]); /* MsgBytes */
Pointer = *((UINT32*) &buffer[offset + 44]); /* MsgPtr */
MaxCount = *((UINT32*) &buffer[offset + 48]); /* MaxCount */
/* Offset */
ActualCount = *((UINT32*) &buffer[offset + 56]); /* ActualCount */
winpr_HexDump(&buffer[offset + 60], ActualCount * 2);
break;
case TSG_ASYNC_MESSAGE_SERVICE_MESSAGE:
packetStringMessage = (PTSG_PACKET_STRING_MESSAGE) malloc(sizeof(TSG_PACKET_STRING_MESSAGE));
ZeroMemory(packetStringMessage, sizeof(TSG_PACKET_STRING_MESSAGE));
packetMsgResponse->messagePacket.serviceMessage = packetStringMessage;
Pointer = *((UINT32*) &buffer[offset + 28]); /* ServiceMessagePtr */
packetStringMessage->isDisplayMandatory = *((INT32*) &buffer[offset + 32]); /* IsDisplayMandatory */
packetStringMessage->isConsentMandatory = *((INT32*) &buffer[offset + 36]); /* IsConsentMandatory */
packetStringMessage->msgBytes = *((UINT32*) &buffer[offset + 40]); /* MsgBytes */
Pointer = *((UINT32*) &buffer[offset + 44]); /* MsgPtr */
MaxCount = *((UINT32*) &buffer[offset + 48]); /* MaxCount */
/* Offset */
ActualCount = *((UINT32*) &buffer[offset + 56]); /* ActualCount */
winpr_HexDump(&buffer[offset + 60], ActualCount * 2);
break;
case TSG_ASYNC_MESSAGE_REAUTH:
packetReauthMessage = (PTSG_PACKET_REAUTH_MESSAGE) malloc(sizeof(TSG_PACKET_REAUTH_MESSAGE));
ZeroMemory(packetReauthMessage, sizeof(TSG_PACKET_REAUTH_MESSAGE));
packetMsgResponse->messagePacket.reauthMessage = packetReauthMessage;
Pointer = *((UINT32*) &buffer[offset + 28]); /* ReauthMessagePtr */
break;
default:
printf("TsProxyMakeTunnelCallReadResponse: unexpected message type: %d\n", SwitchValue);
return FALSE;
break;
}
exit(0);
return TRUE;
}

View File

@ -112,6 +112,7 @@ typedef struct _tsendpointinfo
#define TSG_ASYNC_MESSAGE_CONSENT_MESSAGE 0x00000001
#define TSG_ASYNC_MESSAGE_SERVICE_MESSAGE 0x00000002
#define TSG_ASYNC_MESSAGE_REAUTH 0x00000003
#define TSG_TUNNEL_CALL_ASYNC_MSG_REQUEST 0x00000001
#define TSG_TUNNEL_CANCEL_ASYNC_MSG_REQUEST 0x00000002

View File

@ -597,7 +597,10 @@ BOOL gcc_read_client_core_data(STREAM* s, rdpSettings* settings, UINT16 blockLen
if (highColorDepth > 0)
{
color_depth = highColorDepth;
if (earlyCapabilityFlags & RNS_UD_CS_WANT_32BPP_SESSION)
color_depth = 32;
else
color_depth = highColorDepth;
}
else if (postBeta2ColorDepth > 0)
{
@ -641,7 +644,7 @@ BOOL gcc_read_client_core_data(STREAM* s, rdpSettings* settings, UINT16 blockLen
* If we are in server mode, accept client's color depth only if
* it is smaller than ours. This is what Windows server does.
*/
if (color_depth < settings->ColorDepth || !settings->ServerMode)
if ((color_depth < settings->ColorDepth) || !settings->ServerMode)
settings->ColorDepth = color_depth;
return TRUE;
@ -870,7 +873,7 @@ BOOL gcc_read_server_security_data(STREAM* s, rdpSettings* settings)
data = settings->ServerCertificate;
length = settings->ServerCertificateLength;
if (!certificate_read_server_certificate(settings->RdpServerCertificate, data, length))
if (certificate_read_server_certificate(settings->RdpServerCertificate, data, length) < 1)
return FALSE;
}
else

View File

@ -25,6 +25,8 @@
#include <freerdp/input.h>
#include "message.h"
#include "input.h"
void rdp_write_client_input_pdu_header(STREAM* s, UINT16 number)
@ -368,9 +370,9 @@ BOOL input_recv(rdpInput* input, STREAM* s)
void input_register_client_callbacks(rdpInput* input)
{
rdpRdp* rdp = input->context->rdp;
rdpSettings* settings = input->context->settings;
if (rdp->settings->FastPathInput)
if (settings->FastPathInput)
{
input->SynchronizeEvent = input_send_fastpath_synchronize_event;
input->KeyboardEvent = input_send_fastpath_keyboard_event;
@ -386,6 +388,13 @@ void input_register_client_callbacks(rdpInput* input)
input->MouseEvent = input_send_mouse_event;
input->ExtendedMouseEvent = input_send_extended_mouse_event;
}
input->asynchronous = settings->AsyncInput;
if (input->asynchronous)
{
input->proxy = input_message_proxy_new(input);
}
}
void freerdp_input_send_synchronize_event(rdpInput* input, UINT32 flags)
@ -421,6 +430,11 @@ void freerdp_input_send_extended_mouse_event(rdpInput* input, UINT16 flags, UINT
IFCALL(input->ExtendedMouseEvent, input, flags, x, y);
}
int input_process_events(rdpInput* input)
{
return input_message_queue_process_pending_messages(input);
}
rdpInput* input_new(rdpRdp* rdp)
{
rdpInput* input;
@ -439,6 +453,9 @@ void input_free(rdpInput* input)
{
if (input != NULL)
{
if (input->asynchronous)
input_message_proxy_free(input->proxy);
free(input);
}
}

View File

@ -22,6 +22,7 @@
#include "rdp.h"
#include "fastpath.h"
#include "message.h"
#include <freerdp/input.h>
#include <freerdp/freerdp.h>
@ -50,6 +51,7 @@ void input_send_fastpath_extended_mouse_event(rdpInput* input, UINT16 flags, UIN
BOOL input_recv(rdpInput* input, STREAM* s);
int input_process_events(rdpInput* input);
void input_register_client_callbacks(rdpInput* input);
rdpInput* input_new(rdpRdp* rdp);

View File

@ -2,7 +2,7 @@
* FreeRDP: A Remote Desktop Protocol Implementation
* RDP Licensing
*
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2011-2013 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.
@ -28,7 +28,11 @@
#include "license.h"
//#define LICENSE_NULL_CLIENT_RANDOM 1
#define LICENSE_NULL_PREMASTER_SECRET 1
#ifdef WITH_DEBUG_LICENSE
static const char* const LICENSE_MESSAGE_STRINGS[] =
{
"",
@ -72,6 +76,41 @@ static const char* const state_transitions[] =
"ST_RESET_PHASE_TO_START",
"ST_RESEND_LAST_MESSAGE"
};
void license_print_product_info(PRODUCT_INFO* productInfo)
{
char* CompanyName = NULL;
char* ProductId = NULL;
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) productInfo->pbCompanyName,
productInfo->cbCompanyName / 2, &CompanyName, 0, NULL, NULL);
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) productInfo->pbProductId,
productInfo->cbProductId / 2, &ProductId, 0, NULL, NULL);
printf("ProductInfo:\n");
printf("\tdwVersion: 0x%08X\n", productInfo->dwVersion);
printf("\tCompanyName: %s\n", CompanyName);
printf("\tProductId: %s\n", ProductId);
free(CompanyName);
free(ProductId);
}
void license_print_scope_list(SCOPE_LIST* scopeList)
{
int index;
LICENSE_BLOB* scope;
printf("ScopeList (%d):\n", scopeList->count);
for (index = 0; index < scopeList->count; index++)
{
scope = &scopeList->array[index];
printf("\t%s\n", (char*) scope->data);
}
}
#endif
/**
@ -87,11 +126,13 @@ static const char* const state_transitions[] =
BOOL license_read_preamble(STREAM* s, BYTE* bMsgType, BYTE* flags, UINT16* wMsgSize)
{
/* preamble (4 bytes) */
if(stream_get_left(s) < 4)
if (stream_get_left(s) < 4)
return FALSE;
stream_read_BYTE(s, *bMsgType); /* bMsgType (1 byte) */
stream_read_BYTE(s, *flags); /* flags (1 byte) */
stream_read_UINT16(s, *wMsgSize); /* wMsgSize (2 bytes) */
return TRUE;
}
@ -121,8 +162,10 @@ void license_write_preamble(STREAM* s, BYTE bMsgType, BYTE flags, UINT16 wMsgSiz
STREAM* license_send_stream_init(rdpLicense* license)
{
STREAM* s;
s = transport_send_stream_init(license->rdp->transport, 4096);
stream_seek(s, LICENSE_PACKET_HEADER_MAX_LENGTH);
return s;
}
@ -147,6 +190,7 @@ BOOL license_send(rdpLicense* license, STREAM* s, BYTE type)
sec_flags = SEC_LICENSE_PKT;
wMsgSize = length - LICENSE_PACKET_HEADER_MAX_LENGTH + 4;
/**
* Using EXTENDED_ERROR_MSG_SUPPORTED here would cause mstsc to crash when
* running in server mode! This flag seems to be incorrectly documented.
@ -163,6 +207,7 @@ BOOL license_send(rdpLicense* license, STREAM* s, BYTE type)
#endif
stream_set_pos(s, length);
if (transport_write(license->rdp->transport, s) < 0)
return FALSE;
@ -179,12 +224,12 @@ BOOL license_send(rdpLicense* license, STREAM* s, BYTE type)
BOOL license_recv(rdpLicense* license, STREAM* s)
{
UINT16 length;
UINT16 channelId;
UINT16 sec_flags;
BYTE flags;
BYTE bMsgType;
UINT16 wMsgSize;
UINT16 length;
UINT16 channelId;
UINT16 securityFlags;
if (!rdp_read_header(license->rdp, s, &length, &channelId))
{
@ -192,20 +237,33 @@ BOOL license_recv(rdpLicense* license, STREAM* s)
return FALSE;
}
if(!rdp_read_security_header(s, &sec_flags))
if (!rdp_read_security_header(s, &securityFlags))
return FALSE;
if (!(sec_flags & SEC_LICENSE_PKT))
if (securityFlags & SEC_ENCRYPT)
{
stream_rewind(s, RDP_SECURITY_HEADER_LENGTH);
if (!rdp_decrypt(license->rdp, s, length - 4, securityFlags))
{
printf("rdp_decrypt failed\n");
return FALSE;
}
}
if (!(securityFlags & SEC_LICENSE_PKT))
{
if (!(securityFlags & SEC_ENCRYPT))
stream_rewind(s, RDP_SECURITY_HEADER_LENGTH);
if (rdp_recv_out_of_sequence_pdu(license->rdp, s) != TRUE)
{
printf("Unexpected license packet.\n");
return FALSE;
}
return TRUE;
}
if(!license_read_preamble(s, &bMsgType, &flags, &wMsgSize)) /* preamble (4 bytes) */
if (!license_read_preamble(s, &bMsgType, &flags, &wMsgSize)) /* preamble (4 bytes) */
return FALSE;
DEBUG_LICENSE("Receiving %s Packet", LICENSE_MESSAGE_STRINGS[bMsgType & 0x1F]);
@ -247,12 +305,15 @@ BOOL license_recv(rdpLicense* license, STREAM* s)
void license_generate_randoms(rdpLicense* license)
{
#if 0
crypto_nonce(license->client_random, CLIENT_RANDOM_LENGTH); /* ClientRandom */
crypto_nonce(license->premaster_secret, PREMASTER_SECRET_LENGTH); /* PremasterSecret */
#else
memset(license->client_random, 0, CLIENT_RANDOM_LENGTH); /* ClientRandom */
memset(license->premaster_secret, 0, PREMASTER_SECRET_LENGTH); /* PremasterSecret */
ZeroMemory(license->ClientRandom, CLIENT_RANDOM_LENGTH); /* ClientRandom */
ZeroMemory(license->PremasterSecret, PREMASTER_SECRET_LENGTH); /* PremasterSecret */
#ifndef LICENSE_NULL_CLIENT_RANDOM
crypto_nonce(license->ClientRandom, CLIENT_RANDOM_LENGTH); /* ClientRandom */
#endif
#ifndef LICENSE_NULL_PREMASTER_SECRET
crypto_nonce(license->PremasterSecret, PREMASTER_SECRET_LENGTH); /* PremasterSecret */
#endif
}
@ -263,39 +324,46 @@ void license_generate_randoms(rdpLicense* license)
void license_generate_keys(rdpLicense* license)
{
security_master_secret(license->premaster_secret, license->client_random,
license->server_random, license->master_secret); /* MasterSecret */
security_master_secret(license->PremasterSecret, license->ClientRandom,
license->ServerRandom, license->MasterSecret); /* MasterSecret */
security_session_key_blob(license->master_secret, license->client_random,
license->server_random, license->session_key_blob); /* SessionKeyBlob */
security_session_key_blob(license->MasterSecret, license->ClientRandom,
license->ServerRandom, license->SessionKeyBlob); /* SessionKeyBlob */
security_mac_salt_key(license->session_key_blob, license->client_random,
license->server_random, license->mac_salt_key); /* MacSaltKey */
security_mac_salt_key(license->SessionKeyBlob, license->ClientRandom,
license->ServerRandom, license->MacSaltKey); /* MacSaltKey */
security_licensing_encryption_key(license->session_key_blob, license->client_random,
license->server_random, license->licensing_encryption_key); /* LicensingEncryptionKey */
security_licensing_encryption_key(license->SessionKeyBlob, license->ClientRandom,
license->ServerRandom, license->LicensingEncryptionKey); /* LicensingEncryptionKey */
#ifdef WITH_DEBUG_LICENSE
printf("ClientRandom:\n");
winpr_HexDump(license->client_random, CLIENT_RANDOM_LENGTH);
winpr_HexDump(license->ClientRandom, CLIENT_RANDOM_LENGTH);
printf("\n");
printf("ServerRandom:\n");
winpr_HexDump(license->server_random, SERVER_RANDOM_LENGTH);
winpr_HexDump(license->ServerRandom, SERVER_RANDOM_LENGTH);
printf("\n");
printf("PremasterSecret:\n");
winpr_HexDump(license->premaster_secret, PREMASTER_SECRET_LENGTH);
winpr_HexDump(license->PremasterSecret, PREMASTER_SECRET_LENGTH);
printf("\n");
printf("MasterSecret:\n");
winpr_HexDump(license->master_secret, MASTER_SECRET_LENGTH);
winpr_HexDump(license->MasterSecret, MASTER_SECRET_LENGTH);
printf("\n");
printf("SessionKeyBlob:\n");
winpr_HexDump(license->session_key_blob, SESSION_KEY_BLOB_LENGTH);
winpr_HexDump(license->SessionKeyBlob, SESSION_KEY_BLOB_LENGTH);
printf("\n");
printf("MacSaltKey:\n");
winpr_HexDump(license->mac_salt_key, MAC_SALT_KEY_LENGTH);
winpr_HexDump(license->MacSaltKey, MAC_SALT_KEY_LENGTH);
printf("\n");
printf("LicensingEncryptionKey:\n");
winpr_HexDump(license->licensing_encryption_key, LICENSING_ENCRYPTION_KEY_LENGTH);
winpr_HexDump(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
printf("\n");
#endif
}
@ -309,82 +377,79 @@ void license_generate_hwid(rdpLicense* license)
CryptoMd5 md5;
BYTE* mac_address;
memset(license->hwid, 0, HWID_LENGTH);
ZeroMemory(license->HardwareId, HWID_LENGTH);
mac_address = license->rdp->transport->TcpIn->mac_address;
md5 = crypto_md5_init();
crypto_md5_update(md5, mac_address, 6);
crypto_md5_final(md5, &license->hwid[HWID_PLATFORM_ID_LENGTH]);
crypto_md5_final(md5, &license->HardwareId[HWID_PLATFORM_ID_LENGTH]);
}
void license_get_server_rsa_public_key(rdpLicense* license)
{
BYTE* Exponent;
BYTE* Modulus;
int ModulusLength;
if (license->ServerCertificate->length < 1)
{
certificate_read_server_certificate(license->certificate,
license->rdp->settings->ServerCertificate,
license->rdp->settings->ServerCertificateLength);
}
Exponent = license->certificate->cert_info.exponent;
Modulus = license->certificate->cert_info.Modulus;
ModulusLength = license->certificate->cert_info.ModulusLength;
CopyMemory(license->Exponent, Exponent, 4);
license->ModulusLength = ModulusLength;
license->Modulus = (BYTE*) malloc(ModulusLength);
ZeroMemory(license->Modulus, ModulusLength);
}
void license_encrypt_premaster_secret(rdpLicense* license)
{
BYTE* encrypted_premaster_secret;
#if 0
int key_length;
BYTE* modulus;
BYTE* exponent;
rdpCertificate *certificate;
BYTE* EncryptedPremasterSecret;
if (license->server_certificate->length)
certificate = license->certificate;
else
certificate = license->rdp->settings->server_cert;
exponent = certificate->cert_info.exponent;
modulus = certificate->cert_info.modulus.data;
key_length = certificate->cert_info.modulus.length;
license_get_server_rsa_public_key(license);
#ifdef WITH_DEBUG_LICENSE
printf("modulus (%d bits):\n", key_length * 8);
winpr_HexDump(modulus, key_length);
printf("Modulus (%d bits):\n", license->ModulusLength * 8);
winpr_HexDump(license->Modulus, license->ModulusLength);
printf("\n");
printf("exponent:\n");
winpr_HexDump(exponent, 4);
printf("Exponent:\n");
winpr_HexDump(license->Exponent, 4);
printf("\n");
#endif
encrypted_premaster_secret = (BYTE*) malloc(MODULUS_MAX_SIZE);
memset(encrypted_premaster_secret, 0, MODULUS_MAX_SIZE);
EncryptedPremasterSecret = (BYTE*) malloc(license->ModulusLength);
ZeroMemory(EncryptedPremasterSecret, license->ModulusLength);
crypto_rsa_public_encrypt(license->premaster_secret, PREMASTER_SECRET_LENGTH,
key_length, modulus, exponent, encrypted_premaster_secret);
license->encrypted_premaster_secret->type = BB_RANDOM_BLOB;
license->encrypted_premaster_secret->length = PREMASTER_SECRET_LENGTH;
license->encrypted_premaster_secret->data = encrypted_premaster_secret;
#else
encrypted_premaster_secret = (BYTE*) malloc(MODULUS_MAX_SIZE);
memset(encrypted_premaster_secret, 0, MODULUS_MAX_SIZE);
license->encrypted_premaster_secret->type = BB_RANDOM_BLOB;
license->encrypted_premaster_secret->length = PREMASTER_SECRET_LENGTH;
license->encrypted_premaster_secret->data = encrypted_premaster_secret;
#ifndef LICENSE_NULL_PREMASTER_SECRET
crypto_rsa_public_encrypt(license->PremasterSecret, PREMASTER_SECRET_LENGTH,
license->ModulusLength, license->Modulus, license->Exponent, EncryptedPremasterSecret);
#endif
license->EncryptedPremasterSecret->type = BB_RANDOM_BLOB;
license->EncryptedPremasterSecret->length = PREMASTER_SECRET_LENGTH;
license->EncryptedPremasterSecret->data = EncryptedPremasterSecret;
}
void license_decrypt_platform_challenge(rdpLicense* license)
{
CryptoRc4 rc4;
license->platform_challenge->data =
(BYTE*) malloc(license->encrypted_platform_challenge->length);
license->platform_challenge->length =
license->encrypted_platform_challenge->length;
license->PlatformChallenge->data = (BYTE*) malloc(license->EncryptedPlatformChallenge->length);
license->PlatformChallenge->length = license->EncryptedPlatformChallenge->length;
rc4 = crypto_rc4_init(license->licensing_encryption_key, LICENSING_ENCRYPTION_KEY_LENGTH);
rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
crypto_rc4(rc4, license->encrypted_platform_challenge->length,
license->encrypted_platform_challenge->data,
license->platform_challenge->data);
#ifdef WITH_DEBUG_LICENSE
printf("encrypted_platform challenge:\n");
winpr_HexDump(license->encrypted_platform_challenge->data,
license->encrypted_platform_challenge->length);
printf("platform challenge:\n");
winpr_HexDump(license->platform_challenge->data, license->platform_challenge->length);
#endif
crypto_rc4(rc4, license->EncryptedPlatformChallenge->length,
license->EncryptedPlatformChallenge->data,
license->PlatformChallenge->data);
crypto_rc4_free(rc4);
}
@ -398,19 +463,22 @@ void license_decrypt_platform_challenge(rdpLicense* license)
BOOL license_read_product_info(STREAM* s, PRODUCT_INFO* productInfo)
{
if(stream_get_left(s) < 8)
if (stream_get_left(s) < 8)
return FALSE;
stream_read_UINT32(s, productInfo->dwVersion); /* dwVersion (4 bytes) */
stream_read_UINT32(s, productInfo->cbCompanyName); /* cbCompanyName (4 bytes) */
if(stream_get_left(s) < productInfo->cbCompanyName + 4)
if (stream_get_left(s) < productInfo->cbCompanyName + 4)
return FALSE;
productInfo->pbCompanyName = (BYTE*) malloc(productInfo->cbCompanyName);
stream_read(s, productInfo->pbCompanyName, productInfo->cbCompanyName);
stream_read_UINT32(s, productInfo->cbProductId); /* cbProductId (4 bytes) */
if(stream_get_left(s) < productInfo->cbProductId)
if (stream_get_left(s) < productInfo->cbProductId)
{
free(productInfo->pbCompanyName);
productInfo->pbCompanyName = NULL;
@ -419,6 +487,7 @@ BOOL license_read_product_info(STREAM* s, PRODUCT_INFO* productInfo)
productInfo->pbProductId = (BYTE*) malloc(productInfo->cbProductId);
stream_read(s, productInfo->pbProductId, productInfo->cbProductId);
return TRUE;
}
@ -471,22 +540,23 @@ BOOL license_read_binary_blob(STREAM* s, LICENSE_BLOB* blob)
{
UINT16 wBlobType;
if(stream_get_left(s) < 4)
if (stream_get_left(s) < 4)
return FALSE;
stream_read_UINT16(s, wBlobType); /* wBlobType (2 bytes) */
stream_read_UINT16(s, blob->length); /* wBlobLen (2 bytes) */
if(stream_get_left(s) < blob->length)
if (stream_get_left(s) < blob->length)
return FALSE;
/*
* Server can choose to not send data by setting len to 0.
* Server can choose to not send data by setting length to 0.
* If so, it may not bother to set the type, so shortcut the warning
*/
if (blob->type != BB_ANY_BLOB && blob->length == 0)
if ((blob->type != BB_ANY_BLOB) && (blob->length == 0))
return TRUE;
if (blob->type != wBlobType && blob->type != BB_ANY_BLOB)
if ((blob->type != wBlobType) && (blob->type != BB_ANY_BLOB))
{
printf("license binary blob type (%x) does not match expected type (%x).\n", wBlobType, blob->type);
}
@ -514,18 +584,25 @@ void license_write_binary_blob(STREAM* s, LICENSE_BLOB* blob)
stream_write(s, blob->data, blob->length); /* blobData */
}
void license_write_padded_binary_blob(STREAM* s, LICENSE_BLOB* blob)
void license_write_encrypted_premaster_secret_blob(STREAM* s, LICENSE_BLOB* blob, UINT32 ModulusLength)
{
UINT16 pad_len;
UINT32 length;
length = ModulusLength + 8;
if (blob->length > ModulusLength)
{
printf("license_write_encrypted_premaster_secret_blob: invalid blob\n");
return;
}
pad_len = 72 % blob->length;
stream_write_UINT16(s, blob->type); /* wBlobType (2 bytes) */
stream_write_UINT16(s, blob->length + pad_len); /* wBlobLen (2 bytes) */
stream_write_UINT16(s, length); /* wBlobLen (2 bytes) */
if (blob->length > 0)
stream_write(s, blob->data, blob->length); /* blobData */
stream_write_zero(s, pad_len);
stream_write_zero(s, length - blob->length);
}
/**
@ -572,8 +649,9 @@ BOOL license_read_scope_list(STREAM* s, SCOPE_LIST* scopeList)
UINT32 i;
UINT32 scopeCount;
if(stream_get_left(s) < 4)
if (stream_get_left(s) < 4)
return FALSE;
stream_read_UINT32(s, scopeCount); /* ScopeCount (4 bytes) */
scopeList->count = scopeCount;
@ -583,9 +661,11 @@ BOOL license_read_scope_list(STREAM* s, SCOPE_LIST* scopeList)
for (i = 0; i < scopeCount; i++)
{
scopeList->array[i].type = BB_SCOPE_BLOB;
if(!license_read_binary_blob(s, &scopeList->array[i]))
if (!license_read_binary_blob(s, &scopeList->array[i]))
return FALSE;
}
return TRUE;
}
@ -628,7 +708,7 @@ void license_free_scope_list(SCOPE_LIST* scopeList)
free(scopeList->array[i].data);
}
free(scopeList->array) ;
free(scopeList->array);
free(scopeList);
}
@ -642,34 +722,48 @@ void license_free_scope_list(SCOPE_LIST* scopeList)
BOOL license_read_license_request_packet(rdpLicense* license, STREAM* s)
{
/* ServerRandom (32 bytes) */
if(stream_get_left(s) < 32)
if (stream_get_left(s) < 32)
return FALSE;
stream_read(s, license->server_random, 32);
stream_read(s, license->ServerRandom, 32);
/* ProductInfo */
if (!license_read_product_info(s, license->product_info))
if (!license_read_product_info(s, license->ProductInfo))
return FALSE;
/* KeyExchangeList */
if (!license_read_binary_blob(s, license->key_exchange_list))
if (!license_read_binary_blob(s, license->KeyExchangeList))
return FALSE;
/* ServerCertificate */
if (!license_read_binary_blob(s, license->server_certificate))
if (!license_read_binary_blob(s, license->ServerCertificate))
return FALSE;
/* ScopeList */
if (!license_read_scope_list(s, license->scope_list))
if (!license_read_scope_list(s, license->ScopeList))
return FALSE;
/* Parse Server Certificate */
if (!certificate_read_server_certificate(license->certificate,
license->server_certificate->data, license->server_certificate->length))
license->ServerCertificate->data, license->ServerCertificate->length) < 0)
return FALSE;
license_generate_keys(license);
license_generate_hwid(license);
license_encrypt_premaster_secret(license);
#ifdef WITH_DEBUG_LICENSE
printf("ServerRandom:\n");
winpr_HexDump(license->ServerRandom, 32);
printf("\n");
license_print_product_info(license->ProductInfo);
printf("\n");
license_print_scope_list(license->ScopeList);
printf("\n");
#endif
return TRUE;
}
@ -682,21 +776,45 @@ BOOL license_read_license_request_packet(rdpLicense* license, STREAM* s)
BOOL license_read_platform_challenge_packet(rdpLicense* license, STREAM* s)
{
BYTE MacData[16];
UINT32 ConnectFlags = 0;
DEBUG_LICENSE("Receiving Platform Challenge Packet");
if(stream_get_left(s) < 4)
if (stream_get_left(s) < 4)
return FALSE;
stream_seek(s, 4); /* ConnectFlags, Reserved (4 bytes) */
stream_read_UINT32(s, ConnectFlags); /* ConnectFlags, Reserved (4 bytes) */
/* EncryptedPlatformChallenge */
license->encrypted_platform_challenge->type = BB_ANY_BLOB;
license_read_binary_blob(s, license->encrypted_platform_challenge);
license->encrypted_platform_challenge->type = BB_ENCRYPTED_DATA_BLOB;
license->EncryptedPlatformChallenge->type = BB_ANY_BLOB;
license_read_binary_blob(s, license->EncryptedPlatformChallenge);
license->EncryptedPlatformChallenge->type = BB_ENCRYPTED_DATA_BLOB;
/* MACData (16 bytes) */
if(!stream_skip(s, 16))
if (stream_get_left(s) < 16)
return FALSE;
stream_read(s, MacData, 16); /* MACData (16 bytes) */
license_decrypt_platform_challenge(license);
#ifdef WITH_DEBUG_LICENSE
printf("ConnectFlags: 0x%08X\n", ConnectFlags);
printf("\n");
printf("EncryptedPlatformChallenge:\n");
winpr_HexDump(license->EncryptedPlatformChallenge->data, license->EncryptedPlatformChallenge->length);
printf("\n");
printf("PlatformChallenge:\n");
winpr_HexDump(license->PlatformChallenge->data, license->PlatformChallenge->length);
printf("\n");
printf("MacData:\n");
winpr_HexDump(MacData, 16);
printf("\n");
#endif
return TRUE;
}
@ -738,11 +856,13 @@ BOOL license_read_error_alert_packet(rdpLicense* license, STREAM* s)
UINT32 dwErrorCode;
UINT32 dwStateTransition;
if(stream_get_left(s) < 8)
if (stream_get_left(s) < 8)
return FALSE;
stream_read_UINT32(s, dwErrorCode); /* dwErrorCode (4 bytes) */
stream_read_UINT32(s, dwStateTransition); /* dwStateTransition (4 bytes) */
if(!license_read_binary_blob(s, license->error_info)) /* bbErrorInfo */
if (!license_read_binary_blob(s, license->ErrorInfo)) /* bbErrorInfo */
return FALSE;
#ifdef WITH_DEBUG_LICENSE
@ -776,23 +896,10 @@ BOOL license_read_error_alert_packet(rdpLicense* license, STREAM* s)
default:
break;
}
return TRUE;
}
/**
* Write Platform ID.\n
* @msdn{cc241918}
* @param license license module
* @param s stream
*/
void license_write_platform_id(rdpLicense* license, STREAM* s)
{
stream_write_BYTE(s, 0); /* Client Operating System Version */
stream_write_BYTE(s, 0); /* Independent Software Vendor (ISV) */
stream_write_UINT16(s, 0); /* Client Software Build */
}
/**
* Write a NEW_LICENSE_REQUEST packet.\n
* @msdn{cc241918}
@ -802,12 +909,36 @@ void license_write_platform_id(rdpLicense* license, STREAM* s)
void license_write_new_license_request_packet(rdpLicense* license, STREAM* s)
{
stream_write_UINT32(s, KEY_EXCHANGE_ALG_RSA); /* PreferredKeyExchangeAlg (4 bytes) */
license_write_platform_id(license, s); /* PlatformId (4 bytes) */
stream_write(s, license->client_random, 32); /* ClientRandom (32 bytes) */
license_write_padded_binary_blob(s, license->encrypted_premaster_secret); /* EncryptedPremasterSecret */
license_write_binary_blob(s, license->client_user_name); /* ClientUserName */
license_write_binary_blob(s, license->client_machine_name); /* ClientMachineName */
UINT32 PlatformId;
UINT32 PreferredKeyExchangeAlg = KEY_EXCHANGE_ALG_RSA;
PlatformId = CLIENT_OS_ID_WINNT_POST_52 | CLIENT_IMAGE_ID_MICROSOFT;
stream_write_UINT32(s, PreferredKeyExchangeAlg); /* PreferredKeyExchangeAlg (4 bytes) */
stream_write_UINT32(s, PlatformId); /* PlatformId (4 bytes) */
stream_write(s, license->ClientRandom, 32); /* ClientRandom (32 bytes) */
license_write_encrypted_premaster_secret_blob(s, license->EncryptedPremasterSecret, license->ModulusLength); /* EncryptedPremasterSecret */
license_write_binary_blob(s, license->ClientUserName); /* ClientUserName */
license_write_binary_blob(s, license->ClientMachineName); /* ClientMachineName */
#ifdef WITH_DEBUG_LICENSE
printf("PreferredKeyExchangeAlg: 0x%08X\n", PreferredKeyExchangeAlg);
printf("\n");
printf("ClientRandom:\n");
winpr_HexDump(license->ClientRandom, 32);
printf("\n");
printf("EncryptedPremasterSecret\n");
winpr_HexDump(license->EncryptedPremasterSecret->data, license->EncryptedPremasterSecret->length);
printf("\n");
printf("ClientUserName (%d): %s\n", license->ClientUserName->length, (char*) license->ClientUserName->data);
printf("\n");
printf("ClientMachineName (%d): %s\n", license->ClientMachineName->length, (char*) license->ClientMachineName->data);
printf("\n");
#endif
}
/**
@ -821,6 +952,8 @@ void license_send_new_license_request_packet(rdpLicense* license)
STREAM* s;
char* username;
DEBUG_LICENSE("Sending New License Packet");
s = license_send_stream_init(license);
if (license->rdp->settings->Username != NULL)
@ -828,21 +961,21 @@ void license_send_new_license_request_packet(rdpLicense* license)
else
username = "username";
license->client_user_name->data = (BYTE*) username;
license->client_user_name->length = strlen(username) + 1;
license->ClientUserName->data = (BYTE*) username;
license->ClientUserName->length = strlen(username) + 1;
license->client_machine_name->data = (BYTE*) license->rdp->settings->ClientHostname;
license->client_machine_name->length = strlen(license->rdp->settings->ClientHostname) + 1;
license->ClientMachineName->data = (BYTE*) license->rdp->settings->ClientHostname;
license->ClientMachineName->length = strlen(license->rdp->settings->ClientHostname) + 1;
license_write_new_license_request_packet(license, s);
license_send(license, s, NEW_LICENSE_REQUEST);
license->client_user_name->data = NULL;
license->client_user_name->length = 0;
license->ClientUserName->data = NULL;
license->ClientUserName->length = 0;
license->client_machine_name->data = NULL;
license->client_machine_name->length = 0;
license->ClientMachineName->data = NULL;
license->ClientMachineName->length = 0;
}
/**
@ -853,16 +986,11 @@ void license_send_new_license_request_packet(rdpLicense* license)
* @param mac_data signature
*/
void license_write_platform_challenge_response_packet(rdpLicense* license, STREAM* s, BYTE* mac_data)
void license_write_platform_challenge_response_packet(rdpLicense* license, STREAM* s, BYTE* macData)
{
/* EncryptedPlatformChallengeResponse */
license_write_binary_blob(s, license->encrypted_platform_challenge);
/* EncryptedHWID */
license_write_binary_blob(s, license->encrypted_hwid);
/* MACData */
stream_write(s, mac_data, 16);
license_write_binary_blob(s, license->EncryptedPlatformChallenge); /* EncryptedPlatformChallengeResponse */
license_write_binary_blob(s, license->EncryptedHardwareId); /* EncryptedHWID */
stream_write(s, macData, 16); /* MACData */
}
/**
@ -879,37 +1007,42 @@ void license_send_platform_challenge_response_packet(rdpLicense* license)
CryptoRc4 rc4;
BYTE mac_data[16];
s = license_send_stream_init(license);
DEBUG_LICENSE("Sending Platform Challenge Response Packet");
license->encrypted_platform_challenge->type = BB_DATA_BLOB;
length = license->platform_challenge->length + HWID_LENGTH;
s = license_send_stream_init(license);
license->EncryptedPlatformChallenge->type = BB_DATA_BLOB;
length = license->PlatformChallenge->length + HWID_LENGTH;
buffer = (BYTE*) malloc(length);
memcpy(buffer, license->platform_challenge->data, license->platform_challenge->length);
memcpy(&buffer[license->platform_challenge->length], license->hwid, HWID_LENGTH);
security_mac_data(license->mac_salt_key, buffer, length, mac_data);
CopyMemory(buffer, license->PlatformChallenge->data, license->PlatformChallenge->length);
CopyMemory(&buffer[license->PlatformChallenge->length], license->HardwareId, HWID_LENGTH);
security_mac_data(license->MacSaltKey, buffer, length, mac_data);
free(buffer);
buffer = (BYTE*) malloc(HWID_LENGTH);
rc4 = crypto_rc4_init(license->licensing_encryption_key, LICENSING_ENCRYPTION_KEY_LENGTH);
crypto_rc4(rc4, HWID_LENGTH, license->hwid, buffer);
rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
crypto_rc4(rc4, HWID_LENGTH, license->HardwareId, buffer);
crypto_rc4_free(rc4);
license->EncryptedHardwareId->type = BB_DATA_BLOB;
license->EncryptedHardwareId->data = buffer;
license->EncryptedHardwareId->length = HWID_LENGTH;
#ifdef WITH_DEBUG_LICENSE
printf("Licensing Encryption Key:\n");
winpr_HexDump(license->licensing_encryption_key, 16);
printf("LicensingEncryptionKey:\n");
winpr_HexDump(license->LicensingEncryptionKey, 16);
printf("\n");
printf("HardwareID:\n");
winpr_HexDump(license->hwid, 20);
printf("HardwareId:\n");
winpr_HexDump(license->HardwareId, 20);
printf("\n");
printf("Encrypted HardwareID:\n");
winpr_HexDump(buffer, 20);
printf("EncryptedHardwareId:\n");
winpr_HexDump(license->EncryptedHardwareId->data, 20);
printf("\n");
#endif
license->encrypted_hwid->type = BB_DATA_BLOB;
license->encrypted_hwid->data = buffer;
license->encrypted_hwid->length = HWID_LENGTH;
license_write_platform_challenge_response_packet(license, s, mac_data);
license_send(license, s, PLATFORM_CHALLENGE_RESPONSE);
@ -927,10 +1060,12 @@ BOOL license_send_valid_client_error_packet(rdpLicense* license)
s = license_send_stream_init(license);
DEBUG_LICENSE("Sending Error Alert Packet");
stream_write_UINT32(s, STATUS_VALID_CLIENT); /* dwErrorCode */
stream_write_UINT32(s, ST_NO_TRANSITION); /* dwStateTransition */
license_write_binary_blob(s, license->error_info);
license_write_binary_blob(s, license->ErrorInfo);
return license_send(license, s, ERROR_ALERT);
}
@ -953,19 +1088,18 @@ rdpLicense* license_new(rdpRdp* rdp)
license->rdp = rdp;
license->state = LICENSE_STATE_AWAIT;
//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);
license->server_certificate = license_new_binary_blob(BB_CERTIFICATE_BLOB);
license->client_user_name = license_new_binary_blob(BB_CLIENT_USER_NAME_BLOB);
license->client_machine_name = license_new_binary_blob(BB_CLIENT_MACHINE_NAME_BLOB);
license->platform_challenge = license_new_binary_blob(BB_ANY_BLOB);
license->encrypted_platform_challenge = license_new_binary_blob(BB_ANY_BLOB);
license->encrypted_premaster_secret = license_new_binary_blob(BB_ANY_BLOB);
license->encrypted_hwid = license_new_binary_blob(BB_ENCRYPTED_DATA_BLOB);
license->scope_list = license_new_scope_list();
license->ProductInfo = license_new_product_info();
license->ErrorInfo = license_new_binary_blob(BB_ERROR_BLOB);
license->KeyExchangeList = license_new_binary_blob(BB_KEY_EXCHG_ALG_BLOB);
license->ServerCertificate = license_new_binary_blob(BB_CERTIFICATE_BLOB);
license->ClientUserName = license_new_binary_blob(BB_CLIENT_USER_NAME_BLOB);
license->ClientMachineName = license_new_binary_blob(BB_CLIENT_MACHINE_NAME_BLOB);
license->PlatformChallenge = license_new_binary_blob(BB_ANY_BLOB);
license->EncryptedPlatformChallenge = license_new_binary_blob(BB_ANY_BLOB);
license->EncryptedPremasterSecret = license_new_binary_blob(BB_ANY_BLOB);
license->EncryptedHardwareId = license_new_binary_blob(BB_ENCRYPTED_DATA_BLOB);
license->ScopeList = license_new_scope_list();
license_generate_randoms(license);
}
@ -979,21 +1113,21 @@ rdpLicense* license_new(rdpRdp* rdp)
void license_free(rdpLicense* license)
{
if (license != NULL)
if (license)
{
free(license->Modulus);
certificate_free(license->certificate);
license_free_product_info(license->product_info);
license_free_binary_blob(license->error_info);
license_free_binary_blob(license->key_exchange_list);
license_free_binary_blob(license->server_certificate);
license_free_binary_blob(license->client_user_name);
license_free_binary_blob(license->client_machine_name);
license_free_binary_blob(license->platform_challenge);
license_free_binary_blob(license->encrypted_platform_challenge);
license_free_binary_blob(license->encrypted_premaster_secret);
license_free_binary_blob(license->encrypted_hwid);
license_free_scope_list(license->scope_list);
license_free_product_info(license->ProductInfo);
license_free_binary_blob(license->ErrorInfo);
license_free_binary_blob(license->KeyExchangeList);
license_free_binary_blob(license->ServerCertificate);
license_free_binary_blob(license->ClientUserName);
license_free_binary_blob(license->ClientMachineName);
license_free_binary_blob(license->PlatformChallenge);
license_free_binary_blob(license->EncryptedPlatformChallenge);
license_free_binary_blob(license->EncryptedPremasterSecret);
license_free_binary_blob(license->EncryptedHardwareId);
license_free_scope_list(license->ScopeList);
free(license);
}
}

View File

@ -31,6 +31,7 @@ typedef struct rdp_license rdpLicense;
#include <freerdp/utils/stream.h>
/* Licensing Packet Types */
#define LICENSE_REQUEST 0x01
#define PLATFORM_CHALLENGE 0x02
#define NEW_LICENSE 0x03
@ -40,14 +41,15 @@ typedef struct rdp_license rdpLicense;
#define PLATFORM_CHALLENGE_RESPONSE 0x15
#define ERROR_ALERT 0xFF
#define LICENSE_PKT_CS_MASK (LICENSE_INFO | NEW_LICENSE_REQUEST | PLATFORM_CHALLENGE_RESPONSE | ERROR_ALERT)
#define LICENSE_PKT_SC_MASK (LICENSE_REQUEST | PLATFORM_CHALLENGE | NEW_LICENSE | UPGRADE_LICENSE | ERROR_ALERT)
#define LICENSE_PKT_MASK (LICENSE_PKT_CS_MASK | LICENSE_PKT_SC_MASK)
#define LICENSE_PKT_CS_MASK (LICENSE_INFO | NEW_LICENSE_REQUEST | PLATFORM_CHALLENGE_RESPONSE | ERROR_ALERT)
#define LICENSE_PKT_SC_MASK (LICENSE_REQUEST | PLATFORM_CHALLENGE | NEW_LICENSE | UPGRADE_LICENSE | ERROR_ALERT)
#define LICENSE_PKT_MASK (LICENSE_PKT_CS_MASK | LICENSE_PKT_SC_MASK)
#define LICENSE_PREAMBLE_LENGTH 4
#define LICENSE_PACKET_HEADER_MAX_LENGTH (RDP_PACKET_HEADER_MAX_LENGTH + RDP_SECURITY_HEADER_LENGTH + LICENSE_PREAMBLE_LENGTH)
/* Cryptographic Lengths */
#define CLIENT_RANDOM_LENGTH 32
#define SERVER_RANDOM_LENGTH 32
#define MASTER_SECRET_LENGTH 48
@ -60,13 +62,15 @@ typedef struct rdp_license rdpLicense;
#define HWID_LENGTH 20
#define LICENSING_PADDING_SIZE 8
/* Licensing Preamble Flags */
/* Preamble Flags */
#define PREAMBLE_VERSION_2_0 0x02
#define PREAMBLE_VERSION_3_0 0x03
#define LicenseProtocolVersionMask 0x0F
#define EXTENDED_ERROR_MSG_SUPPORTED 0x80
/* Licensing Binary Blob Types */
/* Binary Blob Types */
#define BB_ANY_BLOB 0x0000
#define BB_DATA_BLOB 0x0001
#define BB_RANDOM_BLOB 0x0002
@ -78,10 +82,12 @@ typedef struct rdp_license rdpLicense;
#define BB_CLIENT_USER_NAME_BLOB 0x000F
#define BB_CLIENT_MACHINE_NAME_BLOB 0x0010
/* Key Exchange Algorithms */
/* License Key Exchange Algorithms */
#define KEY_EXCHANGE_ALG_RSA 0x00000001
/* Licensing Error Codes */
/* License Error Codes */
#define ERR_INVALID_SERVER_CERTIFICATE 0x00000001
#define ERR_NO_LICENSE 0x00000002
#define ERR_INVALID_MAC 0x00000003
@ -92,12 +98,47 @@ typedef struct rdp_license rdpLicense;
#define ERR_INVALID_PRODUCT_ID 0x0000000B
#define ERR_INVALID_MESSAGE_LENGTH 0x0000000C
/* Licensing State Transition Codes */
/* State Transition Codes */
#define ST_TOTAL_ABORT 0x00000001
#define ST_NO_TRANSITION 0x00000002
#define ST_RESET_PHASE_TO_START 0x00000003
#define ST_RESEND_LAST_MESSAGE 0x00000004
/* Platform Challenge Types */
#define WIN32_PLATFORM_CHALLENGE_TYPE 0x0100
#define WIN16_PLATFORM_CHALLENGE_TYPE 0x0200
#define WINCE_PLATFORM_CHALLENGE_TYPE 0x0300
#define OTHER_PLATFORM_CHALLENGE_TYPE 0xFF00
/* License Detail Levels */
#define LICENSE_DETAIL_SIMPLE 0x0001
#define LICENSE_DETAIL_MODERATE 0x0002
#define LICENSE_DETAIL_DETAIL 0x0003
/*
* PlatformId:
*
* The most significant byte of the PlatformId field contains the operating system version of the client.
* The second most significant byte of the PlatformId field identifies the ISV that provided the client image.
* The remaining two bytes in the PlatformId field are used by the ISV to identify the build number of the operating system.
*
* 0x04010000:
*
* CLIENT_OS_ID_WINNT_POST_52 (0x04000000)
* CLIENT_IMAGE_ID_MICROSOFT (0x00010000)
*/
#define CLIENT_OS_ID_WINNT_351 0x01000000
#define CLIENT_OS_ID_WINNT_40 0x02000000
#define CLIENT_OS_ID_WINNT_50 0x03000000
#define CLIENT_OS_ID_WINNT_POST_52 0x04000000
#define CLIENT_IMAGE_ID_MICROSOFT 0x00010000
#define CLIENT_IMAGE_ID_CITRIX 0x00020000
typedef struct
{
UINT32 dwVersion;
@ -131,29 +172,30 @@ typedef enum
struct rdp_license
{
LICENSE_STATE state;
struct rdp_rdp* rdp;
struct rdp_certificate* certificate;
BYTE hwid[HWID_LENGTH];
BYTE modulus[MODULUS_MAX_SIZE];
BYTE exponent[EXPONENT_MAX_SIZE];
BYTE client_random[CLIENT_RANDOM_LENGTH];
BYTE server_random[SERVER_RANDOM_LENGTH];
BYTE master_secret[MASTER_SECRET_LENGTH];
BYTE premaster_secret[PREMASTER_SECRET_LENGTH];
BYTE session_key_blob[SESSION_KEY_BLOB_LENGTH];
BYTE mac_salt_key[MAC_SALT_KEY_LENGTH];
BYTE licensing_encryption_key[LICENSING_ENCRYPTION_KEY_LENGTH];
PRODUCT_INFO* product_info;
LICENSE_BLOB* error_info;
LICENSE_BLOB* key_exchange_list;
LICENSE_BLOB* server_certificate;
LICENSE_BLOB* client_user_name;
LICENSE_BLOB* client_machine_name;
LICENSE_BLOB* platform_challenge;
LICENSE_BLOB* encrypted_premaster_secret;
LICENSE_BLOB* encrypted_platform_challenge;
LICENSE_BLOB* encrypted_hwid;
SCOPE_LIST* scope_list;
rdpRdp* rdp;
rdpCertificate* certificate;
BYTE* Modulus;
UINT32 ModulusLength;
BYTE Exponent[4];
BYTE HardwareId[HWID_LENGTH];
BYTE ClientRandom[CLIENT_RANDOM_LENGTH];
BYTE ServerRandom[SERVER_RANDOM_LENGTH];
BYTE MasterSecret[MASTER_SECRET_LENGTH];
BYTE PremasterSecret[PREMASTER_SECRET_LENGTH];
BYTE SessionKeyBlob[SESSION_KEY_BLOB_LENGTH];
BYTE MacSaltKey[MAC_SALT_KEY_LENGTH];
BYTE LicensingEncryptionKey[LICENSING_ENCRYPTION_KEY_LENGTH];
PRODUCT_INFO* ProductInfo;
LICENSE_BLOB* ErrorInfo;
LICENSE_BLOB* KeyExchangeList;
LICENSE_BLOB* ServerCertificate;
LICENSE_BLOB* ClientUserName;
LICENSE_BLOB* ClientMachineName;
LICENSE_BLOB* PlatformChallenge;
LICENSE_BLOB* EncryptedPremasterSecret;
LICENSE_BLOB* EncryptedPlatformChallenge;
LICENSE_BLOB* EncryptedHardwareId;
SCOPE_LIST* ScopeList;
};
BOOL license_recv(rdpLicense* license, STREAM* s);

1932
libfreerdp/core/message.c Normal file

File diff suppressed because it is too large Load Diff

156
libfreerdp/core/message.h Normal file
View File

@ -0,0 +1,156 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Asynchronous Message Queue
*
* Copyright 2012 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 FREERDP_CORE_MESSAGE_PRIVATE_H
#define FREERDP_CORE_MESSAGE_PRIVATE_H
#include <freerdp/freerdp.h>
#include <freerdp/message.h>
/**
* Update Message Queue
*/
/* Update Proxy Interface */
struct rdp_update_proxy
{
rdpUpdate* update;
/* Update */
pBeginPaint BeginPaint;
pEndPaint EndPaint;
pSetBounds SetBounds;
pSynchronize Synchronize;
pDesktopResize DesktopResize;
pBitmapUpdate BitmapUpdate;
pPalette Palette;
pPlaySound PlaySound;
pRefreshRect RefreshRect;
pSuppressOutput SuppressOutput;
pSurfaceCommand SurfaceCommand;
pSurfaceBits SurfaceBits;
pSurfaceFrameMarker SurfaceFrameMarker;
pSurfaceFrameAcknowledge SurfaceFrameAcknowledge;
/* Primary Update */
pDstBlt DstBlt;
pPatBlt PatBlt;
pScrBlt ScrBlt;
pOpaqueRect OpaqueRect;
pDrawNineGrid DrawNineGrid;
pMultiDstBlt MultiDstBlt;
pMultiPatBlt MultiPatBlt;
pMultiScrBlt MultiScrBlt;
pMultiOpaqueRect MultiOpaqueRect;
pMultiDrawNineGrid MultiDrawNineGrid;
pLineTo LineTo;
pPolyline Polyline;
pMemBlt MemBlt;
pMem3Blt Mem3Blt;
pSaveBitmap SaveBitmap;
pGlyphIndex GlyphIndex;
pFastIndex FastIndex;
pFastGlyph FastGlyph;
pPolygonSC PolygonSC;
pPolygonCB PolygonCB;
pEllipseSC EllipseSC;
pEllipseCB EllipseCB;
/* Secondary Update */
pCacheBitmap CacheBitmap;
pCacheBitmapV2 CacheBitmapV2;
pCacheBitmapV3 CacheBitmapV3;
pCacheColorTable CacheColorTable;
pCacheGlyph CacheGlyph;
pCacheGlyphV2 CacheGlyphV2;
pCacheBrush CacheBrush;
/* Alternate Secondary Update */
pCreateOffscreenBitmap CreateOffscreenBitmap;
pSwitchSurface SwitchSurface;
pCreateNineGridBitmap CreateNineGridBitmap;
pFrameMarker FrameMarker;
pStreamBitmapFirst StreamBitmapFirst;
pStreamBitmapNext StreamBitmapNext;
pDrawGdiPlusFirst DrawGdiPlusFirst;
pDrawGdiPlusNext DrawGdiPlusNext;
pDrawGdiPlusEnd DrawGdiPlusEnd;
pDrawGdiPlusCacheFirst DrawGdiPlusCacheFirst;
pDrawGdiPlusCacheNext DrawGdiPlusCacheNext;
pDrawGdiPlusCacheEnd DrawGdiPlusCacheEnd;
/* Window Update */
pWindowCreate WindowCreate;
pWindowUpdate WindowUpdate;
pWindowIcon WindowIcon;
pWindowCachedIcon WindowCachedIcon;
pWindowDelete WindowDelete;
pNotifyIconCreate NotifyIconCreate;
pNotifyIconUpdate NotifyIconUpdate;
pNotifyIconDelete NotifyIconDelete;
pMonitoredDesktop MonitoredDesktop;
pNonMonitoredDesktop NonMonitoredDesktop;
/* Pointer Update */
pPointerPosition PointerPosition;
pPointerSystem PointerSystem;
pPointerColor PointerColor;
pPointerNew PointerNew;
pPointerCached PointerCached;
};
int update_message_queue_process_message(rdpUpdate* update, wMessage* message);
int update_message_queue_process_pending_messages(rdpUpdate* update);
rdpUpdateProxy* update_message_proxy_new(rdpUpdate* update);
void update_message_proxy_free(rdpUpdateProxy* message);
/**
* Input Message Queue
*/
/* Input Proxy Interface */
struct rdp_input_proxy
{
rdpInput* input;
/* Input */
pSynchronizeEvent SynchronizeEvent;
pKeyboardEvent KeyboardEvent;
pUnicodeKeyboardEvent UnicodeKeyboardEvent;
pMouseEvent MouseEvent;
pExtendedMouseEvent ExtendedMouseEvent;
};
int input_message_queue_process_message(rdpInput* input, wMessage* message);
int input_message_queue_process_pending_messages(rdpInput* input);
rdpInputProxy* input_message_proxy_new(rdpInput* input);
void input_message_proxy_free(rdpInputProxy* proxy);
#endif /* FREERDP_CORE_MESSAGE_PRIVATE_H */

View File

@ -909,8 +909,6 @@ BOOL update_read_glyph_index_order(STREAM* s, ORDER_INFO* orderInfo, GLYPH_INDEX
return TRUE;
}
BOOL update_read_fast_index_order(STREAM* s, ORDER_INFO* orderInfo, FAST_INDEX_ORDER* fast_index)
{
ORDER_FIELD_BYTE(1, fast_index->cacheId);
@ -942,12 +940,10 @@ BOOL update_read_fast_index_order(STREAM* s, ORDER_INFO* orderInfo, FAST_INDEX_O
return TRUE;
}
BOOL update_read_fast_glyph_order(STREAM* s, ORDER_INFO* orderInfo, FAST_GLYPH_ORDER* fast_glyph)
{
GLYPH_DATA_V2* glyph;
BYTE* phold;
GLYPH_DATA_V2* glyph;
ORDER_FIELD_BYTE(1, fast_glyph->cacheId);
ORDER_FIELD_2BYTE(2, fast_glyph->ulCharInc, fast_glyph->flAccel);
@ -968,32 +964,40 @@ BOOL update_read_fast_glyph_order(STREAM* s, ORDER_INFO* orderInfo, FAST_GLYPH_O
{
if (stream_get_left(s) < 1)
return FALSE;
stream_read_BYTE(s, fast_glyph->cbData);
if (stream_get_left(s) < fast_glyph->cbData)
return FALSE;
memcpy(fast_glyph->data, s->p, fast_glyph->cbData);
phold = s->p;
if (!stream_skip(s, 1))
return FALSE;
if ((fast_glyph->cbData > 1) && (fast_glyph->glyph_data == NULL))
if (fast_glyph->cbData > 1)
{
/* parse optional glyph data */
glyph = (GLYPH_DATA_V2*) malloc(sizeof(GLYPH_DATA_V2));
glyph = &fast_glyph->glyphData;
glyph->cacheIndex = fast_glyph->data[0];
if (!update_read_2byte_signed(s, &glyph->x) ||
!update_read_2byte_signed(s, &glyph->y) ||
!update_read_2byte_unsigned(s, &glyph->cx) ||
!update_read_2byte_unsigned(s, &glyph->cy))
return FALSE;
glyph->cb = ((glyph->cx + 7) / 8) * glyph->cy;
glyph->cb += ((glyph->cb % 4) > 0) ? 4 - (glyph->cb % 4) : 0;
if (stream_get_left(s) < glyph->cb)
return FALSE;
glyph->aj = (BYTE*) malloc(glyph->cb);
stream_read(s, glyph->aj, glyph->cb);
fast_glyph->glyph_data = glyph;
}
s->p = phold + fast_glyph->cbData;
}
return TRUE;
@ -1239,25 +1243,26 @@ BOOL update_read_cache_color_table_order(STREAM* s, CACHE_COLOR_TABLE_ORDER* cac
if (stream_get_left(s) < 3)
return FALSE;
stream_read_BYTE(s, cache_color_table_order->cacheIndex); /* cacheIndex (1 byte) */
stream_read_UINT16(s, cache_color_table_order->numberColors); /* numberColors (2 bytes) */
if (cache_color_table_order->numberColors != 256)
{
/* This field MUST be set to 256 */
return FALSE;
}
if (stream_get_left(s) < cache_color_table_order->numberColors * 4)
return FALSE;
colorTable = cache_color_table_order->colorTable;
if (colorTable == NULL)
colorTable = (UINT32*) malloc(cache_color_table_order->numberColors * 4);
else
colorTable = (UINT32*) realloc(colorTable, cache_color_table_order->numberColors * 4);
colorTable = (UINT32*) &cache_color_table_order->colorTable;
for (i = 0; i < (int) cache_color_table_order->numberColors; i++)
{
update_read_color_quad(s, &colorTable[i]);
}
cache_color_table_order->colorTable = colorTable;
return TRUE;
}
@ -1269,19 +1274,17 @@ BOOL update_read_cache_glyph_order(STREAM* s, CACHE_GLYPH_ORDER* cache_glyph_ord
if (stream_get_left(s) < 2)
return FALSE;
stream_read_BYTE(s, cache_glyph_order->cacheId); /* cacheId (1 byte) */
stream_read_BYTE(s, cache_glyph_order->cGlyphs); /* cGlyphs (1 byte) */
for (i = 0; i < (int) cache_glyph_order->cGlyphs; i++)
{
if (cache_glyph_order->glyphData[i] == NULL)
{
cache_glyph_order->glyphData[i] = (GLYPH_DATA*) malloc(sizeof(GLYPH_DATA));
}
glyph = cache_glyph_order->glyphData[i];
glyph = &cache_glyph_order->glyphData[i];
if (stream_get_left(s) < 10)
return FALSE;
stream_read_UINT16(s, glyph->cacheIndex);
stream_read_UINT16(s, lsi16);
glyph->x = lsi16;
@ -1295,13 +1298,16 @@ BOOL update_read_cache_glyph_order(STREAM* s, CACHE_GLYPH_ORDER* cache_glyph_ord
if (stream_get_left(s) < glyph->cb)
return FALSE;
glyph->aj = (BYTE*) malloc(glyph->cb);
stream_read(s, glyph->aj, glyph->cb);
}
if (flags & CG_GLYPH_UNICODE_PRESENT) {
if (flags & CG_GLYPH_UNICODE_PRESENT)
{
return stream_skip(s, cache_glyph_order->cGlyphs * 2);
}
return TRUE;
}
@ -1316,14 +1322,11 @@ BOOL update_read_cache_glyph_v2_order(STREAM* s, CACHE_GLYPH_V2_ORDER* cache_gly
for (i = 0; i < (int) cache_glyph_v2_order->cGlyphs; i++)
{
if (cache_glyph_v2_order->glyphData[i] == NULL)
{
cache_glyph_v2_order->glyphData[i] = (GLYPH_DATA_V2*) malloc(sizeof(GLYPH_DATA_V2));
}
glyph = cache_glyph_v2_order->glyphData[i];
glyph = &cache_glyph_v2_order->glyphData[i];
if (stream_get_left(s) < 1)
return FALSE;
stream_read_BYTE(s, glyph->cacheIndex);
if (!update_read_2byte_signed(s, &glyph->x) ||
@ -1339,13 +1342,16 @@ BOOL update_read_cache_glyph_v2_order(STREAM* s, CACHE_GLYPH_V2_ORDER* cache_gly
if (stream_get_left(s) < glyph->cb)
return FALSE;
glyph->aj = (BYTE*) malloc(glyph->cb);
stream_read(s, glyph->aj, glyph->cb);
}
if (flags & CG_GLYPH_UNICODE_PRESENT) {
if (flags & CG_GLYPH_UNICODE_PRESENT)
{
return stream_skip(s, cache_glyph_v2_order->cGlyphs * 2);
}
return TRUE;
}
@ -1390,6 +1396,7 @@ BOOL update_read_cache_brush_order(STREAM* s, CACHE_BRUSH_ORDER* cache_brush_ord
if (stream_get_left(s) < 6)
return FALSE;
stream_read_BYTE(s, cache_brush_order->index); /* cacheEntry (1 byte) */
stream_read_BYTE(s, iBitmapFormat); /* iBitmapFormat (1 byte) */
@ -1404,8 +1411,6 @@ BOOL update_read_cache_brush_order(STREAM* s, CACHE_BRUSH_ORDER* cache_brush_ord
{
size = (cache_brush_order->bpp == 1) ? 8 : 8 * 8 * cache_brush_order->bpp;
cache_brush_order->data = (BYTE*) malloc(size);
if (cache_brush_order->bpp == 1)
{
if (cache_brush_order->length != 8)
@ -1442,6 +1447,7 @@ BOOL update_read_cache_brush_order(STREAM* s, CACHE_BRUSH_ORDER* cache_brush_ord
{
/* uncompressed brush */
int scanline = (cache_brush_order->bpp / 8) * 8;
if (stream_get_left(s) < scanline * 8)
return FALSE;
@ -1452,6 +1458,7 @@ BOOL update_read_cache_brush_order(STREAM* s, CACHE_BRUSH_ORDER* cache_brush_ord
}
}
}
return TRUE;
}
@ -1560,7 +1567,7 @@ BOOL update_read_stream_bitmap_first_order(STREAM* s, STREAM_BITMAP_FIRST_ORDER*
return TRUE;
}
BOOL update_read_stream_bitmap_next_order(STREAM* s, STREAM_BITMAP_FIRST_ORDER* stream_bitmap_next)
BOOL update_read_stream_bitmap_next_order(STREAM* s, STREAM_BITMAP_NEXT_ORDER* stream_bitmap_next)
{
if (stream_get_left(s) < 5)
return FALSE;

View File

@ -222,7 +222,7 @@ BOOL update_read_switch_surface_order(STREAM* s, SWITCH_SURFACE_ORDER* switch_su
BOOL update_read_create_nine_grid_bitmap_order(STREAM* s, CREATE_NINE_GRID_BITMAP_ORDER* create_nine_grid_bitmap);
BOOL update_read_frame_marker_order(STREAM* s, FRAME_MARKER_ORDER* frame_marker);
BOOL update_read_stream_bitmap_first_order(STREAM* s, STREAM_BITMAP_FIRST_ORDER* stream_bitmap_first);
BOOL update_read_stream_bitmap_next_order(STREAM* s, STREAM_BITMAP_FIRST_ORDER* stream_bitmap_next);
BOOL update_read_stream_bitmap_next_order(STREAM* s, STREAM_BITMAP_NEXT_ORDER* stream_bitmap_next);
BOOL update_read_draw_gdiplus_first_order(STREAM* s, DRAW_GDIPLUS_FIRST_ORDER* draw_gdiplus_first);
BOOL update_read_draw_gdiplus_next_order(STREAM* s, DRAW_GDIPLUS_NEXT_ORDER* draw_gdiplus_next);
BOOL update_read_draw_gdiplus_end_order(STREAM* s, DRAW_GDIPLUS_END_ORDER* draw_gdiplus_end);

View File

@ -255,7 +255,7 @@ static int peer_recv_pdu(freerdp_peer* client, STREAM* s)
return peer_recv_fastpath_pdu(client, s);
}
static BOOL peer_recv_callback(rdpTransport* transport, STREAM* s, void* extra)
static int peer_recv_callback(rdpTransport* transport, STREAM* s, void* extra)
{
freerdp_peer* client = (freerdp_peer*) extra;
rdpRdp* rdp = client->context->rdp;

View File

@ -103,7 +103,7 @@ void rdp_write_security_header(STREAM* s, UINT16 flags)
BOOL rdp_read_share_control_header(STREAM* s, UINT16* length, UINT16* type, UINT16* channel_id)
{
if(stream_get_left(s) < 2)
if (stream_get_left(s) < 2)
return FALSE;
/* Share Control Header */
@ -117,8 +117,8 @@ BOOL rdp_read_share_control_header(STREAM* s, UINT16* length, UINT16* type, UINT
if (*length > 4)
stream_read_UINT16(s, *channel_id); /* pduSource */
else /* Windows XP can send such short DEACTIVATE_ALL PDUs. */
*channel_id = 0;
else
*channel_id = 0; /* Windows XP can send such short DEACTIVATE_ALL PDUs. */
return TRUE;
}
@ -510,6 +510,11 @@ int rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s)
if (compressed_type & PACKET_COMPRESSED)
{
if (stream_get_left(s) < compressed_len - 18)
{
printf("decompress_rdp: not enough bytes for compressed_len=%d\n", compressed_len);
return -1;
}
if (decompress_rdp(rdp->mppc_dec, s->p, compressed_len - 18, compressed_type, &roff, &rlen))
{
comp_stream = stream_new(0);
@ -575,7 +580,7 @@ int rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s)
case DATA_PDU_TYPE_SAVE_SESSION_INFO:
if(!rdp_recv_save_session_info(rdp, comp_stream))
return FALSE;
return -1;
break;
case DATA_PDU_TYPE_FONT_LIST:
@ -640,7 +645,7 @@ BOOL rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, STREAM* s)
UINT16 length;
UINT16 channelId;
if(!rdp_read_share_control_header(s, &length, &type, &channelId))
if (!rdp_read_share_control_header(s, &length, &type, &channelId))
return FALSE;
if (type == PDU_TYPE_DATA)

View File

@ -49,38 +49,38 @@
#include <freerdp/codec/mppc_enc.h>
/* Security Header Flags */
#define SEC_EXCHANGE_PKT 0x0001
#define SEC_ENCRYPT 0x0008
#define SEC_RESET_SEQNO 0x0010
#define SEC_IGNORE_SEQNO 0x0020
#define SEC_INFO_PKT 0x0040
#define SEC_LICENSE_PKT 0x0080
#define SEC_LICENSE_ENCRYPT_CS 0x0200
#define SEC_LICENSE_ENCRYPT_SC 0x0200
#define SEC_REDIRECTION_PKT 0x0400
#define SEC_SECURE_CHECKSUM 0x0800
#define SEC_FLAGSHI_VALID 0x8000
#define SEC_EXCHANGE_PKT 0x0001
#define SEC_ENCRYPT 0x0008
#define SEC_RESET_SEQNO 0x0010
#define SEC_IGNORE_SEQNO 0x0020
#define SEC_INFO_PKT 0x0040
#define SEC_LICENSE_PKT 0x0080
#define SEC_LICENSE_ENCRYPT_CS 0x0200
#define SEC_LICENSE_ENCRYPT_SC 0x0200
#define SEC_REDIRECTION_PKT 0x0400
#define SEC_SECURE_CHECKSUM 0x0800
#define SEC_FLAGSHI_VALID 0x8000
#define SEC_PKT_CS_MASK (SEC_EXCHANGE_PKT | SEC_INFO_PKT)
#define SEC_PKT_SC_MASK (SEC_LICENSE_PKT | SEC_REDIRECTION_PKT)
#define SEC_PKT_MASK (SEC_PKT_CS_MASK | SEC_PKT_SC_MASK)
#define SEC_PKT_CS_MASK (SEC_EXCHANGE_PKT | SEC_INFO_PKT)
#define SEC_PKT_SC_MASK (SEC_LICENSE_PKT | SEC_REDIRECTION_PKT)
#define SEC_PKT_MASK (SEC_PKT_CS_MASK | SEC_PKT_SC_MASK)
#define RDP_SECURITY_HEADER_LENGTH 4
#define RDP_SHARE_CONTROL_HEADER_LENGTH 6
#define RDP_SHARE_DATA_HEADER_LENGTH 12
#define RDP_PACKET_HEADER_MAX_LENGTH (TPDU_DATA_LENGTH + MCS_SEND_DATA_HEADER_MAX_LENGTH)
#define RDP_SECURITY_HEADER_LENGTH 4
#define RDP_SHARE_CONTROL_HEADER_LENGTH 6
#define RDP_SHARE_DATA_HEADER_LENGTH 12
#define RDP_PACKET_HEADER_MAX_LENGTH (TPDU_DATA_LENGTH + MCS_SEND_DATA_HEADER_MAX_LENGTH)
#define PDU_TYPE_DEMAND_ACTIVE 0x1
#define PDU_TYPE_CONFIRM_ACTIVE 0x3
#define PDU_TYPE_DEACTIVATE_ALL 0x6
#define PDU_TYPE_DATA 0x7
#define PDU_TYPE_SERVER_REDIRECTION 0xA
#define PDU_TYPE_DEMAND_ACTIVE 0x1
#define PDU_TYPE_CONFIRM_ACTIVE 0x3
#define PDU_TYPE_DEACTIVATE_ALL 0x6
#define PDU_TYPE_DATA 0x7
#define PDU_TYPE_SERVER_REDIRECTION 0xA
#define FINALIZE_SC_SYNCHRONIZE_PDU 0x01
#define FINALIZE_SC_CONTROL_COOPERATE_PDU 0x02
#define FINALIZE_SC_CONTROL_GRANTED_PDU 0x04
#define FINALIZE_SC_FONT_MAP_PDU 0x08
#define FINALIZE_SC_COMPLETE 0x0F
#define FINALIZE_SC_SYNCHRONIZE_PDU 0x01
#define FINALIZE_SC_CONTROL_COOPERATE_PDU 0x02
#define FINALIZE_SC_CONTROL_GRANTED_PDU 0x04
#define FINALIZE_SC_FONT_MAP_PDU 0x08
#define FINALIZE_SC_COMPLETE 0x0F
/* Data PDU Types */
#define DATA_PDU_TYPE_UPDATE 0x02
@ -110,10 +110,10 @@
#define DATA_PDU_TYPE_FRAME_ACKNOWLEDGE 0x38
/* Stream Identifiers */
#define STREAM_UNDEFINED 0x00
#define STREAM_LOW 0x01
#define STREAM_MED 0x02
#define STREAM_HI 0x04
#define STREAM_UNDEFINED 0x00
#define STREAM_LOW 0x01
#define STREAM_MED 0x02
#define STREAM_HI 0x04
struct rdp_rdp
{
@ -178,7 +178,7 @@ BOOL rdp_send_pdu(rdpRdp* rdp, STREAM* s, UINT16 type, UINT16 channel_id);
STREAM* rdp_data_pdu_init(rdpRdp* rdp);
BOOL rdp_send_data_pdu(rdpRdp* rdp, STREAM* s, BYTE type, UINT16 channel_id);
BOOL rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s);
int rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s);
BOOL rdp_send(rdpRdp* rdp, STREAM* s, UINT16 channel_id);
void rdp_recv(rdpRdp* rdp);

View File

@ -678,10 +678,6 @@ int transport_check_fds(rdpTransport** ptransport)
return 0; /* Packet is not yet completely received. */
}
/*
* A complete packet has been received. In case there are trailing data
* for the next packet, we copy it to the new receive buffer.
*/
received = transport->ReceiveBuffer;
transport->ReceiveBuffer = transport_receive_pool_take(transport);
@ -697,11 +693,9 @@ int transport_check_fds(rdpTransport** ptransport)
* 1: asynchronous return
*/
ReferenceTable_Add(transport->ReceiveReferences, received);
recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra);
ReferenceTable_Release(transport->ReceiveReferences, received);
transport_receive_pool_return(transport, received);
if (recv_status < 0)
status = -1;
@ -749,7 +743,9 @@ STREAM* transport_receive_pool_take(rdpTransport* transport)
pdu = Queue_Dequeue(transport->ReceivePool);
if (!pdu)
{
pdu = stream_new(BUFFER_SIZE);
}
pdu->p = pdu->data;
@ -778,8 +774,13 @@ rdpTransport* transport_new(rdpSettings* settings)
/* a small 0.1ms delay when transport is blocking. */
transport->SleepInterval = 100;
transport->ReceivePool = Queue_New(TRUE, -1, -1);
transport->ReceiveQueue = Queue_New(TRUE, -1, -1);
Queue_Object(transport->ReceivePool)->fnObjectFree = (OBJECT_FREE_FN) stream_free;
Queue_Object(transport->ReceiveQueue)->fnObjectFree = (OBJECT_FREE_FN) stream_free;
/* receive buffer for non-blocking read. */
transport->ReceiveBuffer = stream_new(BUFFER_SIZE);
transport->ReceiveBuffer = transport_receive_pool_take(transport);
transport->ReceiveEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
/* buffers for blocking read/write */
@ -789,14 +790,6 @@ rdpTransport* transport_new(rdpSettings* settings)
transport->blocking = TRUE;
transport->layer = TRANSPORT_LAYER_TCP;
transport->ReceivePool = Queue_New(TRUE, -1, -1);
transport->ReceiveQueue = Queue_New(TRUE, -1, -1);
Queue_Object(transport->ReceivePool)->fnObjectFree = (OBJECT_FREE_FN) stream_free;
Queue_Object(transport->ReceiveQueue)->fnObjectFree = (OBJECT_FREE_FN) stream_free;
transport->ReceiveReferences = ReferenceTable_New(TRUE,
(void*) transport, (REFERENCE_FREE) transport_receive_pool_return);
}
return transport;
@ -806,7 +799,9 @@ void transport_free(rdpTransport* transport)
{
if (transport != NULL)
{
stream_free(transport->ReceiveBuffer);
if (transport->ReceiveBuffer)
stream_free(transport->ReceiveBuffer);
stream_free(transport->ReceiveStream);
stream_free(transport->SendStream);
CloseHandle(transport->ReceiveEvent);
@ -827,8 +822,6 @@ void transport_free(rdpTransport* transport)
Queue_Free(transport->ReceivePool);
Queue_Free(transport->ReceiveQueue);
ReferenceTable_Free(transport->ReceiveReferences);
free(transport);
}
}

View File

@ -45,7 +45,7 @@ typedef struct rdp_transport rdpTransport;
#include <freerdp/settings.h>
#include <freerdp/utils/stream.h>
typedef BOOL (*TransportRecv) (rdpTransport* transport, STREAM* stream, void* extra);
typedef int (*TransportRecv) (rdpTransport* transport, STREAM* stream, void* extra);
struct rdp_transport
{
@ -69,8 +69,6 @@ struct rdp_transport
wQueue* ReceivePool;
wQueue* ReceiveQueue;
wReferenceTable* ReceiveReferences;
};
STREAM* transport_recv_stream_init(rdpTransport* transport, int size);

View File

@ -23,9 +23,11 @@
#include <winpr/crt.h>
#include <winpr/thread.h>
#include <winpr/collections.h>
#include "update.h"
#include "surface.h"
#include "message.h"
#include <freerdp/peer.h>
#include <freerdp/codec/bitmap.h>
@ -241,7 +243,12 @@ BOOL update_read_pointer_color(STREAM* s, POINTER_COLOR_UPDATE* pointer_color)
{
if (stream_get_left(s) < pointer_color->lengthXorMask)
return FALSE;
pointer_color->xorMaskData = (BYTE*) malloc(pointer_color->lengthXorMask);
if (!pointer_color->xorMaskData)
pointer_color->xorMaskData = malloc(pointer_color->lengthXorMask);
else
pointer_color->xorMaskData = realloc(pointer_color->xorMaskData, pointer_color->lengthXorMask);
stream_read(s, pointer_color->xorMaskData, pointer_color->lengthXorMask);
}
@ -249,12 +256,18 @@ BOOL update_read_pointer_color(STREAM* s, POINTER_COLOR_UPDATE* pointer_color)
{
if (stream_get_left(s) < pointer_color->lengthAndMask)
return FALSE;
pointer_color->andMaskData = (BYTE*) malloc(pointer_color->lengthAndMask);
if (!pointer_color->andMaskData)
pointer_color->andMaskData = malloc(pointer_color->lengthAndMask);
else
pointer_color->andMaskData = realloc(pointer_color->andMaskData, pointer_color->lengthAndMask);
stream_read(s, pointer_color->andMaskData, pointer_color->lengthAndMask);
}
if (stream_get_left(s) > 0)
stream_seek_BYTE(s); /* pad (1 byte) */
return TRUE;
}
@ -378,33 +391,50 @@ void update_reset_state(rdpUpdate* update)
rdpPrimaryUpdate* primary = update->primary;
rdpAltSecUpdate* altsec = update->altsec;
memset(&primary->order_info, 0, sizeof(ORDER_INFO));
memset(&primary->dstblt, 0, sizeof(DSTBLT_ORDER));
memset(&primary->patblt, 0, sizeof(PATBLT_ORDER));
memset(&primary->scrblt, 0, sizeof(SCRBLT_ORDER));
memset(&primary->opaque_rect, 0, sizeof(OPAQUE_RECT_ORDER));
memset(&primary->draw_nine_grid, 0, sizeof(DRAW_NINE_GRID_ORDER));
memset(&primary->multi_dstblt, 0, sizeof(MULTI_DSTBLT_ORDER));
memset(&primary->multi_patblt, 0, sizeof(MULTI_PATBLT_ORDER));
memset(&primary->multi_scrblt, 0, sizeof(MULTI_SCRBLT_ORDER));
memset(&primary->multi_opaque_rect, 0, sizeof(MULTI_OPAQUE_RECT_ORDER));
memset(&primary->multi_draw_nine_grid, 0, sizeof(MULTI_DRAW_NINE_GRID_ORDER));
memset(&primary->line_to, 0, sizeof(LINE_TO_ORDER));
memset(&primary->polyline, 0, sizeof(POLYLINE_ORDER));
memset(&primary->memblt, 0, sizeof(MEMBLT_ORDER));
memset(&primary->mem3blt, 0, sizeof(MEM3BLT_ORDER));
memset(&primary->save_bitmap, 0, sizeof(SAVE_BITMAP_ORDER));
memset(&primary->glyph_index, 0, sizeof(GLYPH_INDEX_ORDER));
memset(&primary->fast_index, 0, sizeof(FAST_INDEX_ORDER));
memset(&primary->fast_glyph, 0, sizeof(FAST_GLYPH_ORDER));
memset(&primary->polygon_sc, 0, sizeof(POLYGON_SC_ORDER));
memset(&primary->polygon_cb, 0, sizeof(POLYGON_CB_ORDER));
memset(&primary->ellipse_sc, 0, sizeof(ELLIPSE_SC_ORDER));
memset(&primary->ellipse_cb, 0, sizeof(ELLIPSE_CB_ORDER));
ZeroMemory(&primary->order_info, sizeof(ORDER_INFO));
ZeroMemory(&primary->dstblt, sizeof(DSTBLT_ORDER));
ZeroMemory(&primary->patblt, sizeof(PATBLT_ORDER));
ZeroMemory(&primary->scrblt, sizeof(SCRBLT_ORDER));
ZeroMemory(&primary->opaque_rect, sizeof(OPAQUE_RECT_ORDER));
ZeroMemory(&primary->draw_nine_grid, sizeof(DRAW_NINE_GRID_ORDER));
ZeroMemory(&primary->multi_dstblt, sizeof(MULTI_DSTBLT_ORDER));
ZeroMemory(&primary->multi_patblt, sizeof(MULTI_PATBLT_ORDER));
ZeroMemory(&primary->multi_scrblt, sizeof(MULTI_SCRBLT_ORDER));
ZeroMemory(&primary->multi_opaque_rect, sizeof(MULTI_OPAQUE_RECT_ORDER));
ZeroMemory(&primary->multi_draw_nine_grid, sizeof(MULTI_DRAW_NINE_GRID_ORDER));
ZeroMemory(&primary->line_to, sizeof(LINE_TO_ORDER));
ZeroMemory(&primary->polyline, sizeof(POLYLINE_ORDER));
ZeroMemory(&primary->memblt, sizeof(MEMBLT_ORDER));
ZeroMemory(&primary->mem3blt, sizeof(MEM3BLT_ORDER));
ZeroMemory(&primary->save_bitmap, sizeof(SAVE_BITMAP_ORDER));
ZeroMemory(&primary->glyph_index, sizeof(GLYPH_INDEX_ORDER));
ZeroMemory(&primary->fast_index, sizeof(FAST_INDEX_ORDER));
ZeroMemory(&primary->fast_glyph, sizeof(FAST_GLYPH_ORDER));
ZeroMemory(&primary->polygon_sc, sizeof(POLYGON_SC_ORDER));
ZeroMemory(&primary->polygon_cb, sizeof(POLYGON_CB_ORDER));
ZeroMemory(&primary->ellipse_sc, sizeof(ELLIPSE_SC_ORDER));
ZeroMemory(&primary->ellipse_cb, sizeof(ELLIPSE_CB_ORDER));
primary->order_info.orderType = ORDER_TYPE_PATBLT;
altsec->switch_surface.bitmapId = SCREEN_BITMAP_SURFACE;
IFCALL(altsec->SwitchSurface, update->context, &(altsec->switch_surface));
if (!update->initialState)
{
altsec->switch_surface.bitmapId = SCREEN_BITMAP_SURFACE;
IFCALL(altsec->SwitchSurface, update->context, &(altsec->switch_surface));
}
}
void update_post_connect(rdpUpdate* update)
{
update->asynchronous = update->context->settings->AsyncUpdate;
if (update->asynchronous)
update->proxy = update_message_proxy_new(update);
update->altsec->switch_surface.bitmapId = SCREEN_BITMAP_SURFACE;
IFCALL(update->altsec->SwitchSurface, update->context, &(update->altsec->switch_surface));
update->initialState = FALSE;
}
static void update_begin_paint(rdpContext* context)
@ -703,18 +733,9 @@ void update_register_client_callbacks(rdpUpdate* update)
update->SurfaceFrameAcknowledge = update_send_frame_acknowledge;
}
static void* update_thread(void* arg)
int update_process_messages(rdpUpdate* update)
{
rdpUpdate* update;
update = (rdpUpdate*) arg;
while (WaitForSingleObject(Queue_Event(update->queue), INFINITE) == WAIT_OBJECT_0)
{
}
return NULL;
return update_message_queue_process_pending_messages(update);
}
rdpUpdate* update_new(rdpRdp* rdp)
@ -755,9 +776,7 @@ rdpUpdate* update_new(rdpRdp* rdp)
update->SuppressOutput = update_send_suppress_output;
update->queue = Queue_New(TRUE, -1, -1);
update->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) update_thread, update, 0, NULL);
update->initialState = TRUE;
}
return update;
@ -773,17 +792,23 @@ void update_free(rdpUpdate* update)
free(deleteList->indices);
free(update->bitmap_update.rectangles);
free(update->pointer->pointer_color.andMaskData);
free(update->pointer->pointer_color.xorMaskData);
free(update->pointer->pointer_new.colorPtrAttr.andMaskData);
free(update->pointer->pointer_new.colorPtrAttr.xorMaskData);
free(update->pointer);
free(update->primary->polyline.points);
free(update->primary->polygon_sc.points);
free(update->primary);
free(update->secondary);
free(update->altsec);
free(update->window);
CloseHandle(update->thread);
Queue_Free(update->queue);
if (update->asynchronous)
update_message_proxy_free(update->proxy);
free(update);
}

View File

@ -37,8 +37,11 @@
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_post_connect(rdpUpdate* update);
BOOL update_read_bitmap(rdpUpdate* update, STREAM* s, BITMAP_UPDATE* bitmap_update);
BOOL update_read_palette(rdpUpdate* update, STREAM* s, PALETTE_UPDATE* palette_update);
@ -58,4 +61,6 @@ BOOL update_read_suppress_output(rdpUpdate* update, STREAM* s);
void update_register_server_callbacks(rdpUpdate* update);
void update_register_client_callbacks(rdpUpdate* update);
int update_process_messages(rdpUpdate* update);
#endif /* __UPDATE_H */

View File

@ -23,6 +23,7 @@ set(${MODULE_PREFIX}_SRCS
der.c
ber.c
per.c
base64.c
certificate.c
crypto.c
tls.c)

142
libfreerdp/crypto/base64.c Normal file
View File

@ -0,0 +1,142 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Base64 Encoding & Decoding
*
* Copyright 2011-2012 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <winpr/crt.h>
#include <freerdp/crypto/crypto.h>
static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char* crypto_base64_encode(BYTE* data, int length)
{
int c;
BYTE* q;
char* p;
char* str;
int i = 0;
q = data;
p = str = (char*) malloc((length + 3) * 4 / 3 + 1);
while (i < length)
{
c = q[i++];
c <<= 8;
if (i < length)
c += q[i];
i++;
c <<= 8;
if (i < length)
c += q[i];
i++;
*p++ = base64[(c & 0x00FC0000) >> 18];
*p++ = base64[(c & 0x0003F000) >> 12];
if (i > length + 1)
*p++ = '=';
else
*p++ = base64[(c & 0x00000FC0) >> 6];
if (i > length)
*p++ = '=';
else
*p++ = base64[c & 0x0000003F];
}
*p = 0;
return str;
}
static int base64_decode_char(char c)
{
if (c >= 'A' && c <= 'Z')
return c - 'A';
if (c >= 'a' && c <= 'z')
return c - 'a' + 26;
if (c >= '0' && c <= '9')
return c - '0' + 52;
if (c == '+')
return 62;
if (c == '/')
return 63;
if (c == '=')
return -1;
return -1;
}
static void* base64_decode(BYTE* s, int length, int* data_len)
{
char* p;
int n[4];
BYTE* q;
BYTE* data;
if (length % 4)
return NULL;
n[0] = n[1] = n[2] = n[3] = 0;
q = data = (BYTE*) malloc(length / 4 * 3);
for (p = (char*) s; *p; )
{
n[0] = base64_decode_char(*p++);
n[1] = base64_decode_char(*p++);
n[2] = base64_decode_char(*p++);
n[3] = base64_decode_char(*p++);
if ((n[0] == -1) || (n[1] == -1))
return NULL;
if ((n[2] == -1) && (n[3] != -1))
return NULL;
q[0] = (n[0] << 2) + (n[1] >> 4);
if (n[2] != -1)
q[1] = ((n[1] & 15) << 4) + (n[2] >> 2);
if (n[3] != -1)
q[2] = ((n[2] & 3) << 6) + n[3];
q += 3;
}
*data_len = q - data - (n[2] == -1) - (n[3] == -1);
return data;
}
void crypto_base64_decode(BYTE* enc_data, int length, BYTE** dec_data, int* res_length)
{
*dec_data = base64_decode(enc_data, length, res_length);
}

View File

@ -146,6 +146,7 @@ void crypto_hmac_free(CryptoHmac hmac)
{
if (hmac == NULL)
return;
HMAC_CTX_cleanup(&hmac->hmac_ctx);
free(hmac);
}
@ -258,37 +259,31 @@ static void crypto_rsa_public(const BYTE* input, int length, UINT32 key_length,
static void crypto_rsa_private(const BYTE* input, int length, UINT32 key_length, const BYTE* modulus, const BYTE* private_exponent, BYTE* output)
{
crypto_rsa_common(input, length, key_length, modulus, private_exponent, key_length, output);
}
void crypto_rsa_public_encrypt(const BYTE* input, int length, UINT32 key_length, const BYTE* modulus, const BYTE* exponent, BYTE* output)
{
crypto_rsa_public(input, length, key_length, modulus, exponent, output);
}
void crypto_rsa_public_decrypt(const BYTE* input, int length, UINT32 key_length, const BYTE* modulus, const BYTE* exponent, BYTE* output)
{
crypto_rsa_public(input, length, key_length, modulus, exponent, output);
}
void crypto_rsa_private_encrypt(const BYTE* input, int length, UINT32 key_length, const BYTE* modulus, const BYTE* private_exponent, BYTE* output)
{
crypto_rsa_private(input, length, key_length, modulus, private_exponent, output);
}
void crypto_rsa_private_decrypt(const BYTE* input, int length, UINT32 key_length, const BYTE* modulus, const BYTE* private_exponent, BYTE* output)
{
crypto_rsa_private(input, length, key_length, modulus, private_exponent, output);
}
void crypto_rsa_decrypt(const BYTE* input, int length, UINT32 key_length, const BYTE* modulus, const BYTE* private_exponent, BYTE* output)
{
crypto_rsa_common(input, length, key_length, modulus, private_exponent, key_length, output);
}
@ -529,47 +524,3 @@ void crypto_cert_print_info(X509* xcert)
free(issuer);
free(fp);
}
char* crypto_base64_encode(BYTE* data, int length)
{
BIO* bmem;
BIO* b64;
BUF_MEM *bptr;
char* base64_string;
b64 = BIO_new(BIO_f_base64());
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
bmem = BIO_new(BIO_s_mem());
b64 = BIO_push(b64, bmem);
BIO_write(b64, data, length);
if (BIO_flush(b64) < 1)
return NULL;
BIO_get_mem_ptr(b64, &bptr);
base64_string = malloc(bptr->length);
memcpy(base64_string, bptr->data, bptr->length - 1);
base64_string[bptr->length - 1] = '\0';
BIO_free_all(b64);
return base64_string;
}
void crypto_base64_decode(BYTE* enc_data, int length, BYTE** dec_data, int* res_length)
{
BIO *b64, *bmem;
*dec_data = malloc(length);
memset(*dec_data, 0, length);
b64 = BIO_new(BIO_f_base64());
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
bmem = BIO_new_mem_buf(enc_data, length);
bmem = BIO_push(b64, bmem);
*res_length = BIO_read(bmem, *dec_data, length);
BIO_free_all(bmem);
}

View File

@ -723,6 +723,12 @@ void tls_free(rdpTls* tls)
if (tls->PublicKey)
free(tls->PublicKey);
if (tls->Bindings)
{
free(tls->Bindings->Bindings);
free(tls->Bindings);
}
certificate_store_free(tls->certificate_store);
free(tls);

View File

@ -622,7 +622,7 @@ static int BitBlt_MERGEPAINT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int
static int BitBlt_PATCOPY_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
{
int x, y;
int x, y, xOffset, yOffset;
UINT16* dstp;
UINT16* patp;
UINT16 color16;
@ -647,6 +647,19 @@ static int BitBlt_PATCOPY_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi
}
else
{
/* align pattern to 8x8 grid to make sure transition
between different pattern blocks are smooth */
if (hdcDest->brush->style == GDI_BS_HATCHED)
{
xOffset = nXDest % 8;
yOffset = nYDest % 8 + 2; // +2 added after comparison to mstsc
}
else
{
xOffset = 0;
yOffset = 0;
}
for (y = 0; y < nHeight; y++)
{
dstp = (UINT16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
@ -655,7 +668,7 @@ static int BitBlt_PATCOPY_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi
{
for (x = 0; x < nWidth; x++)
{
patp = (UINT16*) gdi_get_brush_pointer(hdcDest, x, y);
patp = (UINT16*) gdi_get_brush_pointer(hdcDest, x+xOffset, y+yOffset);
*dstp = *patp;
dstp++;
}

View File

@ -169,7 +169,7 @@ static int BitBlt_SRCCOPY_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi
dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
if (srcp != 0 && dstp != 0)
memcpy(dstp, srcp, nWidth * hdcDest->bytesPerPixel);
memmove(dstp, srcp, nWidth * hdcDest->bytesPerPixel);
}
return 0;
@ -506,6 +506,60 @@ static int BitBlt_PSDPxax_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi
return 0;
}
static int BitBlt_SPDSxax_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
{
int x, y;
UINT32* srcp;
UINT32* dstp;
UINT32* patp;
UINT32 color32;
/* D = S ^ (P & (D ^ S)) */
if (hdcDest->brush->style == GDI_BS_SOLID)
{
color32 = gdi_get_color_32bpp(hdcDest, hdcDest->brush->color);
patp = (UINT32*) &color32;
for (y = 0; y < nHeight; y++)
{
srcp = (UINT32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
dstp = (UINT32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
if (dstp != 0)
{
for (x = 0; x < nWidth; x++)
{
*dstp = *srcp ^ (*patp & (*dstp ^ *srcp));
srcp++;
dstp++;
}
}
}
}
else
{
for (y = 0; y < nHeight; y++)
{
srcp = (UINT32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
dstp = (UINT32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
if (dstp != 0)
{
for (x = 0; x < nWidth; x++)
{
patp = (UINT32*) gdi_get_brush_pointer(hdcDest, x, y);
*dstp = *srcp ^ (*patp & (*dstp ^ *srcp));
srcp++;
dstp++;
}
}
}
}
return 0;
}
static int BitBlt_SPna_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
{
int x, y;
@ -664,7 +718,7 @@ static int BitBlt_MERGEPAINT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int
static int BitBlt_PATCOPY_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
{
int x, y;
int x, y, xOffset, yOffset;
UINT32* dstp;
UINT32* patp;
UINT32 color32;
@ -689,6 +743,19 @@ static int BitBlt_PATCOPY_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi
}
else
{
/* align pattern to 8x8 grid to make sure transition
between different pattern blocks are smooth */
if (hdcDest->brush->style == GDI_BS_HATCHED)
{
xOffset = nXDest % 8;
yOffset = nYDest % 8 + 2; // +2 added after comparison to mstsc
}
else
{
xOffset = 0;
yOffset = 0;
}
for (y = 0; y < nHeight; y++)
{
dstp = (UINT32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
@ -697,7 +764,7 @@ static int BitBlt_PATCOPY_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi
{
for (x = 0; x < nWidth; x++)
{
patp = (UINT32*) gdi_get_brush_pointer(hdcDest, x, y);
patp = (UINT32*) gdi_get_brush_pointer(hdcDest, x+xOffset, y+yOffset);
*dstp = *patp;
dstp++;
}
@ -826,6 +893,10 @@ int BitBlt_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeigh
return BitBlt_PSDPxax_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
break;
case GDI_SPDSxax:
return BitBlt_SPDSxax_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
break;
case GDI_NOTSRCCOPY:
return BitBlt_NOTSRCCOPY_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
break;

View File

@ -536,7 +536,7 @@ static int BitBlt_MERGEPAINT_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int n
static int BitBlt_PATCOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
{
int x, y;
int x, y, xOffset, yOffset;
BYTE* dstp;
BYTE* patp;
BYTE palIndex;
@ -559,6 +559,19 @@ static int BitBlt_PATCOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWid
}
else
{
/* align pattern to 8x8 grid to make sure transition
between different pattern blocks are smooth */
if (hdcDest->brush->style == GDI_BS_HATCHED)
{
xOffset = nXDest % 8;
yOffset = nYDest % 8 + 2; // +2 added after comparison to mstsc
}
else
{
xOffset = 0;
yOffset = 0;
}
for (y = 0; y < nHeight; y++)
{
dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
@ -567,7 +580,7 @@ static int BitBlt_PATCOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWid
{
for (x = 0; x < nWidth; x++)
{
patp = gdi_get_brush_pointer(hdcDest, x, y);
patp = gdi_get_brush_pointer(hdcDest, x+xOffset, y+yOffset);
*dstp = *patp;
patp++;

View File

@ -58,3 +58,8 @@ else()
endif()
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/libfreerdp")
if(BUILD_TESTING)
add_subdirectory(test)
endif()

View File

@ -77,6 +77,15 @@ HGDI_BRUSH gdi_CreatePatternBrush(HGDI_BITMAP hbmp)
return hBrush;
}
HGDI_BRUSH gdi_CreateHatchBrush(HGDI_BITMAP hbmp)
{
HGDI_BRUSH hBrush = (HGDI_BRUSH) malloc(sizeof(GDI_BRUSH));
hBrush->objectType = GDIOBJECT_BRUSH;
hBrush->style = GDI_BS_HATCHED;
hBrush->pattern = hbmp;
return hBrush;
}
/**
* Perform a pattern blit operation on the given pixel buffer.\n
* @msdn{dd162778}

View File

@ -312,6 +312,16 @@ static const UINT32 rop3_code_table[] =
0x00FF0062 /* 1 */
};
/* Hatch Patterns as monochrome data */
static BYTE GDI_BS_HACHTED_PATTERNS[] = {
0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, /* HS_HORIZONTAL */
0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, /* HS_VERTICAL */
0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F, /* HS_FDIAGONAL */
0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE, /* HS_BDIAGONAL */
0xF7, 0xF7, 0xF7, 0x00, 0xF7, 0xF7, 0xF7, 0xF7, /* HS_CROSS */
0x7E, 0xBD, 0xDB, 0xE7, 0xE7, 0xDB, 0xBD, 0x7E /* HS_DIACROSS */
};
/* GDI Helper Functions */
INLINE UINT32 gdi_rop3_code(BYTE code)
@ -342,7 +352,7 @@ INLINE BYTE* gdi_get_brush_pointer(HGDI_DC hdcBrush, int x, int y)
if (hdcBrush->brush != NULL)
{
if (hdcBrush->brush->style == GDI_BS_PATTERN)
if ((hdcBrush->brush->style == GDI_BS_PATTERN) || (hdcBrush->brush->style == GDI_BS_HATCHED))
{
HGDI_BITMAP hBmpBrush = hdcBrush->brush->pattern;
@ -439,8 +449,7 @@ void gdi_bitmap_free_ex(gdiBitmap* bitmap)
void gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette)
{
rdpGdi* gdi = context->gdi;
gdi->clrconv->palette->count = palette->number;
gdi->clrconv->palette->entries = palette->entries;
CopyMemory(gdi->clrconv->palette, palette, sizeof(rdpPalette));
}
void gdi_set_bounds(rdpContext* context, rdpBounds* bounds)
@ -489,6 +498,24 @@ void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
gdi_DeleteObject((HGDIOBJECT) gdi->drawing->hdc->brush);
gdi->drawing->hdc->brush = originalBrush;
}
else if (brush->style == GDI_BS_HATCHED)
{
HGDI_BITMAP hBmp;
data = freerdp_mono_image_convert(GDI_BS_HACHTED_PATTERNS + 8 * brush->hatch, 8, 8, 1,
gdi->dstBpp, patblt->backColor, patblt->foreColor, gdi->clrconv);
hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data);
originalBrush = gdi->drawing->hdc->brush;
gdi->drawing->hdc->brush = gdi_CreateHatchBrush(hBmp);
gdi_PatBlt(gdi->drawing->hdc, patblt->nLeftRect, patblt->nTopRect,
patblt->nWidth, patblt->nHeight, gdi_rop3_code(patblt->bRop));
gdi_DeleteObject((HGDIOBJECT) gdi->drawing->hdc->brush);
gdi->drawing->hdc->brush = originalBrush;
}
else if (brush->style == GDI_BS_PATTERN)
{
HGDI_BITMAP hBmp;
@ -634,6 +661,7 @@ void gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
{
BYTE* data;
rdpBrush* brush;
UINT32 foreColor;
UINT32 backColor;
@ -659,6 +687,32 @@ void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
gdi_DeleteObject((HGDIOBJECT) gdi->drawing->hdc->brush);
gdi->drawing->hdc->brush = originalBrush;
}
else if (brush->style == GDI_BS_PATTERN)
{
HGDI_BITMAP hBmp;
if (brush->bpp > 1)
{
data = freerdp_image_convert(brush->data, NULL, 8, 8, gdi->srcBpp, gdi->dstBpp, gdi->clrconv);
}
else
{
data = freerdp_mono_image_convert(brush->data, 8, 8, gdi->srcBpp, gdi->dstBpp,
mem3blt->backColor, mem3blt->foreColor, gdi->clrconv);
}
hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data);
originalBrush = gdi->drawing->hdc->brush;
gdi->drawing->hdc->brush = gdi_CreatePatternBrush(hBmp);
gdi_BitBlt(gdi->drawing->hdc, mem3blt->nLeftRect, mem3blt->nTopRect,
mem3blt->nWidth, mem3blt->nHeight, bitmap->hdc,
mem3blt->nXSrc, mem3blt->nYSrc, gdi_rop3_code(mem3blt->bRop));
gdi_DeleteObject((HGDIOBJECT) gdi->drawing->hdc->brush);
gdi->drawing->hdc->brush = originalBrush;
}
else
{
printf("Mem3Blt unimplemented brush style:%d\n", brush->style);
@ -928,7 +982,7 @@ int gdi_init(freerdp* instance, UINT32 flags, BYTE* buffer)
gdi->bytesPerPixel = 4;
}
}
gdi->hdc = gdi_GetDC();
gdi->hdc->bitsPerPixel = gdi->dstBpp;
gdi->hdc->bytesPerPixel = gdi->bytesPerPixel;
@ -980,7 +1034,9 @@ void gdi_free(freerdp* instance)
gdi_bitmap_free_ex(gdi->tile);
gdi_bitmap_free_ex(gdi->image);
gdi_DeleteDC(gdi->hdc);
rfx_context_free((RFX_CONTEXT*)gdi->rfx_context);
rfx_context_free((RFX_CONTEXT*) gdi->rfx_context);
nsc_context_free((NSC_CONTEXT*) gdi->nsc_context);
free(gdi->clrconv->palette);
free(gdi->clrconv);
free(gdi);
}

View File

@ -244,8 +244,8 @@ void gdi_Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int heigh
gdi_CRgnToRect(x, y, width, height, &rect);
brush = gdi_CreateSolidBrush(fgcolor);
gdi_FillRect(gdi->drawing->hdc, &rect, brush);
gdi_DeleteObject((HGDIOBJECT) brush);
gdi->textColor = gdi_SetTextColor(gdi->drawing->hdc, bgcolor);
}

2
libfreerdp/gdi/test/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
TestGdi
TestGdi.c

View File

@ -0,0 +1,40 @@
set(MODULE_NAME "TestGdi")
set(MODULE_PREFIX "TEST_GDI")
set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
set(${MODULE_PREFIX}_TESTS
TestGdiRop3.c)
create_test_sourcelist(${MODULE_PREFIX}_SRCS
${${MODULE_PREFIX}_DRIVER}
${${MODULE_PREFIX}_TESTS})
include_directories(..)
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${CMOCKERY_LIBRARIES})
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
MONOLITHIC ${MONOLITHIC_BUILD}
MODULE freerdp
MODULES freerdp-gdi)
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
MONOLITHIC ${MONOLITHIC_BUILD}
MODULE winpr
MODULES winpr-crt winpr-utils)
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}")
foreach(test ${${MODULE_PREFIX}_TESTS})
get_filename_component(TestName ${test} NAME_WE)
add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName})
endforeach()
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test")

View File

@ -0,0 +1,238 @@
#include <winpr/crt.h>
#include <winpr/winpr.h>
#include <winpr/collections.h>
/**
* Ternary Raster Operations:
* See "Windows Graphics Programming: Win32 GDI and DirectDraw", chapter 11. Advanced Bitmap Graphics
*
* Operators:
*
* AND & a
* OR | o
* NOT ~ n
* XOR ^ x
*
* Operands:
*
* Pen/Brush P
* Destination D
* Source S
*
* Example:
*
* Raster operation which returns P if S is 1 or D otherwise:
* (rop_S & rop_P) | (~rop_S & rop_D); -> 0xE2 (0x00E20746)
*
* Postfix notation: DSPDxax
* Infix notation: D^(S&(P^D))), (S&P)|(~S&D)
*
* DSPDxax using D^(S&(P^D)):
*
* mov eax, P // P
* xor eax, D // P^D
* and eax, S // S&(P^D)
* xor eax, D // D^(S&(P^D))
* mov D, eax // write result
*
* DSPDxax using (S&P)|(~S&D):
*
* mov eax, S // S
* and eax, P // S&P
* mov ebx, S // S
* not ebx // ~S
* and ebx, D // ~D&D
* or eax, ebx // (S&P)|(~S&D)
* mov D, eax // write result
*
* Raster operation lower word encoding:
*
* _______________________________________________________________________________
* | | | | | | | | | | | | | | | | |
* | Op5 | Op4 | Op3 | Op2 | Op1 | Not| Parse String | Offset |
* |____|____|____|____|____|____|____|____|____|____|____|____|____|____|____|____|
* 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
*
* Operator:
* 0: NOT
* 1: XOR
* 2: OR
* 3: AND
*
* Parse String:
* 0: SPDDDDDD
* 1: SPDSPDSP
* 2: SDPSDPSD
* 3: DDDDDDDD
* 4: DDDDDDDD
* 5: S+SP-DSS
* 6: S+SP-PDS
* 7: S+SD-PDS
*
* The lower word for 0x00E20746 is 0x0746 (00000111 01000110)
*
* 00 Op5 (NOT, n)
* 00 Op4 (NOT, n)
* 01 Op3 (XOR, x)
* 11 Op2 (AND, a)
* 01 Op1 (XOR, x)
* 0 Not (unused)
* 001 String (SPDSPDSP)
* 10 Offset (2)
*
* We shift SPDSPDSP to the left by 2: DSPDSPSP
*
* We have 5 operators: 3 binary operators and the last two are unary operators,
* so only four operands are needed. The parse string is truncated to reflect
* the number of operands we need: DSPD
*
* The operator string (from Op1 to Op5) is xaxnn, which can be simplified to xax
*
* The complete string representing the operation is DSPDxax
*
*/
const BYTE rop_P = 0xF0; /* 11110000 */
const BYTE rop_S = 0xCC; /* 11001100 */
const BYTE rop_D = 0xAA; /* 10101010 */
char* gdi_convert_postfix_to_infix(char* postfix)
{
int i;
int length;
BOOL unary;
wStack* stack;
int al, bl, cl, dl;
char *a, *b, *c, *d;
stack = Stack_New(FALSE);
length = strlen(postfix);
for (i = 0; i < length; i++)
{
if ((postfix[i] == 'P') || (postfix[i] == 'D') || (postfix[i] == 'S'))
{
/* token is an operand, push on the stack */
a = malloc(2);
a[0] = postfix[i];
a[1] = '\0';
//printf("Operand: %s\n", a);
Stack_Push(stack, a);
}
else
{
/* token is an operator */
unary = FALSE;
c = malloc(2);
c[0] = postfix[i];
c[1] = '\0';
if (c[0] == 'a')
{
c[0] = '&';
}
else if (c[0] == 'o')
{
c[0] = '|';
}
else if (c[0] == 'n')
{
c[0] = '~';
unary = TRUE;
}
else if (c[0] == 'x')
{
c[0] = '^';
}
else
{
printf("invalid operator: %s\n", c[0]);
}
//printf("Operator: %s\n", c);
a = (char*) Stack_Pop(stack);
if (unary)
b = NULL;
else
b = (char*) Stack_Pop(stack);
al = strlen(a);
if (b)
bl = strlen(b);
cl = 1;
dl = al + bl + cl + 3;
d = malloc(cl + 1);
sprintf_s(d, dl, "(%s%s%s)", b ? b : "", c, a);
Stack_Push(stack, d);
free(a);
free(b);
free(c);
}
}
d = (char*) Stack_Pop(stack);
Stack_Free(stack);
return d;
}
static char* test_ROP3[] =
{
"DSPDxax",
"PSDPxax",
"SPna",
"DSna",
"DPa",
"PDxn",
"DSxn",
"PSDnox",
"PDSona",
"DSPDxox",
"DPSDonox",
"SPDSxax",
"DPon",
"DPna",
"Pn",
"PDna",
"DPan",
"DSan",
"DSxn",
"DPa",
"D",
"DPno",
"SDno",
"PDno",
"DPo"
};
int TestGdiRop3(int argc, char* argv[])
{
int index;
char* infix;
char* postfix;
for (index = 0; index < sizeof(test_ROP3) / sizeof(test_ROP3[0]); index++)
{
postfix = test_ROP3[index];
infix = gdi_convert_postfix_to_infix(postfix);
printf("%s\t\t%s\n", postfix, infix);
free(infix);
}
return 0;
}

View File

@ -65,7 +65,7 @@ if(WITH_X11)
find_feature(XKBFile ${XKBFILE_FEATURE_TYPE} ${XKBFILE_FEATURE_PURPOSE} ${XKBFILE_FEATURE_DESCRIPTION})
if(WITH_XKBFILE)
if(WITH_XKBFILE AND (NOT APPLE))
add_definitions(-DWITH_XKBFILE)
include_directories(${XKBFILE_INCLUDE_DIRS})
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} ${${MODULE_PREFIX}_XKBFILE_SRCS})

View File

@ -210,18 +210,286 @@ char* freerdp_detect_keymap_from_xkb()
return keymap;
}
#ifdef __APPLE__
const UINT32 KEYCODE_TO_VKCODE_MACOSX[256] =
{
0, /* 0 */
0, /* 1 */
0, /* 2 */
0, /* 3 */
0, /* 4 */
0, /* 5 */
0, /* 6 */
0, /* 7 */
VK_KEY_A, /* 8 */
VK_KEY_S, /* 9 */
VK_KEY_D, /* 10 */
VK_KEY_F, /* 11 */
VK_KEY_H, /* 12 */
VK_KEY_G, /* 13 */
VK_KEY_Z, /* 14 */
VK_KEY_X, /* 15 */
VK_KEY_C, /* 16 */
VK_KEY_V, /* 17 */
VK_OEM_102, /* 18 */
VK_KEY_B, /* 19 */
VK_KEY_Q, /* 20 */
VK_KEY_W, /* 21 */
VK_KEY_E, /* 22 */
VK_KEY_R, /* 23 */
VK_KEY_Y, /* 24 */
VK_KEY_T, /* 25 */
VK_KEY_1, /* 26 */
VK_KEY_2, /* 27 */
VK_KEY_3, /* 28 */
VK_KEY_4, /* 29 */
VK_KEY_6, /* 30 */
VK_KEY_5, /* 31 */
VK_OEM_PLUS, /* 32 */
VK_KEY_9, /* 33 */
VK_KEY_7, /* 34 */
VK_OEM_MINUS, /* 35 */
VK_KEY_8, /* 36 */
VK_KEY_0, /* 37 */
VK_OEM_6, /* 38 */
VK_KEY_O, /* 39 */
VK_KEY_U, /* 40 */
VK_OEM_4, /* 41 */
VK_KEY_I, /* 42 */
VK_KEY_P, /* 43 */
VK_RETURN, /* 44 */
VK_KEY_L, /* 45 */
VK_KEY_J, /* 46 */
VK_OEM_7, /* 47 */
VK_KEY_K, /* 48 */
VK_OEM_1, /* 49 */
VK_OEM_5, /* 50 */
VK_OEM_COMMA, /* 51 */
VK_OEM_2, /* 52 */
VK_KEY_N, /* 53 */
VK_KEY_M, /* 54 */
VK_OEM_PERIOD, /* 55 */
VK_TAB, /* 56 */
VK_SPACE, /* 57 */
VK_OEM_3, /* 58 */
VK_BACK, /* 59 */
0, /* 60 */
VK_ESCAPE, /* 61 */
0, /* 62 */
0, /* 63 */
VK_LSHIFT, /* 64 */
VK_CAPITAL, /* 65 */
VK_LMENU, /* 66 */
VK_LCONTROL, /* 67 */
VK_RSHIFT, /* 68 */
VK_RMENU, /* 69 */
0, /* 70 */
0, /* 71 */
0, /* 72 */
VK_DECIMAL, /* 73 */
0, /* 74 */
VK_MULTIPLY, /* 75 */
0, /* 76 */
VK_ADD, /* 77 */
0, /* 78 */
VK_NUMLOCK, /* 79 */
0, /* 80 */
0, /* 81 */
0, /* 82 */
VK_DIVIDE, /* 83 */
VK_RETURN, /* 84 */
0, /* 85 */
VK_SUBTRACT, /* 86 */
0, /* 87 */
0, /* 88 */
0, /* 89 */
VK_NUMPAD0, /* 90 */
VK_NUMPAD1, /* 91 */
VK_NUMPAD2, /* 92 */
VK_NUMPAD3, /* 93 */
VK_NUMPAD4, /* 94 */
VK_NUMPAD5, /* 95 */
VK_NUMPAD6, /* 96 */
VK_NUMPAD7, /* 97 */
0, /* 98 */
VK_NUMPAD8, /* 99 */
VK_NUMPAD9, /* 100 */
0, /* 101 */
0, /* 102 */
0, /* 103 */
VK_F5, /* 104 */
VK_F6, /* 105 */
VK_F7, /* 106 */
VK_F3, /* 107 */
VK_F8, /* 108 */
VK_F9, /* 109 */
0, /* 110 */
VK_F11, /* 111 */
0, /* 112 */
VK_SNAPSHOT, /* 113 */
0, /* 114 */
VK_SCROLL, /* 115 */
0, /* 116 */
VK_F10, /* 117 */
0, /* 118 */
VK_F12, /* 119 */
0, /* 120 */
VK_PAUSE, /* 121 */
VK_INSERT, /* 122 */
VK_HOME, /* 123 */
VK_PRIOR, /* 124 */
VK_DELETE, /* 125 */
VK_F4, /* 126 */
VK_END, /* 127 */
VK_F2, /* 128 */
VK_NEXT, /* 129 */
VK_F1, /* 130 */
VK_LEFT, /* 131 */
VK_RIGHT, /* 132 */
VK_DOWN, /* 133 */
VK_UP, /* 134 */
0, /* 135 */
0, /* 136 */
0, /* 137 */
0, /* 138 */
0, /* 139 */
0, /* 140 */
0, /* 141 */
0, /* 142 */
0, /* 143 */
0, /* 144 */
0, /* 145 */
0, /* 146 */
0, /* 147 */
0, /* 148 */
0, /* 149 */
0, /* 150 */
0, /* 151 */
0, /* 152 */
0, /* 153 */
0, /* 154 */
0, /* 155 */
0, /* 156 */
0, /* 157 */
0, /* 158 */
0, /* 159 */
0, /* 160 */
0, /* 161 */
0, /* 162 */
0, /* 163 */
0, /* 164 */
0, /* 165 */
0, /* 166 */
0, /* 167 */
0, /* 168 */
0, /* 169 */
0, /* 170 */
0, /* 171 */
0, /* 172 */
0, /* 173 */
0, /* 174 */
0, /* 175 */
0, /* 176 */
0, /* 177 */
0, /* 178 */
0, /* 179 */
0, /* 180 */
0, /* 181 */
0, /* 182 */
0, /* 183 */
0, /* 184 */
0, /* 185 */
0, /* 186 */
0, /* 187 */
0, /* 188 */
0, /* 189 */
0, /* 190 */
0, /* 191 */
0, /* 192 */
0, /* 193 */
0, /* 194 */
0, /* 195 */
0, /* 196 */
0, /* 197 */
0, /* 198 */
0, /* 199 */
0, /* 200 */
0, /* 201 */
0, /* 202 */
0, /* 203 */
0, /* 204 */
0, /* 205 */
0, /* 206 */
0, /* 207 */
0, /* 208 */
0, /* 209 */
0, /* 210 */
0, /* 211 */
0, /* 212 */
0, /* 213 */
0, /* 214 */
0, /* 215 */
0, /* 216 */
0, /* 217 */
0, /* 218 */
0, /* 219 */
0, /* 220 */
0, /* 221 */
0, /* 222 */
0, /* 223 */
0, /* 224 */
0, /* 225 */
0, /* 226 */
0, /* 227 */
0, /* 228 */
0, /* 229 */
0, /* 230 */
0, /* 231 */
0, /* 232 */
0, /* 233 */
0, /* 234 */
0, /* 235 */
0, /* 236 */
0, /* 237 */
0, /* 238 */
0, /* 239 */
0, /* 240 */
0, /* 241 */
0, /* 242 */
0, /* 243 */
0, /* 244 */
0, /* 245 */
0, /* 246 */
0, /* 247 */
0, /* 248 */
0, /* 249 */
0, /* 250 */
0, /* 251 */
0, /* 252 */
0, /* 253 */
0, /* 254 */
0 /* 255 */
};
#endif
UINT32 freerdp_keyboard_init_x11(UINT32 keyboardLayoutId, RDP_SCANCODE x11_keycode_to_rdp_scancode[256])
{
UINT32 vkcode;
UINT32 keycode;
UINT32 keycode_to_vkcode[256];
memset(keycode_to_vkcode, 0, sizeof(keycode_to_vkcode));
memset(x11_keycode_to_rdp_scancode, 0, sizeof(x11_keycode_to_rdp_scancode));
ZeroMemory(keycode_to_vkcode, sizeof(keycode_to_vkcode));
ZeroMemory(x11_keycode_to_rdp_scancode, sizeof(x11_keycode_to_rdp_scancode));
#ifdef __APPLE__
/* Apple X11 breaks XKB detection */
CopyMemory(keycode_to_vkcode, KEYCODE_TO_VKCODE_MACOSX, sizeof(keycode_to_vkcode));
freerdp_keyboard_load_map(keycode_to_vkcode, "macosx(macosx)");
#elif defined(WITH_SUN)
{
char sunkeymap[32];

View File

@ -714,13 +714,12 @@ PRIM_STATIC pstatus_t neon_yCbCrToRGB_16s16s_P3P3(
*/
/* ------------------------------------------------------------------------- */
void primitives_init_colors(
const primitives_hints_t *hints,
primitives_t *prims)
void primitives_init_colors(const primitives_hints_t* hints, primitives_t* prims)
{
prims->RGBToRGB_16s8u_P3AC4R = general_RGBToRGB_16s8u_P3AC4R;
prims->yCbCrToRGB_16s16s_P3P3 = general_yCbCrToRGB_16s16s_P3P3;
prims->RGBToYCbCr_16s16s_P3P3 = general_RGBToYCbCr_16s16s_P3P3;
#if defined(WITH_SSE2)
if (hints->x86_flags & PRIM_X86_SSE2_AVAILABLE)
{
@ -737,8 +736,7 @@ void primitives_init_colors(
}
/* ------------------------------------------------------------------------- */
void primitives_deinit_colors(
primitives_t *prims)
void primitives_deinit_colors(primitives_t* prims)
{
/* Nothing to do. */
}

View File

@ -514,7 +514,7 @@ void* mf_peer_main_loop(void* arg)
client->settings->PrivateKeyFile = _strdup("server.key");
client->settings->NlaSecurity = FALSE;
client->settings->RemoteFxCodec = TRUE;
client->settings->ColorDepth = 32;
client->settings->ColorDepth = 32;
client->settings->SuppressOutput = TRUE;
client->settings->RefreshRect = FALSE;
@ -609,4 +609,4 @@ void* mf_peer_main_loop(void* arg)
freerdp_peer_free(client);
return NULL;
}
}

View File

@ -35,6 +35,10 @@ set(${MODULE_PREFIX}_SRCS
wf_peer.h
wf_rdpsnd.c
wf_rdpsnd.h
wf_directsound.c
wf_directsound.h
wf_wasapi.c
wf_wasapi.h
wf_settings.c
wf_settings.h
wf_info.c

View File

@ -0,0 +1,203 @@
#include "wf_directsound.h"
#include "wf_interface.h"
#include "wf_info.h"
#include "wf_rdpsnd.h"
#include <winpr/windows.h>
#define INITGUID
#include <initguid.h>
#include <objbase.h>
#define CINTERFACE 1
#include <mmsystem.h>
#include <dsound.h>
IDirectSoundCapture8* cap;
IDirectSoundCaptureBuffer8* capBuf;
DSCBUFFERDESC dscbd;
DWORD lastPos;
wfPeerContext* latestPeer;
int wf_directsound_set_latest_peer(wfPeerContext* peer)
{
latestPeer = peer;
return 0;
}
int wf_directsound_activate(rdpsnd_server_context* context)
{
HRESULT hr;
LPDIRECTSOUNDCAPTUREBUFFER pDSCB;
WAVEFORMATEX wfx = {WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0};
printf("RDPSND (direct sound) Activated\n");
hr = DirectSoundCaptureCreate8(NULL, &cap, NULL);
if (FAILED(hr))
{
_tprintf(_T("Failed to create sound capture device\n"));
return;
}
_tprintf(_T("Created sound capture device\n"));
dscbd.dwSize = sizeof(DSCBUFFERDESC);
dscbd.dwFlags = 0;
dscbd.dwBufferBytes = 176400;
dscbd.dwReserved = 0;
dscbd.lpwfxFormat = &wfx;
dscbd.dwFXCount = 0;
dscbd.lpDSCFXDesc = NULL;
hr = cap->lpVtbl->CreateCaptureBuffer(cap, &dscbd, &pDSCB, NULL);
if (FAILED(hr))
{
_tprintf(_T("Failed to create capture buffer\n"));
}
_tprintf(_T("Created capture buffer"));
hr = pDSCB->lpVtbl->QueryInterface(pDSCB, &IID_IDirectSoundCaptureBuffer8, (LPVOID*)&capBuf);
if (FAILED(hr))
{
_tprintf(_T("Failed to QI capture buffer\n"));
}
_tprintf(_T("Created IDirectSoundCaptureBuffer8\n"));
pDSCB->lpVtbl->Release(pDSCB);
context->SelectFormat(context, 4);
context->SetVolume(context, 0x7FFF, 0x7FFF);
lastPos = 0;
CreateThread(NULL, 0, wf_rdpsnd_directsound_thread, latestPeer, 0, NULL);
return 0;
}
DWORD WINAPI wf_rdpsnd_directsound_thread(LPVOID lpParam)
{
HRESULT hr;
DWORD beg = 0;
DWORD end = 0;
DWORD diff, rate;
wfPeerContext* context;
wfInfo* wfi;
VOID* pbCaptureData = NULL;
DWORD dwCaptureLength = 0;
VOID* pbCaptureData2 = NULL;
DWORD dwCaptureLength2 = 0;
VOID* pbPlayData = NULL;
DWORD dwReadPos = 0;
LONG lLockSize = 0;
wfi = wf_info_get_instance();
context = (wfPeerContext*)lpParam;
rate = 1000 / 24;
_tprintf(_T("Trying to start capture\n"));
hr = capBuf->lpVtbl->Start(capBuf, DSCBSTART_LOOPING);
if (FAILED(hr))
{
_tprintf(_T("Failed to start capture\n"));
}
_tprintf(_T("Capture started\n"));
while (1)
{
end = GetTickCount();
diff = end - beg;
if (diff < rate)
{
Sleep(rate - diff);
}
beg = GetTickCount();
if (wf_rdpsnd_lock() > 0)
{
//check for main exit condition
if (wfi->snd_stop == TRUE)
{
wf_rdpsnd_unlock();
break;
}
hr = capBuf->lpVtbl->GetCurrentPosition(capBuf, NULL, &dwReadPos);
if (FAILED(hr))
{
_tprintf(_T("Failed to get read pos\n"));
wf_rdpsnd_unlock();
break;
}
lLockSize = dwReadPos - lastPos;//dscbd.dwBufferBytes;
if (lLockSize < 0) lLockSize += dscbd.dwBufferBytes;
//printf("Last, read, lock = [%d, %d, %d]\n", lastPos, dwReadPos, lLockSize);
if (lLockSize == 0)
{
wf_rdpsnd_unlock();
continue;
}
hr = capBuf->lpVtbl->Lock(capBuf, lastPos, lLockSize, &pbCaptureData, &dwCaptureLength, &pbCaptureData2, &dwCaptureLength2, 0L);
if (FAILED(hr))
{
_tprintf(_T("Failed to lock sound capture buffer\n"));
wf_rdpsnd_unlock();
break;
}
//fwrite(pbCaptureData, 1, dwCaptureLength, pFile);
//fwrite(pbCaptureData2, 1, dwCaptureLength2, pFile);
//FIXME: frames = bytes/(bytespersample * channels)
context->rdpsnd->SendSamples(context->rdpsnd, pbCaptureData, dwCaptureLength/4);
context->rdpsnd->SendSamples(context->rdpsnd, pbCaptureData2, dwCaptureLength2/4);
hr = capBuf->lpVtbl->Unlock(capBuf, pbCaptureData, dwCaptureLength, pbCaptureData2, dwCaptureLength2);
if (FAILED(hr))
{
_tprintf(_T("Failed to unlock sound capture buffer\n"));
wf_rdpsnd_unlock();
return 0;
}
//TODO keep track of location in buffer
lastPos += dwCaptureLength;
lastPos %= dscbd.dwBufferBytes;
lastPos += dwCaptureLength2;
lastPos %= dscbd.dwBufferBytes;
wf_rdpsnd_unlock();
}
}
_tprintf(_T("Trying to stop sound capture\n"));
hr = capBuf->lpVtbl->Stop(capBuf);
if (FAILED(hr))
{
_tprintf(_T("Failed to stop capture\n"));
}
_tprintf(_T("Capture stopped\n"));
capBuf->lpVtbl->Release(capBuf);
cap->lpVtbl->Release(cap);
lastPos = 0;
return 0;
}

View File

@ -0,0 +1,13 @@
#ifndef WF_DSOUND_H
#define WF_DSOUND_H
#include <freerdp/server/rdpsnd.h>
#include "wf_interface.h"
int wf_directsound_set_latest_peer(wfPeerContext* peer);
int wf_directsound_activate(rdpsnd_server_context* context);
DWORD WINAPI wf_rdpsnd_directsound_thread(LPVOID lpParam);
#endif

View File

@ -235,6 +235,7 @@ DWORD WINAPI wf_peer_main_loop(LPVOID lpParam)
settings = client->settings;
settings->RemoteFxCodec = TRUE;
settings->ColorDepth = 32;
settings->NSCodec = FALSE;
settings->JpegCodec = FALSE;
wf_peer_read_settings(client);

View File

@ -3,6 +3,7 @@
* FreeRDP Windows Server (Audio Output)
*
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2013 Corey Clayton <can.of.tuna@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -37,21 +38,17 @@
#include <freerdp/server/rdpsnd.h>
#include "wf_rdpsnd.h"
#include "wf_directsound.h"
#include "wf_wasapi.h"
#include "wf_info.h"
/*
* Here are some temp things that shall be moved
*
*/
IDirectSoundCapture8* cap;
IDirectSoundCaptureBuffer8* capBuf;
DSCBUFFERDESC dscbd;
DWORD lastPos;
#define BYTESPERSEC 176400
//#define BYTESPERSEC 176400
//FIXME support multiple clients
wfPeerContext* latestPeer;
//wfPeerContext* latestPeer;
static const rdpsndFormat test_audio_formats[] =
{
@ -69,54 +66,9 @@ static const rdpsndFormat test_audio_formats[] =
static void wf_peer_rdpsnd_activated(rdpsnd_server_context* context)
{
HRESULT hr;
LPDIRECTSOUNDCAPTUREBUFFER pDSCB;
WAVEFORMATEX wfx = {WAVE_FORMAT_PCM, 2, 44100, BYTESPERSEC, 4, 16, 0};
printf("RDPSND Activated\n");
hr = DirectSoundCaptureCreate8(NULL, &cap, NULL);
if (FAILED(hr))
{
_tprintf(_T("Failed to create sound capture device\n"));
return;
}
_tprintf(_T("Created sound capture device\n"));
dscbd.dwSize = sizeof(DSCBUFFERDESC);
dscbd.dwFlags = 0;
dscbd.dwBufferBytes = BYTESPERSEC;
dscbd.dwReserved = 0;
dscbd.lpwfxFormat = &wfx;
dscbd.dwFXCount = 0;
dscbd.lpDSCFXDesc = NULL;
hr = cap->lpVtbl->CreateCaptureBuffer(cap, &dscbd, &pDSCB, NULL);
if (FAILED(hr))
{
_tprintf(_T("Failed to create capture buffer\n"));
}
_tprintf(_T("Created capture buffer"));
hr = pDSCB->lpVtbl->QueryInterface(pDSCB, &IID_IDirectSoundCaptureBuffer8, (LPVOID*)&capBuf);
if (FAILED(hr))
{
_tprintf(_T("Failed to QI capture buffer\n"));
}
_tprintf(_T("Created IDirectSoundCaptureBuffer8\n"));
pDSCB->lpVtbl->Release(pDSCB);
context->SelectFormat(context, 4);
context->SetVolume(context, 0x7FFF, 0x7FFF);
lastPos = 0;
CreateThread(NULL, 0, wf_rdpsnd_thread, latestPeer, 0, NULL);
//wf_directsound_activate(context);
wf_wasapi_activate(context);
}
int wf_rdpsnd_lock()
@ -186,131 +138,9 @@ BOOL wf_peer_rdpsnd_init(wfPeerContext* context)
context->rdpsnd->Initialize(context->rdpsnd);
latestPeer = context;
wf_directsound_set_latest_peer(context);
wfi->snd_stop = FALSE;
return TRUE;
}
DWORD WINAPI wf_rdpsnd_thread(LPVOID lpParam)
{
HRESULT hr;
DWORD beg = 0;
DWORD end = 0;
DWORD diff, rate;
wfPeerContext* context;
wfInfo* wfi;
VOID* pbCaptureData = NULL;
DWORD dwCaptureLength = 0;
VOID* pbCaptureData2 = NULL;
DWORD dwCaptureLength2 = 0;
VOID* pbPlayData = NULL;
DWORD dwReadPos = 0;
LONG lLockSize = 0;
wfi = wf_info_get_instance();
context = (wfPeerContext*)lpParam;
rate = 1000 / 24;
_tprintf(_T("Trying to start capture\n"));
hr = capBuf->lpVtbl->Start(capBuf, DSCBSTART_LOOPING);
if (FAILED(hr))
{
_tprintf(_T("Failed to start capture\n"));
}
_tprintf(_T("Capture started\n"));
while (1)
{
end = GetTickCount();
diff = end - beg;
if (diff < rate)
{
Sleep(rate - diff);
}
beg = GetTickCount();
if (wf_rdpsnd_lock() > 0)
{
//check for main exit condition
if (wfi->snd_stop == TRUE)
{
wf_rdpsnd_unlock();
break;
}
hr = capBuf->lpVtbl->GetCurrentPosition(capBuf, NULL, &dwReadPos);
if (FAILED(hr))
{
_tprintf(_T("Failed to get read pos\n"));
wf_rdpsnd_unlock();
break;
}
lLockSize = dwReadPos - lastPos;//dscbd.dwBufferBytes;
if (lLockSize < 0) lLockSize += dscbd.dwBufferBytes;
//printf("Last, read, lock = [%d, %d, %d]\n", lastPos, dwReadPos, lLockSize);
if (lLockSize == 0)
{
wf_rdpsnd_unlock();
continue;
}
hr = capBuf->lpVtbl->Lock(capBuf, lastPos, lLockSize, &pbCaptureData, &dwCaptureLength, &pbCaptureData2, &dwCaptureLength2, 0L);
if (FAILED(hr))
{
_tprintf(_T("Failed to lock sound capture buffer\n"));
wf_rdpsnd_unlock();
break;
}
//fwrite(pbCaptureData, 1, dwCaptureLength, pFile);
//fwrite(pbCaptureData2, 1, dwCaptureLength2, pFile);
//FIXME: frames = bytes/(bytespersample * channels)
context->rdpsnd->SendSamples(context->rdpsnd, pbCaptureData, dwCaptureLength/4);
context->rdpsnd->SendSamples(context->rdpsnd, pbCaptureData2, dwCaptureLength2/4);
hr = capBuf->lpVtbl->Unlock(capBuf, pbCaptureData, dwCaptureLength, pbCaptureData2, dwCaptureLength2);
if (FAILED(hr))
{
_tprintf(_T("Failed to unlock sound capture buffer\n"));
wf_rdpsnd_unlock();
return 0;
}
//TODO keep track of location in buffer
lastPos += dwCaptureLength;
lastPos %= dscbd.dwBufferBytes;
lastPos += dwCaptureLength2;
lastPos %= dscbd.dwBufferBytes;
wf_rdpsnd_unlock();
}
}
_tprintf(_T("Trying to stop sound capture\n"));
hr = capBuf->lpVtbl->Stop(capBuf);
if (FAILED(hr))
{
_tprintf(_T("Failed to stop capture\n"));
}
_tprintf(_T("Capture stopped\n"));
capBuf->lpVtbl->Release(capBuf);
cap->lpVtbl->Release(cap);
lastPos = 0;
return 0;
}

View File

@ -30,7 +30,6 @@ int wf_rdpsnd_lock();
int wf_rdpsnd_unlock();
BOOL wf_peer_rdpsnd_init(wfPeerContext* context);
DWORD WINAPI wf_rdpsnd_thread(LPVOID lpParam);
#endif /* WF_RDPSND_H */

326
server/Windows/wf_wasapi.c Normal file
View File

@ -0,0 +1,326 @@
#include "wf_wasapi.h"
#include "wf_info.h"
#include <initguid.h>
#include <mmdeviceapi.h>
#include <Functiondiscoverykeys_devpkey.h>
#include <Audioclient.h>
#define REFTIMES_PER_SEC 10000000
#define REFTIMES_PER_MILLISEC 10000
DEFINE_GUID(CLSID_MMDeviceEnumerator, 0xBCDE0395, 0xE52F, 0x467C,
0x8E, 0x3D, 0xC4, 0x57, 0x92, 0x91, 0x69, 0x2E);
DEFINE_GUID(IID_IMMDeviceEnumerator, 0xA95664D2, 0x9614, 0x4F35,
0xA7, 0x46, 0xDE, 0x8D, 0xB6, 0x36, 0x17, 0xE6);
DEFINE_GUID(IID_IAudioClient, 0x1cb9ad4c, 0xdbfa, 0x4c32, 0xb1,0x78, 0xc2,0xf5,0x68,0xa7,0x03,0xb2);
DEFINE_GUID(IID_IAudioCaptureClient, 0xc8adbd64, 0xe71e, 0x48a0, 0xa4,0xde, 0x18,0x5c,0x39,0x5c,0xd3,0x17);
LPWSTR devStr = NULL;
wfPeerContext* latestPeer = NULL;
int wf_wasapi_set_latest_peer(wfPeerContext* peer)
{
latestPeer = peer;
return 0;
}
int wf_wasapi_activate(rdpsnd_server_context* context)
{
wchar_t * pattern = L"Stereo Mix";
wf_wasapi_get_device_string(pattern, &devStr);
if(devStr == NULL)
{
_tprintf(_T("Failed to match for output device! Disabling rdpsnd.\n"));
return 1;
}
printf("RDPSND (WASAPI) Activated\n");
context->SelectFormat(context, 4);
context->SetVolume(context, 0x7FFF, 0x7FFF);
CreateThread(NULL, 0, wf_rdpsnd_wasapi_thread, latestPeer, 0, NULL);
return 0;
}
int wf_wasapi_get_device_string(LPWSTR pattern, LPWSTR * deviceStr)
{
HRESULT hr;
IMMDeviceEnumerator *pEnumerator = NULL;
IMMDeviceCollection *pCollection = NULL;
IMMDevice *pEndpoint = NULL;
IPropertyStore *pProps = NULL;
LPWSTR pwszID = NULL;
unsigned int count, i;
CoInitialize(NULL);
hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, &IID_IMMDeviceEnumerator, (void **) &pEnumerator);
if (FAILED(hr))
{
_tprintf(_T("Failed to cocreate device enumerator\n"));
exit(1);
}
hr = pEnumerator->lpVtbl->EnumAudioEndpoints(pEnumerator, eCapture, DEVICE_STATE_ACTIVE, &pCollection);
if ( FAILED(hr) )
{
_tprintf(_T("Failed to create endpoint collection\n"));
exit(1);
}
pCollection->lpVtbl->GetCount(pCollection, &count);
_tprintf(_T("Num endpoints: %d\n"), count);
if (count == 0)
{
_tprintf(_T("No endpoints!\n"));
exit(1);
}
for (i = 0; i < count; ++i)
{
PROPVARIANT nameVar;
PropVariantInit(&nameVar);
hr = pCollection->lpVtbl->Item(pCollection, i, &pEndpoint);
if ( FAILED(hr) )
{
_tprintf(_T("Failed to get endpoint %d\n"), i);
exit(1);
}
hr = pEndpoint->lpVtbl->GetId(pEndpoint, &pwszID);
if ( FAILED(hr) )
{
_tprintf(_T("Failed to get endpoint ID\n"));
exit(1);
}
hr = pEndpoint->lpVtbl->OpenPropertyStore(pEndpoint, STGM_READ, &pProps);
if ( FAILED(hr) )
{
_tprintf(_T("Failed to open property store\n"));
exit(1);
}
hr = pProps->lpVtbl->GetValue(pProps, &PKEY_Device_FriendlyName, &nameVar);
if ( FAILED(hr) )
{
_tprintf(_T("Failed to get device friendly name\n"));
exit(1);
}
//do this a more reliable way
if (wcscmp(pattern, nameVar.pwszVal) < 0)
{
unsigned int devStrLen;
_tprintf(_T("Using sound ouput endpoint: [%s] (%s)\n"), nameVar.pwszVal, pwszID);
//_tprintf(_T("matched %d characters\n"), wcscmp(pattern, nameVar.pwszVal));
devStrLen = wcslen(pwszID);
*deviceStr = (LPWSTR) malloc((devStrLen * 2) + 2);
ZeroMemory(*deviceStr, (devStrLen * 2) + 2);
wcscpy_s(*deviceStr, devStrLen+1, pwszID);
}
CoTaskMemFree(pwszID);
pwszID = NULL;
PropVariantClear(&nameVar);
pProps->lpVtbl->Release(pProps);
pProps = NULL;
pEndpoint->lpVtbl->Release(pEndpoint);
pEndpoint = NULL;
}
pCollection->lpVtbl->Release(pCollection);
pCollection = NULL;
pEnumerator->lpVtbl->Release(pEnumerator);
pEnumerator = NULL;
CoUninitialize();
return 0;
}
DWORD WINAPI wf_rdpsnd_wasapi_thread(LPVOID lpParam)
{
IMMDeviceEnumerator *pEnumerator = NULL;
IMMDevice *pDevice = NULL;
IAudioClient *pAudioClient = NULL;
IAudioCaptureClient *pCaptureClient = NULL;
WAVEFORMATEX *pwfx = NULL;
HRESULT hr;
REFERENCE_TIME hnsRequestedDuration = REFTIMES_PER_SEC;
REFERENCE_TIME hnsActualDuration;
UINT32 bufferFrameCount;
UINT32 numFramesAvailable;
UINT32 packetLength = 0;
UINT32 dCount = 0;
BYTE *pData;
wfPeerContext* context;
wfInfo* wfi;
wfi = wf_info_get_instance();
context = (wfPeerContext*)lpParam;
CoInitialize(NULL);
hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, &IID_IMMDeviceEnumerator, (void **) &pEnumerator);
if (FAILED(hr))
{
_tprintf(_T("Failed to cocreate device enumerator\n"));
exit(1);
}
hr = pEnumerator->lpVtbl->GetDevice(pEnumerator, devStr, &pDevice);
if (FAILED(hr))
{
_tprintf(_T("Failed to cocreate get device\n"));
exit(1);
}
hr = pDevice->lpVtbl->Activate(pDevice, &IID_IAudioClient, CLSCTX_ALL, NULL, (void **)&pAudioClient);
if (FAILED(hr))
{
_tprintf(_T("Failed to activate audio client\n"));
exit(1);
}
hr = pAudioClient->lpVtbl->GetMixFormat(pAudioClient, &pwfx);
if (FAILED(hr))
{
_tprintf(_T("Failed to get mix format\n"));
exit(1);
}
//screw it, use our own format
//WAVEFORMATEX wfx = {WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0};
pwfx->wFormatTag = WAVE_FORMAT_PCM;
pwfx->nChannels = 2;
pwfx->nSamplesPerSec = 44100;
pwfx->nAvgBytesPerSec = 176400;
pwfx->nBlockAlign = 4;
pwfx->wBitsPerSample = 16;
pwfx->cbSize = 0;
hr = pAudioClient->lpVtbl->Initialize(
pAudioClient,
AUDCLNT_SHAREMODE_SHARED,
0,
hnsRequestedDuration,
0,
pwfx,
NULL);
if (FAILED(hr))
{
_tprintf(_T("Failed to initialize the audio client\n"));
exit(1);
}
hr = pAudioClient->lpVtbl->GetBufferSize(pAudioClient, &bufferFrameCount);
if (FAILED(hr))
{
_tprintf(_T("Failed to get buffer size\n"));
exit(1);
}
hr = pAudioClient->lpVtbl->GetService(pAudioClient, &IID_IAudioCaptureClient, (void **) &pCaptureClient);
if (FAILED(hr))
{
_tprintf(_T("Failed to get the capture client\n"));
exit(1);
}
hnsActualDuration = (double)REFTIMES_PER_SEC * bufferFrameCount / pwfx->nSamplesPerSec;
hr = pAudioClient->lpVtbl->Start(pAudioClient);
if (FAILED(hr))
{
_tprintf(_T("Failed to start capture\n"));
exit(1);
}
dCount = 0;
while(wfi->snd_stop == FALSE)
{
DWORD flags;
Sleep(hnsActualDuration/REFTIMES_PER_MILLISEC/2);
hr = pCaptureClient->lpVtbl->GetNextPacketSize(pCaptureClient, &packetLength);
if (FAILED(hr))
{
_tprintf(_T("Failed to get packet length\n"));
exit(1);
}
while(packetLength != 0)
{
hr = pCaptureClient->lpVtbl->GetBuffer(pCaptureClient, &pData, &numFramesAvailable, &flags, NULL, NULL);
if (FAILED(hr))
{
_tprintf(_T("Failed to get buffer\n"));
exit(1);
}
//write data here
//fwrite(pData, 1, packetLength * 4, pFile);
context->rdpsnd->SendSamples(context->rdpsnd, pData, packetLength);
hr = pCaptureClient->lpVtbl->ReleaseBuffer(pCaptureClient, numFramesAvailable);
if (FAILED(hr))
{
_tprintf(_T("Failed to release buffer\n"));
exit(1);
}
hr = pCaptureClient->lpVtbl->GetNextPacketSize(pCaptureClient, &packetLength);
if (FAILED(hr))
{
_tprintf(_T("Failed to get packet length\n"));
exit(1);
}
}
}
pAudioClient->lpVtbl->Stop(pAudioClient);
if (FAILED(hr))
{
_tprintf(_T("Failed to stop audio client\n"));
exit(1);
}
CoTaskMemFree(pwfx);
if (pEnumerator != NULL)
pEnumerator->lpVtbl->Release(pEnumerator);
if (pDevice != NULL)
pDevice->lpVtbl->Release(pDevice);
if (pAudioClient != NULL)
pAudioClient->lpVtbl->Release(pAudioClient);
if (pCaptureClient != NULL)
pCaptureClient->lpVtbl->Release(pCaptureClient);
CoUninitialize();
return 0;
}

View File

@ -0,0 +1,16 @@
#ifndef WF_WASAPI_H
#define WF_WASAPI_H
#include <freerdp/server/rdpsnd.h>
#include "wf_interface.h"
//TODO: fix how this is handled
int wf_wasapi_set_latest_peer(wfPeerContext* peer);
int wf_wasapi_activate(rdpsnd_server_context* context);
int wf_wasapi_get_device_string(LPWSTR pattern, LPWSTR * deviceStr);
DWORD WINAPI wf_rdpsnd_wasapi_thread(LPVOID lpParam);
#endif

View File

@ -194,9 +194,10 @@ xfInfo* xf_info_init()
*/
xfi->use_xshm = FALSE;
xfi->display = XOpenDisplay(NULL);
if (!XInitThreads())
printf("warning: XInitThreads() failure\n");
XInitThreads();
xfi->display = XOpenDisplay(NULL);
if (xfi->display == NULL)
{
@ -647,6 +648,7 @@ void* xf_peer_main_loop(void* arg)
settings->PrivateKeyFile = freerdp_construct_path(server_file_path, "server.key");
settings->RemoteFxCodec = TRUE;
settings->ColorDepth = 32;
client->Capabilities = xf_peer_capabilities;
client->PostConnect = xf_peer_post_connect;

Some files were not shown because too many files have changed in this diff Show More