Merge branch 'master' of https://github.com/C-o-r-E/FreeRDP
This commit is contained in:
commit
26989e0cd2
@ -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")
|
||||
|
@ -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})
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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})
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -114,6 +114,7 @@ struct xf_info
|
||||
BOOL disconnect;
|
||||
HCLRCONV clrconv;
|
||||
Window parent_window;
|
||||
HANDLE mutex;
|
||||
|
||||
HGDI_DC hdc;
|
||||
BOOL sw_gdi;
|
||||
|
@ -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)
|
||||
{
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -40,7 +40,6 @@
|
||||
#endif
|
||||
|
||||
#define EXPONENT_MAX_SIZE 4
|
||||
#define MODULUS_MAX_SIZE 256
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
238
include/freerdp/message.h
Normal 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 */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
10
libfreerdp/cache/brush.c
vendored
10
libfreerdp/cache/brush.c
vendored
@ -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)
|
||||
|
35
libfreerdp/cache/glyph.c
vendored
35
libfreerdp/cache/glyph.c
vendored
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
10
libfreerdp/cache/palette.c
vendored
10
libfreerdp/cache/palette.c
vendored
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
17
libfreerdp/cache/pointer.c
vendored
17
libfreerdp/cache/pointer.c
vendored
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -101,6 +101,8 @@ set(${MODULE_PREFIX}_SRCS
|
||||
transport.h
|
||||
update.c
|
||||
update.h
|
||||
message.c
|
||||
message.h
|
||||
channel.c
|
||||
channel.h
|
||||
window.c
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
1932
libfreerdp/core/message.c
Normal file
File diff suppressed because it is too large
Load Diff
156
libfreerdp/core/message.h
Normal file
156
libfreerdp/core/message.h
Normal 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 */
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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
142
libfreerdp/crypto/base64.c
Normal 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);
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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++;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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++;
|
||||
|
@ -58,3 +58,8 @@ else()
|
||||
endif()
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/libfreerdp")
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
|
||||
|
@ -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}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
2
libfreerdp/gdi/test/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
TestGdi
|
||||
TestGdi.c
|
40
libfreerdp/gdi/test/CMakeLists.txt
Normal file
40
libfreerdp/gdi/test/CMakeLists.txt
Normal 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")
|
||||
|
238
libfreerdp/gdi/test/TestGdiRop3.c
Normal file
238
libfreerdp/gdi/test/TestGdiRop3.c
Normal 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;
|
||||
}
|
@ -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})
|
||||
|
@ -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];
|
||||
|
@ -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. */
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
203
server/Windows/wf_directsound.c
Normal file
203
server/Windows/wf_directsound.c
Normal 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;
|
||||
}
|
13
server/Windows/wf_directsound.h
Normal file
13
server/Windows/wf_directsound.h
Normal 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
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
326
server/Windows/wf_wasapi.c
Normal 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;
|
||||
}
|
16
server/Windows/wf_wasapi.h
Normal file
16
server/Windows/wf_wasapi.h
Normal 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
|
@ -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
Loading…
Reference in New Issue
Block a user