Merge remote-tracking branch 'upstream/master' into mh-channel

Conflicts:
	channels/audin/client/oss/audin_oss.c
	channels/drive/client/drive_main.c
	channels/printer/client/printer_cups.c
	channels/printer/client/printer_main.c
	channels/rail/client/rail_main.c
	channels/rdpgfx/client/rdpgfx_main.c
	channels/rdpsnd/client/oss/rdpsnd_oss.c
	channels/remdesk/client/remdesk_main.c
	channels/remdesk/server/remdesk_main.c
	channels/tsmf/client/tsmf_media.c
This commit is contained in:
Martin Haimberger 2015-07-15 01:57:07 -07:00
commit 6ab0187d84
286 changed files with 8505 additions and 3728 deletions

4
.gitignore vendored
View File

@ -94,6 +94,7 @@ client/X11/xfreerdp
client/Mac/xcode client/Mac/xcode
client/Sample/sfreerdp client/Sample/sfreerdp
client/DirectFB/dfreerdp client/DirectFB/dfreerdp
client/Wayland/wlfreerdp
server/Sample/sfreerdp-server server/Sample/sfreerdp-server
server/X11/xfreerdp-server server/X11/xfreerdp-server
xcode xcode
@ -132,6 +133,9 @@ TAGS
# packaging related files # packaging related files
!packaging/scripts/prepare_deb_freerdp-nightly.sh !packaging/scripts/prepare_deb_freerdp-nightly.sh
packaging/deb/freerdp-nightly/freerdp-nightly
packaging/deb/freerdp-nightly/freerdp-nightly-dev
packaging/deb/freerdp-nightly/freerdp-nightly-dbg
# #
.idea .idea

View File

@ -229,7 +229,7 @@ if(CMAKE_COMPILER_IS_GNUCC)
endif() endif()
endif() endif()
if("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") if(${CMAKE_C_COMPILER_ID} STREQUAL "Clang")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-parameter") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-parameter")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-macros -Wno-padded") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-macros -Wno-padded")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-c11-extensions -Wno-gnu") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-c11-extensions -Wno-gnu")
@ -651,17 +651,6 @@ set(FREERDP_EXTENSION_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/freerdp/extensions")
include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include) include_directories(${CMAKE_CURRENT_BINARY_DIR}/include)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
if(BSD)
if(IS_DIRECTORY /usr/local/include)
include_directories(/usr/local/include)
link_directories(/usr/local/lib)
endif()
if(OPENBSD)
if(IS_DIRECTORY /usr/X11R6/include)
include_directories(/usr/X11R6/include)
endif()
endif()
endif()
# Configure files # Configure files
add_definitions("-DHAVE_CONFIG_H") add_definitions("-DHAVE_CONFIG_H")
@ -722,10 +711,6 @@ add_subdirectory(include)
add_subdirectory(libfreerdp) add_subdirectory(libfreerdp)
if(WITH_CHANNELS)
add_subdirectory(channels)
endif()
if (IOS) if (IOS)
set(CMAKE_OSX_DEPLOYMENT_TARGET "") set(CMAKE_OSX_DEPLOYMENT_TARGET "")
if (IOS_PLATFORM MATCHES "SIMULATOR") if (IOS_PLATFORM MATCHES "SIMULATOR")
@ -741,6 +726,22 @@ include_directories("${CMAKE_BINARY_DIR}/rdtk/include")
add_subdirectory(rdtk) add_subdirectory(rdtk)
if(BSD)
if(IS_DIRECTORY /usr/local/include)
include_directories(/usr/local/include)
link_directories(/usr/local/lib)
endif()
if(OPENBSD)
if(IS_DIRECTORY /usr/X11R6/include)
include_directories(/usr/X11R6/include)
endif()
endif()
endif()
if(WITH_CHANNELS)
add_subdirectory(channels)
endif()
if(WITH_CLIENT) if(WITH_CLIENT)
add_subdirectory(client) add_subdirectory(client)
endif() endif()
@ -749,6 +750,7 @@ if(WITH_SERVER)
add_subdirectory(server) add_subdirectory(server)
endif() endif()
# Exporting # Exporting
if(${CMAKE_VERSION} VERSION_GREATER "2.8.10") if(${CMAKE_VERSION} VERSION_GREATER "2.8.10")

View File

@ -102,7 +102,7 @@ static WIN32ERROR audin_process_version(IWTSVirtualChannelCallback* pChannelCall
Stream_Read_UINT32(s, Version); Stream_Read_UINT32(s, Version);
DEBUG_DVC("process_version: Version=%d", Version); DEBUG_DVC("Version=%d", Version);
out = Stream_New(NULL, 5); out = Stream_New(NULL, 5);
@ -142,7 +142,7 @@ static WIN32ERROR audin_process_formats(IWTSVirtualChannelCallback* pChannelCall
UINT32 cbSizeFormatsPacket; UINT32 cbSizeFormatsPacket;
Stream_Read_UINT32(s, NumFormats); Stream_Read_UINT32(s, NumFormats);
DEBUG_DVC("process_formats: NumFormats %d", NumFormats); DEBUG_DVC("NumFormats %d", NumFormats);
if ((NumFormats < 1) || (NumFormats > 1000)) if ((NumFormats < 1) || (NumFormats > 1000))
{ {
WLog_ERR(TAG, "bad NumFormats %d", NumFormats); WLog_ERR(TAG, "bad NumFormats %d", NumFormats);
@ -182,7 +182,7 @@ static WIN32ERROR audin_process_formats(IWTSVirtualChannelCallback* pChannelCall
format.data = Stream_Pointer(s); format.data = Stream_Pointer(s);
Stream_Seek(s, format.cbSize); Stream_Seek(s, format.cbSize);
DEBUG_DVC("process_formats: wFormatTag=%d nChannels=%d nSamplesPerSec=%d " DEBUG_DVC("wFormatTag=%d nChannels=%d nSamplesPerSec=%d "
"nBlockAlign=%d wBitsPerSample=%d cbSize=%d", "nBlockAlign=%d wBitsPerSample=%d cbSize=%d",
format.wFormatTag, format.nChannels, format.nSamplesPerSec, format.wFormatTag, format.nChannels, format.nSamplesPerSec,
format.nBlockAlign, format.wBitsPerSample, format.cbSize); format.nBlockAlign, format.wBitsPerSample, format.cbSize);
@ -195,7 +195,7 @@ static WIN32ERROR audin_process_formats(IWTSVirtualChannelCallback* pChannelCall
continue; continue;
if (audin->device && audin->device->FormatSupported(audin->device, &format)) if (audin->device && audin->device->FormatSupported(audin->device, &format))
{ {
DEBUG_DVC("process_formats: format ok"); DEBUG_DVC("format ok");
/* Store the agreed format in the corresponding index */ /* Store the agreed format in the corresponding index */
callback->formats[callback->formats_count++] = format; callback->formats[callback->formats_count++] = format;
@ -321,7 +321,7 @@ static WIN32ERROR audin_process_open(IWTSVirtualChannelCallback* pChannelCallbac
Stream_Read_UINT32(s, FramesPerPacket); Stream_Read_UINT32(s, FramesPerPacket);
Stream_Read_UINT32(s, initialFormat); Stream_Read_UINT32(s, initialFormat);
DEBUG_DVC("process_open: FramesPerPacket=%d initialFormat=%d", DEBUG_DVC("FramesPerPacket=%d initialFormat=%d",
FramesPerPacket, initialFormat); FramesPerPacket, initialFormat);
if (initialFormat >= (UINT32) callback->formats_count) if (initialFormat >= (UINT32) callback->formats_count)
@ -370,7 +370,7 @@ static WIN32ERROR audin_process_format_change(IWTSVirtualChannelCallback* pChann
Stream_Read_UINT32(s, NewFormat); Stream_Read_UINT32(s, NewFormat);
DEBUG_DVC("process_format_change: NewFormat=%d", NewFormat); DEBUG_DVC("NewFormat=%d", NewFormat);
if (NewFormat >= (UINT32) callback->formats_count) if (NewFormat >= (UINT32) callback->formats_count)
{ {
@ -416,7 +416,7 @@ static WIN32ERROR audin_on_data_received(IWTSVirtualChannelCallback* pChannelCal
Stream_Read_UINT8(data, MessageId); Stream_Read_UINT8(data, MessageId);
DEBUG_DVC("on_data_received: MessageId=0x%x", MessageId); DEBUG_DVC("MessageId=0x%x", MessageId);
switch (MessageId) switch (MessageId)
{ {
@ -451,7 +451,7 @@ static WIN32ERROR audin_on_close(IWTSVirtualChannelCallback* pChannelCallback)
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) callback->plugin; AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) callback->plugin;
WIN32ERROR error = CHANNEL_RC_OK; WIN32ERROR error = CHANNEL_RC_OK;
DEBUG_DVC("on_close"); DEBUG_DVC("...");
if (audin->device) if (audin->device)
{ {
@ -476,7 +476,7 @@ static WIN32ERROR audin_on_new_channel_connection(IWTSListenerCallback* pListene
AUDIN_CHANNEL_CALLBACK* callback; AUDIN_CHANNEL_CALLBACK* callback;
AUDIN_LISTENER_CALLBACK* listener_callback = (AUDIN_LISTENER_CALLBACK*) pListenerCallback; AUDIN_LISTENER_CALLBACK* listener_callback = (AUDIN_LISTENER_CALLBACK*) pListenerCallback;
DEBUG_DVC("on_new_channel_connection"); DEBUG_DVC("...");
callback = (AUDIN_CHANNEL_CALLBACK*) calloc(1, sizeof(AUDIN_CHANNEL_CALLBACK)); callback = (AUDIN_CHANNEL_CALLBACK*) calloc(1, sizeof(AUDIN_CHANNEL_CALLBACK));
if (!callback) if (!callback)
@ -500,7 +500,7 @@ static WIN32ERROR audin_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChanne
{ {
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) pPlugin; AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) pPlugin;
DEBUG_DVC("plugin_initialize"); DEBUG_DVC("...");
audin->listener_callback = (AUDIN_LISTENER_CALLBACK*) calloc(1, sizeof(AUDIN_LISTENER_CALLBACK)); audin->listener_callback = (AUDIN_LISTENER_CALLBACK*) calloc(1, sizeof(AUDIN_LISTENER_CALLBACK));
if (!audin->listener_callback) if (!audin->listener_callback)
@ -522,7 +522,7 @@ static WIN32ERROR audin_plugin_terminated(IWTSPlugin* pPlugin)
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) pPlugin; AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) pPlugin;
WIN32ERROR error = CHANNEL_RC_OK; WIN32ERROR error = CHANNEL_RC_OK;
DEBUG_DVC("plugin_terminated"); DEBUG_DVC("...");
if (audin->device) if (audin->device)
{ {
@ -557,7 +557,7 @@ static WIN32ERROR audin_register_device_plugin(IWTSPlugin* pPlugin, IAudinDevice
return ERROR_ALREADY_EXISTS; return ERROR_ALREADY_EXISTS;
} }
DEBUG_DVC("register_device_plugin: device registered."); DEBUG_DVC("device registered.");
audin->device = device; audin->device = device;
return CHANNEL_RC_OK; return CHANNEL_RC_OK;

View File

@ -190,7 +190,9 @@ static WIN32ERROR audin_opensles_free(IAudinDevice* device)
static BOOL audin_opensles_format_supported(IAudinDevice* device, audinFormat* format) static BOOL audin_opensles_format_supported(IAudinDevice* device, audinFormat* format)
{ {
#ifdef WITH_DEBUG_DVC
AudinOpenSLESDevice* opensles = (AudinOpenSLESDevice*) device; AudinOpenSLESDevice* opensles = (AudinOpenSLESDevice*) device;
#endif
DEBUG_DVC("device=%p, format=%p", opensles, format); DEBUG_DVC("device=%p, format=%p", opensles, format);

View File

@ -29,6 +29,7 @@
#include <winpr/crt.h> #include <winpr/crt.h>
#include <winpr/synch.h> #include <winpr/synch.h>
#include <winpr/string.h>
#include <winpr/thread.h> #include <winpr/thread.h>
#include <winpr/cmdline.h> #include <winpr/cmdline.h>
#include <winpr/win32error.h> #include <winpr/win32error.h>
@ -40,9 +41,9 @@
#include <limits.h> #include <limits.h>
#include <unistd.h> #include <unistd.h>
#if defined(__OpenBSD__) #if defined(__OpenBSD__)
#include <soundcard.h> #include <soundcard.h>
#else #else
#include <sys/soundcard.h> #include <sys/soundcard.h>
#endif #endif
#include <sys/ioctl.h> #include <sys/ioctl.h>
@ -52,7 +53,8 @@
#include "audin_main.h" #include "audin_main.h"
typedef struct _AudinOSSDevice { typedef struct _AudinOSSDevice
{
IAudinDevice iface; IAudinDevice iface;
FREERDP_DSP_CONTEXT* dsp_context; FREERDP_DSP_CONTEXT* dsp_context;
@ -75,86 +77,101 @@ typedef struct _AudinOSSDevice {
WLog_ERR(TAG, "%s: %i - %s\n", _text, _error, strerror(_error)); WLog_ERR(TAG, "%s: %i - %s\n", _text, _error, strerror(_error));
static int audin_oss_get_format(audinFormat *format) { static int audin_oss_get_format(audinFormat* format)
{
switch (format->wFormatTag)
{
case WAVE_FORMAT_PCM:
switch (format->wFormatTag) { switch (format->wBitsPerSample)
case WAVE_FORMAT_PCM: {
switch (format->wBitsPerSample) { case 8:
case 8: return AFMT_S8;
return AFMT_S8; case 16:
case 16: return AFMT_S16_LE;
return AFMT_S16_LE; }
}
break; break;
case WAVE_FORMAT_ALAW: case WAVE_FORMAT_ALAW:
return AFMT_A_LAW; return AFMT_A_LAW;
#if 0 /* This does not work on my desktop. */ #if 0 /* This does not work on my desktop. */
case WAVE_FORMAT_MULAW: case WAVE_FORMAT_MULAW:
return AFMT_MU_LAW; return AFMT_MU_LAW;
#endif #endif
case WAVE_FORMAT_ADPCM: case WAVE_FORMAT_ADPCM:
case WAVE_FORMAT_DVI_ADPCM: case WAVE_FORMAT_DVI_ADPCM:
return AFMT_S16_LE; return AFMT_S16_LE;
} }
return 0; return 0;
} }
static BOOL audin_oss_format_supported(IAudinDevice *device, audinFormat *format) { static BOOL audin_oss_format_supported(IAudinDevice* device, audinFormat* format)
{
int req_fmt = 0; int req_fmt = 0;
if (device == NULL || format == NULL) if (device == NULL || format == NULL)
return FALSE; return FALSE;
switch (format->wFormatTag) { switch (format->wFormatTag)
case WAVE_FORMAT_PCM: {
if (format->cbSize != 0 || case WAVE_FORMAT_PCM:
format->nSamplesPerSec > 48000 ||
(format->wBitsPerSample != 8 && format->wBitsPerSample != 16) || if (format->cbSize != 0 ||
(format->nChannels != 1 && format->nChannels != 2)) format->nSamplesPerSec > 48000 ||
return FALSE; (format->wBitsPerSample != 8 && format->wBitsPerSample != 16) ||
break; (format->nChannels != 1 && format->nChannels != 2))
case WAVE_FORMAT_ADPCM: return FALSE;
case WAVE_FORMAT_DVI_ADPCM:
if (format->nSamplesPerSec > 48000 || break;
format->wBitsPerSample != 4 || case WAVE_FORMAT_ADPCM:
(format->nChannels != 1 && format->nChannels != 2)) case WAVE_FORMAT_DVI_ADPCM:
return FALSE;
break; if (format->nSamplesPerSec > 48000 ||
format->wBitsPerSample != 4 ||
(format->nChannels != 1 && format->nChannels != 2))
return FALSE;
break;
} }
req_fmt = audin_oss_get_format(format); req_fmt = audin_oss_get_format(format);
if (req_fmt == 0) if (req_fmt == 0)
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
static WIN32ERROR audin_oss_set_format(IAudinDevice *device, audinFormat *format, UINT32 FramesPerPacket) { static WIN32ERROR audin_oss_set_format(IAudinDevice* device, audinFormat* format, UINT32 FramesPerPacket)
AudinOSSDevice *oss = (AudinOSSDevice*)device; {
AudinOSSDevice* oss = (AudinOSSDevice*)device;
if (device == NULL || format == NULL) if (device == NULL || format == NULL)
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
oss->FramesPerPacket = FramesPerPacket; oss->FramesPerPacket = FramesPerPacket;
CopyMemory(&(oss->format), format, sizeof(audinFormat)); CopyMemory(&(oss->format), format, sizeof(audinFormat));
switch (format->wFormatTag) {
case WAVE_FORMAT_ADPCM: switch (format->wFormatTag)
case WAVE_FORMAT_DVI_ADPCM: {
oss->FramesPerPacket *= 4; /* Compression ratio. */ case WAVE_FORMAT_ADPCM:
oss->format.wBitsPerSample *= 4; case WAVE_FORMAT_DVI_ADPCM:
break; oss->FramesPerPacket *= 4; /* Compression ratio. */
oss->format.wBitsPerSample *= 4;
break;
} }
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
static void *audin_oss_thread_func(void *arg) static void* audin_oss_thread_func(void* arg)
{ {
char dev_name[PATH_MAX] = "/dev/dsp"; char dev_name[PATH_MAX] = "/dev/dsp";
int pcm_handle = -1; char mixer_name[PATH_MAX] = "/dev/mixer";
BYTE *buffer = NULL, *encoded_data; int pcm_handle = -1, mixer_handle;
BYTE* buffer = NULL, *encoded_data;
int tmp, buffer_size, encoded_size; int tmp, buffer_size, encoded_size;
AudinOSSDevice *oss = (AudinOSSDevice*)arg; AudinOSSDevice* oss = (AudinOSSDevice*)arg;
WIN32ERROR error; WIN32ERROR error;
if (arg == NULL) if (arg == NULL)
@ -164,54 +181,102 @@ static void *audin_oss_thread_func(void *arg)
} }
if (oss->dev_unit != -1) if (oss->dev_unit != -1)
snprintf(dev_name, (PATH_MAX - 1), "/dev/dsp%i", oss->dev_unit); {
sprintf_s(dev_name, (PATH_MAX - 1), "/dev/dsp%i", oss->dev_unit);
sprintf_s(mixer_name, PATH_MAX - 1, "/dev/mixer%i", oss->dev_unit);
}
WLog_INFO(TAG, "open: %s", dev_name); WLog_INFO(TAG, "open: %s", dev_name);
if ((pcm_handle = open(dev_name, O_RDONLY)) < 0) {
if ((pcm_handle = open(dev_name, O_RDONLY)) < 0)
{
OSS_LOG_ERR("sound dev open failed", errno); OSS_LOG_ERR("sound dev open failed", errno);
error = (WIN32ERROR)errno; error = (WIN32ERROR)errno;
goto err_out; goto err_out;
} }
/* Set rec volume to 100%. */
if ((mixer_handle = open(mixer_name, O_RDWR)) < 0)
{
OSS_LOG_ERR("mixer open failed, not critical", errno);
}
else
{
tmp = (100 | (100 << 8));
if (ioctl(mixer_handle, MIXER_WRITE(SOUND_MIXER_MIC), &tmp) == -1)
OSS_LOG_ERR("WRITE_MIXER - SOUND_MIXER_MIC, not critical", errno);
tmp = (100 | (100 << 8));
if (ioctl(mixer_handle, MIXER_WRITE(SOUND_MIXER_RECLEV), &tmp) == -1)
OSS_LOG_ERR("WRITE_MIXER - SOUND_MIXER_RECLEV, not critical", errno);
close(mixer_handle);
}
#if 0 /* FreeBSD OSS implementation at this moment (2015.03) does not set PCM_CAP_INPUT flag. */ #if 0 /* FreeBSD OSS implementation at this moment (2015.03) does not set PCM_CAP_INPUT flag. */
tmp = 0; tmp = 0;
if (ioctl(pcm_handle, SNDCTL_DSP_GETCAPS, &tmp) == -1) {
if (ioctl(pcm_handle, SNDCTL_DSP_GETCAPS, &tmp) == -1)
{
OSS_LOG_ERR("SNDCTL_DSP_GETCAPS failed, try ignory", errno); OSS_LOG_ERR("SNDCTL_DSP_GETCAPS failed, try ignory", errno);
} else if ((tmp & PCM_CAP_INPUT) == 0) { }
else if ((tmp & PCM_CAP_INPUT) == 0)
{
OSS_LOG_ERR("Device does not supports playback", EOPNOTSUPP); OSS_LOG_ERR("Device does not supports playback", EOPNOTSUPP);
goto err_out; goto err_out;
} }
#endif #endif
/* Set format. */ /* Set format. */
tmp = audin_oss_get_format(&oss->format); tmp = audin_oss_get_format(&oss->format);
if (ioctl(pcm_handle, SNDCTL_DSP_SETFMT, &tmp) == -1) if (ioctl(pcm_handle, SNDCTL_DSP_SETFMT, &tmp) == -1)
OSS_LOG_ERR("SNDCTL_DSP_SETFMT failed", errno); OSS_LOG_ERR("SNDCTL_DSP_SETFMT failed", errno);
tmp = oss->format.nChannels; tmp = oss->format.nChannels;
if (ioctl(pcm_handle, SNDCTL_DSP_CHANNELS, &tmp) == -1) if (ioctl(pcm_handle, SNDCTL_DSP_CHANNELS, &tmp) == -1)
OSS_LOG_ERR("SNDCTL_DSP_CHANNELS failed", errno); OSS_LOG_ERR("SNDCTL_DSP_CHANNELS failed", errno);
tmp = oss->format.nSamplesPerSec; tmp = oss->format.nSamplesPerSec;
if (ioctl(pcm_handle, SNDCTL_DSP_SPEED, &tmp) == -1) if (ioctl(pcm_handle, SNDCTL_DSP_SPEED, &tmp) == -1)
OSS_LOG_ERR("SNDCTL_DSP_SPEED failed", errno); OSS_LOG_ERR("SNDCTL_DSP_SPEED failed", errno);
tmp = oss->format.nBlockAlign; tmp = oss->format.nBlockAlign;
if (ioctl(pcm_handle, SNDCTL_DSP_SETFRAGMENT, &tmp) == -1) if (ioctl(pcm_handle, SNDCTL_DSP_SETFRAGMENT, &tmp) == -1)
OSS_LOG_ERR("SNDCTL_DSP_SETFRAGMENT failed", errno); OSS_LOG_ERR("SNDCTL_DSP_SETFRAGMENT failed", errno);
buffer_size = (oss->FramesPerPacket * oss->format.nChannels * (oss->format.wBitsPerSample / 8)); buffer_size = (oss->FramesPerPacket * oss->format.nChannels * (oss->format.wBitsPerSample / 8));
buffer = (BYTE*)calloc(1, (buffer_size + sizeof(void*))); buffer = (BYTE*)malloc((buffer_size + sizeof(void*)));
if (NULL == buffer) {
if (NULL == buffer)
{
OSS_LOG_ERR("malloc() fail", errno); OSS_LOG_ERR("malloc() fail", errno);
error = ERROR_NOT_ENOUGH_MEMORY; error = ERROR_NOT_ENOUGH_MEMORY;
goto err_out; goto err_out;
} }
ZeroMemory(buffer, buffer_size);
freerdp_dsp_context_reset_adpcm(oss->dsp_context); freerdp_dsp_context_reset_adpcm(oss->dsp_context);
while (WaitForSingleObject(oss->stopEvent, 0) != WAIT_OBJECT_0) { while (WaitForSingleObject(oss->stopEvent, 0) != WAIT_OBJECT_0)
{
tmp = read(pcm_handle, buffer, buffer_size); tmp = read(pcm_handle, buffer, buffer_size);
if (tmp < 0) { /* Error happen. */
/* Error happen. */
if (tmp < 0)
{
OSS_LOG_ERR("read() error", errno); OSS_LOG_ERR("read() error", errno);
continue; continue;
} }
if (tmp < buffer_size) /* Not enouth data. */ if (tmp < buffer_size) /* Not enouth data. */
continue; continue;
/* Process. */ /* Process. */
switch (oss->format.wFormatTag) { switch (oss->format.wFormatTag) {
case WAVE_FORMAT_ADPCM: case WAVE_FORMAT_ADPCM:
@ -253,11 +318,13 @@ err_out:
setChannelError(oss->rdpcontext, error, "audin_oss_thread_func reported an error"); setChannelError(oss->rdpcontext, error, "audin_oss_thread_func reported an error");
if (pcm_handle != -1) if (pcm_handle != -1)
{
WLog_INFO(TAG, "close: %s", dev_name);
close(pcm_handle); close(pcm_handle);
}
free(buffer); free(buffer);
ExitThread(0); ExitThread(0);
return NULL; return NULL;
} }
@ -284,19 +351,19 @@ static WIN32ERROR audin_oss_open(IAudinDevice *device, AudinReceive receive, voi
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
static WIN32ERROR audin_oss_close(IAudinDevice *device) { static WIN32ERROR audin_oss_close(IAudinDevice *device)
{
AudinOSSDevice *oss = (AudinOSSDevice*)device; AudinOSSDevice *oss = (AudinOSSDevice*)device;
if (device == NULL) if (device == NULL)
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
if (oss->stopEvent != NULL) { if (oss->stopEvent != NULL)
{
SetEvent(oss->stopEvent); SetEvent(oss->stopEvent);
WaitForSingleObject(oss->thread, INFINITE); WaitForSingleObject(oss->thread, INFINITE);
CloseHandle(oss->stopEvent); CloseHandle(oss->stopEvent);
oss->stopEvent = NULL; oss->stopEvent = NULL;
CloseHandle(oss->thread); CloseHandle(oss->thread);
oss->thread = NULL; oss->thread = NULL;
} }
@ -307,7 +374,8 @@ static WIN32ERROR audin_oss_close(IAudinDevice *device) {
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
static WIN32ERROR audin_oss_free(IAudinDevice *device) { static WIN32ERROR audin_oss_free(IAudinDevice* device)
{
AudinOSSDevice *oss = (AudinOSSDevice*)device; AudinOSSDevice *oss = (AudinOSSDevice*)device;
int error; int error;
@ -320,39 +388,40 @@ static WIN32ERROR audin_oss_free(IAudinDevice *device) {
WLog_ERR(TAG, "audin_oss_close failed with error code %d!", error); WLog_ERR(TAG, "audin_oss_close failed with error code %d!", error);
} }
freerdp_dsp_context_free(oss->dsp_context); freerdp_dsp_context_free(oss->dsp_context);
free(oss); free(oss);
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
COMMAND_LINE_ARGUMENT_A audin_oss_args[] = { COMMAND_LINE_ARGUMENT_A audin_oss_args[] =
{
{ "dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "audio device name" }, { "dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "audio device name" },
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
}; };
static WIN32ERROR audin_oss_parse_addin_args(AudinOSSDevice *device, ADDIN_ARGV *args) { static WIN32ERROR audin_oss_parse_addin_args(AudinOSSDevice *device, ADDIN_ARGV *args)
{
int status; int status;
char *str_num, *eptr; char* str_num, *eptr;
DWORD flags; DWORD flags;
COMMAND_LINE_ARGUMENT_A *arg; COMMAND_LINE_ARGUMENT_A* arg;
AudinOSSDevice *oss = (AudinOSSDevice*)device; AudinOSSDevice* oss = (AudinOSSDevice*)device;
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_IGN_UNKNOWN_KEYWORD; flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_IGN_UNKNOWN_KEYWORD;
status = CommandLineParseArgumentsA(args->argc, (const char**)args->argv, audin_oss_args, flags, oss, NULL, NULL); status = CommandLineParseArgumentsA(args->argc, (const char**)args->argv, audin_oss_args, flags, oss, NULL, NULL);
if (status < 0) if (status < 0)
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
arg = audin_oss_args; arg = audin_oss_args;
do { do
{
if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT)) if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
continue; continue;
CommandLineSwitchStart(arg) CommandLineSwitchStart(arg)
CommandLineSwitchCase(arg, "dev")
CommandLineSwitchCase(arg, "dev") { {
str_num = _strdup(arg->Value); str_num = _strdup(arg->Value);
if (!str_num) if (!str_num)
{ {
@ -360,14 +429,15 @@ static WIN32ERROR audin_oss_parse_addin_args(AudinOSSDevice *device, ADDIN_ARGV
return CHANNEL_RC_NO_MEMORY; return CHANNEL_RC_NO_MEMORY;
} }
oss->dev_unit = strtol(str_num, &eptr, 10); oss->dev_unit = strtol(str_num, &eptr, 10);
if (oss->dev_unit < 0 || *eptr != '\0') if (oss->dev_unit < 0 || *eptr != '\0')
oss->dev_unit = -1; oss->dev_unit = -1;
free(str_num); free(str_num);
} }
CommandLineSwitchEnd(arg) CommandLineSwitchEnd(arg)
} while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); }
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
@ -375,7 +445,8 @@ static WIN32ERROR audin_oss_parse_addin_args(AudinOSSDevice *device, ADDIN_ARGV
#define freerdp_audin_client_subsystem_entry oss_freerdp_audin_client_subsystem_entry #define freerdp_audin_client_subsystem_entry oss_freerdp_audin_client_subsystem_entry
#endif #endif
WIN32ERROR freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints) { WIN32ERROR freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints)
{
ADDIN_ARGV *args; ADDIN_ARGV *args;
AudinOSSDevice *oss; AudinOSSDevice *oss;
WIN32ERROR error; WIN32ERROR error;
@ -395,7 +466,6 @@ WIN32ERROR freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POIN
oss->rdpcontext = pEntryPoints->rdpcontext; oss->rdpcontext = pEntryPoints->rdpcontext;
oss->dev_unit = -1; oss->dev_unit = -1;
args = pEntryPoints->args; args = pEntryPoints->args;
if ((error = audin_oss_parse_addin_args(oss, args))) if ((error = audin_oss_parse_addin_args(oss, args)))

View File

@ -548,7 +548,7 @@ WIN32ERROR cliprdr_temp_directory(CliprdrClientContext* context, CLIPRDR_TEMP_DI
if (length > 520) if (length > 520)
length = 520; length = 520;
Stream_Write(s, tempDirectory->szTempDir, length * 2); Stream_Write(s, wszTempDir, length * 2);
Stream_Zero(s, (520 - length) * 2); Stream_Zero(s, (520 - length) * 2);
free(wszTempDir); free(wszTempDir);

View File

@ -38,6 +38,7 @@
#include <string.h> #include <string.h>
#include <winpr/crt.h> #include <winpr/crt.h>
#include <winpr/string.h>
#include <winpr/synch.h> #include <winpr/synch.h>
#include <winpr/thread.h> #include <winpr/thread.h>
#include <winpr/stream.h> #include <winpr/stream.h>
@ -846,7 +847,7 @@ WIN32ERROR DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
/* Special case: path[0] == '%' -> user home dir */ /* Special case: path[0] == '%' -> user home dir */
if (strcmp(drive->Path, "%") == 0) if (strcmp(drive->Path, "%") == 0)
{ {
_snprintf(buf, sizeof(buf), "%s\\", getenv("USERPROFILE")); sprintf_s(buf, sizeof(buf), "%s\\", getenv("USERPROFILE"));
free(drive->Path); free(drive->Path);
drive->Path = _strdup(buf); drive->Path = _strdup(buf);
if (!drive->Path) if (!drive->Path)
@ -868,7 +869,7 @@ WIN32ERROR DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
if (*dev > 'B') if (*dev > 'B')
{ {
/* Suppress disk drives A and B to avoid pesty messages */ /* Suppress disk drives A and B to avoid pesty messages */
len = _snprintf(buf, sizeof(buf) - 4, "%s", drive->Name); len = sprintf_s(buf, sizeof(buf) - 4, "%s", drive->Name);
buf[len] = '_'; buf[len] = '_';
buf[len + 1] = dev[0]; buf[len + 1] = dev[0];
buf[len + 2] = 0; buf[len + 2] = 0;

View File

@ -32,6 +32,7 @@
#include <cups/cups.h> #include <cups/cups.h>
#include <winpr/crt.h> #include <winpr/crt.h>
#include <winpr/string.h>
#include <freerdp/channels/rdpdr.h> #include <freerdp/channels/rdpdr.h>
@ -72,7 +73,7 @@ static void printer_cups_get_printjob_name(char* buf, int size)
tt = time(NULL); tt = time(NULL);
t = localtime(&tt); t = localtime(&tt);
snprintf(buf, size - 1, "FreeRDP Print Job %d%02d%02d%02d%02d%02d", sprintf_s(buf, size - 1, "FreeRDP Print Job %d%02d%02d%02d%02d%02d",
t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec); t->tm_hour, t->tm_min, t->tm_sec);
} }
@ -94,6 +95,7 @@ static WIN32ERROR printer_cups_write_printjob(rdpPrintJob* printjob, BYTE* data,
if (fwrite(data, 1, size, fp) < size) if (fwrite(data, 1, size, fp) < size)
{ {
return ERROR_INTERNAL_ERROR; return ERROR_INTERNAL_ERROR;
// FIXME once this function doesn't return void anymore!
} }
fclose(fp); fclose(fp);

View File

@ -28,6 +28,7 @@
#include <string.h> #include <string.h>
#include <winpr/crt.h> #include <winpr/crt.h>
#include <winpr/string.h>
#include <winpr/synch.h> #include <winpr/synch.h>
#include <winpr/thread.h> #include <winpr/thread.h>
#include <winpr/stream.h> #include <winpr/stream.h>
@ -288,7 +289,7 @@ WIN32ERROR printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinte
WLog_ERR(TAG, "malloc failed!"); WLog_ERR(TAG, "malloc failed!");
return CHANNEL_RC_NO_MEMORY; return CHANNEL_RC_NO_MEMORY;
} }
snprintf(port, 10, "PRN%d", printer->id); sprintf_s(port, 10, "PRN%d", printer->id);
printer_dev = (PRINTER_DEVICE*) calloc(1, sizeof(PRINTER_DEVICE)); printer_dev = (PRINTER_DEVICE*) calloc(1, sizeof(PRINTER_DEVICE));
if (!printer_dev) if (!printer_dev)

View File

@ -24,6 +24,7 @@
#endif #endif
#include <winpr/crt.h> #include <winpr/crt.h>
#include <winpr/string.h>
#include <winpr/windows.h> #include <winpr/windows.h>
#include <time.h> #include <time.h>
@ -71,7 +72,7 @@ static void printer_win_get_printjob_name(char* buf, int size)
tt = time(NULL); tt = time(NULL);
t = localtime(&tt); t = localtime(&tt);
snprintf(buf, size - 1, "FreeRDP Print Job %d%02d%02d%02d%02d%02d", sprintf_s(buf, size - 1, "FreeRDP Print Job %d%02d%02d%02d%02d%02d",
t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec); t->tm_hour, t->tm_min, t->tm_sec);
} }

View File

@ -33,7 +33,3 @@ rdpPrinterDriver* printer_win_get_driver(void);
#endif #endif
#ifdef WIN32
#define snprintf _snprintf
#endif

View File

@ -43,6 +43,8 @@
#include "rdpgfx_main.h" #include "rdpgfx_main.h"
#define TAG CHANNELS_TAG("rdpgfx.client")
WIN32ERROR rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback) WIN32ERROR rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback)
{ {
WIN32ERROR error; WIN32ERROR error;
@ -87,7 +89,7 @@ WIN32ERROR rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback)
header.pduLength = RDPGFX_HEADER_SIZE + 2 + (pdu.capsSetCount * RDPGFX_CAPSET_SIZE); header.pduLength = RDPGFX_HEADER_SIZE + 2 + (pdu.capsSetCount * RDPGFX_CAPSET_SIZE);
WLog_Print(gfx->log, WLOG_DEBUG, "SendCapsAdvertisePdu"); WLog_DBG(TAG, "SendCapsAdvertisePdu");
s = Stream_New(NULL, header.pduLength); s = Stream_New(NULL, header.pduLength);
if (!s) if (!s)
@ -144,7 +146,7 @@ WIN32ERROR rdpgfx_recv_caps_confirm_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStre
/*TODO: interpret this answer*/ /*TODO: interpret this answer*/
WLog_Print(gfx->log, WLOG_DEBUG, "RecvCapsConfirmPdu: version: 0x%04X flags: 0x%04X", WLog_DBG(TAG, "RecvCapsConfirmPdu: version: 0x%04X flags: 0x%04X",
capsSet.version, capsSet.flags); capsSet.version, capsSet.flags);
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
@ -161,7 +163,7 @@ WIN32ERROR rdpgfx_send_frame_acknowledge_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
header.cmdId = RDPGFX_CMDID_FRAMEACKNOWLEDGE; header.cmdId = RDPGFX_CMDID_FRAMEACKNOWLEDGE;
header.pduLength = RDPGFX_HEADER_SIZE + 12; header.pduLength = RDPGFX_HEADER_SIZE + 12;
WLog_Print(gfx->log, WLOG_DEBUG, "SendFrameAcknowledgePdu: %d", pdu->frameId); WLog_DBG(TAG, "SendFrameAcknowledgePdu: %d", pdu->frameId);
s = Stream_New(NULL, header.pduLength); s = Stream_New(NULL, header.pduLength);
if (!s) if (!s)
@ -244,7 +246,7 @@ WIN32ERROR rdpgfx_recv_reset_graphics_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wSt
Stream_Seek(s, pad); /* pad (total size is 340 bytes) */ Stream_Seek(s, pad); /* pad (total size is 340 bytes) */
WLog_Print(gfx->log, WLOG_DEBUG, "RecvResetGraphicsPdu: width: %d height: %d count: %d", WLog_DBG(TAG, "RecvResetGraphicsPdu: width: %d height: %d count: %d",
pdu.width, pdu.height, pdu.monitorCount); pdu.width, pdu.height, pdu.monitorCount);
if (context) if (context)
@ -274,7 +276,7 @@ WIN32ERROR rdpgfx_recv_evict_cache_entry_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
Stream_Read_UINT16(s, pdu.cacheSlot); /* cacheSlot (2 bytes) */ Stream_Read_UINT16(s, pdu.cacheSlot); /* cacheSlot (2 bytes) */
WLog_Print(gfx->log, WLOG_DEBUG, "RecvEvictCacheEntryPdu: cacheSlot: %d", pdu.cacheSlot); WLog_DBG(TAG, "RecvEvictCacheEntryPdu: cacheSlot: %d", pdu.cacheSlot);
if (context) if (context)
{ {
@ -321,7 +323,7 @@ WIN32ERROR rdpgfx_recv_cache_import_reply_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
Stream_Read_UINT16(s, pdu.cacheSlots[index]); /* cacheSlot (2 bytes) */ Stream_Read_UINT16(s, pdu.cacheSlots[index]); /* cacheSlot (2 bytes) */
} }
WLog_Print(gfx->log, WLOG_DEBUG, "RecvCacheImportReplyPdu: importedEntriesCount: %d", WLog_DBG(TAG, "RecvCacheImportReplyPdu: importedEntriesCount: %d",
pdu.importedEntriesCount); pdu.importedEntriesCount);
if (context) if (context)
@ -354,7 +356,7 @@ WIN32ERROR rdpgfx_recv_create_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wSt
Stream_Read_UINT16(s, pdu.height); /* height (2 bytes) */ Stream_Read_UINT16(s, pdu.height); /* height (2 bytes) */
Stream_Read_UINT8(s, pdu.pixelFormat); /* RDPGFX_PIXELFORMAT (1 byte) */ Stream_Read_UINT8(s, pdu.pixelFormat); /* RDPGFX_PIXELFORMAT (1 byte) */
WLog_Print(gfx->log, WLOG_DEBUG, "RecvCreateSurfacePdu: surfaceId: %d width: %d height: %d pixelFormat: 0x%02X", WLog_DBG(TAG, "RecvCreateSurfacePdu: surfaceId: %d width: %d height: %d pixelFormat: 0x%02X",
pdu.surfaceId, pdu.width, pdu.height, pdu.pixelFormat); pdu.surfaceId, pdu.width, pdu.height, pdu.pixelFormat);
if (context) if (context)
@ -382,7 +384,7 @@ WIN32ERROR rdpgfx_recv_delete_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wSt
Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */
WLog_Print(gfx->log, WLOG_DEBUG, "RecvDeleteSurfacePdu: surfaceId: %d", pdu.surfaceId); WLog_DBG(TAG, "RecvDeleteSurfacePdu: surfaceId: %d", pdu.surfaceId);
if (context) if (context)
{ {
@ -410,7 +412,7 @@ WIN32ERROR rdpgfx_recv_start_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStrea
Stream_Read_UINT32(s, pdu.timestamp); /* timestamp (4 bytes) */ Stream_Read_UINT32(s, pdu.timestamp); /* timestamp (4 bytes) */
Stream_Read_UINT32(s, pdu.frameId); /* frameId (4 bytes) */ Stream_Read_UINT32(s, pdu.frameId); /* frameId (4 bytes) */
WLog_Print(gfx->log, WLOG_DEBUG, "RecvStartFramePdu: frameId: %d timestamp: 0x%04X", WLog_DBG(TAG, "RecvStartFramePdu: frameId: %d timestamp: 0x%04X",
pdu.frameId, pdu.timestamp); pdu.frameId, pdu.timestamp);
if (context) if (context)
@ -441,7 +443,7 @@ WIN32ERROR rdpgfx_recv_end_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream*
Stream_Read_UINT32(s, pdu.frameId); /* frameId (4 bytes) */ Stream_Read_UINT32(s, pdu.frameId); /* frameId (4 bytes) */
WLog_Print(gfx->log, WLOG_DEBUG, "RecvEndFramePdu: frameId: %d", pdu.frameId); WLog_DBG(TAG, "RecvEndFramePdu: frameId: %d", pdu.frameId);
if (context) if (context)
{ {
@ -503,7 +505,7 @@ WIN32ERROR rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
pdu.bitmapData = Stream_Pointer(s); pdu.bitmapData = Stream_Pointer(s);
Stream_Seek(s, pdu.bitmapDataLength); Stream_Seek(s, pdu.bitmapDataLength);
WLog_Print(gfx->log, WLOG_DEBUG, "RecvWireToSurface1Pdu: surfaceId: %d codecId: %s (0x%04X) pixelFormat: 0x%04X " WLog_DBG(TAG, "RecvWireToSurface1Pdu: surfaceId: %d codecId: %s (0x%04X) pixelFormat: 0x%04X "
"destRect: left: %d top: %d right: %d bottom: %d bitmapDataLength: %d", "destRect: left: %d top: %d right: %d bottom: %d bitmapDataLength: %d",
(int) pdu.surfaceId, rdpgfx_get_codec_id_string(pdu.codecId), pdu.codecId, pdu.pixelFormat, (int) pdu.surfaceId, rdpgfx_get_codec_id_string(pdu.codecId), pdu.codecId, pdu.pixelFormat,
pdu.destRect.left, pdu.destRect.top, pdu.destRect.right, pdu.destRect.bottom, pdu.destRect.left, pdu.destRect.top, pdu.destRect.right, pdu.destRect.bottom,
@ -564,9 +566,10 @@ WIN32ERROR rdpgfx_recv_wire_to_surface_2_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
pdu.bitmapData = Stream_Pointer(s); pdu.bitmapData = Stream_Pointer(s);
Stream_Seek(s, pdu.bitmapDataLength); Stream_Seek(s, pdu.bitmapDataLength);
WLog_Print(gfx->log, WLOG_DEBUG, "RecvWireToSurface2Pdu: surfaceId: %d codecId: 0x%04X " WLog_DBG(TAG, "RecvWireToSurface2Pdu: surfaceId: %d codecId: %s (0x%04X) "
"codecContextId: %d pixelFormat: 0x%04X bitmapDataLength: %d", "codecContextId: %d pixelFormat: 0x%04X bitmapDataLength: %d",
(int) pdu.surfaceId, pdu.codecId, pdu.codecContextId, pdu.pixelFormat, pdu.bitmapDataLength); (int) pdu.surfaceId, rdpgfx_get_codec_id_string(pdu.codecId), pdu.codecId,
pdu.codecContextId, pdu.pixelFormat, pdu.bitmapDataLength);
cmd.surfaceId = pdu.surfaceId; cmd.surfaceId = pdu.surfaceId;
cmd.codecId = pdu.codecId; cmd.codecId = pdu.codecId;
@ -607,7 +610,7 @@ WIN32ERROR rdpgfx_recv_delete_encoding_context_pdu(RDPGFX_CHANNEL_CALLBACK* call
Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */
Stream_Read_UINT32(s, pdu.codecContextId); /* codecContextId (4 bytes) */ Stream_Read_UINT32(s, pdu.codecContextId); /* codecContextId (4 bytes) */
WLog_Print(gfx->log, WLOG_DEBUG, "RecvDeleteEncodingContextPdu: surfaceId: %d codecContextId: %d", WLog_DBG(TAG, "RecvDeleteEncodingContextPdu: surfaceId: %d codecContextId: %d",
pdu.surfaceId, pdu.codecContextId); pdu.surfaceId, pdu.codecContextId);
if (context) if (context)
@ -668,7 +671,7 @@ WIN32ERROR rdpgfx_recv_solid_fill_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream
} }
} }
WLog_Print(gfx->log, WLOG_DEBUG, "RecvSolidFillPdu: surfaceId: %d fillRectCount: %d", WLog_DBG(TAG, "RecvSolidFillPdu: surfaceId: %d fillRectCount: %d",
pdu.surfaceId, pdu.fillRectCount); pdu.surfaceId, pdu.fillRectCount);
if (context) if (context)
@ -733,7 +736,7 @@ WIN32ERROR rdpgfx_recv_surface_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
} }
} }
WLog_Print(gfx->log, WLOG_DEBUG, "RecvSurfaceToSurfacePdu: surfaceIdSrc: %d surfaceIdDest: %d " WLog_DBG(TAG, "RecvSurfaceToSurfacePdu: surfaceIdSrc: %d surfaceIdDest: %d "
"left: %d top: %d right: %d bottom: %d destPtsCount: %d", "left: %d top: %d right: %d bottom: %d destPtsCount: %d",
pdu.surfaceIdSrc, pdu.surfaceIdDest, pdu.surfaceIdSrc, pdu.surfaceIdDest,
pdu.rectSrc.left, pdu.rectSrc.top, pdu.rectSrc.right, pdu.rectSrc.bottom, pdu.rectSrc.left, pdu.rectSrc.top, pdu.rectSrc.right, pdu.rectSrc.bottom,
@ -773,7 +776,7 @@ WIN32ERROR rdpgfx_recv_surface_to_cache_pdu(RDPGFX_CHANNEL_CALLBACK* callback, w
return error; return error;
} }
WLog_Print(gfx->log, WLOG_DEBUG, "RecvSurfaceToCachePdu: surfaceId: %d cacheKey: 0x%08X cacheSlot: %d " WLog_DBG(TAG, "RecvSurfaceToCachePdu: surfaceId: %d cacheKey: 0x%08X cacheSlot: %d "
"left: %d top: %d right: %d bottom: %d", "left: %d top: %d right: %d bottom: %d",
pdu.surfaceId, (int) pdu.cacheKey, pdu.cacheSlot, pdu.surfaceId, (int) pdu.cacheKey, pdu.cacheSlot,
pdu.rectSrc.left, pdu.rectSrc.top, pdu.rectSrc.left, pdu.rectSrc.top,
@ -833,7 +836,7 @@ WIN32ERROR rdpgfx_recv_cache_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, w
} }
} }
WLog_Print(gfx->log, WLOG_DEBUG, "RdpGfxRecvCacheToSurfacePdu: cacheSlot: %d surfaceId: %d destPtsCount: %d", WLog_DBG(TAG, "RdpGfxRecvCacheToSurfacePdu: cacheSlot: %d surfaceId: %d destPtsCount: %d",
pdu.cacheSlot, (int) pdu.surfaceId, pdu.destPtsCount); pdu.cacheSlot, (int) pdu.surfaceId, pdu.destPtsCount);
if (context) if (context)
@ -866,7 +869,7 @@ WIN32ERROR rdpgfx_recv_map_surface_to_output_pdu(RDPGFX_CHANNEL_CALLBACK* callba
Stream_Read_UINT32(s, pdu.outputOriginX); /* outputOriginX (4 bytes) */ Stream_Read_UINT32(s, pdu.outputOriginX); /* outputOriginX (4 bytes) */
Stream_Read_UINT32(s, pdu.outputOriginY); /* outputOriginY (4 bytes) */ Stream_Read_UINT32(s, pdu.outputOriginY); /* outputOriginY (4 bytes) */
WLog_Print(gfx->log, WLOG_DEBUG, "RecvMapSurfaceToOutputPdu: surfaceId: %d outputOriginX: %d outputOriginY: %d", WLog_DBG(TAG, "RecvMapSurfaceToOutputPdu: surfaceId: %d outputOriginX: %d outputOriginY: %d",
(int) pdu.surfaceId, pdu.outputOriginX, pdu.outputOriginY); (int) pdu.surfaceId, pdu.outputOriginX, pdu.outputOriginY);
if (context) if (context)
@ -897,7 +900,7 @@ WIN32ERROR rdpgfx_recv_map_surface_to_window_pdu(RDPGFX_CHANNEL_CALLBACK* callba
Stream_Read_UINT32(s, pdu.mappedWidth); /* mappedWidth (4 bytes) */ Stream_Read_UINT32(s, pdu.mappedWidth); /* mappedWidth (4 bytes) */
Stream_Read_UINT32(s, pdu.mappedHeight); /* mappedHeight (4 bytes) */ Stream_Read_UINT32(s, pdu.mappedHeight); /* mappedHeight (4 bytes) */
WLog_Print(gfx->log, WLOG_DEBUG, "RecvMapSurfaceToWindowPdu: surfaceId: %d windowId: 0x%04X mappedWidth: %d mappedHeight: %d", WLog_DBG(TAG, "RecvMapSurfaceToWindowPdu: surfaceId: %d windowId: 0x%04X mappedWidth: %d mappedHeight: %d",
pdu.surfaceId, (int) pdu.windowId, pdu.mappedWidth, pdu.mappedHeight); pdu.surfaceId, (int) pdu.windowId, pdu.mappedWidth, pdu.mappedHeight);
if (context && context->MapSurfaceToWindow) if (context && context->MapSurfaceToWindow)
@ -926,7 +929,7 @@ WIN32ERROR rdpgfx_recv_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s)
} }
#if 1 #if 1
WLog_Print(gfx->log, WLOG_DEBUG, "cmdId: %s (0x%04X) flags: 0x%04X pduLength: %d", WLog_DBG(TAG, "cmdId: %s (0x%04X) flags: 0x%04X pduLength: %d",
rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId, header.flags, header.pduLength); rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId, header.flags, header.pduLength);
#endif #endif
@ -1077,9 +1080,6 @@ static WIN32ERROR rdpgfx_on_data_received(IWTSVirtualChannelCallback* pChannelCa
Stream_Free(s, TRUE); Stream_Free(s, TRUE);
//free(Stream_Buffer(data));
//Stream_Free(data,TRUE);
return error; return error;
} }
@ -1088,7 +1088,7 @@ static WIN32ERROR rdpgfx_on_open(IWTSVirtualChannelCallback* pChannelCallback)
RDPGFX_CHANNEL_CALLBACK* callback = (RDPGFX_CHANNEL_CALLBACK*) pChannelCallback; RDPGFX_CHANNEL_CALLBACK* callback = (RDPGFX_CHANNEL_CALLBACK*) pChannelCallback;
RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
WLog_Print(gfx->log, WLOG_DEBUG, "OnOpen"); WLog_DBG(TAG, "OnOpen");
return rdpgfx_send_caps_advertise_pdu(callback); return rdpgfx_send_caps_advertise_pdu(callback);
} }
@ -1098,7 +1098,7 @@ static WIN32ERROR rdpgfx_on_close(IWTSVirtualChannelCallback* pChannelCallback)
RDPGFX_CHANNEL_CALLBACK* callback = (RDPGFX_CHANNEL_CALLBACK*) pChannelCallback; RDPGFX_CHANNEL_CALLBACK* callback = (RDPGFX_CHANNEL_CALLBACK*) pChannelCallback;
RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
WLog_Print(gfx->log, WLOG_DEBUG, "OnClose"); WLog_DBG(TAG, "OnClose");
free(callback); free(callback);
@ -1155,7 +1155,7 @@ static WIN32ERROR rdpgfx_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChann
gfx->listener->pInterface = gfx->iface.pInterface; gfx->listener->pInterface = gfx->iface.pInterface;
WLog_Print(gfx->log, WLOG_DEBUG, "Initialize"); WLog_DBG(TAG, "Initialize");
return error; return error;
} }
@ -1169,7 +1169,7 @@ static WIN32ERROR rdpgfx_plugin_terminated(IWTSPlugin* pPlugin)
RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;
WIN32ERROR error = CHANNEL_RC_OK; WIN32ERROR error = CHANNEL_RC_OK;
WLog_Print(gfx->log, WLOG_DEBUG, "Terminated"); WLog_DBG(TAG, "Terminated");
if (gfx->listener_callback) if (gfx->listener_callback)
{ {
@ -1351,7 +1351,6 @@ WIN32ERROR DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
return CHANNEL_RC_NO_MEMORY; return CHANNEL_RC_NO_MEMORY;
} }
gfx->log = WLog_Get(TAG);
gfx->settings = (rdpSettings*) pEntryPoints->GetRdpSettings(pEntryPoints); gfx->settings = (rdpSettings*) pEntryPoints->GetRdpSettings(pEntryPoints);
gfx->iface.Initialize = rdpgfx_plugin_initialize; gfx->iface.Initialize = rdpgfx_plugin_initialize;
@ -1360,6 +1359,7 @@ WIN32ERROR DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
gfx->iface.Terminated = rdpgfx_plugin_terminated; gfx->iface.Terminated = rdpgfx_plugin_terminated;
gfx->SurfaceTable = HashTable_New(TRUE); gfx->SurfaceTable = HashTable_New(TRUE);
if (!gfx->SurfaceTable) if (!gfx->SurfaceTable)
{ {
free (gfx); free (gfx);

View File

@ -32,8 +32,6 @@
#include <freerdp/codec/zgfx.h> #include <freerdp/codec/zgfx.h>
#include <freerdp/freerdp.h> #include <freerdp/freerdp.h>
#define TAG CHANNELS_TAG("rdpgfx.client")
struct _RDPGFX_CHANNEL_CALLBACK struct _RDPGFX_CHANNEL_CALLBACK
{ {
IWTSVirtualChannelCallback iface; IWTSVirtualChannelCallback iface;
@ -61,7 +59,6 @@ struct _RDPGFX_PLUGIN
IWTSListener* listener; IWTSListener* listener;
RDPGFX_LISTENER_CALLBACK* listener_callback; RDPGFX_LISTENER_CALLBACK* listener_callback;
wLog* log;
rdpSettings* settings; rdpSettings* settings;
BOOL ThinClient; BOOL ThinClient;

View File

@ -77,7 +77,7 @@ typedef struct opensl_stream {
/* /*
* Set the volume input level. * Set the volume input level.
*/ */
void android_SetOutputVolume(OPENSL_STREAM *p, int level); void android_SetInputVolume(OPENSL_STREAM *p, int level);
/* /*
* Get the current output mute setting. * Get the current output mute setting.
*/ */

View File

@ -28,6 +28,7 @@
#include <string.h> #include <string.h>
#include <winpr/crt.h> #include <winpr/crt.h>
#include <winpr/string.h>
#include <winpr/cmdline.h> #include <winpr/cmdline.h>
#include <winpr/sysinfo.h> #include <winpr/sysinfo.h>
#include <winpr/collections.h> #include <winpr/collections.h>
@ -39,9 +40,9 @@
#include <limits.h> #include <limits.h>
#include <unistd.h> #include <unistd.h>
#if defined(__OpenBSD__) #if defined(__OpenBSD__)
#include <soundcard.h> #include <soundcard.h>
#else #else
#include <sys/soundcard.h> #include <sys/soundcard.h>
#endif #endif
#include <sys/ioctl.h> #include <sys/ioctl.h>
@ -53,7 +54,8 @@
typedef struct rdpsnd_oss_plugin rdpsndOssPlugin; typedef struct rdpsnd_oss_plugin rdpsndOssPlugin;
struct rdpsnd_oss_plugin { struct rdpsnd_oss_plugin
{
rdpsndDevicePlugin device; rdpsndDevicePlugin device;
int pcm_handle; int pcm_handle;
@ -65,68 +67,85 @@ struct rdpsnd_oss_plugin {
int latency; int latency;
AUDIO_FORMAT format; AUDIO_FORMAT format;
FREERDP_DSP_CONTEXT *dsp_context; FREERDP_DSP_CONTEXT* dsp_context;
}; };
#define OSS_LOG_ERR(_text, _error) \ #define OSS_LOG_ERR(_text, _error) \
if (_error != 0) \ { \
WLog_ERR(TAG, "%s: %i - %s", _text, _error, strerror(_error)); if (_error != 0) \
WLog_ERR(TAG, "%s: %i - %s", _text, _error, strerror(_error)); \
}
static int rdpsnd_oss_get_format(AUDIO_FORMAT *format) { static int rdpsnd_oss_get_format(AUDIO_FORMAT* format)
{
switch (format->wFormatTag)
{
case WAVE_FORMAT_PCM:
switch (format->wFormatTag) { switch (format->wBitsPerSample)
case WAVE_FORMAT_PCM: {
switch (format->wBitsPerSample) { case 8:
case 8: return AFMT_S8;
return AFMT_S8; case 16:
case 16: return AFMT_S16_LE;
return AFMT_S16_LE; }
}
break; break;
case WAVE_FORMAT_ALAW: case WAVE_FORMAT_ALAW:
return AFMT_A_LAW; return AFMT_A_LAW;
#if 0 /* This does not work on my desktop. */ #if 0 /* This does not work on my desktop. */
case WAVE_FORMAT_MULAW: case WAVE_FORMAT_MULAW:
return AFMT_MU_LAW; return AFMT_MU_LAW;
#endif #endif
case WAVE_FORMAT_ADPCM: case WAVE_FORMAT_ADPCM:
case WAVE_FORMAT_DVI_ADPCM: case WAVE_FORMAT_DVI_ADPCM:
return AFMT_S16_LE; return AFMT_S16_LE;
} }
return 0; return 0;
} }
static BOOL rdpsnd_oss_format_supported(rdpsndDevicePlugin *device, AUDIO_FORMAT *format) { static BOOL rdpsnd_oss_format_supported(rdpsndDevicePlugin* device, AUDIO_FORMAT* format)
{
int req_fmt = 0; int req_fmt = 0;
rdpsndOssPlugin *oss = (rdpsndOssPlugin*)device; rdpsndOssPlugin* oss = (rdpsndOssPlugin*)device;
if (device == NULL || format == NULL) if (device == NULL || format == NULL)
return FALSE; return FALSE;
switch (format->wFormatTag) { switch (format->wFormatTag)
case WAVE_FORMAT_PCM: {
if (format->cbSize != 0 || case WAVE_FORMAT_PCM:
format->nSamplesPerSec > 48000 ||
(format->wBitsPerSample != 8 && format->wBitsPerSample != 16) || if (format->cbSize != 0 ||
(format->nChannels != 1 && format->nChannels != 2)) format->nSamplesPerSec > 48000 ||
return FALSE; (format->wBitsPerSample != 8 && format->wBitsPerSample != 16) ||
break; (format->nChannels != 1 && format->nChannels != 2))
case WAVE_FORMAT_ADPCM: return FALSE;
case WAVE_FORMAT_DVI_ADPCM:
if (format->nSamplesPerSec > 48000 || break;
format->wBitsPerSample != 4 || case WAVE_FORMAT_ADPCM:
(format->nChannels != 1 && format->nChannels != 2)) case WAVE_FORMAT_DVI_ADPCM:
return FALSE;
break; if (format->nSamplesPerSec > 48000 ||
format->wBitsPerSample != 4 ||
(format->nChannels != 1 && format->nChannels != 2))
return FALSE;
break;
} }
req_fmt = rdpsnd_oss_get_format(format); req_fmt = rdpsnd_oss_get_format(format);
if (oss->pcm_handle != -1) { /* Check really supported formats by dev. */
/* Check really supported formats by dev. */
if (oss->pcm_handle != -1)
{
if ((req_fmt & oss->supported_formats) == 0) if ((req_fmt & oss->supported_formats) == 0)
return FALSE; return FALSE;
} else { }
else
{
if (req_fmt == 0) if (req_fmt == 0)
return FALSE; return FALSE;
} }
@ -134,17 +153,18 @@ static BOOL rdpsnd_oss_format_supported(rdpsndDevicePlugin *device, AUDIO_FORMAT
return TRUE; return TRUE;
} }
static BOOL rdpsnd_oss_set_format(rdpsndDevicePlugin *device, AUDIO_FORMAT *format, int latency) { static BOOL rdpsnd_oss_set_format(rdpsndDevicePlugin* device, AUDIO_FORMAT* format, int latency)
{
int tmp; int tmp;
rdpsndOssPlugin *oss = (rdpsndOssPlugin*)device; rdpsndOssPlugin* oss = (rdpsndOssPlugin*)device;
if (device == NULL || oss->pcm_handle == -1 || format == NULL) if (device == NULL || oss->pcm_handle == -1 || format == NULL)
return FALSE; return FALSE;
oss->latency = latency; oss->latency = latency;
CopyMemory(&(oss->format), format, sizeof(AUDIO_FORMAT)); CopyMemory(&(oss->format), format, sizeof(AUDIO_FORMAT));
tmp = rdpsnd_oss_get_format(format); tmp = rdpsnd_oss_get_format(format);
if (ioctl(oss->pcm_handle, SNDCTL_DSP_SETFMT, &tmp) == -1) if (ioctl(oss->pcm_handle, SNDCTL_DSP_SETFMT, &tmp) == -1)
{ {
OSS_LOG_ERR("SNDCTL_DSP_SETFMT failed", errno); OSS_LOG_ERR("SNDCTL_DSP_SETFMT failed", errno);
@ -152,6 +172,7 @@ static BOOL rdpsnd_oss_set_format(rdpsndDevicePlugin *device, AUDIO_FORMAT *form
} }
tmp = format->nChannels; tmp = format->nChannels;
if (ioctl(oss->pcm_handle, SNDCTL_DSP_CHANNELS, &tmp) == -1) if (ioctl(oss->pcm_handle, SNDCTL_DSP_CHANNELS, &tmp) == -1)
{ {
OSS_LOG_ERR("SNDCTL_DSP_CHANNELS failed", errno); OSS_LOG_ERR("SNDCTL_DSP_CHANNELS failed", errno);
@ -159,6 +180,7 @@ static BOOL rdpsnd_oss_set_format(rdpsndDevicePlugin *device, AUDIO_FORMAT *form
} }
tmp = format->nSamplesPerSec; tmp = format->nSamplesPerSec;
if (ioctl(oss->pcm_handle, SNDCTL_DSP_SPEED, &tmp) == -1) if (ioctl(oss->pcm_handle, SNDCTL_DSP_SPEED, &tmp) == -1)
{ {
OSS_LOG_ERR("SNDCTL_DSP_SPEED failed", errno); OSS_LOG_ERR("SNDCTL_DSP_SPEED failed", errno);
@ -166,6 +188,7 @@ static BOOL rdpsnd_oss_set_format(rdpsndDevicePlugin *device, AUDIO_FORMAT *form
} }
tmp = format->nBlockAlign; tmp = format->nBlockAlign;
if (ioctl(oss->pcm_handle, SNDCTL_DSP_SETFRAGMENT, &tmp) == -1) if (ioctl(oss->pcm_handle, SNDCTL_DSP_SETFRAGMENT, &tmp) == -1)
{ {
OSS_LOG_ERR("SNDCTL_DSP_SETFRAGMENT failed", errno); OSS_LOG_ERR("SNDCTL_DSP_SETFRAGMENT failed", errno);
@ -175,21 +198,26 @@ static BOOL rdpsnd_oss_set_format(rdpsndDevicePlugin *device, AUDIO_FORMAT *form
return TRUE; return TRUE;
} }
static void rdpsnd_oss_open_mixer(rdpsndOssPlugin *oss) { static void rdpsnd_oss_open_mixer(rdpsndOssPlugin* oss)
{
int devmask = 0; int devmask = 0;
char mixer[PATH_MAX] = "/dev/mixer"; char mixer_name[PATH_MAX] = "/dev/mixer";
if (oss->mixer_handle != -1) if (oss->mixer_handle != -1)
return; return;
if (oss->dev_unit != -1) if (oss->dev_unit != -1)
snprintf(mixer, PATH_MAX - 1, "/dev/mixer%i", oss->dev_unit); sprintf_s(mixer_name, PATH_MAX - 1, "/dev/mixer%i", oss->dev_unit);
if ((oss->mixer_handle = open(mixer, O_RDWR)) < 0) {
if ((oss->mixer_handle = open(mixer_name, O_RDWR)) < 0)
{
OSS_LOG_ERR("mixer open failed", errno); OSS_LOG_ERR("mixer open failed", errno);
oss->mixer_handle = -1; oss->mixer_handle = -1;
return; return;
} }
if (ioctl(oss->mixer_handle, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
if (ioctl(oss->mixer_handle, SOUND_MIXER_READ_DEVMASK, &devmask) == -1)
{
OSS_LOG_ERR("SOUND_MIXER_READ_DEVMASK failed", errno); OSS_LOG_ERR("SOUND_MIXER_READ_DEVMASK failed", errno);
close(oss->mixer_handle); close(oss->mixer_handle);
oss->mixer_handle = -1; oss->mixer_handle = -1;
@ -197,18 +225,21 @@ static void rdpsnd_oss_open_mixer(rdpsndOssPlugin *oss) {
} }
} }
static BOOL rdpsnd_oss_open(rdpsndDevicePlugin *device, AUDIO_FORMAT *format, int latency) { static BOOL rdpsnd_oss_open(rdpsndDevicePlugin* device, AUDIO_FORMAT* format, int latency)
{
char dev_name[PATH_MAX] = "/dev/dsp"; char dev_name[PATH_MAX] = "/dev/dsp";
rdpsndOssPlugin *oss = (rdpsndOssPlugin*)device; rdpsndOssPlugin* oss = (rdpsndOssPlugin*)device;
if (device == NULL || oss->pcm_handle != -1) if (device == NULL || oss->pcm_handle != -1)
return TRUE; return TRUE;
if (oss->dev_unit != -1) if (oss->dev_unit != -1)
snprintf(dev_name, PATH_MAX - 1, "/dev/dsp%i", oss->dev_unit); sprintf_s(dev_name, PATH_MAX - 1, "/dev/dsp%i", oss->dev_unit);
WLog_INFO(TAG, "open: %s", dev_name); WLog_INFO(TAG, "open: %s", dev_name);
if ((oss->pcm_handle = open(dev_name, O_WRONLY)) < 0) {
if ((oss->pcm_handle = open(dev_name, O_WRONLY)) < 0)
{
OSS_LOG_ERR("sound dev open failed", errno); OSS_LOG_ERR("sound dev open failed", errno);
oss->pcm_handle = -1; oss->pcm_handle = -1;
return FALSE; return FALSE;
@ -217,17 +248,22 @@ static BOOL rdpsnd_oss_open(rdpsndDevicePlugin *device, AUDIO_FORMAT *format, in
#if 0 /* FreeBSD OSS implementation at this moment (2015.03) does not set PCM_CAP_OUTPUT flag. */ #if 0 /* FreeBSD OSS implementation at this moment (2015.03) does not set PCM_CAP_OUTPUT flag. */
int mask = 0; int mask = 0;
if (ioctl(oss->pcm_handle, SNDCTL_DSP_GETCAPS, &mask) == -1) { if (ioctl(oss->pcm_handle, SNDCTL_DSP_GETCAPS, &mask) == -1)
{
OSS_LOG_ERR("SNDCTL_DSP_GETCAPS failed, try ignory", errno); OSS_LOG_ERR("SNDCTL_DSP_GETCAPS failed, try ignory", errno);
} else if ((mask & PCM_CAP_OUTPUT) == 0) { }
else if ((mask & PCM_CAP_OUTPUT) == 0)
{
OSS_LOG_ERR("Device does not supports playback", EOPNOTSUPP); OSS_LOG_ERR("Device does not supports playback", EOPNOTSUPP);
close(oss->pcm_handle); close(oss->pcm_handle);
oss->pcm_handle = -1; oss->pcm_handle = -1;
return; return;
} }
#endif #endif
if (ioctl(oss->pcm_handle, SNDCTL_DSP_GETFMTS, &oss->supported_formats) == -1) { if (ioctl(oss->pcm_handle, SNDCTL_DSP_GETFMTS, &oss->supported_formats) == -1)
{
OSS_LOG_ERR("SNDCTL_DSP_GETFMTS failed", errno); OSS_LOG_ERR("SNDCTL_DSP_GETFMTS failed", errno);
close(oss->pcm_handle); close(oss->pcm_handle);
oss->pcm_handle = -1; oss->pcm_handle = -1;
@ -240,41 +276,46 @@ static BOOL rdpsnd_oss_open(rdpsndDevicePlugin *device, AUDIO_FORMAT *format, in
return TRUE; return TRUE;
} }
static void rdpsnd_oss_close(rdpsndDevicePlugin *device) { static void rdpsnd_oss_close(rdpsndDevicePlugin* device)
rdpsndOssPlugin *oss = (rdpsndOssPlugin*)device; {
rdpsndOssPlugin* oss = (rdpsndOssPlugin*)device;
if (device == NULL) if (device == NULL)
return; return;
if (oss->pcm_handle != -1) { if (oss->pcm_handle != -1)
{
WLog_INFO(TAG, "close: dsp");
close(oss->pcm_handle); close(oss->pcm_handle);
oss->pcm_handle = -1; oss->pcm_handle = -1;
} }
if (oss->mixer_handle != -1) { if (oss->mixer_handle != -1)
{
WLog_INFO(TAG, "close: mixer");
close(oss->mixer_handle); close(oss->mixer_handle);
oss->mixer_handle = -1; oss->mixer_handle = -1;
} }
} }
static void rdpsnd_oss_free(rdpsndDevicePlugin *device) { static void rdpsnd_oss_free(rdpsndDevicePlugin* device)
rdpsndOssPlugin *oss = (rdpsndOssPlugin*)device; {
rdpsndOssPlugin* oss = (rdpsndOssPlugin*)device;
if (device == NULL) if (device == NULL)
return; return;
rdpsnd_oss_close(device); rdpsnd_oss_close(device);
freerdp_dsp_context_free(oss->dsp_context); freerdp_dsp_context_free(oss->dsp_context);
free(oss); free(oss);
} }
static UINT32 rdpsnd_oss_get_volume(rdpsndDevicePlugin *device) { static UINT32 rdpsnd_oss_get_volume(rdpsndDevicePlugin* device)
{
int vol; int vol;
UINT32 dwVolume; UINT32 dwVolume;
UINT16 dwVolumeLeft, dwVolumeRight; UINT16 dwVolumeLeft, dwVolumeRight;
rdpsndOssPlugin *oss = (rdpsndOssPlugin*)device; rdpsndOssPlugin* oss = (rdpsndOssPlugin*)device;
/* On error return 50% volume. */ /* On error return 50% volume. */
dwVolumeLeft = ((50 * 0xFFFF) / 100); /* 50% */ dwVolumeLeft = ((50 * 0xFFFF) / 100); /* 50% */
dwVolumeRight = ((50 * 0xFFFF) / 100); /* 50% */ dwVolumeRight = ((50 * 0xFFFF) / 100); /* 50% */
@ -283,7 +324,8 @@ static UINT32 rdpsnd_oss_get_volume(rdpsndDevicePlugin *device) {
if (device == NULL || oss->mixer_handle == -1) if (device == NULL || oss->mixer_handle == -1)
return dwVolume; return dwVolume;
if (ioctl(oss->mixer_handle, MIXER_READ(SOUND_MIXER_VOLUME), &vol) == -1) { if (ioctl(oss->mixer_handle, MIXER_READ(SOUND_MIXER_VOLUME), &vol) == -1)
{
OSS_LOG_ERR("MIXER_READ", errno); OSS_LOG_ERR("MIXER_READ", errno);
return dwVolume; return dwVolume;
} }
@ -291,30 +333,32 @@ static UINT32 rdpsnd_oss_get_volume(rdpsndDevicePlugin *device) {
dwVolumeLeft = (((vol & 0x7f) * 0xFFFF) / 100); dwVolumeLeft = (((vol & 0x7f) * 0xFFFF) / 100);
dwVolumeRight = ((((vol >> 8) & 0x7f) * 0xFFFF) / 100); dwVolumeRight = ((((vol >> 8) & 0x7f) * 0xFFFF) / 100);
dwVolume = ((dwVolumeLeft << 16) | dwVolumeRight); dwVolume = ((dwVolumeLeft << 16) | dwVolumeRight);
return dwVolume; return dwVolume;
} }
static BOOL rdpsnd_oss_set_volume(rdpsndDevicePlugin *device, UINT32 value) { static BOOL rdpsnd_oss_set_volume(rdpsndDevicePlugin* device, UINT32 value)
{
int left, right; int left, right;
rdpsndOssPlugin *oss = (rdpsndOssPlugin*)device; rdpsndOssPlugin* oss = (rdpsndOssPlugin*)device;
if (device == NULL || oss->mixer_handle == -1) if (device == NULL || oss->mixer_handle == -1)
return FALSE; return FALSE;
left = (value & 0xFFFF); left = (((value & 0xFFFF) * 100) / 0xFFFF);
right = ((value >> 16) & 0xFFFF); right = ((((value >> 16) & 0xFFFF) * 100) / 0xFFFF);
if (left < 0) if (left < 0)
left = 0; left = 0;
else if (left > 100) else if (left > 100)
left = 100; left = 100;
if (right < 0) if (right < 0)
right = 0; right = 0;
else if (right > 100) else if (right > 100)
right = 100; right = 100;
left |= (right << 8); left |= (right << 8);
if (ioctl(oss->mixer_handle, MIXER_WRITE(SOUND_MIXER_VOLUME), &left) == -1) if (ioctl(oss->mixer_handle, MIXER_WRITE(SOUND_MIXER_VOLUME), &left) == -1)
{ {
OSS_LOG_ERR("WRITE_MIXER", errno); OSS_LOG_ERR("WRITE_MIXER", errno);
@ -324,45 +368,36 @@ static BOOL rdpsnd_oss_set_volume(rdpsndDevicePlugin *device, UINT32 value) {
return TRUE; return TRUE;
} }
static BOOL rdpsnd_oss_wave_decode(rdpsndDevicePlugin *device, RDPSND_WAVE *wave) { static BOOL rdpsnd_oss_wave_decode(rdpsndDevicePlugin* device, RDPSND_WAVE* wave)
int size; {
BYTE *data; rdpsndOssPlugin* oss = (rdpsndOssPlugin*)device;
rdpsndOssPlugin *oss = (rdpsndOssPlugin*)device;
if (device == NULL || wave == NULL) if (device == NULL || wave == NULL)
return FALSE; return FALSE;
switch (oss->format.wFormatTag) { switch (oss->format.wFormatTag)
case WAVE_FORMAT_ADPCM: {
oss->dsp_context->decode_ms_adpcm(oss->dsp_context, case WAVE_FORMAT_ADPCM:
wave->data, wave->length, oss->format.nChannels, oss->format.nBlockAlign); oss->dsp_context->decode_ms_adpcm(oss->dsp_context,
size = oss->dsp_context->adpcm_size; wave->data, wave->length, oss->format.nChannels, oss->format.nBlockAlign);
data = oss->dsp_context->adpcm_buffer; wave->length = oss->dsp_context->adpcm_size;
break; wave->data = oss->dsp_context->adpcm_buffer;
case WAVE_FORMAT_DVI_ADPCM: break;
oss->dsp_context->decode_ima_adpcm(oss->dsp_context, case WAVE_FORMAT_DVI_ADPCM:
wave->data, wave->length, oss->format.nChannels, oss->format.nBlockAlign); oss->dsp_context->decode_ima_adpcm(oss->dsp_context,
size = oss->dsp_context->adpcm_size; wave->data, wave->length, oss->format.nChannels, oss->format.nBlockAlign);
data = oss->dsp_context->adpcm_buffer; wave->length = oss->dsp_context->adpcm_size;
break; wave->data = oss->dsp_context->adpcm_buffer;
default: break;
size = wave->length;
data = wave->data;
} }
wave->data = (BYTE*)malloc(size);
if (!wave->data)
return FALSE;
CopyMemory(wave->data, data, size);
wave->length = size;
return TRUE; return TRUE;
} }
static void rdpsnd_oss_wave_play(rdpsndDevicePlugin *device, RDPSND_WAVE *wave) { static void rdpsnd_oss_wave_play(rdpsndDevicePlugin* device, RDPSND_WAVE* wave)
BYTE *data; {
int offset, size, status; BYTE* data;
rdpsndOssPlugin *oss = (rdpsndOssPlugin*)device; int offset, size, status, latency;
rdpsndOssPlugin* oss = (rdpsndOssPlugin*)device;
if (device == NULL || wave == NULL) if (device == NULL || wave == NULL)
return; return;
@ -370,64 +405,72 @@ static void rdpsnd_oss_wave_play(rdpsndDevicePlugin *device, RDPSND_WAVE *wave)
offset = 0; offset = 0;
data = wave->data; data = wave->data;
size = wave->length; size = wave->length;
latency = oss->latency;
while (offset < size) { while (offset < size)
{
status = write(oss->pcm_handle, &data[offset], (size - offset)); status = write(oss->pcm_handle, &data[offset], (size - offset));
if (status < 0) {
if (status < 0)
{
OSS_LOG_ERR("write fail", errno); OSS_LOG_ERR("write fail", errno);
rdpsnd_oss_close(device); rdpsnd_oss_close(device);
rdpsnd_oss_open(device, NULL, 0); rdpsnd_oss_open(device, NULL, latency);
break; break;
} }
offset += status; offset += status;
} }
/* From rdpsnd_main.c */
wave->wTimeStampB = wave->wTimeStampA + wave->wAudioLength + 65;
wave->wLocalTimeB = wave->wLocalTimeA + wave->wAudioLength + 65;
free(data); /* From rdpsnd_main.c */
wave->wTimeStampB = wave->wTimeStampA + wave->wAudioLength + 65 + latency;
wave->wLocalTimeB = wave->wLocalTimeA + wave->wAudioLength + 65 + latency;
} }
static COMMAND_LINE_ARGUMENT_A rdpsnd_oss_args[] = { static COMMAND_LINE_ARGUMENT_A rdpsnd_oss_args[] =
{
{ "dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "device" }, { "dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "device" },
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
}; };
static int rdpsnd_oss_parse_addin_args(rdpsndDevicePlugin *device, ADDIN_ARGV *args) { static int rdpsnd_oss_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV* args)
{
int status; int status;
char *str_num, *eptr; char* str_num, *eptr;
DWORD flags; DWORD flags;
COMMAND_LINE_ARGUMENT_A *arg; COMMAND_LINE_ARGUMENT_A* arg;
rdpsndOssPlugin *oss = (rdpsndOssPlugin*)device; rdpsndOssPlugin* oss = (rdpsndOssPlugin*)device;
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_IGN_UNKNOWN_KEYWORD; flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_IGN_UNKNOWN_KEYWORD;
status = CommandLineParseArgumentsA(args->argc, (const char**)args->argv, rdpsnd_oss_args, flags, oss, NULL, NULL); status = CommandLineParseArgumentsA(args->argc, (const char**)args->argv, rdpsnd_oss_args, flags, oss, NULL, NULL);
if (status < 0) if (status < 0)
return status; return status;
arg = rdpsnd_oss_args; arg = rdpsnd_oss_args;
do { do
{
if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT)) if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
continue; continue;
CommandLineSwitchStart(arg) CommandLineSwitchStart(arg)
CommandLineSwitchCase(arg, "dev")
CommandLineSwitchCase(arg, "dev") { {
str_num = _strdup(arg->Value); str_num = _strdup(arg->Value);
if (!str_num) if (!str_num)
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
oss->dev_unit = strtol(str_num, &eptr, 10); oss->dev_unit = strtol(str_num, &eptr, 10);
if (oss->dev_unit < 0 || *eptr != '\0') if (oss->dev_unit < 0 || *eptr != '\0')
oss->dev_unit = -1; oss->dev_unit = -1;
free(str_num); free(str_num);
} }
CommandLineSwitchEnd(arg) CommandLineSwitchEnd(arg)
} while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); }
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
return status; return status;
} }
@ -436,14 +479,13 @@ static int rdpsnd_oss_parse_addin_args(rdpsndDevicePlugin *device, ADDIN_ARGV *a
#define freerdp_rdpsnd_client_subsystem_entry oss_freerdp_rdpsnd_client_subsystem_entry #define freerdp_rdpsnd_client_subsystem_entry oss_freerdp_rdpsnd_client_subsystem_entry
#endif #endif
WIN32ERROR freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints) { WIN32ERROR freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints)
ADDIN_ARGV *args; {
rdpsndOssPlugin *oss; ADDIN_ARGV* args;
rdpsndOssPlugin* oss;
oss = (rdpsndOssPlugin*)calloc(1, sizeof(rdpsndOssPlugin)); oss = (rdpsndOssPlugin*)calloc(1, sizeof(rdpsndOssPlugin));
if (!oss) if (!oss)
return CHANNEL_RC_NO_MEMORY; return CHANNEL_RC_NO_MEMORY;
oss->device.Open = rdpsnd_oss_open; oss->device.Open = rdpsnd_oss_open;
oss->device.FormatSupported = rdpsnd_oss_format_supported; oss->device.FormatSupported = rdpsnd_oss_format_supported;
oss->device.SetFormat = rdpsnd_oss_set_format; oss->device.SetFormat = rdpsnd_oss_set_format;
@ -453,14 +495,11 @@ WIN32ERROR freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_PO
oss->device.WavePlay = rdpsnd_oss_wave_play; oss->device.WavePlay = rdpsnd_oss_wave_play;
oss->device.Close = rdpsnd_oss_close; oss->device.Close = rdpsnd_oss_close;
oss->device.Free = rdpsnd_oss_free; oss->device.Free = rdpsnd_oss_free;
oss->pcm_handle = -1; oss->pcm_handle = -1;
oss->mixer_handle = -1; oss->mixer_handle = -1;
oss->dev_unit = -1; oss->dev_unit = -1;
args = pEntryPoints->args; args = pEntryPoints->args;
rdpsnd_oss_parse_addin_args((rdpsndDevicePlugin*)oss, args); rdpsnd_oss_parse_addin_args((rdpsndDevicePlugin*)oss, args);
oss->dsp_context = freerdp_dsp_context_new(); oss->dsp_context = freerdp_dsp_context_new();
if (!oss->dsp_context) if (!oss->dsp_context)
{ {

View File

@ -40,7 +40,7 @@ RemdeskClientContext* remdesk_get_client_interface(remdeskPlugin* remdesk)
return pInterface; return pInterface;
} }
WIN32ERROR remdesk_virtual_channel_write(remdeskPlugin* remdesk, wStream* s) static WIN32ERROR remdesk_virtual_channel_write(remdeskPlugin* remdesk, wStream* s)
{ {
UINT32 status; UINT32 status;

View File

@ -29,7 +29,7 @@
#include "remdesk_main.h" #include "remdesk_main.h"
WIN32ERROR remdesk_virtual_channel_write(RemdeskServerContext* context, wStream* s) static WIN32ERROR remdesk_virtual_channel_write(RemdeskServerContext* context, wStream* s)
{ {
BOOL status; BOOL status;
ULONG BytesWritten = 0; ULONG BytesWritten = 0;

View File

@ -62,6 +62,10 @@ if(WITH_GSTREAMER_0_10 OR WITH_GSTREAMER_1_0)
endif() endif()
endif() endif()
if(WITH_OSS)
add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "oss" "audio")
endif()
if(WITH_ALSA) if(WITH_ALSA)
add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "alsa" "audio") add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "alsa" "audio")
endif() endif()

View File

@ -68,8 +68,7 @@ static BOOL tsmf_alsa_open(ITSMFAudioDevice *audio, const char *device)
TSMFAlsaAudioDevice *alsa = (TSMFAlsaAudioDevice *) audio; TSMFAlsaAudioDevice *alsa = (TSMFAlsaAudioDevice *) audio;
if(!device) if(!device)
{ {
if(!alsa->device[0]) strncpy(alsa->device, "default", sizeof(alsa->device));
strncpy(alsa->device, "default", sizeof(alsa->device));
} }
else else
{ {

View File

@ -25,7 +25,11 @@
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <string.h>
#include <err.h>
#include <errno.h>
#include <winpr/thread.h> #include <winpr/thread.h>
#include <winpr/string.h>
#include <gst/gst.h> #include <gst/gst.h>
#if GST_VERSION_MAJOR > 0 #if GST_VERSION_MAJOR > 0
@ -61,8 +65,8 @@ struct X11Handle
static const char* get_shm_id() static const char* get_shm_id()
{ {
static char shm_id[64]; static char shm_id[128];
snprintf(shm_id, sizeof(shm_id), "com.freerdp.xfreerdp.tsmf_%016X", GetCurrentProcessId()); sprintf_s(shm_id, sizeof(shm_id), "/com.freerdp.xfreerdp.tsmf_%016X", GetCurrentProcessId());
return shm_id; return shm_id;
} }
@ -87,7 +91,6 @@ int tsmf_platform_create(TSMFGstreamerDecoder* decoder)
return -1; return -1;
hdl = calloc(1, sizeof(struct X11Handle)); hdl = calloc(1, sizeof(struct X11Handle));
if (!hdl) if (!hdl)
{ {
WLog_ERR(TAG, "Could not allocate handle."); WLog_ERR(TAG, "Could not allocate handle.");
@ -95,26 +98,21 @@ int tsmf_platform_create(TSMFGstreamerDecoder* decoder)
} }
decoder->platform = hdl; decoder->platform = hdl;
hdl->shmid = shm_open(get_shm_id(), O_RDWR, PROT_READ | PROT_WRITE);; hdl->shmid = shm_open(get_shm_id(), (O_RDWR | O_CREAT), (PROT_READ | PROT_WRITE));
if (hdl->shmid == -1)
if (hdl->shmid < 0)
{ {
WLog_ERR(TAG, "failed to get access to shared memory - shmget()"); WLog_ERR(TAG, "failed to get access to shared memory - shmget(%s): %i - %s", get_shm_id(), errno, strerror(errno));
return -2; return -2;
} }
else
{
hdl->xfwin = mmap(0, sizeof(void *), PROT_READ | PROT_WRITE, MAP_SHARED, hdl->shmid, 0);
}
if (hdl->xfwin == (int*)-1) hdl->xfwin = mmap(0, sizeof(void *), PROT_READ | PROT_WRITE, MAP_SHARED, hdl->shmid, 0);
if (hdl->xfwin == MAP_FAILED)
{ {
WLog_ERR(TAG, "shmat failed!"); WLog_ERR(TAG, "shmat failed!");
return -3; return -3;
} }
hdl->disp = XOpenDisplay(NULL); hdl->disp = XOpenDisplay(NULL);
if (!hdl->disp) if (!hdl->disp)
{ {
WLog_ERR(TAG, "Failed to open display"); WLog_ERR(TAG, "Failed to open display");

View File

@ -31,6 +31,8 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <winpr/string.h>
#include <gst/gst.h> #include <gst/gst.h>
#include <gst/app/gstappsrc.h> #include <gst/app/gstappsrc.h>
#include <gst/app/gstappsink.h> #include <gst/app/gstappsink.h>
@ -422,9 +424,9 @@ BOOL tsmf_gstreamer_pipeline_build(TSMFGstreamerDecoder* mdecoder)
* The only fixed elements necessary are appsrc and the volume element for audio streams. * The only fixed elements necessary are appsrc and the volume element for audio streams.
* The rest could easily be provided in gstreamer pipeline notation from command line. */ * The rest could easily be provided in gstreamer pipeline notation from command line. */
if (mdecoder->media_type == TSMF_MAJOR_TYPE_VIDEO) if (mdecoder->media_type == TSMF_MAJOR_TYPE_VIDEO)
snprintf(pipeline, sizeof(pipeline), "%s %s %s name=outsink", appsrc, video, tsmf_platform_get_video_sink()); sprintf_s(pipeline, sizeof(pipeline), "%s %s %s name=outsink", appsrc, video, tsmf_platform_get_video_sink());
else else
snprintf(pipeline, sizeof(pipeline), "%s %s %s name=outsink", appsrc, audio, tsmf_platform_get_audio_sink()); sprintf_s(pipeline, sizeof(pipeline), "%s %s %s name=outsink", appsrc, audio, tsmf_platform_get_audio_sink());
DEBUG_TSMF("pipeline=%s", pipeline); DEBUG_TSMF("pipeline=%s", pipeline);
mdecoder->pipe = gst_parse_launch(pipeline, NULL); mdecoder->pipe = gst_parse_launch(pipeline, NULL);

View File

@ -0,0 +1,32 @@
# FreeRDP: A Remote Desktop Protocol Implementation
# FreeRDP cmake build script
#
# Copyright (c) 2015 Rozhuk Ivan <rozhuk.im@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.
define_channel_client_subsystem("tsmf" "oss" "audio")
set(${MODULE_PREFIX}_SRCS
tsmf_oss.c)
include_directories(..)
include_directories(${OSS_INCLUDE_DIRS})
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
target_link_libraries(${MODULE_NAME} freerdp ${OSS_LIBRARIES})
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)

View File

@ -0,0 +1,251 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Video Redirection Virtual Channel - OSS Audio Device
*
* Copyright (c) 2015 Rozhuk Ivan <rozhuk.im@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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <winpr/crt.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <libgen.h>
#include <limits.h>
#include <unistd.h>
#include <sys/soundcard.h>
#include <sys/ioctl.h>
#include <freerdp/types.h>
#include <freerdp/codec/dsp.h>
#include "tsmf_audio.h"
typedef struct _TSMFOSSAudioDevice
{
ITSMFAudioDevice iface;
char dev_name[PATH_MAX];
int pcm_handle;
UINT32 sample_rate;
UINT32 channels;
UINT32 bits_per_sample;
UINT32 data_size_last;
} TSMFOssAudioDevice;
#define OSS_LOG_ERR(_text, _error) \
if (_error != 0) \
WLog_ERR(TAG, "%s: %i - %s", _text, _error, strerror(_error));
static BOOL tsmf_oss_open(ITSMFAudioDevice* audio, const char* device)
{
int tmp;
TSMFOssAudioDevice* oss = (TSMFOssAudioDevice*)audio;
if (oss == NULL || oss->pcm_handle != -1)
return FALSE;
if (device == NULL) /* Default device. */
{
strncpy(oss->dev_name, "/dev/dsp", sizeof(oss->dev_name));
}
else
{
strncpy(oss->dev_name, device, sizeof(oss->dev_name));
}
if ((oss->pcm_handle = open(oss->dev_name, O_WRONLY)) < 0)
{
OSS_LOG_ERR("sound dev open failed", errno);
oss->pcm_handle = -1;
return FALSE;
}
#if 0 /* FreeBSD OSS implementation at this moment (2015.03) does not set PCM_CAP_OUTPUT flag. */
tmp = 0;
if (ioctl(oss->pcm_handle, SNDCTL_DSP_GETCAPS, &mask) == -1)
{
OSS_LOG_ERR("SNDCTL_DSP_GETCAPS failed, try ignory", errno);
}
else if ((mask & PCM_CAP_OUTPUT) == 0)
{
OSS_LOG_ERR("Device does not supports playback", EOPNOTSUPP);
close(oss->pcm_handle);
oss->pcm_handle = -1;
return FALSE;
}
#endif
tmp = 0;
if (ioctl(oss->pcm_handle, SNDCTL_DSP_GETFMTS, &tmp) == -1)
{
OSS_LOG_ERR("SNDCTL_DSP_GETFMTS failed", errno);
close(oss->pcm_handle);
oss->pcm_handle = -1;
return FALSE;
}
if ((AFMT_S16_LE & tmp) == 0)
{
OSS_LOG_ERR("SNDCTL_DSP_GETFMTS - AFMT_S16_LE", EOPNOTSUPP);
close(oss->pcm_handle);
oss->pcm_handle = -1;
return FALSE;
}
WLog_INFO(TAG, "open: %s", oss->dev_name);
return TRUE;
}
static BOOL tsmf_oss_set_format(ITSMFAudioDevice* audio, UINT32 sample_rate, UINT32 channels, UINT32 bits_per_sample)
{
int tmp;
TSMFOssAudioDevice* oss = (TSMFOssAudioDevice*)audio;
if (oss == NULL || oss->pcm_handle == -1)
return FALSE;
oss->sample_rate = sample_rate;
oss->channels = channels;
oss->bits_per_sample = bits_per_sample;
tmp = AFMT_S16_LE;
if (ioctl(oss->pcm_handle, SNDCTL_DSP_SETFMT, &tmp) == -1)
OSS_LOG_ERR("SNDCTL_DSP_SETFMT failed", errno);
tmp = channels;
if (ioctl(oss->pcm_handle, SNDCTL_DSP_CHANNELS, &tmp) == -1)
OSS_LOG_ERR("SNDCTL_DSP_CHANNELS failed", errno);
tmp = sample_rate;
if (ioctl(oss->pcm_handle, SNDCTL_DSP_SPEED, &tmp) == -1)
OSS_LOG_ERR("SNDCTL_DSP_SPEED failed", errno);
tmp = ((bits_per_sample / 8) * channels * sample_rate);
if (ioctl(oss->pcm_handle, SNDCTL_DSP_SETFRAGMENT, &tmp) == -1)
OSS_LOG_ERR("SNDCTL_DSP_SETFRAGMENT failed", errno);
DEBUG_TSMF("sample_rate %d channels %d bits_per_sample %d",
sample_rate, channels, bits_per_sample);
return TRUE;
}
static BOOL tsmf_oss_play(ITSMFAudioDevice* audio, BYTE* data, UINT32 data_size)
{
int status;
UINT32 offset;
TSMFOssAudioDevice* oss = (TSMFOssAudioDevice*)audio;
DEBUG_TSMF("tsmf_oss_play: data_size %d", data_size);
if (oss == NULL || oss->pcm_handle == -1)
return FALSE;
if (data == NULL || data_size == 0)
{
free(data);
return TRUE;
}
offset = 0;
oss->data_size_last = data_size;
while (offset < data_size)
{
status = write(oss->pcm_handle, &data[offset], (data_size - offset));
if (status < 0)
{
OSS_LOG_ERR("write fail", errno);
free(data);
return FALSE;
}
offset += status;
}
free(data);
return TRUE;
}
static UINT64 tsmf_oss_get_latency(ITSMFAudioDevice* audio)
{
UINT64 latency = 0;
TSMFOssAudioDevice* oss = (TSMFOssAudioDevice*)audio;
if (oss == NULL)
return 0;
//latency = ((oss->data_size_last / (oss->bits_per_sample / 8)) * oss->sample_rate);
//WLog_INFO(TAG, "latency: %zu", latency);
return latency;
}
static void tsmf_oss_flush(ITSMFAudioDevice* audio)
{
}
static void tsmf_oss_free(ITSMFAudioDevice* audio)
{
TSMFOssAudioDevice* oss = (TSMFOssAudioDevice*)audio;
if (oss == NULL)
return;
if (oss->pcm_handle != -1)
{
WLog_INFO(TAG, "close: %s", oss->dev_name);
close(oss->pcm_handle);
}
free(oss);
}
#ifdef STATIC_CHANNELS
#define freerdp_tsmf_client_audio_subsystem_entry oss_freerdp_tsmf_client_audio_subsystem_entry
#endif
ITSMFAudioDevice* freerdp_tsmf_client_audio_subsystem_entry(void)
{
TSMFOssAudioDevice* oss;
oss = (TSMFOssAudioDevice*)malloc(sizeof(TSMFOssAudioDevice));
ZeroMemory(oss, sizeof(TSMFOssAudioDevice));
oss->iface.Open = tsmf_oss_open;
oss->iface.SetFormat = tsmf_oss_set_format;
oss->iface.Play = tsmf_oss_play;
oss->iface.GetLatency = tsmf_oss_get_latency;
oss->iface.Flush = tsmf_oss_flush;
oss->iface.Free = tsmf_oss_free;
oss->pcm_handle = -1;
return (ITSMFAudioDevice*)oss;
}

View File

@ -49,6 +49,11 @@ static ITSMFAudioDevice* tsmf_load_audio_device_by_name(const char* name, const
{ {
audio->Free(audio); audio->Free(audio);
audio = NULL; audio = NULL;
WLog_ERR(TAG, "failed to open, name: %s, device: %s", name, device);
}
else
{
WLog_DBG(TAG, "name: %s, device: %s", name, device);
} }
return audio; return audio;
@ -56,7 +61,7 @@ static ITSMFAudioDevice* tsmf_load_audio_device_by_name(const char* name, const
ITSMFAudioDevice* tsmf_load_audio_device(const char* name, const char* device) ITSMFAudioDevice* tsmf_load_audio_device(const char* name, const char* device)
{ {
ITSMFAudioDevice* audio; ITSMFAudioDevice* audio = NULL;
if (name) if (name)
{ {
@ -64,10 +69,29 @@ ITSMFAudioDevice* tsmf_load_audio_device(const char* name, const char* device)
} }
else else
{ {
audio = tsmf_load_audio_device_by_name("pulse", device); #if defined(WITH_PULSE)
if (!audio)
audio = tsmf_load_audio_device_by_name("pulse", device);
#endif
#if defined(WITH_OSS)
if (!audio)
audio = tsmf_load_audio_device_by_name("oss", device);
#endif
#if defined(WITH_ALSA)
if (!audio) if (!audio)
audio = tsmf_load_audio_device_by_name("alsa", device); audio = tsmf_load_audio_device_by_name("alsa", device);
#endif
}
if (audio == NULL)
{
WLog_ERR(TAG, "no sound device.");
}
else
{
WLog_DBG(TAG, "name: %s, device: %s", name, device);
} }
return audio; return audio;

View File

@ -399,8 +399,8 @@ static WIN32ERROR tsmf_plugin_terminated(IWTSPlugin* pPlugin)
COMMAND_LINE_ARGUMENT_A tsmf_args[] = COMMAND_LINE_ARGUMENT_A tsmf_args[] =
{ {
{ "audio", COMMAND_LINE_VALUE_REQUIRED, "<subsystem>", NULL, NULL, -1, NULL, "audio subsystem" }, { "sys", COMMAND_LINE_VALUE_REQUIRED, "<subsystem>", NULL, NULL, -1, NULL, "audio subsystem" },
{ "audio-dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "audio device name" }, { "dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "audio device name" },
{ "decoder", COMMAND_LINE_VALUE_REQUIRED, "<subsystem>", NULL, NULL, -1, NULL, "decoder subsystem" }, { "decoder", COMMAND_LINE_VALUE_REQUIRED, "<subsystem>", NULL, NULL, -1, NULL, "decoder subsystem" },
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
}; };
@ -426,13 +426,13 @@ static WIN32ERROR tsmf_process_addin_args(IWTSPlugin *pPlugin, ADDIN_ARGV *args)
if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT)) if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
continue; continue;
CommandLineSwitchStart(arg) CommandLineSwitchStart(arg)
CommandLineSwitchCase(arg, "audio") CommandLineSwitchCase(arg, "sys")
{ {
tsmf->audio_name = _strdup(arg->Value); tsmf->audio_name = _strdup(arg->Value);
if (!tsmf->audio_name) if (!tsmf->audio_name)
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
} }
CommandLineSwitchCase(arg, "audio-dev") CommandLineSwitchCase(arg, "dev")
{ {
tsmf->audio_device = _strdup(arg->Value); tsmf->audio_device = _strdup(arg->Value);
if (!tsmf->audio_device) if (!tsmf->audio_device)

View File

@ -39,6 +39,7 @@
#include <winpr/crt.h> #include <winpr/crt.h>
#include <winpr/synch.h> #include <winpr/synch.h>
#include <winpr/string.h>
#include <winpr/thread.h> #include <winpr/thread.h>
#include <winpr/stream.h> #include <winpr/stream.h>
#include <winpr/collections.h> #include <winpr/collections.h>
@ -320,7 +321,7 @@ static char* guid_to_string(const BYTE* guid, char* str, size_t len)
return NULL; return NULL;
for (i=0; i<GUID_SIZE && len > 2*i; i++) for (i=0; i<GUID_SIZE && len > 2*i; i++)
snprintf(str + (2*i), len - 2*i, "%02X", guid[i]); sprintf_s(str + (2*i), len - 2*i, "%02X", guid[i]);
return str; return str;
} }
@ -397,10 +398,10 @@ static BOOL tsmf_sample_playback_video(TSMF_SAMPLE* sample)
if ((frame_id % 30) == 0) if ((frame_id % 30) == 0)
{ {
snprintf(buf, sizeof(buf), "/tmp/FreeRDP_Frame_%d.ppm", frame_id); sprintf_s(buf, sizeof(buf), "/tmp/FreeRDP_Frame_%d.ppm", frame_id);
fp = fopen(buf, "wb"); fp = fopen(buf, "wb");
fwrite("P5\n", 1, 3, fp); fwrite("P5\n", 1, 3, fp);
snprintf(buf, sizeof(buf), "%d %d\n", sample->stream->width, sample->stream->height); sprintf_s(buf, sizeof(buf), "%d %d\n", sample->stream->width, sample->stream->height);
fwrite(buf, 1, strlen(buf), fp); fwrite(buf, 1, strlen(buf), fp);
fwrite("255\n", 1, 4, fp); fwrite("255\n", 1, 4, fp);
fwrite(sample->data, 1, sample->stream->width * sample->stream->height, fp); fwrite(sample->data, 1, sample->stream->width * sample->stream->height, fp);
@ -432,13 +433,13 @@ static BOOL tsmf_sample_playback_audio(TSMF_SAMPLE* sample)
DEBUG_TSMF("MessageId %d EndTime %d consumed.", DEBUG_TSMF("MessageId %d EndTime %d consumed.",
sample->sample_id, (int)sample->end_time); sample->sample_id, (int)sample->end_time);
if (sample->stream->audio && sample->data) if (stream->audio && sample->data)
{ {
ret = sample->stream->audio->Play(sample->stream->audio, sample->data, sample->decoded_size); ret = sample->stream->audio->Play(sample->stream->audio, sample->data, sample->decoded_size);
sample->data = NULL; sample->data = NULL;
sample->decoded_size = 0; sample->decoded_size = 0;
if (stream->audio && stream->audio->GetLatency) if (stream->audio->GetLatency)
latency = stream->audio->GetLatency(stream->audio); latency = stream->audio->GetLatency(stream->audio);
} }
else else

View File

@ -18,15 +18,28 @@
define_channel("urbdrc") define_channel("urbdrc")
if(NOT WIN32) if(NOT WIN32)
find_package(DevD)
find_package(UDev) find_package(UDev)
find_package(UUID) find_package(UUID)
find_package(DbusGlib) find_package(DbusGlib)
find_package(libusb-1.0) find_package(libusb-1.0)
endif() endif()
if(UDEV_FOUND AND UUID_FOUND AND DBUS_GLIB_FOUND AND LIBUSB_1_FOUND) if(DEVD_FOUND OR UDEV_FOUND)
set(URBDRC_DEPENDENCIES_FOUND TRUE) if(UUID_FOUND AND DBUS_GLIB_FOUND AND LIBUSB_1_FOUND)
message(STATUS "Found all URBDRC dependencies") set(URBDRC_DEPENDENCIES_FOUND TRUE)
message(STATUS "Found all URBDRC dependencies")
else()
if(NOT UUID_FOUND)
message(STATUS "URBDRC dependencie not found: UUID")
endif()
if(NOT DBUS_GLIB_FOUND)
message(STATUS "URBDRC dependencie not found: DBUS_GLIB")
endif()
if(NOT LIBUSB_1_FOUND)
message(STATUS "URBDRC dependencie not found: LIBUSB_1")
endif()
endif()
endif() endif()
if(WITH_CLIENT_CHANNELS) if(WITH_CLIENT_CHANNELS)

View File

@ -39,8 +39,10 @@ add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE
set(${MODULE_PREFIX}_LIBS set(${MODULE_PREFIX}_LIBS
${DBUS_GLIB_LIBRARIES} ${DBUS_GLIB_LIBRARIES}
${UDEV_LIBRARIES}
${UUID_LIBRARIES}) ${UUID_LIBRARIES})
if (UDEV_FOUND AND UDEV_LIBRARIES)
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${UDEV_LIBRARIES})
endif()
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} winpr freerdp) set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} winpr freerdp)

View File

@ -1285,7 +1285,7 @@ static int urb_os_feature_descriptor_request(URBDRC_CHANNEL_CALLBACK * callback,
data_read_UINT32(data + 0, RequestId); data_read_UINT32(data + 0, RequestId);
data_read_BYTE(data + 4, Recipient); /** Recipient */ data_read_BYTE(data + 4, Recipient); /** Recipient */
Recipient = Recipient && 0x1f; Recipient = (Recipient & 0x1f); /* XXX: origin: Recipient && 0x1f !? */
data_read_BYTE(data + 5, InterfaceNumber); /** InterfaceNumber */ data_read_BYTE(data + 5, InterfaceNumber); /** InterfaceNumber */
data_read_BYTE(data + 6, Ms_PageIndex); /** Ms_PageIndex */ data_read_BYTE(data + 6, Ms_PageIndex); /** Ms_PageIndex */
data_read_UINT16(data + 7, Ms_featureDescIndex); /** Ms_featureDescIndex */ data_read_UINT16(data + 7, Ms_featureDescIndex); /** Ms_featureDescIndex */

View File

@ -22,7 +22,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#if defined(__linux__)
#include <libudev.h> #include <libudev.h>
#endif
#include "libusb_udevice.h" #include "libusb_udevice.h"
@ -455,8 +457,7 @@ static void print_status(enum libusb_transfer_status status)
static LIBUSB_DEVICE* udev_get_libusb_dev(int bus_number, int dev_number) static LIBUSB_DEVICE* udev_get_libusb_dev(int bus_number, int dev_number)
{ {
int i; ssize_t i, total_device;
ssize_t total_device;
LIBUSB_DEVICE** libusb_list; LIBUSB_DEVICE** libusb_list;
total_device = libusb_get_device_list(NULL, &libusb_list); total_device = libusb_get_device_list(NULL, &libusb_list);
@ -492,7 +493,69 @@ static LIBUSB_DEVICE_DESCRIPTOR* udev_new_descript(LIBUSB_DEVICE* libusb_dev)
return descriptor; return descriptor;
} }
/* Get HUB handle */ /* Get HUB handle */
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
static int udev_get_hub_handle(UDEVICE* pdev, UINT16 bus_number, UINT16 dev_number) {
int error;
ssize_t i, total_device, ports_cnt;
uint8_t port_numbers[16];
LIBUSB_DEVICE **libusb_list;
total_device = libusb_get_device_list(NULL, &libusb_list);
/* Look for device. */
error = -1;
for (i = 0; i < total_device; i ++)
{
if ((bus_number != libusb_get_bus_number(libusb_list[i])) ||
(dev_number != libusb_get_device_address(libusb_list[i])))
continue;
error = libusb_open(libusb_list[i], &pdev->hub_handle);
if (error < 0)
{
WLog_ERR(TAG,"libusb_open error: %i - %s", error, libusb_strerror(error));
break;
}
/* get port number */
error = libusb_get_port_numbers(libusb_list[i], port_numbers, sizeof(port_numbers));
libusb_close(pdev->hub_handle);
if (error < 1)
{ /* Prevent open hub, treat as error. */
WLog_ERR(TAG,"libusb_get_port_numbers error: %i - %s", error, libusb_strerror(error));
break;
}
pdev->port_number = port_numbers[(error - 1)];
error = 0;
WLog_DBG(TAG, " Port: %d", pdev->port_number);
/* gen device path */
sprintf(pdev->path, "ugen%d.%d", bus_number, dev_number);
WLog_DBG(TAG, " DevPath: %s", pdev->path);
break;
}
/* Look for device hub. */
if (error == 0)
{
error = -1;
for (i = 0; i < total_device; i ++)
{
if ((bus_number != libusb_get_bus_number(libusb_list[i])) ||
(1 != libusb_get_device_address(libusb_list[i]))) /* Root hub allways first on bus. */
continue;
WLog_DBG(TAG, " Open hub: %d", bus_number);
error = libusb_open(libusb_list[i], &pdev->hub_handle);
if (error < 0)
WLog_ERR(TAG,"libusb_open error: %i - %s", error, libusb_strerror(error));
break;
}
}
libusb_free_device_list(libusb_list, 1);
if (error < 0)
return -1;
WLog_DBG(TAG, "libusb_open success!");
return 0;
}
#endif
#if defined(__linux__)
static int udev_get_hub_handle(UDEVICE* pdev, UINT16 bus_number, UINT16 dev_number) static int udev_get_hub_handle(UDEVICE* pdev, UINT16 bus_number, UINT16 dev_number)
{ {
struct udev* udev; struct udev* udev;
@ -627,6 +690,7 @@ static int udev_get_hub_handle(UDEVICE* pdev, UINT16 bus_number, UINT16 dev_numb
/* Success! */ /* Success! */
return 0; return 0;
} }
#endif
static int libusb_udev_select_interface(IUDEVICE* idev, BYTE InterfaceNumber, BYTE AlternateSetting) static int libusb_udev_select_interface(IUDEVICE* idev, BYTE InterfaceNumber, BYTE AlternateSetting)
{ {
@ -1211,6 +1275,7 @@ static int libusb_udev_query_device_port_status(IUDEVICE* idev, UINT32* UsbdStat
UDEVICE* pdev = (UDEVICE*) idev; UDEVICE* pdev = (UDEVICE*) idev;
int success = 0, ret; int success = 0, ret;
WLog_DBG(TAG,"...");
if (pdev->hub_handle != NULL) if (pdev->hub_handle != NULL)
{ {
ret = idev->control_transfer(idev, 0xffff, 0, 0, ret = idev->control_transfer(idev, 0xffff, 0, 0,
@ -1815,10 +1880,10 @@ int udev_new_by_id(UINT16 idVendor, UINT16 idProduct, IUDEVICE*** devArray)
UDEVICE** array; UDEVICE** array;
UINT16 bus_number; UINT16 bus_number;
UINT16 dev_number; UINT16 dev_number;
ssize_t total_device; ssize_t i, total_device;
int i, status, num = 0; int status, num = 0;
WLog_ERR(TAG, "VID: 0x%04X PID: 0x%04X", idVendor, idProduct); WLog_INFO(TAG, "VID: 0x%04X, PID: 0x%04X", idVendor, idProduct);
array = (UDEVICE**) malloc(16 * sizeof(UDEVICE*)); array = (UDEVICE**) malloc(16 * sizeof(UDEVICE*));
@ -1839,7 +1904,7 @@ int udev_new_by_id(UINT16 idVendor, UINT16 idProduct, IUDEVICE*** devArray)
if (status < 0) if (status < 0)
{ {
WLog_ERR(TAG, "libusb_open: (by id) error: 0x%08X (%d)", status, status); WLog_ERR(TAG, "libusb_open: (by id) error: 0x%08X (%d)", status, status);
zfree(descriptor); zfree(descriptor);
zfree(array[num]); zfree(array[num]);
continue; continue;

View File

@ -23,7 +23,11 @@
#ifndef __LIBUSB_UDEVICE_H #ifndef __LIBUSB_UDEVICE_H
#define __LIBUSB_UDEVICE_H #define __LIBUSB_UDEVICE_H
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
#include <libusb.h>
#else
#include <libusb-1.0/libusb.h> #include <libusb-1.0/libusb.h>
#endif
#include "urbdrc_types.h" #include "urbdrc_types.h"
#include "request_queue.h" #include "request_queue.h"

View File

@ -612,5 +612,7 @@ int freerdp_urbdrc_client_subsystem_entry(PFREERDP_URBDRC_SERVICE_ENTRY_POINTS p
pEntryPoints->pRegisterUDEVMAN(pEntryPoints->plugin, (IUDEVMAN*) udevman); pEntryPoints->pRegisterUDEVMAN(pEntryPoints->plugin, (IUDEVMAN*) udevman);
WLog_DBG(TAG, "UDEVMAN device registered.");
return 0; return 0;
} }

View File

@ -24,10 +24,20 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <time.h> #include <time.h>
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <err.h>
#endif
#if defined(__linux__)
#include <libudev.h> #include <libudev.h>
#endif
#include <winpr/crt.h> #include <winpr/crt.h>
#include <winpr/synch.h> #include <winpr/synch.h>
#include <winpr/string.h>
#include <winpr/cmdline.h> #include <winpr/cmdline.h>
#include <freerdp/dvc.h> #include <freerdp/dvc.h>
@ -48,10 +58,10 @@ static int func_hardware_id_format(IUDEVICE* pdev, char(*HardwareIds)[DEVICE_HAR
idProduct = (UINT16)pdev->query_device_descriptor(pdev, ID_PRODUCT); idProduct = (UINT16)pdev->query_device_descriptor(pdev, ID_PRODUCT);
bcdDevice = (UINT16)pdev->query_device_descriptor(pdev, BCD_DEVICE); bcdDevice = (UINT16)pdev->query_device_descriptor(pdev, BCD_DEVICE);
snprintf(str, sizeof(str), "USB\\VID_%04X&PID_%04X", idVendor, idProduct); sprintf_s(str, sizeof(str), "USB\\VID_%04X&PID_%04X", idVendor, idProduct);
strcpy(HardwareIds[1], str); strcpy(HardwareIds[1], str);
snprintf(str, sizeof(str), "%s&REV_%04X", HardwareIds[1], bcdDevice); sprintf_s(str, sizeof(str), "%s&REV_%04X", HardwareIds[1], bcdDevice);
strcpy(HardwareIds[0], str); strcpy(HardwareIds[0], str);
return 0; return 0;
@ -68,20 +78,20 @@ static int func_compat_id_format(IUDEVICE* pdev, char (*CompatibilityIds)[DEVICE
if(!(pdev->isCompositeDevice(pdev))) if(!(pdev->isCompositeDevice(pdev)))
{ {
snprintf(str, sizeof(str),"USB\\Class_%02X", bDeviceClass); sprintf_s(str, sizeof(str),"USB\\Class_%02X", bDeviceClass);
strcpy(CompatibilityIds[2], str); strcpy(CompatibilityIds[2], str);
snprintf(str, sizeof(str),"%s&SubClass_%02X", CompatibilityIds[2], bDeviceSubClass); sprintf_s(str, sizeof(str),"%s&SubClass_%02X", CompatibilityIds[2], bDeviceSubClass);
strcpy(CompatibilityIds[1], str); strcpy(CompatibilityIds[1], str);
snprintf(str, sizeof(str),"%s&Prot_%02X", CompatibilityIds[1], bDeviceProtocol); sprintf_s(str, sizeof(str),"%s&Prot_%02X", CompatibilityIds[1], bDeviceProtocol);
strcpy(CompatibilityIds[0], str); strcpy(CompatibilityIds[0], str);
} }
else else
{ {
snprintf(str, sizeof(str),"USB\\DevClass_00"); sprintf_s(str, sizeof(str),"USB\\DevClass_00");
strcpy(CompatibilityIds[2], str); strcpy(CompatibilityIds[2], str);
snprintf(str, sizeof(str),"%s&SubClass_00", CompatibilityIds[2]); sprintf_s(str, sizeof(str),"%s&SubClass_00", CompatibilityIds[2]);
strcpy(CompatibilityIds[1], str); strcpy(CompatibilityIds[1], str);
snprintf(str, sizeof(str),"%s&Prot_00", CompatibilityIds[1]); sprintf_s(str, sizeof(str),"%s&Prot_00", CompatibilityIds[1]);
strcpy(CompatibilityIds[0], str); strcpy(CompatibilityIds[0], str);
} }
@ -152,10 +162,10 @@ static int func_container_id_generate(IUDEVICE* pdev, char* strContainerId)
p = path; p = path;
ZeroMemory(containerId, sizeof(containerId)); ZeroMemory(containerId, sizeof(containerId));
snprintf((char*)containerId, sizeof(containerId), "%04X%04X%s", idVendor, idProduct, p); sprintf_s((char*)containerId, sizeof(containerId), "%04X%04X%s", idVendor, idProduct, p);
/* format */ /* format */
snprintf(strContainerId, DEVICE_CONTAINER_STR_SIZE, sprintf_s(strContainerId, DEVICE_CONTAINER_STR_SIZE,
"{%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x}", "{%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
containerId[0], containerId[1],containerId[2], containerId[3], containerId[0], containerId[1],containerId[2], containerId[3],
containerId[4], containerId[5], containerId[6], containerId[7], containerId[4], containerId[5], containerId[6], containerId[7],
@ -170,10 +180,10 @@ static int func_instance_id_generate(IUDEVICE* pdev, char* strInstanceId)
UINT8 instanceId[17]; UINT8 instanceId[17];
ZeroMemory(instanceId, sizeof(instanceId)); ZeroMemory(instanceId, sizeof(instanceId));
snprintf((char*)instanceId, sizeof(instanceId), "\\%s", pdev->getPath(pdev)); sprintf_s((char*)instanceId, sizeof(instanceId), "\\%s", pdev->getPath(pdev));
/* format */ /* format */
snprintf(strInstanceId, DEVICE_INSTANCE_STR_SIZE, sprintf_s(strInstanceId, DEVICE_INSTANCE_STR_SIZE,
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
instanceId[0], instanceId[1],instanceId[2], instanceId[3], instanceId[0], instanceId[1],instanceId[2], instanceId[3],
instanceId[4], instanceId[5], instanceId[6], instanceId[7], instanceId[4], instanceId[5], instanceId[6], instanceId[7],
@ -449,6 +459,266 @@ static WIN32ERROR urbdrc_exchange_capabilities(URBDRC_CHANNEL_CALLBACK* callback
return error; return error;
} }
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
static char *devd_get_val(char *buf, size_t buf_size, const char *val_name, size_t val_name_size, size_t *val_size) {
char *ret, *buf_end, *ptr;
buf_end = (buf + buf_size);
for (ret = buf; ret != NULL && ret < buf_end;)
{
ret = memmem(ret, (buf_end - ret), val_name, val_name_size);
if (ret == NULL)
return NULL;
/* Found. */
/* Check: space before or buf+1. */
if ((buf + 1) < ret && ret[-1] != ' ')
{
ret += val_name_size;
continue;
}
/* Check: = after name and size for value. */
ret += val_name_size;
if ((ret + 1) >= buf_end)
return NULL;
if (ret[0] != '=')
continue;
ret ++;
break;
}
if (ret == NULL || val_size == NULL)
return ret;
/* Calc value data size. */
ptr = memchr(ret, ' ', (buf_end - ret));
if (ptr == NULL) /* End of string/last value. */
ptr = buf_end;
(*val_size) = (ptr - ret);
return ret;
}
static void *urbdrc_search_usb_device(void *arg) {
USB_SEARCHMAN *searchman = (USB_SEARCHMAN*)arg;
URBDRC_PLUGIN *urbdrc = (URBDRC_PLUGIN*)searchman->urbdrc;
IUDEVMAN *udevman = urbdrc->udevman;
IWTSVirtualChannelManager *channel_mgr = urbdrc->listener_callback->channel_mgr;
IWTSVirtualChannel *dvc_channel;
USB_SEARCHDEV *sdev;
IUDEVICE *pdev;
HANDLE listobj[2];
HANDLE mon_fd;
int devd_skt;
char buf[4096], *val, *ptr, *end_val;
ssize_t data_size;
size_t val_size, tm;
int idVendor, idProduct;
int busnum, devnum;
int action, success, error, found, on_close;
struct sockaddr_un sun;
WLog_DBG(TAG, "urbdrc_search_usb_device - devd: start");
devd_skt = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
if (devd_skt == -1)
{
WLog_ERR(TAG, "Can't create devd socket: error = %i", errno);
goto err_out;
}
memset(&sun, 0, sizeof(sun));
sun.sun_family = PF_LOCAL;
sun.sun_len = sizeof(sun);
strlcpy(sun.sun_path, "/var/run/devd.seqpacket.pipe", sizeof(sun.sun_path));
if (-1 == connect(devd_skt, (struct sockaddr*)&sun, sizeof(sun)))
{
WLog_ERR(TAG, "Can't connect devd socket: error = %i - %s", errno, strerror(errno));
goto err_out;
}
/* Get the file descriptor (fd) for the monitor.
This fd will get passed to select() */
mon_fd = CreateFileDescriptorEvent(NULL, TRUE, FALSE, devd_skt);
listobj[0] = searchman->term_event;
listobj[1] = mon_fd;
while (WaitForMultipleObjects(2, listobj, FALSE, INFINITE) != WAIT_OBJECT_0)
{
WLog_DBG(TAG, "======= SEARCH ======= ");
/* !system=USB subsystem=DEVICE type=ATTACH ugen=ugen3.3 cdev=ugen3.3 vendor=0x046d product=0x082d devclass=0xef devsubclass=0x02 sernum="6E7D726F" release=0x0011 mode=host port=4 parent=ugen3.1 */
/* !system=USB subsystem=DEVICE type=DETACH ugen=ugen3.3 cdev=ugen3.3 vendor=0x046d product=0x082d devclass=0xef devsubclass=0x02 sernum="6E7D726F" release=0x0011 mode=host port=4 parent=ugen3.1 */
data_size = read(devd_skt, buf, (sizeof(buf) - 1));
if (data_size == -1)
{
WLog_ERR(TAG, "devd socket read: error = %i", errno);
break;
}
buf[data_size] = 0;
WLog_DBG(TAG, "devd event: %s", buf);
if (buf[0] != '!') /* Skeep non notify events. */
continue;
/* Check: system=USB */
val = devd_get_val(buf, data_size, "system", 6, &val_size);
if (val == NULL || val_size != 3 || memcmp(val, "USB", 3) != 0)
continue;
/* Check: subsystem=DEVICE */
val = devd_get_val(buf, data_size, "subsystem", 9, &val_size);
if (val == NULL || val_size != 6 || memcmp(val, "DEVICE", 6) != 0)
continue;
/* Get event type. */
val = devd_get_val(buf, data_size, "type", 4, &val_size);
if (val == NULL || val_size != 6)
continue;
action = -1;
if (memcmp(val, "ATTACH", 6) == 0)
action = 0;
if (memcmp(val, "DETACH", 6) == 0)
action = 1;
if (action == -1)
continue; /* Skeep other actions. */
/* Get bus and dev num. */
/* ugen=ugen3.3 */
val = devd_get_val(buf, data_size, "ugen", 4, &val_size);
if (val == NULL || val_size < 7 || memcmp(val, "ugen", 4) != 0)
continue;
val += 4;
val_size -= 4;
ptr = memchr(val, '.', val_size);
if (ptr == NULL)
continue;
/* Prepare strings. */
ptr[0] = 0;
ptr ++;
val[val_size] = 0;
/* Extract numbers. */
busnum = atoi(val);
devnum = atoi(ptr);
/* Restore spaces. */
ptr[-1] = ' ';
val[val_size] = ' ';
/* Handle event. */
dvc_channel = NULL;
switch (action)
{
case 0: /* ATTACH */
sdev = NULL;
success = 0;
found = 0;
/* vendor=0x046d */
val = devd_get_val(buf, data_size, "vendor", 6, &val_size);
if (val == NULL || val_size < 1)
continue;
val[val_size] = 0;
idVendor = strtol(val, NULL, 16);
val[val_size] = ' ';
/* product=0x082d */
val = devd_get_val(buf, data_size, "product", 7, &val_size);
if (val == NULL || val_size < 1)
continue;
val[val_size] = 0;
idProduct = strtol(val, NULL, 16);
val[val_size] = ' ';
WLog_DBG(TAG, "ATTACH: bus: %i, dev: %i, ven: %i, prod: %i", busnum, devnum, idVendor, idProduct);
dvc_channel = channel_mgr->FindChannelById(channel_mgr, urbdrc->first_channel_id);
searchman->rewind(searchman);
while (dvc_channel && searchman->has_next(searchman))
{
sdev = searchman->get_next(searchman);
if (sdev->idVendor == idVendor &&
sdev->idProduct == idProduct)
{
WLog_VRB(TAG, "Searchman Found Device: %04x:%04x",
sdev->idVendor, sdev->idProduct);
found = 1;
break;
}
}
if (!found && udevman->isAutoAdd(udevman))
{
WLog_VRB(TAG, "Auto Find Device: %04x:%04x ",
idVendor, idProduct);
found = 2;
}
if (found)
{
success = udevman->register_udevice(udevman, busnum, devnum,
searchman->UsbDevice, 0, 0, UDEVMAN_FLAG_ADD_BY_ADDR);
}
if (success)
{
searchman->UsbDevice ++;
usleep(400000);
error = urdbrc_send_virtual_channel_add(dvc_channel, 0);
if (found == 1)
searchman->remove(searchman, sdev->idVendor, sdev->idProduct);
}
break;
case 1: /* DETACH */
pdev = NULL;
on_close = 0;
WLog_DBG(TAG, "DETACH: bus: %i, dev: %i", busnum, devnum);
usleep(500000);
udevman->loading_lock(udevman);
udevman->rewind(udevman);
while (udevman->has_next(udevman))
{
pdev = udevman->get_next(udevman);
if (pdev->get_bus_number(pdev) == busnum &&
pdev->get_dev_number(pdev) == devnum)
{
dvc_channel = channel_mgr->FindChannelById(channel_mgr, pdev->get_channel_id(pdev));
if (dvc_channel == NULL)
{
WLog_ERR(TAG, "SEARCH: dvc_channel %d is NULL!!", pdev->get_channel_id(pdev));
func_close_udevice(searchman, pdev);
break;
}
if (!pdev->isSigToEnd(pdev))
{
dvc_channel->Write(dvc_channel, 0, NULL, NULL);
pdev->SigToEnd(pdev);
}
on_close = 1;
break;
}
}
udevman->loading_unlock(udevman);
usleep(300000);
if (pdev && on_close && dvc_channel &&
pdev->isSigToEnd(pdev) &&
!(pdev->isChannelClosed(pdev)))
{
dvc_channel->Close(dvc_channel);
}
break;
}
}
CloseHandle(mon_fd);
err_out:
close(devd_skt);
sem_post(&searchman->sem_term);
WLog_DBG(TAG, "urbdrc_search_usb_device - devd: end");
return 0;
}
#endif
#if defined (__linux__)
static void* urbdrc_search_usb_device(void* arg) static void* urbdrc_search_usb_device(void* arg)
{ {
USB_SEARCHMAN* searchman = (USB_SEARCHMAN*) arg; USB_SEARCHMAN* searchman = (USB_SEARCHMAN*) arg;
@ -486,7 +756,9 @@ static void* urbdrc_search_usb_device(void* arg)
/* Get the file descriptor (fd) for the monitor. /* Get the file descriptor (fd) for the monitor.
This fd will get passed to select() */ This fd will get passed to select() */
if (!(mon_fd = CreateFileDescriptorEvent(NULL, TRUE, FALSE, udev_monitor_get_fd(mon)))) mon_fd = CreateFileDescriptorEvent(NULL, TRUE, FALSE,
udev_monitor_get_fd(mon), WINPR_FD_READ);
if (!mon_fd)
goto fail_create_monfd_event; goto fail_create_monfd_event;
while (1) while (1)
@ -672,6 +944,7 @@ fail_create_monfd_event:
return 0; return 0;
} }
#endif
void* urbdrc_new_device_create(void* arg) void* urbdrc_new_device_create(void* arg)
{ {
@ -688,8 +961,10 @@ void* urbdrc_new_device_create(void* arg)
UINT32 FunctionId; UINT32 FunctionId;
int i = 0, found = 0; int i = 0, found = 0;
WLog_DBG(TAG, "...");
channel_mgr = urbdrc->listener_callback->channel_mgr; channel_mgr = urbdrc->listener_callback->channel_mgr;
ChannelId = channel_mgr->GetChannelId(callback->channel); ChannelId = channel_mgr->GetChannelId(callback->channel);
data_read_UINT32(pBuffer + 0, MessageId); data_read_UINT32(pBuffer + 0, MessageId);
data_read_UINT32(pBuffer + 4, FunctionId); data_read_UINT32(pBuffer + 4, FunctionId);
@ -762,6 +1037,8 @@ static WIN32ERROR urbdrc_process_channel_notification(URBDRC_CHANNEL_CALLBACK* c
WIN32ERROR error = CHANNEL_RC_OK; WIN32ERROR error = CHANNEL_RC_OK;
URBDRC_PLUGIN* urbdrc = (URBDRC_PLUGIN*) callback->plugin; URBDRC_PLUGIN* urbdrc = (URBDRC_PLUGIN*) callback->plugin;
WLog_DBG(TAG, "...");
data_read_UINT32(pBuffer + 0, MessageId); data_read_UINT32(pBuffer + 0, MessageId);
data_read_UINT32(pBuffer + 4, FunctionId); data_read_UINT32(pBuffer + 4, FunctionId);
@ -824,7 +1101,7 @@ static WIN32ERROR urbdrc_on_data_received(IWTSVirtualChannelCallback* pChannelCa
UINT32 Mask; UINT32 Mask;
WIN32ERROR error = CHANNEL_RC_OK; WIN32ERROR error = CHANNEL_RC_OK;
char* pBuffer = (char*)Stream_Pointer(data); char* pBuffer = (char*)Stream_Pointer(data);
UINT32 cbSize = Stream_GetRemainingLength(data); UINT32 cbSize = Stream_GetRemainingLength(data);
if (callback == NULL) if (callback == NULL)
return 0; return 0;

View File

@ -30,7 +30,11 @@
#include <freerdp/channels/log.h> #include <freerdp/channels/log.h>
#include <freerdp/utils/msusb.h> #include <freerdp/utils/msusb.h>
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
#include <uuid.h>
#else
#include <uuid/uuid.h> #include <uuid/uuid.h>
#endif
#include <pthread.h> #include <pthread.h>
#include <semaphore.h> #include <semaphore.h>

1
client/.gitignore vendored
View File

@ -7,4 +7,5 @@
!/Sample !/Sample
!/Windows !/Windows
!/X11 !/X11
!/Wayland
!/CMakeLists.txt !/CMakeLists.txt

View File

@ -69,20 +69,20 @@ void android_clear_event(ANDROID_EVENT_QUEUE * queue)
} }
} }
void android_push_event(freerdp * inst, ANDROID_EVENT* event) BOOL android_push_event(freerdp * inst, ANDROID_EVENT* event)
{ {
androidContext* aCtx = (androidContext*)inst->context; androidContext* aCtx = (androidContext*)inst->context;
if (aCtx->event_queue->count >= aCtx->event_queue->size) if (aCtx->event_queue->count >= aCtx->event_queue->size)
{ {
int new_size; int new_size;
int new_events; void* new_events;
new_size = aCtx->event_queue->size * 2; new_size = aCtx->event_queue->size * 2;
new_events = realloc((void*) aCtx->event_queue->events, new_events = realloc((void*) aCtx->event_queue->events,
sizeof(ANDROID_EVENT*) * new_size); sizeof(ANDROID_EVENT*) * new_size);
if (!new_events) if (!new_events)
return; return FALSE;
aCtx->event_queue->events = new_events; aCtx->event_queue->events = new_events;
aCtx->event_queue->size = new_size; aCtx->event_queue->size = new_size;
} }
@ -90,6 +90,7 @@ void android_push_event(freerdp * inst, ANDROID_EVENT* event)
aCtx->event_queue->events[(aCtx->event_queue->count)++] = event; aCtx->event_queue->events[(aCtx->event_queue->count)++] = event;
android_set_event(aCtx->event_queue); android_set_event(aCtx->event_queue);
return TRUE;
} }
ANDROID_EVENT* android_peek_event(ANDROID_EVENT_QUEUE * queue) ANDROID_EVENT* android_peek_event(ANDROID_EVENT_QUEUE * queue)
@ -226,8 +227,9 @@ ANDROID_EVENT_KEY* android_event_key_new(int flags, UINT16 scancode)
{ {
ANDROID_EVENT_KEY* event; ANDROID_EVENT_KEY* event;
event = (ANDROID_EVENT_KEY*) malloc(sizeof(ANDROID_EVENT_KEY)); event = (ANDROID_EVENT_KEY*) calloc(1, sizeof(ANDROID_EVENT_KEY));
memset(event, 0, sizeof(ANDROID_EVENT_KEY)); if (!event)
return NULL;
event->type = EVENT_TYPE_KEY; event->type = EVENT_TYPE_KEY;
event->flags = flags; event->flags = flags;
@ -245,8 +247,9 @@ ANDROID_EVENT_KEY* android_event_unicodekey_new(UINT16 key)
{ {
ANDROID_EVENT_KEY* event; ANDROID_EVENT_KEY* event;
event = (ANDROID_EVENT_KEY*) malloc(sizeof(ANDROID_EVENT_KEY)); event = (ANDROID_EVENT_KEY*) calloc(1, sizeof(ANDROID_EVENT_KEY));
memset(event, 0, sizeof(ANDROID_EVENT_KEY)); if (!event)
return NULL;
event->type = EVENT_TYPE_KEY_UNICODE; event->type = EVENT_TYPE_KEY_UNICODE;
event->scancode = key; event->scancode = key;
@ -263,8 +266,9 @@ ANDROID_EVENT_CURSOR* android_event_cursor_new(UINT16 flags, UINT16 x, UINT16 y)
{ {
ANDROID_EVENT_CURSOR* event; ANDROID_EVENT_CURSOR* event;
event = (ANDROID_EVENT_CURSOR*) malloc(sizeof(ANDROID_EVENT_CURSOR)); event = (ANDROID_EVENT_CURSOR*) calloc(1, sizeof(ANDROID_EVENT_CURSOR));
memset(event, 0, sizeof(ANDROID_EVENT_CURSOR)); if (!event)
return NULL;
event->type = EVENT_TYPE_CURSOR; event->type = EVENT_TYPE_CURSOR;
event->x = x; event->x = x;
@ -283,8 +287,9 @@ ANDROID_EVENT* android_event_disconnect_new()
{ {
ANDROID_EVENT* event; ANDROID_EVENT* event;
event = (ANDROID_EVENT*) malloc(sizeof(ANDROID_EVENT)); event = (ANDROID_EVENT*) calloc(1, sizeof(ANDROID_EVENT));
memset(event, 0, sizeof(ANDROID_EVENT)); if (!event)
return NULL;
event->type = EVENT_TYPE_DISCONNECT; event->type = EVENT_TYPE_DISCONNECT;
return event; return event;
@ -299,13 +304,19 @@ ANDROID_EVENT_CLIPBOARD* android_event_clipboard_new(void* data, int data_length
{ {
ANDROID_EVENT_CLIPBOARD* event; ANDROID_EVENT_CLIPBOARD* event;
event = (ANDROID_EVENT_CLIPBOARD*) malloc(sizeof(ANDROID_EVENT_CLIPBOARD)); event = (ANDROID_EVENT_CLIPBOARD*) calloc(1, sizeof(ANDROID_EVENT_CLIPBOARD));
memset(event, 0, sizeof(ANDROID_EVENT_CLIPBOARD)); if (!event)
return NULL;
event->type = EVENT_TYPE_CLIPBOARD; event->type = EVENT_TYPE_CLIPBOARD;
if (data) if (data)
{ {
event->data = malloc(data_length); event->data = malloc(data_length);
if (!event->data)
{
free(event);
return NULL;
}
memcpy(event->data, data, data_length); memcpy(event->data, data, data_length);
event->data_length = data_length; event->data_length = data_length;
} }
@ -322,12 +333,16 @@ void android_event_clipboard_free(ANDROID_EVENT_CLIPBOARD* event)
} }
} }
void android_event_queue_init(freerdp * inst) BOOL android_event_queue_init(freerdp * inst)
{ {
androidContext* aCtx = (androidContext*)inst->context; androidContext* aCtx = (androidContext*)inst->context;
aCtx->event_queue = (ANDROID_EVENT_QUEUE*) malloc(sizeof(ANDROID_EVENT_QUEUE)); aCtx->event_queue = (ANDROID_EVENT_QUEUE*) calloc(1, sizeof(ANDROID_EVENT_QUEUE));
memset(aCtx->event_queue, 0, sizeof(ANDROID_EVENT_QUEUE)); if (!aCtx->event_queue)
{
WLog_ERR(TAG, "android_event_queue_init: memory allocation failed");
return FALSE;
}
aCtx->event_queue->pipe_fd[0] = -1; aCtx->event_queue->pipe_fd[0] = -1;
aCtx->event_queue->pipe_fd[1] = -1; aCtx->event_queue->pipe_fd[1] = -1;
@ -335,9 +350,21 @@ void android_event_queue_init(freerdp * inst)
aCtx->event_queue->size = 16; aCtx->event_queue->size = 16;
aCtx->event_queue->count = 0; aCtx->event_queue->count = 0;
aCtx->event_queue->events = (ANDROID_EVENT**) malloc(sizeof(ANDROID_EVENT*) * aCtx->event_queue->size); aCtx->event_queue->events = (ANDROID_EVENT**) malloc(sizeof(ANDROID_EVENT*) * aCtx->event_queue->size);
if (!aCtx->event_queue->events)
{
WLog_ERR(TAG, "android_event_queue_init: memory allocation failed");
free(aCtx->event_queue);
return FALSE;
}
if (pipe(aCtx->event_queue->pipe_fd) < 0) if (pipe(aCtx->event_queue->pipe_fd) < 0)
WLog_ERR(TAG, "android_pre_connect: pipe failed"); {
WLog_ERR(TAG, "android_event_queue_init: pipe creation failed");
free(aCtx->event_queue->events);
free(aCtx->event_queue);
return FALSE;
}
return TRUE;
} }
void android_event_queue_uninit(freerdp * inst) void android_event_queue_uninit(freerdp * inst)

View File

@ -62,7 +62,7 @@ typedef struct _ANDROID_EVENT_QUEUE ANDROID_EVENT_QUEUE;
int android_is_event_set(ANDROID_EVENT_QUEUE * queue); int android_is_event_set(ANDROID_EVENT_QUEUE * queue);
void android_set_event(ANDROID_EVENT_QUEUE * queue); void android_set_event(ANDROID_EVENT_QUEUE * queue);
void android_clear_event(ANDROID_EVENT_QUEUE * queue); void android_clear_event(ANDROID_EVENT_QUEUE * queue);
void android_push_event(freerdp * inst, ANDROID_EVENT* event); BOOL android_push_event(freerdp * inst, ANDROID_EVENT* event);
ANDROID_EVENT* android_peek_event(ANDROID_EVENT_QUEUE * queue); ANDROID_EVENT* android_peek_event(ANDROID_EVENT_QUEUE * queue);
ANDROID_EVENT* android_pop_event(ANDROID_EVENT_QUEUE * queue); ANDROID_EVENT* android_pop_event(ANDROID_EVENT_QUEUE * queue);
int android_process_event(ANDROID_EVENT_QUEUE * queue, freerdp * inst); int android_process_event(ANDROID_EVENT_QUEUE * queue, freerdp * inst);
@ -79,7 +79,7 @@ void android_event_unicodekey_free(ANDROID_EVENT_KEY* event);
void android_event_cursor_free(ANDROID_EVENT_CURSOR* event); void android_event_cursor_free(ANDROID_EVENT_CURSOR* event);
void android_event_disconnect_free(ANDROID_EVENT* event); void android_event_disconnect_free(ANDROID_EVENT* event);
void android_event_clipboard_free(ANDROID_EVENT_CLIPBOARD* event); void android_event_clipboard_free(ANDROID_EVENT_CLIPBOARD* event);
void android_event_queue_init(freerdp * inst); BOOL android_event_queue_init(freerdp * inst);
void android_event_queue_uninit(freerdp * inst); void android_event_queue_uninit(freerdp * inst);
#endif /* FREERDP_ANDROID_EVENT_H */ #endif /* FREERDP_ANDROID_EVENT_H */

View File

@ -4,6 +4,7 @@
Copyright 2010-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com> Copyright 2010-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
Copyright 2013 Thincast Technologies GmbH, Author: Armin Novak Copyright 2013 Thincast Technologies GmbH, Author: Armin Novak
Copyright 2015 Bernhard Miklautz <bernhard.miklautz@thincast.com>
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
@ -35,6 +36,7 @@
#include <freerdp/locale/keyboard.h> #include <freerdp/locale/keyboard.h>
#include <freerdp/primitives.h> #include <freerdp/primitives.h>
#include <freerdp/version.h> #include <freerdp/version.h>
#include <freerdp/settings.h>
#include <android/bitmap.h> #include <android/bitmap.h>
@ -48,15 +50,21 @@
#include "jni/prof.h" #include "jni/prof.h"
#endif #endif
BOOL android_context_new(freerdp* instance, rdpContext* context)
static BOOL android_context_new(freerdp* instance, rdpContext* context)
{ {
if (!(context->channels = freerdp_channels_new())) if (!(context->channels = freerdp_channels_new()))
return FALSE; return FALSE;
android_event_queue_init(instance);
if (!android_event_queue_init(instance))
{
freerdp_channels_free(context->channels);
return FALSE;
}
return TRUE; return TRUE;
} }
void android_context_free(freerdp* instance, rdpContext* context) static void android_context_free(freerdp* instance, rdpContext* context)
{ {
if (context && context->channels) if (context && context->channels)
{ {
@ -67,14 +75,14 @@ void android_context_free(freerdp* instance, rdpContext* context)
android_event_queue_uninit(instance); android_event_queue_uninit(instance);
} }
void android_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEventArgs* e) static void android_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEventArgs* e)
{ {
rdpSettings* settings = context->settings; rdpSettings* settings = context->settings;
androidContext* afc = (androidContext*) context; androidContext* afc = (androidContext*) context;
if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0) if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0)
{ {
DEBUG_ANDROID("Unhandled case.. RDPEI_DVC_CHANNEL_NAME");
} }
else if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0) else if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0)
{ {
@ -87,14 +95,14 @@ void android_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnecte
} }
} }
void android_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnectedEventArgs* e) static void android_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnectedEventArgs* e)
{ {
rdpSettings* settings = context->settings; rdpSettings* settings = context->settings;
androidContext* afc = (androidContext*) context; androidContext* afc = (androidContext*) context;
if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0) if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0)
{ {
DEBUG_ANDROID("Unhandled case.. RDPEI_DVC_CHANNEL_NAME");
} }
else if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0) else if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0)
{ {
@ -107,7 +115,7 @@ void android_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisco
} }
} }
BOOL android_begin_paint(rdpContext* context) static BOOL android_begin_paint(rdpContext* context)
{ {
rdpGdi* gdi = context->gdi; rdpGdi* gdi = context->gdi;
gdi->primary->hdc->hwnd->invalid->null = 1; gdi->primary->hdc->hwnd->invalid->null = 1;
@ -115,7 +123,7 @@ BOOL android_begin_paint(rdpContext* context)
return TRUE; return TRUE;
} }
BOOL android_end_paint(rdpContext* context) static BOOL android_end_paint(rdpContext* context)
{ {
int i; int i;
int ninvalid; int ninvalid;
@ -158,7 +166,7 @@ BOOL android_end_paint(rdpContext* context)
return TRUE; return TRUE;
} }
BOOL android_desktop_resize(rdpContext* context) static BOOL android_desktop_resize(rdpContext* context)
{ {
DEBUG_ANDROID("ui_desktop_resize"); DEBUG_ANDROID("ui_desktop_resize");
@ -172,7 +180,7 @@ BOOL android_desktop_resize(rdpContext* context)
return TRUE; return TRUE;
} }
BOOL android_pre_connect(freerdp* instance) static BOOL android_pre_connect(freerdp* instance)
{ {
DEBUG_ANDROID("android_pre_connect"); DEBUG_ANDROID("android_pre_connect");
@ -233,7 +241,8 @@ static BOOL android_post_connect(freerdp* instance)
settings->DesktopWidth, settings->DesktopHeight, settings->DesktopWidth, settings->DesktopHeight,
settings->ColorDepth); settings->ColorDepth);
instance->context->cache = cache_new(settings); if (!(instance->context->cache = cache_new(settings)))
return FALSE;
if (instance->settings->ColorDepth > 16) if (instance->settings->ColorDepth > 16)
gdi_flags = CLRBUF_32BPP | CLRCONV_ALPHA | CLRCONV_INVERT; gdi_flags = CLRBUF_32BPP | CLRCONV_ALPHA | CLRCONV_INVERT;
@ -247,7 +256,8 @@ static BOOL android_post_connect(freerdp* instance)
instance->update->EndPaint = android_end_paint; instance->update->EndPaint = android_end_paint;
instance->update->DesktopResize = android_desktop_resize; instance->update->DesktopResize = android_desktop_resize;
freerdp_channels_post_connect(instance->context->channels, instance); if (freerdp_channels_post_connect(instance->context->channels, instance) < 0)
return FALSE;
freerdp_callback("OnConnectionSuccess", "(I)V", instance); freerdp_callback("OnConnectionSuccess", "(I)V", instance);
@ -256,11 +266,12 @@ static BOOL android_post_connect(freerdp* instance)
static void android_post_disconnect(freerdp* instance) static void android_post_disconnect(freerdp* instance)
{ {
DEBUG_ANDROID("android_post_disconnect");
gdi_free(instance); gdi_free(instance);
cache_free(instance->context->cache); cache_free(instance->context->cache);
} }
BOOL android_authenticate(freerdp* instance, char** username, char** password, char** domain) static BOOL android_authenticate(freerdp* instance, char** username, char** password, char** domain)
{ {
DEBUG_ANDROID("Authenticate user:"); DEBUG_ANDROID("Authenticate user:");
DEBUG_ANDROID(" Username: %s", *username); DEBUG_ANDROID(" Username: %s", *username);
@ -293,7 +304,7 @@ BOOL android_authenticate(freerdp* instance, char** username, char** password, c
return ((res == JNI_TRUE) ? TRUE : FALSE); return ((res == JNI_TRUE) ? TRUE : FALSE);
} }
BOOL android_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint) static BOOL android_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint)
{ {
DEBUG_ANDROID("Certificate details:"); DEBUG_ANDROID("Certificate details:");
DEBUG_ANDROID("\tSubject: %s", subject); DEBUG_ANDROID("\tSubject: %s", subject);
@ -317,7 +328,7 @@ BOOL android_verify_certificate(freerdp* instance, char* subject, char* issuer,
return ((res == JNI_TRUE) ? TRUE : FALSE); return ((res == JNI_TRUE) ? TRUE : FALSE);
} }
BOOL android_verify_changed_certificate(freerdp* instance, char* subject, char* issuer, char* new_fingerprint, char* old_fingerprint) static BOOL android_verify_changed_certificate(freerdp* instance, char* subject, char* issuer, char* new_fingerprint, char* old_fingerprint)
{ {
return android_verify_certificate(instance, subject, issuer, new_fingerprint); return android_verify_certificate(instance, subject, issuer, new_fingerprint);
} }
@ -332,15 +343,17 @@ static void* jni_input_thread(void* arg)
assert(NULL != instance); assert(NULL != instance);
assert(NULL != aCtx); assert(NULL != aCtx);
DEBUG_ANDROID("Start."); DEBUG_ANDROID("input_thread Start.");
if (!(queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE))) if (!(queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE)))
goto fail_get_message_queue; goto fail_get_message_queue;
if (!(event[0] = CreateFileDescriptorEvent(NULL, FALSE, FALSE, aCtx->event_queue->pipe_fd[0]))) if (!(event[0] = CreateFileDescriptorEvent(NULL, FALSE, FALSE,
aCtx->event_queue->pipe_fd[0], WINPR_FD_READ)))
goto fail_create_event_0; goto fail_create_event_0;
if (!(event[1] = CreateFileDescriptorEvent(NULL, FALSE, FALSE, aCtx->event_queue->pipe_fd[1]))) if (!(event[1] = CreateFileDescriptorEvent(NULL, FALSE, FALSE,
aCtx->event_queue->pipe_fd[1], WINPR_FD_READ)))
goto fail_create_event_1; goto fail_create_event_1;
if (!(event[2] = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE))) if (!(event[2] = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE)))
@ -365,7 +378,7 @@ static void* jni_input_thread(void* arg)
} }
while(1); while(1);
DEBUG_ANDROID("Quit."); DEBUG_ANDROID("input_thread Quit.");
fail_get_message_queue_event: fail_get_message_queue_event:
CloseHandle(event[1]); CloseHandle(event[1]);
@ -388,7 +401,7 @@ static void* jni_channels_thread(void* arg)
assert(NULL != instance); assert(NULL != instance);
DEBUG_ANDROID("Start."); DEBUG_ANDROID("Channels_thread Start.");
channels = instance->context->channels; channels = instance->context->channels;
event = freerdp_channels_get_event_handle(instance); event = freerdp_channels_get_event_handle(instance);
@ -401,7 +414,7 @@ static void* jni_channels_thread(void* arg)
break; break;
} }
DEBUG_ANDROID("Quit."); DEBUG_ANDROID("channels_thread Quit.");
ExitThread(0); ExitThread(0);
return NULL; return NULL;
@ -613,11 +626,11 @@ disconnect:
CloseHandle(input_thread); CloseHandle(input_thread);
} }
DEBUG_ANDROID("Disconnecting..."); DEBUG_ANDROID("run Disconnecting...");
freerdp_disconnect(instance); freerdp_disconnect(instance);
freerdp_callback("OnDisconnected", "(I)V", instance); freerdp_callback("OnDisconnected", "(I)V", instance);
DEBUG_ANDROID("Quit."); DEBUG_ANDROID("run Quit.");
return 0; return 0;
} }
@ -626,13 +639,13 @@ static void* android_thread_func(void* param)
{ {
freerdp* instance = param; freerdp* instance = param;
DEBUG_ANDROID("Start."); DEBUG_ANDROID("android_thread_func Start.");
assert(instance); assert(instance);
android_freerdp_run(instance); android_freerdp_run(instance);
DEBUG_ANDROID("Quit."); DEBUG_ANDROID("android_thread_func Quit.");
ExitThread(0); ExitThread(0);
return NULL; return NULL;
@ -649,7 +662,7 @@ JNIEXPORT jint JNICALL jni_freerdp_new(JNIEnv *env, jclass cls)
// create instance // create instance
if (!(instance = freerdp_new())) if (!(instance = freerdp_new()))
return NULL; return (jint)NULL;
instance->PreConnect = android_pre_connect; instance->PreConnect = android_pre_connect;
instance->PostConnect = android_post_connect; instance->PostConnect = android_post_connect;
instance->PostDisconnect = android_post_disconnect; instance->PostDisconnect = android_post_disconnect;
@ -705,12 +718,20 @@ JNIEXPORT jboolean JNICALL jni_freerdp_disconnect(JNIEnv *env, jclass cls, jint
freerdp* inst = (freerdp*)instance; freerdp* inst = (freerdp*)instance;
androidContext* ctx = (androidContext*)inst->context; androidContext* ctx = (androidContext*)inst->context;
ANDROID_EVENT* event = (ANDROID_EVENT*)android_event_disconnect_new(); ANDROID_EVENT* event = (ANDROID_EVENT*)android_event_disconnect_new();
if (!event)
return JNI_FALSE;
DEBUG_ANDROID("DISCONNECT!");
assert(inst); assert(inst);
assert(ctx); assert(ctx);
assert(event); assert(event);
android_push_event(inst, event); if (!android_push_event(inst, event))
{
android_event_disconnect_free(event);
return JNI_FALSE;
}
WaitForSingleObject(ctx->thread, INFINITE); WaitForSingleObject(ctx->thread, INFINITE);
CloseHandle(ctx->thread); CloseHandle(ctx->thread);
@ -721,43 +742,71 @@ JNIEXPORT jboolean JNICALL jni_freerdp_disconnect(JNIEnv *env, jclass cls, jint
return (jboolean) JNI_TRUE; return (jboolean) JNI_TRUE;
} }
JNIEXPORT void JNICALL jni_freerdp_cancel_connection(JNIEnv *env, jclass cls, jint instance) JNIEXPORT jboolean JNICALL jni_freerdp_cancel_connection(JNIEnv *env, jclass cls, jint instance)
{ {
jni_freerdp_disconnect(env, cls, instance); return jni_freerdp_disconnect(env, cls, instance);
} }
JNIEXPORT void JNICALL jni_freerdp_set_data_directory(JNIEnv *env, jclass cls, jint instance, jstring jdirectory) JNIEXPORT jboolean JNICALL jni_freerdp_set_data_directory(JNIEnv *env, jclass cls, jint instance, jstring jdirectory)
{ {
freerdp* inst = (freerdp*)instance; freerdp* inst = (freerdp*)instance;
rdpSettings * settings = inst->settings; rdpSettings * settings = inst->settings;
const jbyte *directory = (*env)->GetStringUTFChars(env, jdirectory, NULL); const jbyte* directory = (*env)->GetStringUTFChars(env, jdirectory, NULL);
if (!directory)
return JNI_FALSE;
free(settings->HomePath); free(settings->HomePath);
free(settings->ConfigPath); free(settings->ConfigPath);
settings->HomePath = settings->ConfigPath = NULL;
int config_dir_len = strlen(directory) + 10; /* +9 chars for /.freerdp and +1 for \0 */ int config_dir_len = strlen(directory) + 10; /* +9 chars for /.freerdp and +1 for \0 */
char* config_dir_buf = (char*)malloc(config_dir_len); char* config_dir_buf = (char*)malloc(config_dir_len);
if (!config_dir_buf)
goto out_malloc_fail;
strcpy(config_dir_buf, directory); strcpy(config_dir_buf, directory);
strcat(config_dir_buf, "/.freerdp"); strcat(config_dir_buf, "/.freerdp");
settings->HomePath = strdup(directory); settings->HomePath = strdup(directory);
if (!settings->HomePath)
goto out_strdup_fail;
settings->ConfigPath = config_dir_buf; /* will be freed by freerdp library */ settings->ConfigPath = config_dir_buf; /* will be freed by freerdp library */
(*env)->ReleaseStringUTFChars(env, jdirectory, directory); (*env)->ReleaseStringUTFChars(env, jdirectory, directory);
return JNI_TRUE;
out_strdup_fail:
free(config_dir_buf);
out_malloc_fail:
(*env)->ReleaseStringUTFChars(env, jdirectory, directory);
return JNI_FALSE;
} }
JNIEXPORT void JNICALL jni_freerdp_set_connection_info(JNIEnv *env, jclass cls, jint instance, JNIEXPORT jboolean JNICALL jni_freerdp_set_connection_info(JNIEnv *env, jclass cls, jint instance,
jstring jhostname, jstring jusername, jstring jpassword, jstring jdomain, jint width, jint height, jstring jhostname, jstring jusername, jstring jpassword, jstring jdomain, jint width, jint height,
jint color_depth, jint port, jboolean console, jint security, jstring jcertname) jint color_depth, jint port, jboolean console, jint security, jstring jcertname)
{ {
freerdp* inst = (freerdp*)instance; freerdp* inst = (freerdp*)instance;
rdpSettings * settings = inst->settings; rdpSettings * settings = inst->settings;
const jbyte *hostname = (*env)->GetStringUTFChars(env, jhostname, NULL); const jbyte *hostname;
const jbyte *username = (*env)->GetStringUTFChars(env, jusername, NULL); const jbyte *username;
const jbyte *password = (*env)->GetStringUTFChars(env, jpassword, NULL); const jbyte *password;
const jbyte *domain = (*env)->GetStringUTFChars(env, jdomain, NULL); const jbyte *domain;
const jbyte *certname = (*env)->GetStringUTFChars(env, jcertname, NULL); const jbyte *certname;
if(!(hostname = (*env)->GetStringUTFChars(env, jhostname, NULL)))
return JNI_FALSE;
if (!(username = (*env)->GetStringUTFChars(env, jusername, NULL)))
goto out_fail_username;
if (!(password = (*env)->GetStringUTFChars(env, jpassword, NULL)))
goto out_fail_password;
if (!(domain = (*env)->GetStringUTFChars(env, jdomain, NULL)))
goto out_fail_domain;
if (!(certname = (*env)->GetStringUTFChars(env, jcertname, NULL)))
goto out_fail_certname;
DEBUG_ANDROID("hostname: %s", (char*) hostname); DEBUG_ANDROID("hostname: %s", (char*) hostname);
DEBUG_ANDROID("username: %s", (char*) username); DEBUG_ANDROID("username: %s", (char*) username);
@ -779,21 +828,30 @@ JNIEXPORT void JNICALL jni_freerdp_set_connection_info(JNIEnv *env, jclass cls,
if (color_depth <= 16) if (color_depth <= 16)
settings->DesktopWidth &= (~1); settings->DesktopWidth &= (~1);
settings->ServerHostname = strdup(hostname); if (!(settings->ServerHostname = strdup(hostname)))
goto out_fail_strdup;
if (username && strlen(username) > 0) if (username && strlen(username) > 0)
settings->Username = strdup(username); {
if (!(settings->Username = strdup(username)))
goto out_fail_strdup;
}
if (password && strlen(password) > 0) if (password && strlen(password) > 0)
{ {
settings->Password = strdup(password); if (!(settings->Password = strdup(password)))
goto out_fail_strdup;
settings->AutoLogonEnabled = TRUE; settings->AutoLogonEnabled = TRUE;
} }
settings->Domain = strdup(domain); if (!(settings->Domain = strdup(domain)))
goto out_fail_strdup;
if (certname && strlen(certname) > 0) if (certname && strlen(certname) > 0)
settings->CertificateName = strdup(certname); {
if (!(settings->CertificateName = strdup(certname)))
goto out_fail_strdup;
}
settings->ConsoleSession = (console == JNI_TRUE) ? TRUE : FALSE; settings->ConsoleSession = (console == JNI_TRUE) ? TRUE : FALSE;
@ -840,7 +898,20 @@ JNIEXPORT void JNICALL jni_freerdp_set_connection_info(JNIEnv *env, jclass cls,
(*env)->ReleaseStringUTFChars(env, jdomain, domain); (*env)->ReleaseStringUTFChars(env, jdomain, domain);
(*env)->ReleaseStringUTFChars(env, jcertname, certname); (*env)->ReleaseStringUTFChars(env, jcertname, certname);
return; return JNI_TRUE;
out_fail_strdup:
(*env)->ReleaseStringUTFChars(env, jcertname, certname);
out_fail_certname:
(*env)->ReleaseStringUTFChars(env, jdomain, domain);
out_fail_domain:
(*env)->ReleaseStringUTFChars(env, jpassword, password);
out_fail_password:
(*env)->ReleaseStringUTFChars(env, jusername, username);
out_fail_username:
(*env)->ReleaseStringUTFChars(env, jhostname, hostname);
return JNI_FALSE;
} }
JNIEXPORT void JNICALL jni_freerdp_set_performance_flags( JNIEXPORT void JNICALL jni_freerdp_set_performance_flags(
@ -881,16 +952,23 @@ JNIEXPORT void JNICALL jni_freerdp_set_performance_flags(
DEBUG_ANDROID("performance_flags: %04X", settings->PerformanceFlags); DEBUG_ANDROID("performance_flags: %04X", settings->PerformanceFlags);
} }
JNIEXPORT void JNICALL jni_freerdp_set_advanced_settings(JNIEnv *env, jclass cls, JNIEXPORT jboolean JNICALL jni_freerdp_set_advanced_settings(JNIEnv *env, jclass cls,
jint instance, jstring jRemoteProgram, jstring jWorkDir, jint instance, jstring jRemoteProgram, jstring jWorkDir,
jboolean async_channel, jboolean async_transport, jboolean async_input, jboolean async_channel, jboolean async_transport, jboolean async_input,
jboolean async_update) jboolean async_update)
{ {
freerdp* inst = (freerdp*)instance; freerdp* inst = (freerdp*)instance;
rdpSettings * settings = inst->settings; rdpSettings * settings = inst->settings;
jboolean ret = JNI_FALSE;
const jbyte *remote_program = (*env)->GetStringUTFChars(env, jRemoteProgram, NULL); const jbyte *remote_program;
const jbyte *work_dir = (*env)->GetStringUTFChars(env, jWorkDir, NULL); const jbyte *work_dir;
if (!(remote_program = (*env)->GetStringUTFChars(env, jRemoteProgram, NULL)))
return JNI_FALSE;
if (!(work_dir = (*env)->GetStringUTFChars(env, jWorkDir, NULL)))
goto out_fail_work_dir;
DEBUG_ANDROID("Remote Program: %s", (char*) remote_program); DEBUG_ANDROID("Remote Program: %s", (char*) remote_program);
DEBUG_ANDROID("Work Dir: %s", (char*) work_dir); DEBUG_ANDROID("Work Dir: %s", (char*) work_dir);
@ -902,36 +980,56 @@ JNIEXPORT void JNICALL jni_freerdp_set_advanced_settings(JNIEnv *env, jclass cls
settings->AsyncInput = async_input; settings->AsyncInput = async_input;
if (remote_program && strlen(remote_program) > 0) if (remote_program && strlen(remote_program) > 0)
settings->AlternateShell = strdup(remote_program); {
if (!(settings->AlternateShell = strdup(remote_program)))
goto out_fail_strdup;
}
if (work_dir && strlen(work_dir) > 0) if (work_dir && strlen(work_dir) > 0)
settings->ShellWorkingDirectory = strdup(work_dir); {
if (!(settings->ShellWorkingDirectory = strdup(work_dir)))
goto out_fail_strdup;
}
(*env)->ReleaseStringUTFChars(env, jRemoteProgram, remote_program); ret = JNI_TRUE;
out_fail_strdup:
(*env)->ReleaseStringUTFChars(env, jWorkDir, work_dir); (*env)->ReleaseStringUTFChars(env, jWorkDir, work_dir);
out_fail_work_dir:
(*env)->ReleaseStringUTFChars(env, jRemoteProgram, remote_program);
return ret;
} }
JNIEXPORT void JNICALL jni_freerdp_set_drive_redirection(JNIEnv *env, jclass cls, jint instance, jstring jpath) JNIEXPORT jboolean JNICALL jni_freerdp_set_drive_redirection(JNIEnv *env, jclass cls, jint instance, jstring jpath)
{ {
freerdp* inst = (freerdp*)instance; freerdp* inst = (freerdp*)instance;
rdpSettings * settings = inst->settings; rdpSettings * settings = inst->settings;
char* args[] = {"drive", "Android", ""}; char* args[] = {"drive", "Android", ""};
jboolean ret = JNI_FALSE;
const jbyte *path = (*env)->GetStringUTFChars(env, jpath, NULL); const jbyte *path = (*env)->GetStringUTFChars(env, jpath, NULL);
if (!path)
return JNI_FALSE;
DEBUG_ANDROID("drive redirect: %s", (char*)path); DEBUG_ANDROID("drive redirect: %s", (char*)path);
args[2] = (char*)path; args[2] = (char*)path;
freerdp_client_add_device_channel(settings, 3, args); if (freerdp_client_add_device_channel(settings, 3, args) == -1)
{
settings->DeviceRedirection = FALSE;
goto out_fail;
}
settings->DeviceRedirection = TRUE; settings->DeviceRedirection = TRUE;
ret = JNI_TRUE;
out_fail:
(*env)->ReleaseStringUTFChars(env, jpath, path); (*env)->ReleaseStringUTFChars(env, jpath, path);
return ret;
} }
JNIEXPORT void JNICALL jni_freerdp_set_sound_redirection(JNIEnv *env, JNIEXPORT jboolean JNICALL jni_freerdp_set_sound_redirection(JNIEnv *env,
jclass cls, jint instance, jint redirect) jclass cls, jint instance, jint redirect)
{ {
char** p;
int count = 1;
freerdp* inst = (freerdp*)instance; freerdp* inst = (freerdp*)instance;
rdpSettings * settings = inst->settings; rdpSettings * settings = inst->settings;
@ -939,23 +1037,24 @@ JNIEXPORT void JNICALL jni_freerdp_set_sound_redirection(JNIEnv *env,
redirect ? ((redirect == 1) ? "Server" : "Redirect") : "None"); redirect ? ((redirect == 1) ? "Server" : "Redirect") : "None");
settings->AudioPlayback = (redirect == 2) ? TRUE : FALSE; settings->AudioPlayback = (redirect == 2) ? TRUE : FALSE;
settings->RemoteConsoleAudio = (redirect == 1) ? TRUE : FALSE;
if (settings->AudioPlayback) if (settings->AudioPlayback)
{ {
p = malloc(sizeof(char*)); int ret;
p[0] = "rdpsnd"; char* p[1] = {"rdpsnd"};
int count = 1;
freerdp_client_add_static_channel(settings, count, p); ret = freerdp_client_add_static_channel(settings, count, p);
free(p); if(ret == -1)
return JNI_FALSE;
} }
settings->RemoteConsoleAudio = (redirect == 1) ? TRUE : FALSE;
return JNI_TRUE;
} }
JNIEXPORT void JNICALL jni_freerdp_set_microphone_redirection(JNIEnv *env, JNIEXPORT jboolean JNICALL jni_freerdp_set_microphone_redirection(JNIEnv *env,
jclass cls, jint instance, jboolean enable) jclass cls, jint instance, jboolean enable)
{ {
char** p;
int count = 1;
freerdp* inst = (freerdp*)instance; freerdp* inst = (freerdp*)instance;
rdpSettings * settings = inst->settings; rdpSettings * settings = inst->settings;
@ -964,13 +1063,17 @@ JNIEXPORT void JNICALL jni_freerdp_set_microphone_redirection(JNIEnv *env,
settings->AudioCapture = enable; settings->AudioCapture = enable;
if (enable) if (enable)
{ {
p = malloc(sizeof(char*)); int ret;
p[0] = "audin"; char* p[1] = {"audin"};
int count = 1;
freerdp_client_add_dynamic_channel(settings, count, p); ret = freerdp_client_add_dynamic_channel(settings, count, p);
if (ret == -1)
return JNI_FALSE;
free(p);
} }
return JNI_TRUE;
} }
JNIEXPORT void JNICALL jni_freerdp_set_clipboard_redirection(JNIEnv *env, jclass cls, jint instance, jboolean enable) JNIEXPORT void JNICALL jni_freerdp_set_clipboard_redirection(JNIEnv *env, jclass cls, jint instance, jboolean enable)
@ -983,16 +1086,26 @@ JNIEXPORT void JNICALL jni_freerdp_set_clipboard_redirection(JNIEnv *env, jclass
settings->RedirectClipboard = enable ? TRUE : FALSE; settings->RedirectClipboard = enable ? TRUE : FALSE;
} }
JNIEXPORT void JNICALL jni_freerdp_set_gateway_info(JNIEnv *env, jclass cls, jint instance, jstring jgatewayhostname, jint port, JNIEXPORT jboolean JNICALL jni_freerdp_set_gateway_info(JNIEnv *env, jclass cls, jint instance, jstring jgatewayhostname, jint port,
jstring jgatewayusername, jstring jgatewaypassword, jstring jgatewaydomain) jstring jgatewayusername, jstring jgatewaypassword, jstring jgatewaydomain)
{ {
freerdp* inst = (freerdp*)instance; freerdp* inst = (freerdp*)instance;
rdpSettings * settings = inst->settings; rdpSettings * settings = inst->settings;
jboolean ret = JNI_FALSE;
const jbyte *gatewayhostname = (*env)->GetStringUTFChars(env, jgatewayhostname, NULL); const jbyte *gatewayhostname;
const jbyte *gatewayusername = (*env)->GetStringUTFChars(env, jgatewayusername, NULL); const jbyte *gatewayusername;
const jbyte *gatewaypassword = (*env)->GetStringUTFChars(env, jgatewaypassword, NULL); const jbyte *gatewaypassword;
const jbyte *gatewaydomain = (*env)->GetStringUTFChars(env, jgatewaydomain, NULL); const jbyte *gatewaydomain;
if (!(gatewayhostname = (*env)->GetStringUTFChars(env, jgatewayhostname, NULL)))
return JNI_FALSE;
if (!(gatewayusername = (*env)->GetStringUTFChars(env, jgatewayusername, NULL)))
goto out_fail_username;
if (!(gatewaypassword = (*env)->GetStringUTFChars(env, jgatewaypassword, NULL)))
goto out_fail_password;
if (!(gatewaydomain = (*env)->GetStringUTFChars(env, jgatewaydomain, NULL)))
goto out_fail_domain;
DEBUG_ANDROID("gatewayhostname: %s", (char*) gatewayhostname); DEBUG_ANDROID("gatewayhostname: %s", (char*) gatewayhostname);
DEBUG_ANDROID("gatewayport: %d", port); DEBUG_ANDROID("gatewayport: %d", port);
@ -1000,19 +1113,33 @@ JNIEXPORT void JNICALL jni_freerdp_set_gateway_info(JNIEnv *env, jclass cls, jin
DEBUG_ANDROID("gatewaypassword: %s", (char*) gatewaypassword); DEBUG_ANDROID("gatewaypassword: %s", (char*) gatewaypassword);
DEBUG_ANDROID("gatewaydomain: %s", (char*) gatewaydomain); DEBUG_ANDROID("gatewaydomain: %s", (char*) gatewaydomain);
settings->GatewayHostname = strdup(gatewayhostname);
settings->GatewayPort = port; settings->GatewayPort = port;
settings->GatewayUsername = strdup(gatewayusername);
settings->GatewayPassword = strdup(gatewaypassword);
settings->GatewayDomain = strdup(gatewaydomain);
settings->GatewayUsageMethod = TSC_PROXY_MODE_DIRECT; settings->GatewayUsageMethod = TSC_PROXY_MODE_DIRECT;
settings->GatewayEnabled = TRUE; settings->GatewayEnabled = TRUE;
settings->GatewayUseSameCredentials = FALSE; settings->GatewayUseSameCredentials = FALSE;
settings->GatewayHostname = strdup(gatewayhostname);
settings->GatewayUsername = strdup(gatewayusername);
settings->GatewayPassword = strdup(gatewaypassword);
settings->GatewayDomain = strdup(gatewaydomain);
if (!settings->GatewayHostname || !settings->GatewayUsername ||
!settings->GatewayPassword || !settings->GatewayDomain)
{
goto out_fail_strdup;
}
(*env)->ReleaseStringUTFChars(env, jgatewayhostname, gatewayhostname);
(*env)->ReleaseStringUTFChars(env, jgatewayusername, gatewayusername); ret = JNI_TRUE;
(*env)->ReleaseStringUTFChars(env, jgatewaypassword, gatewaypassword);
out_fail_strdup:
(*env)->ReleaseStringUTFChars(env, jgatewaydomain, gatewaydomain); (*env)->ReleaseStringUTFChars(env, jgatewaydomain, gatewaydomain);
out_fail_domain:
(*env)->ReleaseStringUTFChars(env, jgatewaypassword, gatewaypassword);
out_fail_password:
(*env)->ReleaseStringUTFChars(env, jgatewayusername, gatewayusername);
out_fail_username:
(*env)->ReleaseStringUTFChars(env, jgatewayhostname, gatewayhostname);
return ret;
} }
static void copy_pixel_buffer(UINT8* dstBuf, UINT8* srcBuf, int x, int y, int width, int height, int wBuf, int hBuf, int bpp) static void copy_pixel_buffer(UINT8* dstBuf, UINT8* srcBuf, int x, int y, int width, int height, int wBuf, int hBuf, int bpp)
@ -1065,7 +1192,7 @@ JNIEXPORT jboolean JNICALL jni_freerdp_update_graphics(
return JNI_TRUE; return JNI_TRUE;
} }
JNIEXPORT void JNICALL jni_freerdp_send_key_event( JNIEXPORT jboolean JNICALL jni_freerdp_send_key_event(
JNIEnv *env, jclass cls, jint instance, jint keycode, jboolean down) JNIEnv *env, jclass cls, jint instance, jint keycode, jboolean down)
{ {
DWORD scancode; DWORD scancode;
@ -1077,54 +1204,86 @@ JNIEXPORT void JNICALL jni_freerdp_send_key_event(
int flags = (down == JNI_TRUE) ? KBD_FLAGS_DOWN : KBD_FLAGS_RELEASE; int flags = (down == JNI_TRUE) ? KBD_FLAGS_DOWN : KBD_FLAGS_RELEASE;
flags |= (scancode & KBDEXT) ? KBD_FLAGS_EXTENDED : 0; flags |= (scancode & KBDEXT) ? KBD_FLAGS_EXTENDED : 0;
event = (ANDROID_EVENT*) android_event_key_new(flags, scancode & 0xFF); event = (ANDROID_EVENT*) android_event_key_new(flags, scancode & 0xFF);
if (!event)
return JNI_FALSE;
android_push_event(inst, event); if (!android_push_event(inst, event))
{
android_event_key_free((ANDROID_EVENT_KEY *)event);
return JNI_FALSE;
}
DEBUG_ANDROID("send_key_event: %d, %d", (int)scancode, flags); DEBUG_ANDROID("send_key_event: %d, %d", (int)scancode, flags);
return JNI_TRUE;
} }
JNIEXPORT void JNICALL jni_freerdp_send_unicodekey_event( JNIEXPORT jboolean JNICALL jni_freerdp_send_unicodekey_event(
JNIEnv *env, jclass cls, jint instance, jint keycode) JNIEnv *env, jclass cls, jint instance, jint keycode)
{ {
ANDROID_EVENT* event; ANDROID_EVENT* event;
freerdp* inst = (freerdp*)instance; freerdp* inst = (freerdp*)instance;
event = (ANDROID_EVENT*) android_event_unicodekey_new(keycode); event = (ANDROID_EVENT*) android_event_unicodekey_new(keycode);
android_push_event(inst, event); if (!event)
return JNI_FALSE;
if (!android_push_event(inst, event))
{
android_event_unicodekey_free((ANDROID_EVENT_KEY *)event);
return JNI_FALSE;
}
DEBUG_ANDROID("send_unicodekey_event: %d", keycode); DEBUG_ANDROID("send_unicodekey_event: %d", keycode);
return JNI_TRUE;
} }
JNIEXPORT void JNICALL jni_freerdp_send_cursor_event( JNIEXPORT jboolean JNICALL jni_freerdp_send_cursor_event(
JNIEnv *env, jclass cls, jint instance, jint x, jint y, jint flags) JNIEnv *env, jclass cls, jint instance, jint x, jint y, jint flags)
{ {
ANDROID_EVENT* event; ANDROID_EVENT* event;
freerdp* inst = (freerdp*)instance; freerdp* inst = (freerdp*)instance;
event = (ANDROID_EVENT*) android_event_cursor_new(flags, x, y); event = (ANDROID_EVENT*) android_event_cursor_new(flags, x, y);
android_push_event(inst, event); if (!event)
return JNI_FALSE;
if (!android_push_event(inst, event))
{
android_event_cursor_free((ANDROID_EVENT_CURSOR *)event);
return JNI_FALSE;
}
DEBUG_ANDROID("send_cursor_event: (%d, %d), %d", x, y, flags); DEBUG_ANDROID("send_cursor_event: (%d, %d), %d", x, y, flags);
return JNI_TRUE;
} }
JNIEXPORT void JNICALL jni_freerdp_send_clipboard_data(JNIEnv *env, jclass cls, jint instance, jstring jdata) JNIEXPORT jboolean JNICALL jni_freerdp_send_clipboard_data(JNIEnv *env, jclass cls, jint instance, jstring jdata)
{ {
ANDROID_EVENT* event; ANDROID_EVENT* event;
freerdp* inst = (freerdp*)instance; freerdp* inst = (freerdp*)instance;
const jbyte *data = jdata != NULL ? (*env)->GetStringUTFChars(env, jdata, NULL) : NULL; const jbyte *data = jdata != NULL ? (*env)->GetStringUTFChars(env, jdata, NULL) : NULL;
int data_length = data ? strlen(data) : 0; int data_length = data ? strlen(data) : 0;
jboolean ret = JNI_FALSE;;
event = (ANDROID_EVENT*) android_event_clipboard_new((void*)data, data_length); event = (ANDROID_EVENT*) android_event_clipboard_new((void*)data, data_length);
android_push_event(inst, event); if (!event)
goto out_fail;
if (!android_push_event(inst, event))
{
android_event_clipboard_free((ANDROID_EVENT_CLIPBOARD *)event);
goto out_fail;
}
DEBUG_ANDROID("send_clipboard_data: (%s)", data); DEBUG_ANDROID("send_clipboard_data: (%s)", data);
ret = JNI_TRUE;
out_fail:
if (data) if (data)
(*env)->ReleaseStringUTFChars(env, jdata, data); (*env)->ReleaseStringUTFChars(env, jdata, data);
return ret;
} }
JNIEXPORT jstring JNICALL jni_freerdp_get_version(JNIEnv *env, jclass cls) JNIEXPORT jstring JNICALL jni_freerdp_get_version(JNIEnv *env, jclass cls)
{ {
return (*env)->NewStringUTF(env, GIT_REVISION); return (*env)->NewStringUTF(env, GIT_REVISION);
} }

View File

@ -44,27 +44,27 @@ JNIEXPORT jint JNICALL jni_freerdp_new(JNIEnv *env, jclass cls);
JNIEXPORT void JNICALL jni_freerdp_free(JNIEnv *env, jclass cls, jint instance); JNIEXPORT void JNICALL jni_freerdp_free(JNIEnv *env, jclass cls, jint instance);
JNIEXPORT jboolean JNICALL jni_freerdp_connect(JNIEnv *env, jclass cls, jint instance); JNIEXPORT jboolean JNICALL jni_freerdp_connect(JNIEnv *env, jclass cls, jint instance);
JNIEXPORT jboolean JNICALL jni_freerdp_disconnect(JNIEnv *env, jclass cls, jint instance); JNIEXPORT jboolean JNICALL jni_freerdp_disconnect(JNIEnv *env, jclass cls, jint instance);
JNIEXPORT void JNICALL jni_freerdp_cancel_connection(JNIEnv *env, jclass cls, jint instance); JNIEXPORT jboolean JNICALL jni_freerdp_cancel_connection(JNIEnv *env, jclass cls, jint instance);
JNIEXPORT void JNICALL jni_freerdp_set_connection_info(JNIEnv *env, jclass cls, jint instance, JNIEXPORT jboolean JNICALL jni_freerdp_set_connection_info(JNIEnv *env, jclass cls, jint instance,
jstring jhostname, jstring jusername, jstring jpassword, jstring jdomain, jint width, jstring jhostname, jstring jusername, jstring jpassword, jstring jdomain, jint width,
jint height, jint color_depth, jint port, jboolean console, jint security, jstring jcertname); jint height, jint color_depth, jint port, jboolean console, jint security, jstring jcertname);
JNIEXPORT void JNICALL jni_freerdp_set_performance_flags(JNIEnv *env, jclass cls, jint instance, jboolean remotefx, jboolean disableWallpaper, jboolean disableFullWindowDrag, JNIEXPORT void JNICALL jni_freerdp_set_performance_flags(JNIEnv *env, jclass cls, jint instance, jboolean remotefx, jboolean disableWallpaper, jboolean disableFullWindowDrag,
jboolean disableMenuAnimations, jboolean disableTheming, jboolean enableFontSmoothing, jboolean enableDesktopComposition); jboolean disableMenuAnimations, jboolean disableTheming, jboolean enableFontSmoothing, jboolean enableDesktopComposition);
JNIEXPORT void JNICALL jni_freerdp_set_advanced_settings(JNIEnv *env, jclass cls, JNIEXPORT jboolean JNICALL jni_freerdp_set_advanced_settings(JNIEnv *env, jclass cls,
jint instance, jstring jRemoteProgram, jstring jWorkDir, jint instance, jstring jRemoteProgram, jstring jWorkDir,
jboolean async_channel, jboolean async_transport, jboolean async_input, jboolean async_channel, jboolean async_transport, jboolean async_input,
jboolean async_update); jboolean async_update);
JNIEXPORT void JNICALL jni_freerdp_set_drive_redirection(JNIEnv *env, jclass cls, jint instance, jstring jpath); JNIEXPORT jboolean JNICALL jni_freerdp_set_drive_redirection(JNIEnv *env, jclass cls, jint instance, jstring jpath);
JNIEXPORT void JNICALL jni_freerdp_set_sound_redirection(JNIEnv *env, jclass cls, jint instance, jint redirect); JNIEXPORT jboolean JNICALL jni_freerdp_set_sound_redirection(JNIEnv *env, jclass cls, jint instance, jint redirect);
JNIEXPORT void JNICALL jni_freerdp_set_microphone_redirection(JNIEnv *env, jclass cls, jint instance, jboolean enable); JNIEXPORT jboolean JNICALL jni_freerdp_set_microphone_redirection(JNIEnv *env, jclass cls, jint instance, jboolean enable);
JNIEXPORT void JNICALL jni_freerdp_set_clipboard_redirection(JNIEnv *env, jclass cls, jint instance, jboolean enable); JNIEXPORT void JNICALL jni_freerdp_set_clipboard_redirection(JNIEnv *env, jclass cls, jint instance, jboolean enable);
JNIEXPORT void JNICALL jni_freerdp_set_gateway_info(JNIEnv *env, jclass cls, jint instance, jstring jgatewayhostname, jint port, jstring jgatewayusername, jstring jgatewaypassword, jstring jgatewaydomain); JNIEXPORT jboolean JNICALL jni_freerdp_set_gateway_info(JNIEnv *env, jclass cls, jint instance, jstring jgatewayhostname, jint port, jstring jgatewayusername, jstring jgatewaypassword, jstring jgatewaydomain);
JNIEXPORT void JNICALL jni_freerdp_set_data_directory(JNIEnv *env, jclass cls, jint instance, jstring jdirectory); JNIEXPORT jboolean JNICALL jni_freerdp_set_data_directory(JNIEnv *env, jclass cls, jint instance, jstring jdirectory);
JNIEXPORT jboolean JNICALL jni_freerdp_update_graphics(JNIEnv *env, jclass cls, jint instance, jobject bitmap, jint x, jint y, jint width, jint height); JNIEXPORT jboolean JNICALL jni_freerdp_update_graphics(JNIEnv *env, jclass cls, jint instance, jobject bitmap, jint x, jint y, jint width, jint height);
JNIEXPORT void JNICALL jni_freerdp_send_cursor_event(JNIEnv *env, jclass cls, jint instance, jint x, jint y, jint flags); JNIEXPORT jboolean JNICALL jni_freerdp_send_cursor_event(JNIEnv *env, jclass cls, jint instance, jint x, jint y, jint flags);
JNIEXPORT void JNICALL jni_freerdp_send_key_event(JNIEnv *env, jclass cls, jint instance, jint keycode, jboolean down); JNIEXPORT jboolean JNICALL jni_freerdp_send_key_event(JNIEnv *env, jclass cls, jint instance, jint keycode, jboolean down);
JNIEXPORT void JNICALL jni_freerdp_send_unicodekey_event(JNIEnv *env, jclass cls, jint instance, jint keycode); JNIEXPORT jboolean JNICALL jni_freerdp_send_unicodekey_event(JNIEnv *env, jclass cls, jint instance, jint keycode);
JNIEXPORT void JNICALL jni_freerdp_send_clipboard_data(JNIEnv *env, jclass cls, jint instance, jstring jdata); JNIEXPORT jboolean JNICALL jni_freerdp_send_clipboard_data(JNIEnv *env, jclass cls, jint instance, jstring jdata);
JNIEXPORT jstring JNICALL jni_freerdp_get_version(JNIEnv *env, jclass cls); JNIEXPORT jstring JNICALL jni_freerdp_get_version(JNIEnv *env, jclass cls);
#endif /* __ANDROID_FREERDP_H */ #endif /* __ANDROID_FREERDP_H */

View File

@ -99,6 +99,8 @@ char* get_string_from_string_builder(JNIEnv* env, jobject strBuilder)
// read string // read string
native_str = (*env)->GetStringUTFChars(env, strObj, NULL); native_str = (*env)->GetStringUTFChars(env, strObj, NULL);
if (!native_str)
return NULL;
result = strdup(native_str); result = strdup(native_str);
(*env)->ReleaseStringUTFChars(env, strObj, native_str); (*env)->ReleaseStringUTFChars(env, strObj, native_str);

View File

@ -40,32 +40,32 @@ JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_free
return jni_freerdp_disconnect(env, cls, instance); return jni_freerdp_disconnect(env, cls, instance);
} }
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1cancel_1connection(JNIEnv *env, jclass cls, jint instance) JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1cancel_1connection(JNIEnv *env, jclass cls, jint instance)
{ {
jni_freerdp_cancel_connection(env, cls, instance); return jni_freerdp_cancel_connection(env, cls, instance);
} }
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1connection_1info(JNIEnv *env, jclass cls, jint instance, JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1connection_1info(JNIEnv *env, jclass cls, jint instance,
jstring jhostname, jstring jusername, jstring jpassword, jstring jdomain, jint width, jint height, jint color_depth, jint port, jstring jhostname, jstring jusername, jstring jpassword, jstring jdomain, jint width, jint height, jint color_depth, jint port,
jboolean console, jint security, jstring certname) jboolean console, jint security, jstring certname)
{ {
jni_freerdp_set_connection_info(env, cls, instance, jhostname, jusername, jpassword, jdomain, return jni_freerdp_set_connection_info(env, cls, instance, jhostname, jusername, jpassword, jdomain,
width, height, color_depth, port, console, security, certname); width, height, color_depth, port, console, security, certname);
} }
JNIEXPORT void JNICALL JNIEXPORT jboolean JNICALL
Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1advanced_1settings( Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1advanced_1settings(
JNIEnv *env, jclass cls, jint instance, jstring remote_program, jstring work_dir, JNIEnv *env, jclass cls, jint instance, jstring remote_program, jstring work_dir,
jboolean async_channel, jboolean async_transport, jboolean async_input, jboolean async_channel, jboolean async_transport, jboolean async_input,
jboolean async_update) jboolean async_update)
{ {
jni_freerdp_set_advanced_settings(env, cls, instance, remote_program, work_dir, return jni_freerdp_set_advanced_settings(env, cls, instance, remote_program, work_dir,
async_channel, async_transport, async_input, async_update); async_channel, async_transport, async_input, async_update);
} }
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1data_1directory(JNIEnv *env, jclass cls, jint instance, jstring directory) JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1data_1directory(JNIEnv *env, jclass cls, jint instance, jstring directory)
{ {
jni_freerdp_set_data_directory(env, cls, instance, directory); return jni_freerdp_set_data_directory(env, cls, instance, directory);
} }
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1performance_1flags( JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1performance_1flags(
@ -81,28 +81,28 @@ JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_
jni_freerdp_set_clipboard_redirection(env, cls, inst, enable); jni_freerdp_set_clipboard_redirection(env, cls, inst, enable);
} }
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1sound_1redirection JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1sound_1redirection
(JNIEnv *env, jclass cls, jint inst, jint redirect) (JNIEnv *env, jclass cls, jint inst, jint redirect)
{ {
jni_freerdp_set_sound_redirection(env, cls, inst, redirect); return jni_freerdp_set_sound_redirection(env, cls, inst, redirect);
} }
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1microphone_1redirection JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1microphone_1redirection
(JNIEnv *env, jclass cls, jint inst, jboolean redirect) (JNIEnv *env, jclass cls, jint inst, jboolean redirect)
{ {
jni_freerdp_set_microphone_redirection(env, cls, inst, redirect); return jni_freerdp_set_microphone_redirection(env, cls, inst, redirect);
} }
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1drive_1redirection JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1drive_1redirection
(JNIEnv *env, jclass cls, jint inst, jstring path) (JNIEnv *env, jclass cls, jint inst, jstring path)
{ {
jni_freerdp_set_drive_redirection(env, cls, inst, path); return jni_freerdp_set_drive_redirection(env, cls, inst, path);
} }
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1gateway_1info JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1gateway_1info
(JNIEnv *env, jclass cls, jint inst, jstring hostname, jint port, jstring username, jstring password, jstring domain) (JNIEnv *env, jclass cls, jint inst, jstring hostname, jint port, jstring username, jstring password, jstring domain)
{ {
jni_freerdp_set_gateway_info(env, cls, inst, hostname, port, username, password, domain); return jni_freerdp_set_gateway_info(env, cls, inst, hostname, port, username, password, domain);
} }
JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1update_1graphics( JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1update_1graphics(
@ -111,28 +111,28 @@ JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_free
return jni_freerdp_update_graphics(env, cls, instance, bitmap, x, y, width, height); return jni_freerdp_update_graphics(env, cls, instance, bitmap, x, y, width, height);
} }
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1send_1cursor_1event( JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1send_1cursor_1event(
JNIEnv *env, jclass cls, jint instance, jint x, jint y, jint flags) JNIEnv *env, jclass cls, jint instance, jint x, jint y, jint flags)
{ {
jni_freerdp_send_cursor_event(env, cls, instance, x, y, flags); return jni_freerdp_send_cursor_event(env, cls, instance, x, y, flags);
} }
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1send_1key_1event( JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1send_1key_1event(
JNIEnv *env, jclass cls, jint instance, jint keycode, jboolean down) JNIEnv *env, jclass cls, jint instance, jint keycode, jboolean down)
{ {
jni_freerdp_send_key_event(env, cls, instance, keycode, down); return jni_freerdp_send_key_event(env, cls, instance, keycode, down);
} }
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1send_1unicodekey_1event JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1send_1unicodekey_1event
(JNIEnv *env, jclass cls, jint instance, jint keycode) (JNIEnv *env, jclass cls, jint instance, jint keycode)
{ {
jni_freerdp_send_unicodekey_event(env, cls, instance, keycode); return jni_freerdp_send_unicodekey_event(env, cls, instance, keycode);
} }
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1send_1clipboard_1data JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1send_1clipboard_1data
(JNIEnv *env, jclass cls, jint instance, jstring data) (JNIEnv *env, jclass cls, jint instance, jstring data)
{ {
jni_freerdp_send_clipboard_data(env, cls, instance, data); return jni_freerdp_send_clipboard_data(env, cls, instance, data);
} }
JNIEXPORT jstring JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1get_1version(JNIEnv *env, jclass cls) JNIEXPORT jstring JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1get_1version(JNIEnv *env, jclass cls)

View File

@ -42,17 +42,17 @@ JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_free
/* /*
* Class: com_freerdp_freerdpcore_services_LibFreeRDP * Class: com_freerdp_freerdpcore_services_LibFreeRDP
* Method: freerdp_cancel_connection * Method: freerdp_cancel_connection
* Signature: (I)V * Signature: (I)Z
*/ */
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1cancel_1connection JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1cancel_1connection
(JNIEnv *, jclass, jint); (JNIEnv *, jclass, jint);
/* /*
* Class: com_freerdp_freerdpcore_services_LibFreeRDP * Class: com_freerdp_freerdpcore_services_LibFreeRDP
* Method: freerdp_set_connection_info * Method: freerdp_set_connection_info
* Signature: (ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIIZILjava/lang/String;)V * Signature: (ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIIZILjava/lang/String;)Z
*/ */
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1connection_1info JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1connection_1info
(JNIEnv *, jclass, jint, jstring, jstring, jstring, jstring, jint, jint, jint, jint, jboolean, jint, jstring); (JNIEnv *, jclass, jint, jstring, jstring, jstring, jstring, jint, jint, jint, jint, jboolean, jint, jstring);
/* /*
@ -66,17 +66,17 @@ JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_
/* /*
* Class: com_freerdp_freerdpcore_services_LibFreeRDP * Class: com_freerdp_freerdpcore_services_LibFreeRDP
* Method: freerdp_set_advanced_settings * Method: freerdp_set_advanced_settings
* Signature: (ILjava/lang/String;Ljava/lang/String;ZZZZ)V * Signature: (ILjava/lang/String;Ljava/lang/String;ZZZZ)Z
*/ */
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1advanced_1settings JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1advanced_1settings
(JNIEnv *, jclass, jint, jstring, jstring, jboolean, jboolean, jboolean, jboolean); (JNIEnv *, jclass, jint, jstring, jstring, jboolean, jboolean, jboolean, jboolean);
/* /*
* Class: com_freerdp_freerdpcore_services_LibFreeRDP * Class: com_freerdp_freerdpcore_services_LibFreeRDP
* Method: freerdp_set_data_directory * Method: freerdp_set_data_directory
* Signature: (ILjava/lang/String;)V * Signature: (ILjava/lang/String;)Z
*/ */
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1data_1directory JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1data_1directory
(JNIEnv *, jclass, jint, jstring); (JNIEnv *, jclass, jint, jstring);
/* /*
@ -90,33 +90,33 @@ JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_
/* /*
* Class: com_freerdp_freerdpcore_services_LibFreeRDP * Class: com_freerdp_freerdpcore_services_LibFreeRDP
* Method: freerdp_set_sound_redirection * Method: freerdp_set_sound_redirection
* Signature: (IZ)V * Signature: (II)Z
*/ */
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1sound_1redirection JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1sound_1redirection
(JNIEnv *, jclass, jint, jint); (JNIEnv *, jclass, jint, jint);
/* /*
* Class: com_freerdp_freerdpcore_services_LibFreeRDP * Class: com_freerdp_freerdpcore_services_LibFreeRDP
* Method: freerdp_set_microphone_redirection * Method: freerdp_set_microphone_redirection
* Signature: (IZ)V * Signature: (IZ)Z
*/ */
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1microphone_1redirection JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1microphone_1redirection
(JNIEnv *, jclass, jint, jboolean); (JNIEnv *, jclass, jint, jboolean);
/* /*
* Class: com_freerdp_freerdpcore_services_LibFreeRDP * Class: com_freerdp_freerdpcore_services_LibFreeRDP
* Method: freerdp_set_drive_redirection * Method: freerdp_set_drive_redirection
* Signature: (ILjava/lang/String;)V * Signature: (ILjava/lang/String;)Z
*/ */
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1drive_1redirection JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1drive_1redirection
(JNIEnv *, jclass, jint, jstring); (JNIEnv *, jclass, jint, jstring);
/* /*
* Class: com_freerdp_freerdpcore_services_LibFreeRDP * Class: com_freerdp_freerdpcore_services_LibFreeRDP
* Method: freerdp_set_gateway_info * Method: freerdp_set_gateway_info
* Signature: (ILjava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V * Signature: (ILjava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z
*/ */
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1gateway_1info JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1gateway_1info
(JNIEnv *, jclass, jint, jstring, jint, jstring, jstring, jstring); (JNIEnv *, jclass, jint, jstring, jint, jstring, jstring, jstring);
/* /*
@ -130,33 +130,33 @@ JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_free
/* /*
* Class: com_freerdp_freerdpcore_services_LibFreeRDP * Class: com_freerdp_freerdpcore_services_LibFreeRDP
* Method: freerdp_send_cursor_event * Method: freerdp_send_cursor_event
* Signature: (IIII)V * Signature: (IIII)Z
*/ */
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1send_1cursor_1event JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1send_1cursor_1event
(JNIEnv *, jclass, jint, jint, jint, jint); (JNIEnv *, jclass, jint, jint, jint, jint);
/* /*
* Class: com_freerdp_freerdpcore_services_LibFreeRDP * Class: com_freerdp_freerdpcore_services_LibFreeRDP
* Method: freerdp_send_key_event * Method: freerdp_send_key_event
* Signature: (IIZ)V * Signature: (IIZ)Z
*/ */
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1send_1key_1event JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1send_1key_1event
(JNIEnv *, jclass, jint, jint, jboolean); (JNIEnv *, jclass, jint, jint, jboolean);
/* /*
* Class: com_freerdp_freerdpcore_services_LibFreeRDP * Class: com_freerdp_freerdpcore_services_LibFreeRDP
* Method: freerdp_send_unicodekey_event * Method: freerdp_send_unicodekey_event
* Signature: (II)V * Signature: (II)Z
*/ */
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1send_1unicodekey_1event JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1send_1unicodekey_1event
(JNIEnv *, jclass, jint, jint); (JNIEnv *, jclass, jint, jint);
/* /*
* Class: com_freerdp_freerdpcore_services_LibFreeRDP * Class: com_freerdp_freerdpcore_services_LibFreeRDP
* Method: freerdp_send_clipboard_data * Method: freerdp_send_clipboard_data
* Signature: (ILjava/lang/String;)V * Signature: (ILjava/lang/String;)Z
*/ */
JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1send_1clipboard_1data JNIEXPORT jboolean JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1send_1clipboard_1data
(JNIEnv *, jclass, jint, jstring); (JNIEnv *, jclass, jint, jstring);
/* /*

View File

@ -23,9 +23,9 @@ public class LibFreeRDP
private static native void freerdp_free(int inst); private static native void freerdp_free(int inst);
private static native boolean freerdp_connect(int inst); private static native boolean freerdp_connect(int inst);
private static native boolean freerdp_disconnect(int inst); private static native boolean freerdp_disconnect(int inst);
private static native void freerdp_cancel_connection(int inst); private static native boolean freerdp_cancel_connection(int inst);
private static native void freerdp_set_connection_info(int inst, private static native boolean freerdp_set_connection_info(int inst,
String hostname, String username, String password, String domain, String hostname, String username, String password, String domain,
int width, int height, int color_depth, int port, boolean console, int width, int height, int color_depth, int port, boolean console,
int security, String certname); int security, String certname);
@ -35,27 +35,27 @@ public class LibFreeRDP
boolean disableMenuAnimations, boolean disableTheming, boolean disableMenuAnimations, boolean disableTheming,
boolean enableFontSmoothing, boolean enableDesktopComposition); boolean enableFontSmoothing, boolean enableDesktopComposition);
private static native void freerdp_set_advanced_settings(int inst, private static native boolean freerdp_set_advanced_settings(int inst,
String remoteProgram, String workDir, boolean async_channel, String remoteProgram, String workDir, boolean async_channel,
boolean async_transport, boolean async_input, boolean async_update); boolean async_transport, boolean async_input, boolean async_update);
private static native void freerdp_set_data_directory(int inst, String directory); private static native boolean freerdp_set_data_directory(int inst, String directory);
private static native void freerdp_set_clipboard_redirection(int inst, boolean enable); private static native void freerdp_set_clipboard_redirection(int inst, boolean enable);
private static native void freerdp_set_sound_redirection(int inst, int redirect); private static native boolean freerdp_set_sound_redirection(int inst, int redirect);
private static native void freerdp_set_microphone_redirection(int inst, boolean enable); private static native boolean freerdp_set_microphone_redirection(int inst, boolean enable);
private static native void freerdp_set_drive_redirection(int inst, String path); private static native boolean freerdp_set_drive_redirection(int inst, String path);
private static native void freerdp_set_gateway_info(int inst, String gatewayhostname, int port, private static native boolean freerdp_set_gateway_info(int inst, String gatewayhostname, int port,
String gatewayusername, String gatewaypassword, String gatewaydomain); String gatewayusername, String gatewaypassword, String gatewaydomain);
private static native boolean freerdp_update_graphics(int inst, private static native boolean freerdp_update_graphics(int inst,
Bitmap bitmap, int x, int y, int width, int height); Bitmap bitmap, int x, int y, int width, int height);
private static native void freerdp_send_cursor_event(int inst, int x, int y, int flags); private static native boolean freerdp_send_cursor_event(int inst, int x, int y, int flags);
private static native void freerdp_send_key_event(int inst, int keycode, boolean down); private static native boolean freerdp_send_key_event(int inst, int keycode, boolean down);
private static native void freerdp_send_unicodekey_event(int inst, int keycode); private static native boolean freerdp_send_unicodekey_event(int inst, int keycode);
private static native void freerdp_send_clipboard_data(int inst, String data); private static native boolean freerdp_send_clipboard_data(int inst, String data);
private static native String freerdp_get_version(); private static native String freerdp_get_version();
@ -106,9 +106,9 @@ public class LibFreeRDP
return freerdp_disconnect(inst); return freerdp_disconnect(inst);
} }
public static void cancelConnection(int inst) public static boolean cancelConnection(int inst)
{ {
freerdp_cancel_connection(inst); return freerdp_cancel_connection(inst);
} }
public static boolean setConnectionInfo(int inst, BookmarkBase bookmark) public static boolean setConnectionInfo(int inst, BookmarkBase bookmark)
@ -185,9 +185,9 @@ public class LibFreeRDP
return true; return true;
} }
public static void setDataDirectory(int inst, String directory) public static boolean setDataDirectory(int inst, String directory)
{ {
freerdp_set_data_directory(inst, directory); return freerdp_set_data_directory(inst, directory);
} }
public static boolean updateGraphics(int inst, Bitmap bitmap, int x, int y, int width, int height) public static boolean updateGraphics(int inst, Bitmap bitmap, int x, int y, int width, int height)
@ -195,24 +195,24 @@ public class LibFreeRDP
return freerdp_update_graphics(inst, bitmap, x, y, width, height); return freerdp_update_graphics(inst, bitmap, x, y, width, height);
} }
public static void sendCursorEvent(int inst, int x, int y, int flags) public static boolean sendCursorEvent(int inst, int x, int y, int flags)
{ {
freerdp_send_cursor_event(inst, x, y, flags); return freerdp_send_cursor_event(inst, x, y, flags);
} }
public static void sendKeyEvent(int inst, int keycode, boolean down) public static boolean sendKeyEvent(int inst, int keycode, boolean down)
{ {
freerdp_send_key_event(inst, keycode, down); return freerdp_send_key_event(inst, keycode, down);
} }
public static void sendUnicodeKeyEvent(int inst, int keycode) public static boolean sendUnicodeKeyEvent(int inst, int keycode)
{ {
freerdp_send_unicodekey_event(inst, keycode); return freerdp_send_unicodekey_event(inst, keycode);
} }
public static void sendClipboardData(int inst, String data) public static boolean sendClipboardData(int inst, String data)
{ {
freerdp_send_clipboard_data(inst, data); return freerdp_send_clipboard_data(inst, data);
} }
private static void OnConnectionSuccess(int inst) private static void OnConnectionSuccess(int inst)

View File

@ -179,9 +179,7 @@ BOOL df_pre_connect(freerdp* instance)
freerdp_channels_pre_connect(instance->context->channels, instance); freerdp_channels_pre_connect(instance->context->channels, instance);
instance->context->cache = cache_new(instance->settings); return (instance->context->cache = cache_new(instance->settings)) != NULL;
return TRUE;
} }
BOOL df_post_connect(freerdp* instance) BOOL df_post_connect(freerdp* instance)
@ -237,9 +235,7 @@ BOOL df_post_connect(freerdp* instance)
pointer_cache_register_callbacks(instance->update); pointer_cache_register_callbacks(instance->update);
df_register_graphics(instance->context->graphics); df_register_graphics(instance->context->graphics);
freerdp_channels_post_connect(instance->context->channels, instance); return freerdp_channels_post_connect(instance->context->channels, instance) >= 0;
return TRUE;
} }
BOOL df_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint) BOOL df_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint)

View File

@ -122,9 +122,7 @@ static BOOL tf_post_connect(freerdp* instance)
instance->update->BeginPaint = tf_begin_paint; instance->update->BeginPaint = tf_begin_paint;
instance->update->EndPaint = tf_end_paint; instance->update->EndPaint = tf_end_paint;
freerdp_channels_post_connect(instance->context->channels, instance); return (freerdp_channels_post_connect(instance->context->channels, instance) >= 0);
return TRUE;
} }
static void* tf_client_thread_proc(freerdp* instance) static void* tf_client_thread_proc(freerdp* instance)

View File

@ -149,9 +149,9 @@ wlfWindow* wlf_CreateDesktopWindow(wlfContext* wlfc, char* name, int width, int
wlf_ResizeDesktopWindow(wlfc, window, width, height); wlf_ResizeDesktopWindow(wlfc, window, width, height);
wl_surface_damage(window->surface, 0, 0, window->width, window->height); wl_surface_damage(window->surface, 0, 0, window->width, window->height);
}
wlf_SetWindowText(wlfc, window, name); wlf_SetWindowText(wlfc, window, name);
}
return window; return window;
} }

View File

@ -142,7 +142,7 @@ static BOOL wl_post_connect(freerdp* instance)
/* put Wayland data in the context here */ /* put Wayland data in the context here */
context->window = window; context->window = window;
if (freerdp_channels_post_connect(instance->context->channels, instance)) if (freerdp_channels_post_connect(instance->context->channels, instance) < 0)
return FALSE; return FALSE;
wlf_UpdateWindowArea(context, window, 0, 0, gdi->width, gdi->height); wlf_UpdateWindowArea(context, window, 0, 0, gdi->width, gdi->height);

View File

@ -50,6 +50,7 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
rdpContext* context; rdpContext* context;
rdpSettings* settings; rdpSettings* settings;
RDP_CLIENT_ENTRY_POINTS clientEntryPoints; RDP_CLIENT_ENTRY_POINTS clientEntryPoints;
int ret = 0;
ZeroMemory(&clientEntryPoints, sizeof(RDP_CLIENT_ENTRY_POINTS)); ZeroMemory(&clientEntryPoints, sizeof(RDP_CLIENT_ENTRY_POINTS));
clientEntryPoints.Size = sizeof(RDP_CLIENT_ENTRY_POINTS); clientEntryPoints.Size = sizeof(RDP_CLIENT_ENTRY_POINTS);
@ -66,9 +67,26 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
context->argc = __argc; context->argc = __argc;
context->argv = (char**) malloc(sizeof(char*) * __argc); context->argv = (char**) malloc(sizeof(char*) * __argc);
if (!context->argv)
{
ret = 1;
goto out;
}
for (index = 0; index < context->argc; index++) for (index = 0; index < context->argc; index++)
{
context->argv[index] = _strdup(__argv[index]); context->argv[index] = _strdup(__argv[index]);
if (!context->argv[index])
{
ret = 1;
for (--index; index >= 0; --index)
free(context->argv[index]);
free(context->argv);
context->argv = NULL;
goto out;
}
}
status = freerdp_client_settings_parse_command_line(settings, context->argc, context->argv, FALSE); status = freerdp_client_settings_parse_command_line(settings, context->argc, context->argv, FALSE);
@ -89,8 +107,8 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
GetExitCodeThread(thread, &dwExitCode); GetExitCodeThread(thread, &dwExitCode);
freerdp_client_stop(context); freerdp_client_stop(context);
out:
freerdp_client_context_free(context); freerdp_client_context_free(context);
return 0; return ret;
} }

View File

@ -275,7 +275,8 @@ BOOL wf_pre_connect(freerdp* instance)
wfc->clrconv->palette = NULL; wfc->clrconv->palette = NULL;
wfc->clrconv->alpha = FALSE; wfc->clrconv->alpha = FALSE;
instance->context->cache = cache_new(settings); if (!(instance->context->cache = cache_new(settings)))
return FALSE;
desktopWidth = settings->DesktopWidth; desktopWidth = settings->DesktopWidth;
desktopHeight = settings->DesktopHeight; desktopHeight = settings->DesktopHeight;
@ -321,7 +322,7 @@ BOOL wf_pre_connect(freerdp* instance)
(settings->DesktopWidth > 4096) || (settings->DesktopHeight > 4096)) (settings->DesktopWidth > 4096) || (settings->DesktopHeight > 4096))
{ {
WLog_ERR(TAG, "invalid dimensions %d %d", settings->DesktopWidth, settings->DesktopHeight); WLog_ERR(TAG, "invalid dimensions %d %d", settings->DesktopWidth, settings->DesktopHeight);
return 1; return FALSE;
} }
freerdp_set_param_uint32(settings, FreeRDP_KeyboardLayout, (int) GetKeyboardLayout(0) & 0x0000FFFF); freerdp_set_param_uint32(settings, FreeRDP_KeyboardLayout, (int) GetKeyboardLayout(0) & 0x0000FFFF);
@ -484,7 +485,8 @@ BOOL wf_post_connect(freerdp* instance)
instance->update->BitmapUpdate = wf_gdi_bitmap_update; instance->update->BitmapUpdate = wf_gdi_bitmap_update;
} }
freerdp_channels_post_connect(context->channels, instance); if (freerdp_channels_post_connect(context->channels, instance) < 0)
return FALSE;
if (wfc->fullscreen) if (wfc->fullscreen)
floatbar_window_create(wfc); floatbar_window_create(wfc);
@ -492,8 +494,6 @@ BOOL wf_post_connect(freerdp* instance)
return TRUE; return TRUE;
} }
static const char wfTargetName[] = "TARGET";
static CREDUI_INFOA wfUiInfo = static CREDUI_INFOA wfUiInfo =
{ {
sizeof(CREDUI_INFOA), sizeof(CREDUI_INFOA),
@ -518,7 +518,9 @@ BOOL wf_authenticate(freerdp* instance, char** username, char** password, char**
ZeroMemory(Password, sizeof(Password)); ZeroMemory(Password, sizeof(Password));
dwFlags = CREDUI_FLAGS_DO_NOT_PERSIST | CREDUI_FLAGS_EXCLUDE_CERTIFICATES; dwFlags = CREDUI_FLAGS_DO_NOT_PERSIST | CREDUI_FLAGS_EXCLUDE_CERTIFICATES;
status = CredUIPromptForCredentialsA(&wfUiInfo, wfTargetName, NULL, 0, status = CredUIPromptForCredentialsA(&wfUiInfo,
instance->settings->ServerHostname,
NULL, 0,
UserName, CREDUI_MAX_USERNAME_LENGTH + 1, UserName, CREDUI_MAX_USERNAME_LENGTH + 1,
Password, CREDUI_MAX_PASSWORD_LENGTH + 1, &fSave, dwFlags); Password, CREDUI_MAX_PASSWORD_LENGTH + 1, &fSave, dwFlags);
@ -534,11 +536,31 @@ BOOL wf_authenticate(freerdp* instance, char** username, char** password, char**
status = CredUIParseUserNameA(UserName, User, sizeof(User), Domain, sizeof(Domain)); status = CredUIParseUserNameA(UserName, User, sizeof(User), Domain, sizeof(Domain));
//WLog_ERR(TAG, "User: %s Domain: %s Password: %s", User, Domain, Password); //WLog_ERR(TAG, "User: %s Domain: %s Password: %s", User, Domain, Password);
*username = _strdup(User); *username = _strdup(User);
if (!(*username))
{
WLog_ERR(TAG, "strdup failed", status);
return FALSE;
}
if (strlen(Domain) > 0) if (strlen(Domain) > 0)
*domain = _strdup(Domain); *domain = _strdup(Domain);
else
*domain = _strdup("\0");
if (!(*domain))
{
free(*username);
WLog_ERR(TAG, "strdup failed", status);
return FALSE;
}
*password = _strdup(Password); *password = _strdup(Password);
if (!(*password))
{
free(*username);
free(*domain);
return FALSE;
}
return TRUE; return TRUE;
} }
@ -871,6 +893,10 @@ int freerdp_client_load_settings_from_rdp_file(wfContext* wfc, char* filename)
if (filename) if (filename)
{ {
settings->ConnectionFile = _strdup(filename); settings->ConnectionFile = _strdup(filename);
if (!settings->ConnectionFile)
{
return 3;
}
// free old settings file // free old settings file
freerdp_client_rdp_file_free(wfc->connectionRdpFile); freerdp_client_rdp_file_free(wfc->connectionRdpFile);

View File

@ -552,6 +552,8 @@ BOOL xf_create_window(xfContext* xfc)
if (settings->WindowTitle) if (settings->WindowTitle)
{ {
windowTitle = _strdup(settings->WindowTitle); windowTitle = _strdup(settings->WindowTitle);
if (!windowTitle)
return FALSE;
} }
else if (settings->ServerPort == 3389) else if (settings->ServerPort == 3389)
{ {
@ -999,6 +1001,8 @@ BOOL xf_pre_connect(freerdp* instance)
if (login_name) if (login_name)
{ {
settings->Username = _strdup(login_name); settings->Username = _strdup(login_name);
if (!settings->Username)
return FALSE;
WLog_INFO(TAG, "No user name set. - Using login name: %s", settings->Username); WLog_INFO(TAG, "No user name set. - Using login name: %s", settings->Username);
} }
} }
@ -1016,9 +1020,13 @@ BOOL xf_pre_connect(freerdp* instance)
} }
if (!context->cache) if (!context->cache)
context->cache = cache_new(settings); {
if (!(context->cache = cache_new(settings)))
return FALSE;
}
xf_keyboard_init(xfc); if (!xf_keyboard_init(xfc))
return FALSE;
xf_detect_monitors(xfc, &maxWidth, &maxHeight); xf_detect_monitors(xfc, &maxWidth, &maxHeight);
@ -1165,7 +1173,8 @@ BOOL xf_post_connect(freerdp* instance)
update->SetKeyboardIndicators = xf_keyboard_set_indicators; update->SetKeyboardIndicators = xf_keyboard_set_indicators;
xfc->clipboard = xf_clipboard_new(xfc); xfc->clipboard = xf_clipboard_new(xfc);
freerdp_channels_post_connect(channels, instance); if (freerdp_channels_post_connect(channels, instance) < 0)
return FALSE;
EventArgsInit(&e, "xfreerdp"); EventArgsInit(&e, "xfreerdp");
e.width = settings->DesktopWidth; e.width = settings->DesktopWidth;
@ -1186,6 +1195,8 @@ static void xf_post_disconnect(freerdp* instance)
context = instance->context; context = instance->context;
xfc = (xfContext*) context; xfc = (xfContext*) context;
freerdp_channels_disconnect(context->channels, instance);
gdi_free(instance); gdi_free(instance);
if (xfc->clipboard) if (xfc->clipboard)
@ -1203,8 +1214,6 @@ static void xf_post_disconnect(freerdp* instance)
} }
xf_keyboard_free(xfc); xf_keyboard_free(xfc);
freerdp_channels_disconnect(context->channels, instance);
} }
/** Callback set in the rdp_freerdp structure, and used to get the user's password, /** Callback set in the rdp_freerdp structure, and used to get the user's password,
@ -1422,8 +1431,8 @@ void* xf_client_thread(void* param)
xfContext* xfc; xfContext* xfc;
freerdp* instance; freerdp* instance;
rdpContext* context; rdpContext* context;
HANDLE inputEvent; HANDLE inputEvent = NULL;
HANDLE inputThread; HANDLE inputThread = NULL;
rdpChannels* channels; rdpChannels* channels;
rdpSettings* settings; rdpSettings* settings;
@ -1781,7 +1790,7 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context)
xfc->invert = (ImageByteOrder(xfc->display) == MSBFirst) ? TRUE : FALSE; xfc->invert = (ImageByteOrder(xfc->display) == MSBFirst) ? TRUE : FALSE;
xfc->complex_regions = TRUE; xfc->complex_regions = TRUE;
xfc->x11event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfc->xfds); xfc->x11event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfc->xfds, WINPR_FD_READ);
if (!xfc->x11event) if (!xfc->x11event)
{ {
WLog_ERR(TAG, "Could not create xfds event"); WLog_ERR(TAG, "Could not create xfds event");

View File

@ -838,7 +838,20 @@ static WIN32ERROR xf_cliprdr_server_format_list(CliprdrClientContext* context, C
{ {
format = &formatList->formats[i]; format = &formatList->formats[i];
clipboard->serverFormats[i].formatId = format->formatId; clipboard->serverFormats[i].formatId = format->formatId;
clipboard->serverFormats[i].formatName = _strdup(format->formatName); if (format->formatName)
{
clipboard->serverFormats[i].formatName = _strdup(format->formatName);
if (!clipboard->serverFormats[i].formatName)
{
for (--i; i >= 0; --i)
free(clipboard->serverFormats[i].formatName);
clipboard->numServerFormats = 0;
free(clipboard->serverFormats);
clipboard->serverFormats = NULL;
return -1;
}
}
} }
clipboard->numTargets = 2; clipboard->numTargets = 2;
@ -1106,6 +1119,12 @@ xfClipboard* xf_clipboard_new(xfContext* xfc)
clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "text/html", False); clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "text/html", False);
clipboard->clientFormats[n].formatId = CB_FORMAT_HTML; clipboard->clientFormats[n].formatId = CB_FORMAT_HTML;
clipboard->clientFormats[n].formatName = _strdup("HTML Format"); clipboard->clientFormats[n].formatName = _strdup("HTML Format");
if (!clipboard->clientFormats[n].formatName)
{
ClipboardDestroy(clipboard->system);
free(clipboard);
return NULL;
}
n++; n++;
clipboard->numClientFormats = n; clipboard->numClientFormats = n;

View File

@ -87,7 +87,6 @@ const char* const X11_EVENT_STRINGS[] =
BOOL xf_event_action_script_init(xfContext* xfc) BOOL xf_event_action_script_init(xfContext* xfc)
{ {
int exitCode;
char* xevent; char* xevent;
FILE* actionScript; FILE* actionScript;
char buffer[1024] = { 0 }; char buffer[1024] = { 0 };
@ -102,18 +101,22 @@ BOOL xf_event_action_script_init(xfContext* xfc)
actionScript = popen(command, "r"); actionScript = popen(command, "r");
if (actionScript < 0) if (!actionScript)
return FALSE; return FALSE;
while (fgets(buffer, sizeof(buffer), actionScript)) while (fgets(buffer, sizeof(buffer), actionScript))
{ {
strtok(buffer, "\n"); strtok(buffer, "\n");
xevent = _strdup(buffer); xevent = _strdup(buffer);
if (ArrayList_Add(xfc->xevents, xevent) < 0) if (!xevent || ArrayList_Add(xfc->xevents, xevent) < 0)
{
ArrayList_Free(xfc->xevents);
xfc->xevents = NULL;
return FALSE; return FALSE;
}
} }
exitCode = pclose(actionScript); pclose(actionScript);
return TRUE; return TRUE;
} }
@ -127,23 +130,22 @@ void xf_event_action_script_free(xfContext* xfc)
} }
} }
int xf_event_execute_action_script(xfContext* xfc, XEvent* event) static BOOL xf_event_execute_action_script(xfContext* xfc, XEvent* event)
{ {
int index; int index;
int count; int count;
char* name; char* name;
int exitCode;
FILE* actionScript; FILE* actionScript;
BOOL match = FALSE; BOOL match = FALSE;
const char* xeventName; const char* xeventName;
char buffer[1024] = { 0 }; char buffer[1024] = { 0 };
char command[1024] = { 0 }; char command[1024] = { 0 };
if (!xfc->actionScript) if (!xfc->actionScript || !xfc->xevents)
return 1; return FALSE;
if (event->type > (sizeof(X11_EVENT_STRINGS) / sizeof(const char*))) if (event->type > (sizeof(X11_EVENT_STRINGS) / sizeof(const char*)))
return 1; return FALSE;
xeventName = X11_EVENT_STRINGS[event->type]; xeventName = X11_EVENT_STRINGS[event->type];
@ -161,24 +163,24 @@ int xf_event_execute_action_script(xfContext* xfc, XEvent* event)
} }
if (!match) if (!match)
return 1; return FALSE;
sprintf_s(command, sizeof(command), "%s xevent %s %d", sprintf_s(command, sizeof(command), "%s xevent %s %d",
xfc->actionScript, xeventName, (int) xfc->window->handle); xfc->actionScript, xeventName, (int) xfc->window->handle);
actionScript = popen(command, "r"); actionScript = popen(command, "r");
if (actionScript < 0) if (!actionScript)
return -1; return FALSE;
while (fgets(buffer, sizeof(buffer), actionScript)) while (fgets(buffer, sizeof(buffer), actionScript))
{ {
strtok(buffer, "\n"); strtok(buffer, "\n");
} }
exitCode = pclose(actionScript); pclose(actionScript);
return 1; return TRUE;
} }
void xf_event_adjust_coordinates(xfContext* xfc, int* x, int *y) void xf_event_adjust_coordinates(xfContext* xfc, int* x, int *y)

View File

@ -221,7 +221,7 @@ BOOL xf_set_rop3(xfContext* xfc, int rop3)
UINT32 xf_convert_rdp_order_color(xfContext* xfc, UINT32 color) UINT32 xf_convert_rdp_order_color(xfContext* xfc, UINT32 color)
{ {
UINT32 r, g, b; UINT32 r = 0, g = 0, b = 0;
switch (xfc->srcBpp) switch (xfc->srcBpp)
{ {

View File

@ -112,7 +112,7 @@ int xf_OutputUpdate(xfContext* xfc, xfGfxSurface* surface)
region16_clear(&surface->invalidRegion); region16_clear(&surface->invalidRegion);
XSetClipMask(xfc->display, xfc->gc, None); XSetClipMask(xfc->display, xfc->gc, None);
XSync(xfc->display, True); XSync(xfc->display, False);
return 1; return 1;
} }

View File

@ -45,7 +45,6 @@
BOOL xf_keyboard_action_script_init(xfContext* xfc) BOOL xf_keyboard_action_script_init(xfContext* xfc)
{ {
int exitCode;
FILE* keyScript; FILE* keyScript;
char* keyCombination; char* keyCombination;
char buffer[1024] = { 0 }; char buffer[1024] = { 0 };
@ -61,11 +60,11 @@ BOOL xf_keyboard_action_script_init(xfContext* xfc)
xfc->actionScript = _strdup("/usr/share/freerdp/action.sh"); xfc->actionScript = _strdup("/usr/share/freerdp/action.sh");
if (!xfc->actionScript) if (!xfc->actionScript)
return 0; return FALSE;
xfc->keyCombinations = ArrayList_New(TRUE); xfc->keyCombinations = ArrayList_New(TRUE);
if (!xfc->keyCombinations) if (!xfc->keyCombinations)
return 0; return FALSE;
ArrayList_Object(xfc->keyCombinations)->fnObjectFree = free; ArrayList_Object(xfc->keyCombinations)->fnObjectFree = free;
@ -73,24 +72,30 @@ BOOL xf_keyboard_action_script_init(xfContext* xfc)
keyScript = popen(command, "r"); keyScript = popen(command, "r");
if (keyScript < 0) if (!keyScript)
{ {
free(xfc->actionScript); free(xfc->actionScript);
xfc->actionScript = NULL; xfc->actionScript = NULL;
return 0; return FALSE;
} }
while (fgets(buffer, sizeof(buffer), keyScript) != NULL) while (fgets(buffer, sizeof(buffer), keyScript) != NULL)
{ {
strtok(buffer, "\n"); strtok(buffer, "\n");
keyCombination = _strdup(buffer); keyCombination = _strdup(buffer);
if (ArrayList_Add(xfc->keyCombinations, keyCombination) < 0) if (!keyCombination || ArrayList_Add(xfc->keyCombinations, keyCombination) < 0)
return 0; {
ArrayList_Free(xfc->keyCombinations);
free(xfc->actionScript);
xfc->actionScript = NULL;
pclose(keyScript);
return FALSE;
}
} }
exitCode = pclose(keyScript); pclose(keyScript);
return xf_event_action_script_init(xfc); return xf_event_action_script_init(xfc);
} }
void xf_keyboard_action_script_free(xfContext* xfc) void xf_keyboard_action_script_free(xfContext* xfc)
@ -110,7 +115,7 @@ void xf_keyboard_action_script_free(xfContext* xfc)
} }
} }
void xf_keyboard_init(xfContext* xfc) BOOL xf_keyboard_init(xfContext* xfc)
{ {
xf_keyboard_clear(xfc); xf_keyboard_clear(xfc);
@ -121,9 +126,11 @@ void xf_keyboard_init(xfContext* xfc)
if (xfc->modifierMap) if (xfc->modifierMap)
XFreeModifiermap(xfc->modifierMap); XFreeModifiermap(xfc->modifierMap);
xfc->modifierMap = XGetModifierMapping(xfc->display); if (!(xfc->modifierMap = XGetModifierMapping(xfc->display)))
return FALSE;
xf_keyboard_action_script_init(xfc); xf_keyboard_action_script_init(xfc);
return TRUE;
} }
void xf_keyboard_free(xfContext* xfc) void xf_keyboard_free(xfContext* xfc)
@ -407,7 +414,7 @@ int xf_keyboard_execute_action_script(xfContext* xfc, XF_MODIFIER_KEYS* mod, Key
keyScript = popen(command, "r"); keyScript = popen(command, "r");
if (keyScript < 0) if (!keyScript)
return -1; return -1;
while (fgets(buffer, sizeof(buffer), keyScript) != NULL) while (fgets(buffer, sizeof(buffer), keyScript) != NULL)

View File

@ -44,7 +44,7 @@ struct _XF_MODIFIER_KEYS
}; };
typedef struct _XF_MODIFIER_KEYS XF_MODIFIER_KEYS; typedef struct _XF_MODIFIER_KEYS XF_MODIFIER_KEYS;
void xf_keyboard_init(xfContext* xfc); BOOL xf_keyboard_init(xfContext* xfc);
void xf_keyboard_free(xfContext* xfc); void xf_keyboard_free(xfContext* xfc);
void xf_keyboard_clear(xfContext* xfc); void xf_keyboard_clear(xfContext* xfc);
void xf_keyboard_key_press(xfContext* xfc, BYTE keycode, KeySym keysym); void xf_keyboard_key_press(xfContext* xfc, BYTE keycode, KeySym keysym);

View File

@ -312,6 +312,11 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI
{ {
appWindow->title = _strdup("RdpRailWindow"); appWindow->title = _strdup("RdpRailWindow");
} }
if (!appWindow->title)
{
free(appWindow);
return FALSE;
}
HashTable_Add(xfc->railWindows, (void*) (UINT_PTR) orderInfo->windowId, (void*) appWindow); HashTable_Add(xfc->railWindows, (void*) (UINT_PTR) orderInfo->windowId, (void*) appWindow);

View File

@ -187,6 +187,7 @@ int xf_tsmf_xv_video_frame_event(TsmfClientContext* tsmf, TSMF_VIDEO_FRAME_EVENT
else else
{ {
WLog_DBG(TAG, "pixel format 0x%X not supported by hardware.", pixfmt); WLog_DBG(TAG, "pixel format 0x%X not supported by hardware.", pixfmt);
free(xrects);
return -1003; return -1003;
} }
@ -213,6 +214,7 @@ int xf_tsmf_xv_video_frame_event(TsmfClientContext* tsmf, TSMF_VIDEO_FRAME_EVENT
if (!XShmAttach(xfc->display, &shminfo)) if (!XShmAttach(xfc->display, &shminfo))
{ {
XFree(image); XFree(image);
free(xrects);
WLog_DBG(TAG, "XShmAttach failed."); WLog_DBG(TAG, "XShmAttach failed.");
return -1004; return -1004;
} }

View File

@ -36,6 +36,7 @@
#include <winpr/thread.h> #include <winpr/thread.h>
#include <winpr/crt.h> #include <winpr/crt.h>
#include <winpr/string.h>
#include <freerdp/rail.h> #include <freerdp/rail.h>
#include <freerdp/log.h> #include <freerdp/log.h>
@ -335,7 +336,7 @@ static void xf_SetWindowPID(xfContext* xfc, Window window, pid_t pid)
static const char* get_shm_id() static const char* get_shm_id()
{ {
static char shm_id[64]; static char shm_id[64];
snprintf(shm_id, sizeof(shm_id), "com.freerdp.xfreerdp.tsmf_%016X", GetCurrentProcessId()); sprintf_s(shm_id, sizeof(shm_id), "/com.freerdp.xfreerdp.tsmf_%016X", GetCurrentProcessId());
return shm_id; return shm_id;
} }
@ -368,7 +369,7 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig
CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap | CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
CWBorderPixel | CWWinGravity | CWBitGravity, &xfc->attribs); CWBorderPixel | CWWinGravity | CWBitGravity, &xfc->attribs);
window->shmid = shm_open(get_shm_id(), O_CREAT | O_EXCL | O_RDWR, S_IREAD | S_IWRITE); window->shmid = shm_open(get_shm_id(), (O_CREAT | O_RDWR), (S_IREAD | S_IWRITE));
if (window->shmid < 0) if (window->shmid < 0)
{ {
@ -382,7 +383,7 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig
mem = mmap(0, sizeof(window->handle), PROT_READ | PROT_WRITE, MAP_SHARED, window->shmid, 0); mem = mmap(0, sizeof(window->handle), PROT_READ | PROT_WRITE, MAP_SHARED, window->shmid, 0);
if (mem == ((int*) -1)) if (mem == MAP_FAILED)
{ {
DEBUG_X11("xf_CreateDesktopWindow: failed to assign pointer to the memory address - shmat()\n"); DEBUG_X11("xf_CreateDesktopWindow: failed to assign pointer to the memory address - shmat()\n");
} }
@ -659,7 +660,7 @@ int xf_AppWindowInit(xfContext* xfc, xfAppWindow* appWindow)
else else
{ {
class = malloc(sizeof("RAIL:00000000")); class = malloc(sizeof("RAIL:00000000"));
snprintf(class, sizeof("RAIL:00000000"), "RAIL:%08X", appWindow->windowId); sprintf_s(class, sizeof("RAIL:00000000"), "RAIL:%08X", appWindow->windowId);
class_hints->res_class = class; class_hints->res_class = class;
} }

View File

@ -213,13 +213,20 @@ int freerdp_client_settings_parse_command_line(rdpSettings* settings, int argc,
int freerdp_client_settings_parse_connection_file(rdpSettings* settings, const char* filename) int freerdp_client_settings_parse_connection_file(rdpSettings* settings, const char* filename)
{ {
rdpFile* file; rdpFile* file;
int ret = -1;
file = freerdp_client_rdp_file_new(); file = freerdp_client_rdp_file_new();
freerdp_client_parse_rdp_file(file, filename); if (!file)
freerdp_client_populate_settings_from_rdp_file(file, settings); return -1;
freerdp_client_rdp_file_free(file); if (!freerdp_client_parse_rdp_file(file, filename))
goto out;
if (!freerdp_client_populate_settings_from_rdp_file(file, settings))
goto out;
return 0; ret = 0;
out:
freerdp_client_rdp_file_free(file);
return ret;
} }
int freerdp_client_settings_parse_connection_file_buffer(rdpSettings* settings, const BYTE* buffer, size_t size) int freerdp_client_settings_parse_connection_file_buffer(rdpSettings* settings, const BYTE* buffer, size_t size)
@ -228,6 +235,8 @@ int freerdp_client_settings_parse_connection_file_buffer(rdpSettings* settings,
int status = -1; int status = -1;
file = freerdp_client_rdp_file_new(); file = freerdp_client_rdp_file_new();
if (!file)
return -1;
if (freerdp_client_parse_rdp_file_buffer(file, buffer, size) if (freerdp_client_parse_rdp_file_buffer(file, buffer, size)
&& freerdp_client_populate_settings_from_rdp_file(file, settings)) && freerdp_client_populate_settings_from_rdp_file(file, settings))
@ -243,18 +252,23 @@ int freerdp_client_settings_parse_connection_file_buffer(rdpSettings* settings,
int freerdp_client_settings_write_connection_file(const rdpSettings* settings, const char* filename, BOOL unicode) int freerdp_client_settings_write_connection_file(const rdpSettings* settings, const char* filename, BOOL unicode)
{ {
rdpFile* file; rdpFile* file;
int ret = -1;
file = freerdp_client_rdp_file_new(); file = freerdp_client_rdp_file_new();
if (!file)
return -1;
if (!freerdp_client_populate_rdp_file_from_settings(file, settings)) if (!freerdp_client_populate_rdp_file_from_settings(file, settings))
return -1; goto out;
if (!freerdp_client_write_rdp_file(file, filename, unicode)) if (!freerdp_client_write_rdp_file(file, filename, unicode))
return -1; goto out;
ret = 0;
out:
freerdp_client_rdp_file_free(file); freerdp_client_rdp_file_free(file);
return 0; return ret;
} }
int freerdp_client_settings_parse_assistance_file(rdpSettings* settings, const char* filename) int freerdp_client_settings_parse_assistance_file(rdpSettings* settings, const char* filename)

View File

@ -91,10 +91,10 @@ COMMAND_LINE_ARGUMENT_A args[] =
{ "compression-level", COMMAND_LINE_VALUE_REQUIRED, "<level>", NULL, NULL, -1, NULL, "Compression level (0,1,2)" }, { "compression-level", COMMAND_LINE_VALUE_REQUIRED, "<level>", NULL, NULL, -1, NULL, "Compression level (0,1,2)" },
{ "shell", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Alternate shell" }, { "shell", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Alternate shell" },
{ "shell-dir", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Shell working directory" }, { "shell-dir", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Shell working directory" },
{ "sound", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, "audio", "Audio output (sound)" }, { "sound", COMMAND_LINE_VALUE_OPTIONAL, "[sys][dev][format][rate][channel][latency][quality]", NULL, NULL, -1, "audio", "Audio output (sound)" },
{ "microphone", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, "mic", "Audio input (microphone)" }, { "microphone", COMMAND_LINE_VALUE_OPTIONAL, "[sys][dev][format][rate][channel]", NULL, NULL, -1, "mic", "Audio input (microphone)" },
{ "audio-mode", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Audio output mode" }, { "audio-mode", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Audio output mode" },
{ "multimedia", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, "mmr", "Redirect multimedia (video)" }, { "multimedia", COMMAND_LINE_VALUE_OPTIONAL, "[sys][dev][decoder]", NULL, NULL, -1, "mmr", "Redirect multimedia (video)" },
{ "network", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Network connection type" }, { "network", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Network connection type" },
{ "drive", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Redirect drive" }, { "drive", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Redirect drive" },
{ "drives", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Redirect all drives" }, { "drives", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Redirect all drives" },
@ -104,7 +104,7 @@ COMMAND_LINE_ARGUMENT_A args[] =
{ "parallel", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, NULL, "Redirect parallel device" }, { "parallel", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, NULL, "Redirect parallel device" },
{ "smartcard", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, NULL, "Redirect smartcard device" }, { "smartcard", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, NULL, "Redirect smartcard device" },
{ "printer", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, NULL, "Redirect printer device" }, { "printer", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, NULL, "Redirect printer device" },
{ "usb", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Redirect USB device" }, { "usb", COMMAND_LINE_VALUE_REQUIRED, "[dbg][dev][id|addr][auto]", NULL, NULL, -1, NULL, "Redirect USB device" },
{ "multitouch", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Redirect multitouch input" }, { "multitouch", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Redirect multitouch input" },
{ "gestures", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Consume multitouch input locally" }, { "gestures", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Consume multitouch input locally" },
{ "echo", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, "echo", "Echo channel" }, { "echo", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, "echo", "Echo channel" },
@ -216,6 +216,8 @@ int freerdp_client_print_command_line_help(int argc, char** argv)
{ {
length = (int)(strlen(arg->Name) + strlen(arg->Format) + 2); length = (int)(strlen(arg->Name) + strlen(arg->Format) + 2);
str = (char*) calloc(length + 1UL, sizeof(char)); str = (char*) calloc(length + 1UL, sizeof(char));
if (!str)
return -1;
sprintf_s(str, length + 1, "%s:%s", arg->Name, arg->Format); sprintf_s(str, length + 1, "%s:%s", arg->Name, arg->Format);
printf("%-20s", str); printf("%-20s", str);
free(str); free(str);
@ -231,6 +233,8 @@ int freerdp_client_print_command_line_help(int argc, char** argv)
{ {
length = (int) strlen(arg->Name) + 32; length = (int) strlen(arg->Name) + 32;
str = (char*) calloc(length + 1UL, sizeof(char)); str = (char*) calloc(length + 1UL, sizeof(char));
if (!str)
return -1;
sprintf_s(str, length + 1, "%s (default:%s)", arg->Name, sprintf_s(str, length + 1, "%s (default:%s)", arg->Name,
arg->Default ? "on" : "off"); arg->Default ? "on" : "off");
@ -264,10 +268,13 @@ int freerdp_client_print_command_line_help(int argc, char** argv)
printf("Printer Redirection: /printer:<device>,<driver>\n"); printf("Printer Redirection: /printer:<device>,<driver>\n");
printf("\n"); printf("\n");
printf("Audio Output Redirection: /sound:sys:oss,dev:1,format:1\n");
printf("Audio Output Redirection: /sound:sys:alsa\n"); printf("Audio Output Redirection: /sound:sys:alsa\n");
printf("Audio Input Redirection: /microphone:sys:oss,dev:1,format:1\n");
printf("Audio Input Redirection: /microphone:sys:alsa\n"); printf("Audio Input Redirection: /microphone:sys:alsa\n");
printf("\n"); printf("\n");
printf("Multimedia Redirection: /multimedia:sys:oss,dev:/dev/dsp1,decoder:ffmpeg\n");
printf("Multimedia Redirection: /multimedia:sys:alsa\n"); printf("Multimedia Redirection: /multimedia:sys:alsa\n");
printf("USB Device Redirection: /usb:id,dev:054c:0268\n"); printf("USB Device Redirection: /usb:id,dev:054c:0268\n");
printf("\n"); printf("\n");
@ -292,7 +299,8 @@ int freerdp_client_command_line_pre_filter(void* context, int index, int argc, L
if (_stricmp(&(argv[index])[length - 4], ".rdp") == 0) if (_stricmp(&(argv[index])[length - 4], ".rdp") == 0)
{ {
settings = (rdpSettings*) context; settings = (rdpSettings*) context;
settings->ConnectionFile = _strdup(argv[index]); if (!(settings->ConnectionFile = _strdup(argv[index])))
return COMMAND_LINE_ERROR_MEMORY;
return 1; return 1;
} }
@ -303,7 +311,8 @@ int freerdp_client_command_line_pre_filter(void* context, int index, int argc, L
if (_stricmp(&(argv[index])[length - 13], ".msrcIncident") == 0) if (_stricmp(&(argv[index])[length - 13], ".msrcIncident") == 0)
{ {
settings = (rdpSettings*) context; settings = (rdpSettings*) context;
settings->AssistanceFile = _strdup(argv[index]); if (!(settings->AssistanceFile = _strdup(argv[index])))
return COMMAND_LINE_ERROR_MEMORY;
return 1; return 1;
} }
@ -332,12 +341,31 @@ int freerdp_client_add_device_channel(rdpSettings* settings, int count, char** p
drive->Type = RDPDR_DTYP_FILESYSTEM; drive->Type = RDPDR_DTYP_FILESYSTEM;
if (count > 1) if (count > 1)
drive->Name = _strdup(params[1]); {
if (!(drive->Name = _strdup(params[1])))
{
free(drive);
return -1;
}
}
if (count > 2) if (count > 2)
drive->Path = _strdup(params[2]); {
if (!(drive->Path = _strdup(params[2])))
{
free(drive->Name);
free(drive);
return -1;
}
}
freerdp_device_collection_add(settings, (RDPDR_DEVICE*) drive); if (!freerdp_device_collection_add(settings, (RDPDR_DEVICE*) drive))
{
free(drive->Path);
free(drive->Name);
free(drive);
return -1;
}
return 1; return 1;
} }
@ -361,12 +389,33 @@ int freerdp_client_add_device_channel(rdpSettings* settings, int count, char** p
printer->Type = RDPDR_DTYP_PRINT; printer->Type = RDPDR_DTYP_PRINT;
if (count > 1) if (count > 1)
printer->Name = _strdup(params[1]); {
if (!(printer->Name = _strdup(params[1])))
{
free(printer);
return -1;
}
}
if (count > 2) if (count > 2)
printer->DriverName = _strdup(params[2]); {
if (!(printer->DriverName = _strdup(params[2])))
{
free(printer->Name);
free(printer);
return -1;
}
}
if (!freerdp_device_collection_add(settings, (RDPDR_DEVICE*) printer))
{
free(printer->DriverName);
free(printer->Name);
free(printer);
return -1;
}
freerdp_device_collection_add(settings, (RDPDR_DEVICE*) printer);
} }
return 1; return 1;
@ -391,12 +440,30 @@ int freerdp_client_add_device_channel(rdpSettings* settings, int count, char** p
smartcard->Type = RDPDR_DTYP_SMARTCARD; smartcard->Type = RDPDR_DTYP_SMARTCARD;
if (count > 1) if (count > 1)
smartcard->Name = _strdup(params[1]); {
if (!(smartcard->Name = _strdup(params[1])))
{
free(smartcard);
return -1;
}
}
if (count > 2) if (count > 2)
smartcard->Path = _strdup(params[2]); {
if (!(smartcard->Path = _strdup(params[2])))
freerdp_device_collection_add(settings, (RDPDR_DEVICE*) smartcard); {
free(smartcard->Name);
free(smartcard);
return -1;
}
}
if (!freerdp_device_collection_add(settings, (RDPDR_DEVICE*) smartcard))
{
free(smartcard->Path);
free(smartcard->Name);
free(smartcard);
return -1;
}
} }
return 1; return 1;
@ -419,18 +486,56 @@ int freerdp_client_add_device_channel(rdpSettings* settings, int count, char** p
serial->Type = RDPDR_DTYP_SERIAL; serial->Type = RDPDR_DTYP_SERIAL;
if (count > 1) if (count > 1)
serial->Name = _strdup(params[1]); {
if (!(serial->Name = _strdup(params[1])))
{
free(serial);
return -1;
}
}
if (count > 2) if (count > 2)
serial->Path = _strdup(params[2]); {
if (!(serial->Path = _strdup(params[2])))
{
free(serial->Name);
free(serial);
return -1;
}
}
if (count > 3) if (count > 3)
serial->Driver = _strdup(params[3]); {
if (!(serial->Driver = _strdup(params[3])))
{
free(serial->Path);
free(serial->Name);
free(serial);
return -1;
}
}
if (count > 4) if (count > 4)
serial->Permissive = _strdup(params[4]); {
if (!(serial->Permissive = _strdup(params[4])))
{
free(serial->Driver);
free(serial->Path);
free(serial->Name);
free(serial);
return -1;
}
}
freerdp_device_collection_add(settings, (RDPDR_DEVICE*) serial); if (!freerdp_device_collection_add(settings, (RDPDR_DEVICE*) serial))
{
free(serial->Permissive);
free(serial->Driver);
free(serial->Path);
free(serial->Name);
free(serial);
return -1;
}
return 1; return 1;
} }
@ -452,12 +557,31 @@ int freerdp_client_add_device_channel(rdpSettings* settings, int count, char** p
parallel->Type = RDPDR_DTYP_PARALLEL; parallel->Type = RDPDR_DTYP_PARALLEL;
if (count > 1) if (count > 1)
parallel->Name = _strdup(params[1]); {
if (!(parallel->Name = _strdup(params[1])))
{
free(parallel);
return -1;
}
}
if (count > 2) if (count > 2)
parallel->Path = _strdup(params[2]); {
if (!(parallel->Path = _strdup(params[2])))
{
free(parallel->Name);
free(parallel);
return -1;
}
}
freerdp_device_collection_add(settings, (RDPDR_DEVICE*) parallel); if (!freerdp_device_collection_add(settings, (RDPDR_DEVICE*) parallel))
{
free(parallel->Path);
free(parallel->Name);
free(parallel);
return -1;
}
return 1; return 1;
} }
@ -470,17 +594,40 @@ int freerdp_client_add_static_channel(rdpSettings* settings, int count, char** p
int index; int index;
ADDIN_ARGV* args; ADDIN_ARGV* args;
args = (ADDIN_ARGV*) malloc(sizeof(ADDIN_ARGV)); args = (ADDIN_ARGV*) calloc(1, sizeof(ADDIN_ARGV));
if (!args)
return -1;
args->argc = count; args->argc = count;
args->argv = (char**) calloc(args->argc, sizeof(char*)); args->argv = (char**) calloc(args->argc, sizeof(char*));
if (!args->argv)
goto error_argv;
for (index = 0; index < args->argc; index++) for (index = 0; index < args->argc; index++)
{
args->argv[index] = _strdup(params[index]); args->argv[index] = _strdup(params[index]);
if (!args->argv[index])
{
for (--index; index >= 0; --index)
free(args->argv[index]);
freerdp_static_channel_collection_add(settings, args); goto error_argv_strdup;
}
}
if (!freerdp_static_channel_collection_add(settings, args))
goto error_argv_index;
return 0; return 0;
error_argv_index:
for (index = 0; index < args->argc; index++)
free(args->argv[index]);
error_argv_strdup:
free(args->argv);
error_argv:
free(args);
return -1;
} }
int freerdp_client_add_dynamic_channel(rdpSettings* settings, int count, char** params) int freerdp_client_add_dynamic_channel(rdpSettings* settings, int count, char** params)
@ -489,16 +636,39 @@ int freerdp_client_add_dynamic_channel(rdpSettings* settings, int count, char**
ADDIN_ARGV* args; ADDIN_ARGV* args;
args = (ADDIN_ARGV*) malloc(sizeof(ADDIN_ARGV)); args = (ADDIN_ARGV*) malloc(sizeof(ADDIN_ARGV));
if (!args)
return -1;
args->argc = count; args->argc = count;
args->argv = (char**) calloc(args->argc, sizeof(char*)); args->argv = (char**) calloc(args->argc, sizeof(char*));
if (!args->argv)
goto error_argv;
for (index = 0; index < args->argc; index++) for (index = 0; index < args->argc; index++)
{
args->argv[index] = _strdup(params[index]); args->argv[index] = _strdup(params[index]);
if (!args->argv[index])
{
for (--index; index >= 0; --index)
free(args->argv[index]);
freerdp_dynamic_channel_collection_add(settings, args); goto error_argv_strdup;
}
}
if (!freerdp_dynamic_channel_collection_add(settings, args))
goto error_argv_index;
return 0; return 0;
error_argv_index:
for (index = 0; index < args->argc; index++)
free(args->argv[index]);
error_argv_strdup:
free(args->argv);
error_argv:
free(args);
return -1;
} }
static char** freerdp_command_line_parse_comma_separated_values(char* list, int* count) static char** freerdp_command_line_parse_comma_separated_values(char* list, int* count)
@ -522,6 +692,8 @@ static char** freerdp_command_line_parse_comma_separated_values(char* list, int*
nArgs = nCommas + 1; nArgs = nCommas + 1;
p = (char**) calloc((nArgs + 1UL), sizeof(char*)); p = (char**) calloc((nArgs + 1UL), sizeof(char*));
if (!p)
return NULL;
str = (char*) list; str = (char*) list;
@ -553,7 +725,7 @@ static char** freerdp_command_line_parse_comma_separated_values_offset(char* lis
return NULL; return NULL;
p = t; p = t;
if (count > 0) if (count > 0)
MoveMemory(&p[1], p, sizeof(char*) * *count); MoveMemory(&p[1], p, sizeof(char*) * *count);
(*count)++; (*count)++;
return p; return p;
@ -562,6 +734,7 @@ static char** freerdp_command_line_parse_comma_separated_values_offset(char* lis
int freerdp_client_command_line_post_filter(void* context, COMMAND_LINE_ARGUMENT_A* arg) int freerdp_client_command_line_post_filter(void* context, COMMAND_LINE_ARGUMENT_A* arg)
{ {
rdpSettings* settings = (rdpSettings*) context; rdpSettings* settings = (rdpSettings*) context;
int status = 0;
CommandLineSwitchStart(arg) CommandLineSwitchStart(arg)
@ -586,7 +759,7 @@ int freerdp_client_command_line_post_filter(void* context, COMMAND_LINE_ARGUMENT
p = freerdp_command_line_parse_comma_separated_values(arg->Value, &count); p = freerdp_command_line_parse_comma_separated_values(arg->Value, &count);
freerdp_client_add_static_channel(settings, count, p); status = freerdp_client_add_static_channel(settings, count, p);
free(p); free(p);
} }
@ -712,7 +885,7 @@ int freerdp_client_command_line_post_filter(void* context, COMMAND_LINE_ARGUMENT
p = freerdp_command_line_parse_comma_separated_values_offset(arg->Value, &count); p = freerdp_command_line_parse_comma_separated_values_offset(arg->Value, &count);
p[0] = "rdpsnd"; p[0] = "rdpsnd";
freerdp_client_add_static_channel(settings, count, p); status = freerdp_client_add_static_channel(settings, count, p);
free(p); free(p);
} }
@ -724,7 +897,7 @@ int freerdp_client_command_line_post_filter(void* context, COMMAND_LINE_ARGUMENT
count = 1; count = 1;
p[0] = "rdpsnd"; p[0] = "rdpsnd";
freerdp_client_add_static_channel(settings, count, p); status = freerdp_client_add_static_channel(settings, count, p);
} }
} }
CommandLineSwitchCase(arg, "microphone") CommandLineSwitchCase(arg, "microphone")
@ -789,33 +962,58 @@ int freerdp_client_command_line_post_filter(void* context, COMMAND_LINE_ARGUMENT
CommandLineSwitchEnd(arg) CommandLineSwitchEnd(arg)
return 0; return status;
} }
int freerdp_parse_username(char* username, char** user, char** domain) int freerdp_parse_username(char* username, char** user, char** domain)
{ {
char* p; char* p;
int length; int length = 0;
p = strchr(username, '\\'); p = strchr(username, '\\');
*user = NULL;
*domain = NULL;
if (p) if (p)
{ {
length = (int) (p - username); length = (int) (p - username);
*user = _strdup(&p[1]);
if (!*user)
return -1;
*domain = (char*) calloc(length + 1UL, sizeof(char)); *domain = (char*) calloc(length + 1UL, sizeof(char));
if (!*domain)
{
free (*user);
*user = NULL;
return -1;
}
strncpy(*domain, username, length); strncpy(*domain, username, length);
(*domain)[length] = '\0'; (*domain)[length] = '\0';
*user = _strdup(&p[1]);
} }
else else if (username)
{ {
/* Do not break up the name for '@'; both credSSP and the /* Do not break up the name for '@'; both credSSP and the
* ClientInfo PDU expect 'user@corp.net' to be transmitted * ClientInfo PDU expect 'user@corp.net' to be transmitted
* as username 'user@corp.net', domain empty. * as username 'user@corp.net', domain empty (not NULL!).
*/ */
*user = _strdup(username); *user = _strdup(username);
*domain = NULL; if (!*user)
return -1;
*domain = _strdup("\0");
if (!*domain)
{
free(*user);
*user = NULL;
return -1;
}
} }
else
return -1;
return 0; return 0;
} }
@ -932,6 +1130,8 @@ int freerdp_map_keyboard_layout_name_to_id(char* name)
RDP_KEYBOARD_LAYOUT* layouts; RDP_KEYBOARD_LAYOUT* layouts;
layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_STANDARD); layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_STANDARD);
if (!layouts)
return -1;
for (i = 0; layouts[i].code; i++) for (i = 0; layouts[i].code; i++)
{ {
@ -945,6 +1145,8 @@ int freerdp_map_keyboard_layout_name_to_id(char* name)
return id; return id;
layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_VARIANT); layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_VARIANT);
if (!layouts)
return -1;
for (i = 0; layouts[i].code; i++) for (i = 0; layouts[i].code; i++)
{ {
@ -958,6 +1160,8 @@ int freerdp_map_keyboard_layout_name_to_id(char* name)
return id; return id;
layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_IME); layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_IME);
if (!layouts)
return -1;
for (i = 0; layouts[i].code; i++) for (i = 0; layouts[i].code; i++)
{ {
@ -1156,18 +1360,21 @@ int freerdp_client_settings_command_line_status_print(rdpSettings* settings, int
RDP_KEYBOARD_LAYOUT* layouts; RDP_KEYBOARD_LAYOUT* layouts;
layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_STANDARD); layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_STANDARD);
//if (!layouts) /* FIXME*/
printf("\nKeyboard Layouts\n"); printf("\nKeyboard Layouts\n");
for (i = 0; layouts[i].code; i++) for (i = 0; layouts[i].code; i++)
printf("0x%08X\t%s\n", (int) layouts[i].code, layouts[i].name); printf("0x%08X\t%s\n", (int) layouts[i].code, layouts[i].name);
free(layouts); free(layouts);
layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_VARIANT); layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_VARIANT);
//if (!layouts) /* FIXME*/
printf("\nKeyboard Layout Variants\n"); printf("\nKeyboard Layout Variants\n");
for (i = 0; layouts[i].code; i++) for (i = 0; layouts[i].code; i++)
printf("0x%08X\t%s\n", (int) layouts[i].code, layouts[i].name); printf("0x%08X\t%s\n", (int) layouts[i].code, layouts[i].name);
free(layouts); free(layouts);
layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_IME); layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_IME);
//if (!layouts) /* FIXME*/
printf("\nKeyboard Input Method Editors (IMEs)\n"); printf("\nKeyboard Input Method Editors (IMEs)\n");
for (i = 0; layouts[i].code; i++) for (i = 0; layouts[i].code; i++)
printf("0x%08X\t%s\n", (int) layouts[i].code, layouts[i].name); printf("0x%08X\t%s\n", (int) layouts[i].code, layouts[i].name);
@ -1198,6 +1405,8 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
int argc, char** argv, BOOL allowUnknown) int argc, char** argv, BOOL allowUnknown)
{ {
char* p; char* p;
char* user = NULL;
char* gwUser = NULL;
char* str; char* str;
int length; int length;
int status; int status;
@ -1209,7 +1418,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
if (compatibility) if (compatibility)
{ {
WLog_WARN(TAG, "Using deprecated command-line interface!"); WLog_WARN(TAG, "Using deprecated command-line interface!");
return freerdp_client_parse_old_command_line_arguments(argc, argv, settings); return freerdp_client_parse_old_command_line_arguments(argc, argv, settings);
} }
else else
@ -1249,13 +1458,16 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
{ {
length = (int) (p - arg->Value); length = (int) (p - arg->Value);
settings->ServerPort = atoi(&p[1]); settings->ServerPort = atoi(&p[1]);
settings->ServerHostname = (char*) calloc(length + 1UL, sizeof(char)); if (!(settings->ServerHostname = (char*) calloc(length + 1UL, sizeof(char))))
return COMMAND_LINE_ERROR_MEMORY;
strncpy(settings->ServerHostname, arg->Value, length); strncpy(settings->ServerHostname, arg->Value, length);
settings->ServerHostname[length] = '\0'; settings->ServerHostname[length] = '\0';
} }
else else
{ {
settings->ServerHostname = _strdup(arg->Value); if (!(settings->ServerHostname = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
} }
} }
else /* ipv6 */ else /* ipv6 */
@ -1266,7 +1478,8 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
continue; continue;
length = p2 - p; length = p2 - p;
settings->ServerHostname = (char*) calloc(length, sizeof(char)); if (!(settings->ServerHostname = (char*) calloc(length, sizeof(char))))
return COMMAND_LINE_ERROR;
strncpy(settings->ServerHostname, p+1, length-1); strncpy(settings->ServerHostname, p+1, length-1);
if (*(p2 + 1) == ':') if (*(p2 + 1) == ':')
{ {
@ -1277,7 +1490,9 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
} }
CommandLineSwitchCase(arg, "spn-class") CommandLineSwitchCase(arg, "spn-class")
{ {
settings->AuthenticationServiceClass = _strdup(arg->Value); if (!(settings->AuthenticationServiceClass = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
} }
CommandLineSwitchCase(arg, "credentials-delegation") CommandLineSwitchCase(arg, "credentials-delegation")
{ {
@ -1291,7 +1506,8 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
if (arg->Flags & COMMAND_LINE_VALUE_PRESENT) if (arg->Flags & COMMAND_LINE_VALUE_PRESENT)
{ {
settings->SendPreconnectionPdu = TRUE; settings->SendPreconnectionPdu = TRUE;
settings->PreconnectionBlob = _strdup(arg->Value); if (!(settings->PreconnectionBlob = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
} }
} }
CommandLineSwitchCase(arg, "w") CommandLineSwitchCase(arg, "w")
@ -1304,7 +1520,8 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
} }
CommandLineSwitchCase(arg, "size") CommandLineSwitchCase(arg, "size")
{ {
str = _strdup(arg->Value); if (!(str = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
p = strchr(str, 'x'); p = strchr(str, 'x');
@ -1358,6 +1575,8 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
int count = 0; int count = 0;
p = freerdp_command_line_parse_comma_separated_values(arg->Value, &count); p = freerdp_command_line_parse_comma_separated_values(arg->Value, &count);
if (!p)
return COMMAND_LINE_ERROR_MEMORY;
if (count > 16) if (count > 16)
count = 16; count = 16;
@ -1378,7 +1597,8 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
} }
CommandLineSwitchCase(arg, "t") CommandLineSwitchCase(arg, "t")
{ {
settings->WindowTitle = _strdup(arg->Value); if (!(settings->WindowTitle = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
} }
CommandLineSwitchCase(arg, "decorations") CommandLineSwitchCase(arg, "decorations")
{ {
@ -1390,7 +1610,8 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
if (arg->Value) if (arg->Value)
{ {
str = _strdup(arg->Value); if (!(str = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
if ((p = strchr(str, 'x'))) if ((p = strchr(str, 'x')))
{ {
*p = '\0'; *p = '\0';
@ -1417,11 +1638,13 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
{ {
settings->ConsoleSession = TRUE; settings->ConsoleSession = TRUE;
settings->RestrictedAdminModeRequired = TRUE; settings->RestrictedAdminModeRequired = TRUE;
settings->PasswordHash = _strdup(arg->Value); if (!(settings->PasswordHash = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
} }
CommandLineSwitchCase(arg, "client-hostname") CommandLineSwitchCase(arg, "client-hostname")
{ {
settings->ClientHostname = _strdup(arg->Value); if (!(settings->ClientHostname = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
} }
CommandLineSwitchCase(arg, "kbd") CommandLineSwitchCase(arg, "kbd")
{ {
@ -1436,11 +1659,15 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
if (id == 0) if (id == 0)
{ {
id = (unsigned long int) freerdp_map_keyboard_layout_name_to_id(arg->Value); id = (unsigned long int) freerdp_map_keyboard_layout_name_to_id(arg->Value);
if (id == -1)
if (!id) WLog_ERR(TAG, "A problem occured while mapping the layout name to id");
else if (id == 0)
{ {
WLog_ERR(TAG, "Could not identify keyboard layout: %s", arg->Value); WLog_ERR(TAG, "Could not identify keyboard layout: %s", arg->Value);
WLog_ERR(TAG, "Use /kbd-list to list available layouts");
} }
if (id <= 0)
return COMMAND_LINE_STATUS_PRINT;
} }
settings->KeyboardLayout = (UINT32) id; settings->KeyboardLayout = (UINT32) id;
@ -1459,21 +1686,17 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
} }
CommandLineSwitchCase(arg, "u") CommandLineSwitchCase(arg, "u")
{ {
char* user; user = _strdup(arg->Value);
char* domain;
freerdp_parse_username(arg->Value, &user, &domain);
settings->Username = user;
settings->Domain = domain;
} }
CommandLineSwitchCase(arg, "d") CommandLineSwitchCase(arg, "d")
{ {
settings->Domain = _strdup(arg->Value); if (!(settings->Domain = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
} }
CommandLineSwitchCase(arg, "p") CommandLineSwitchCase(arg, "p")
{ {
settings->Password = _strdup(arg->Value); if (!(settings->Password = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
} }
CommandLineSwitchCase(arg, "g") CommandLineSwitchCase(arg, "g")
{ {
@ -1485,18 +1708,21 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
{ {
length = (int) (p - arg->Value); length = (int) (p - arg->Value);
settings->GatewayPort = atoi(&p[1]); settings->GatewayPort = atoi(&p[1]);
settings->GatewayHostname = (char*) calloc(length + 1UL, sizeof(char)); if (!(settings->GatewayHostname = (char*) calloc(length + 1UL, sizeof(char))))
return COMMAND_LINE_ERROR_MEMORY;
strncpy(settings->GatewayHostname, arg->Value, length); strncpy(settings->GatewayHostname, arg->Value, length);
settings->GatewayHostname[length] = '\0'; settings->GatewayHostname[length] = '\0';
} }
else else
{ {
settings->GatewayHostname = _strdup(arg->Value); if (!(settings->GatewayHostname = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
} }
} }
else else
{ {
settings->GatewayHostname = _strdup(settings->ServerHostname); if (!(settings->GatewayHostname = _strdup(settings->ServerHostname)))
return COMMAND_LINE_ERROR_MEMORY;
} }
settings->GatewayEnabled = TRUE; settings->GatewayEnabled = TRUE;
@ -1506,24 +1732,21 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
} }
CommandLineSwitchCase(arg, "gu") CommandLineSwitchCase(arg, "gu")
{ {
char* user; if (!(gwUser = _strdup(arg->Value)))
char* domain; return COMMAND_LINE_ERROR_MEMORY;
freerdp_parse_username(arg->Value, &user, &domain);
settings->GatewayUsername = user;
settings->GatewayDomain = domain;
settings->GatewayUseSameCredentials = FALSE; settings->GatewayUseSameCredentials = FALSE;
} }
CommandLineSwitchCase(arg, "gd") CommandLineSwitchCase(arg, "gd")
{ {
settings->GatewayDomain = _strdup(arg->Value); if (!(settings->GatewayDomain = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
settings->GatewayUseSameCredentials = FALSE; settings->GatewayUseSameCredentials = FALSE;
} }
CommandLineSwitchCase(arg, "gp") CommandLineSwitchCase(arg, "gp")
{ {
settings->GatewayPassword = _strdup(arg->Value); if (!(settings->GatewayPassword = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
settings->GatewayUseSameCredentials = FALSE; settings->GatewayUseSameCredentials = FALSE;
} }
CommandLineSwitchCase(arg, "gt") CommandLineSwitchCase(arg, "gt")
@ -1567,7 +1790,8 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
} }
CommandLineSwitchCase(arg, "app") CommandLineSwitchCase(arg, "app")
{ {
settings->RemoteApplicationProgram = _strdup(arg->Value); if (!(settings->RemoteApplicationProgram = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
settings->RemoteApplicationMode = TRUE; settings->RemoteApplicationMode = TRUE;
settings->RemoteAppLanguageBarSupported = TRUE; settings->RemoteAppLanguageBarSupported = TRUE;
@ -1577,28 +1801,35 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
} }
CommandLineSwitchCase(arg, "load-balance-info") CommandLineSwitchCase(arg, "load-balance-info")
{ {
settings->LoadBalanceInfo = (BYTE*) _strdup(arg->Value); if (!(settings->LoadBalanceInfo = (BYTE*) _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
settings->LoadBalanceInfoLength = (UINT32) strlen((char*) settings->LoadBalanceInfo); settings->LoadBalanceInfoLength = (UINT32) strlen((char*) settings->LoadBalanceInfo);
} }
CommandLineSwitchCase(arg, "app-name") CommandLineSwitchCase(arg, "app-name")
{ {
settings->RemoteApplicationName = _strdup(arg->Value); if (!(settings->RemoteApplicationName = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
} }
CommandLineSwitchCase(arg, "app-icon") CommandLineSwitchCase(arg, "app-icon")
{ {
settings->RemoteApplicationIcon = _strdup(arg->Value); if (!(settings->RemoteApplicationIcon = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
} }
CommandLineSwitchCase(arg, "app-cmd") CommandLineSwitchCase(arg, "app-cmd")
{ {
settings->RemoteApplicationCmdLine = _strdup(arg->Value); if (!(settings->RemoteApplicationCmdLine = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
} }
CommandLineSwitchCase(arg, "app-file") CommandLineSwitchCase(arg, "app-file")
{ {
settings->RemoteApplicationFile = _strdup(arg->Value); if (!(settings->RemoteApplicationFile = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
} }
CommandLineSwitchCase(arg, "app-guid") CommandLineSwitchCase(arg, "app-guid")
{ {
settings->RemoteApplicationGuid = _strdup(arg->Value); if (!(settings->RemoteApplicationGuid = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
} }
CommandLineSwitchCase(arg, "compression") CommandLineSwitchCase(arg, "compression")
{ {
@ -1622,11 +1853,13 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
} }
CommandLineSwitchCase(arg, "shell") CommandLineSwitchCase(arg, "shell")
{ {
settings->AlternateShell = _strdup(arg->Value); if (!(settings->AlternateShell = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
} }
CommandLineSwitchCase(arg, "shell-dir") CommandLineSwitchCase(arg, "shell-dir")
{ {
settings->ShellWorkingDirectory = _strdup(arg->Value); if (!(settings->ShellWorkingDirectory = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
} }
CommandLineSwitchCase(arg, "audio-mode") CommandLineSwitchCase(arg, "audio-mode")
{ {
@ -1778,7 +2011,8 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
CommandLineSwitchCase(arg, "pcb") CommandLineSwitchCase(arg, "pcb")
{ {
settings->SendPreconnectionPdu = TRUE; settings->SendPreconnectionPdu = TRUE;
settings->PreconnectionBlob = _strdup(arg->Value); if (!(settings->PreconnectionBlob = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
} }
CommandLineSwitchCase(arg, "pcid") CommandLineSwitchCase(arg, "pcid")
{ {
@ -1818,7 +2052,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
} }
else else
{ {
WLog_ERR(TAG, "unknown protocol security: %s", arg->Value); WLog_ERR(TAG, "unknown protocol security: %s", arg->Value);
} }
} }
CommandLineSwitchCase(arg, "encryption-methods") CommandLineSwitchCase(arg, "encryption-methods")
@ -1842,7 +2076,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
else if (!strcmp(p[i], "FIPS")) else if (!strcmp(p[i], "FIPS"))
settings->EncryptionMethods |= ENCRYPTION_METHOD_FIPS; settings->EncryptionMethods |= ENCRYPTION_METHOD_FIPS;
else else
WLog_ERR(TAG, "unknown encryption method '%s'", p[i]); WLog_ERR(TAG, "unknown encryption method '%s'", p[i]);
} }
free(p); free(p);
@ -1868,20 +2102,24 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
{ {
if (strcmp(arg->Value, "netmon") == 0) if (strcmp(arg->Value, "netmon") == 0)
{ {
settings->AllowedTlsCiphers = _strdup("ALL:!ECDH"); if (!(settings->AllowedTlsCiphers = _strdup("ALL:!ECDH")))
return COMMAND_LINE_ERROR_MEMORY;
} }
else if (strcmp(arg->Value, "ma") == 0) else if (strcmp(arg->Value, "ma") == 0)
{ {
settings->AllowedTlsCiphers = _strdup("AES128-SHA"); if (!(settings->AllowedTlsCiphers = _strdup("AES128-SHA")))
return COMMAND_LINE_ERROR_MEMORY;
} }
else else
{ {
settings->AllowedTlsCiphers = _strdup(arg->Value); if (!(settings->AllowedTlsCiphers = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
} }
} }
CommandLineSwitchCase(arg, "cert-name") CommandLineSwitchCase(arg, "cert-name")
{ {
settings->CertificateName = _strdup(arg->Value); if (!(settings->CertificateName = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
} }
CommandLineSwitchCase(arg, "cert-ignore") CommandLineSwitchCase(arg, "cert-ignore")
{ {
@ -1970,11 +2208,13 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
} }
CommandLineSwitchCase(arg, "wm-class") CommandLineSwitchCase(arg, "wm-class")
{ {
settings->WmClass = _strdup(arg->Value); if (!(settings->WmClass = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
} }
CommandLineSwitchCase(arg, "play-rfx") CommandLineSwitchCase(arg, "play-rfx")
{ {
settings->PlayRemoteFxFile = _strdup(arg->Value); if (!(settings->PlayRemoteFxFile = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
settings->PlayRemoteFx = TRUE; settings->PlayRemoteFx = TRUE;
} }
CommandLineSwitchCase(arg, "auth-only") CommandLineSwitchCase(arg, "auth-only")
@ -1998,7 +2238,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
} }
else else
{ {
WLog_ERR(TAG, "reconnect-cookie: invalid base64 '%s'", arg->Value); WLog_ERR(TAG, "reconnect-cookie: invalid base64 '%s'", arg->Value);
} }
} }
CommandLineSwitchCase(arg, "print-reconnect-cookie") CommandLineSwitchCase(arg, "print-reconnect-cookie")
@ -2008,7 +2248,8 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
CommandLineSwitchCase(arg, "assistance") CommandLineSwitchCase(arg, "assistance")
{ {
settings->RemoteAssistanceMode = TRUE; settings->RemoteAssistanceMode = TRUE;
settings->RemoteAssistancePassword = _strdup(arg->Value); if (!(settings->RemoteAssistancePassword = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
} }
CommandLineSwitchDefault(arg) CommandLineSwitchDefault(arg)
{ {
@ -2018,6 +2259,29 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
} }
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
if (!settings->Domain && user)
{
int ret;
ret = freerdp_parse_username(user, &settings->Username, &settings->Domain);
free(user);
if (ret != 0 )
return COMMAND_LINE_ERROR;
}
else
settings->Username = user;
if (!settings->GatewayDomain && gwUser)
{
int ret;
ret = freerdp_parse_username(gwUser, &settings->GatewayUsername,
&settings->GatewayDomain);
free(gwUser);
if (ret != 0)
return COMMAND_LINE_ERROR;
}
else
settings->GatewayUsername = gwUser;
freerdp_performance_flags_make(settings); freerdp_performance_flags_make(settings);
if (settings->SupportGraphicsPipeline) if (settings->SupportGraphicsPipeline)
@ -2062,7 +2326,7 @@ int freerdp_client_load_static_channel_addin(rdpChannels* channels, rdpSettings*
{ {
if (freerdp_channels_client_load(channels, settings, entry, data) == 0) if (freerdp_channels_client_load(channels, settings, entry, data) == 0)
{ {
WLog_INFO(TAG, "loading channel %s", name); WLog_INFO(TAG, "loading channel %s", name);
return 0; return 0;
} }
} }

View File

@ -89,7 +89,7 @@ COMMAND_LINE_ARGUMENT_A old_args[] =
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
}; };
void freerdp_client_old_parse_hostname(char* str, char** ServerHostname, UINT32* ServerPort) BOOL freerdp_client_old_parse_hostname(char* str, char** ServerHostname, UINT32* ServerPort)
{ {
char* p; char* p;
@ -97,7 +97,8 @@ void freerdp_client_old_parse_hostname(char* str, char** ServerHostname, UINT32*
&& (p[1] == 0 || (p[1] == ':' && !strchr(p + 2, ':')))) && (p[1] == 0 || (p[1] == ':' && !strchr(p + 2, ':'))))
{ {
/* Either "[...]" or "[...]:..." with at most one : after the brackets */ /* Either "[...]" or "[...]:..." with at most one : after the brackets */
*ServerHostname = _strdup(str + 1); if (!(*ServerHostname = _strdup(str + 1)))
return FALSE;
if ((p = strchr((char*) *ServerHostname, ']'))) if ((p = strchr((char*) *ServerHostname, ']')))
{ {
@ -110,7 +111,8 @@ void freerdp_client_old_parse_hostname(char* str, char** ServerHostname, UINT32*
else else
{ {
/* Port number is cut off and used if exactly one : in the string */ /* Port number is cut off and used if exactly one : in the string */
*ServerHostname = _strdup(str); if (!(*ServerHostname = _strdup(str)))
return FALSE;
if ((p = strchr((char*) *ServerHostname, ':')) && !strchr(p + 1, ':')) if ((p = strchr((char*) *ServerHostname, ':')) && !strchr(p + 1, ':'))
{ {
@ -118,6 +120,7 @@ void freerdp_client_old_parse_hostname(char* str, char** ServerHostname, UINT32*
*ServerPort = atoi(p + 1); *ServerPort = atoi(p + 1);
} }
} }
return TRUE;
} }
int freerdp_client_old_process_plugin(rdpSettings* settings, ADDIN_ARGV* args) int freerdp_client_old_process_plugin(rdpSettings* settings, ADDIN_ARGV* args)
@ -183,7 +186,8 @@ int freerdp_client_old_process_plugin(rdpSettings* settings, ADDIN_ARGV* args)
return 1; return 1;
args_handled++; args_handled++;
settings->RemoteApplicationProgram = _strdup(args->argv[1]); if (!(settings->RemoteApplicationProgram = _strdup(args->argv[1])))
return -1;
} }
else else
{ {
@ -211,8 +215,9 @@ int freerdp_client_old_command_line_pre_filter(void* context, int index, int arg
return -1; return -1;
} }
freerdp_client_old_parse_hostname((char*) argv[index], if (!freerdp_client_old_parse_hostname((char*) argv[index],
&settings->ServerHostname, &settings->ServerPort); &settings->ServerHostname, &settings->ServerPort))
return -1;
return 2; return 2;
} }
@ -240,7 +245,14 @@ int freerdp_client_old_command_line_pre_filter(void* context, int index, int arg
return -1; return -1;
args = (ADDIN_ARGV*) malloc(sizeof(ADDIN_ARGV)); args = (ADDIN_ARGV*) malloc(sizeof(ADDIN_ARGV));
if (!args)
return -1;
args->argv = (char**) calloc(argc, sizeof(char*)); args->argv = (char**) calloc(argc, sizeof(char*));
if (!args->argv)
{
free(args);
return -1;
}
args->argc = 1; args->argc = 1;
if ((index < argc - 1) && strcmp("--data", argv[index + 1]) == 0) if ((index < argc - 1) && strcmp("--data", argv[index + 1]) == 0)
@ -250,9 +262,14 @@ int freerdp_client_old_command_line_pre_filter(void* context, int index, int arg
while ((index < argc) && (strcmp("--", argv[index]) != 0)) while ((index < argc) && (strcmp("--", argv[index]) != 0))
{ {
args_handled ++; args_handled++;
args->argc = 1; args->argc = 1;
args->argv[0] = _strdup(argv[t]); if (!(args->argv[0] = _strdup(argv[t])))
{
free(args->argv);
free(args);
return -1;
}
for (j = 0, p = (char*) argv[index]; (j < 4) && (p != NULL); j++) for (j = 0, p = (char*) argv[index]; (j < 4) && (p != NULL); j++)
{ {
@ -277,14 +294,31 @@ int freerdp_client_old_command_line_pre_filter(void* context, int index, int arg
if (p != NULL) if (p != NULL)
{ {
length = (int) (p - a); length = (int) (p - a);
args->argv[j + 1] = (char*) malloc(length + 1); if (!(args->argv[j + 1] = (char*) malloc(length + 1)))
{
for (; j >= 0; --j)
free(args->argv[j]);
free(args->argv);
free(args);
return -1;
}
CopyMemory(args->argv[j + 1], a, length); CopyMemory(args->argv[j + 1], a, length);
args->argv[j + 1][length] = '\0'; args->argv[j + 1][length] = '\0';
p++; p++;
} }
else else
{ {
args->argv[j + 1] = _strdup(a); if (!(args->argv[j + 1] = _strdup(a)))
{
for (; j >= 0; --j)
free(args->argv[j]);
free(args->argv);
free(args);
return -1;
}
} }
args->argc++; args->argc++;
@ -306,7 +340,12 @@ int freerdp_client_old_command_line_pre_filter(void* context, int index, int arg
{ {
if (settings) if (settings)
{ {
args->argv[0] = _strdup(argv[t]); if (!(args->argv[0] = _strdup(argv[t])))
{
free(args->argv);
free(args);
return -1;
}
args_handled = freerdp_client_old_process_plugin(settings, args); args_handled = freerdp_client_old_process_plugin(settings, args);
free (args->argv[0]); free (args->argv[0]);
} }
@ -459,8 +498,9 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
} }
CommandLineSwitchCase(arg, "c") CommandLineSwitchCase(arg, "c")
{ {
settings->ShellWorkingDirectory = _strdup(arg->Value);
WLog_WARN(TAG, "-c %s -> /shell-dir:%s", arg->Value, arg->Value); WLog_WARN(TAG, "-c %s -> /shell-dir:%s", arg->Value, arg->Value);
if (!(settings->ShellWorkingDirectory = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
} }
CommandLineSwitchCase(arg, "D") CommandLineSwitchCase(arg, "D")
{ {
@ -469,12 +509,14 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
} }
CommandLineSwitchCase(arg, "T") CommandLineSwitchCase(arg, "T")
{ {
settings->WindowTitle = _strdup(arg->Value); if (!(settings->WindowTitle = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
WLog_WARN(TAG, "-T %s -> /title:%s", arg->Value, arg->Value); WLog_WARN(TAG, "-T %s -> /title:%s", arg->Value, arg->Value);
} }
CommandLineSwitchCase(arg, "d") CommandLineSwitchCase(arg, "d")
{ {
settings->Domain = _strdup(arg->Value); if (!(settings->Domain = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
WLog_WARN(TAG, "-d %s -> /d:%s", arg->Value, arg->Value); WLog_WARN(TAG, "-d %s -> /d:%s", arg->Value, arg->Value);
} }
CommandLineSwitchCase(arg, "f") CommandLineSwitchCase(arg, "f")
@ -484,7 +526,8 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
} }
CommandLineSwitchCase(arg, "g") CommandLineSwitchCase(arg, "g")
{ {
str = _strdup(arg->Value); if (!(str = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
p = strchr(str, 'x'); p = strchr(str, 'x');
@ -511,7 +554,8 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
} }
CommandLineSwitchCase(arg, "n") CommandLineSwitchCase(arg, "n")
{ {
settings->ClientHostname = _strdup(arg->Value); if (!(settings->ClientHostname = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
WLog_WARN(TAG, "-n -> /client-hostname:%s", arg->Value); WLog_WARN(TAG, "-n -> /client-hostname:%s", arg->Value);
} }
CommandLineSwitchCase(arg, "o") CommandLineSwitchCase(arg, "o")
@ -521,14 +565,16 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
} }
CommandLineSwitchCase(arg, "p") CommandLineSwitchCase(arg, "p")
{ {
settings->Password = _strdup(arg->Value); if (!(settings->Password = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
WLog_WARN(TAG, "-p ****** -> /p:******"); WLog_WARN(TAG, "-p ****** -> /p:******");
/* Hide the value from 'ps'. */ /* Hide the value from 'ps'. */
FillMemory(arg->Value, strlen(arg->Value), '*'); FillMemory(arg->Value, strlen(arg->Value), '*');
} }
CommandLineSwitchCase(arg, "s") CommandLineSwitchCase(arg, "s")
{ {
settings->AlternateShell = _strdup(arg->Value); if (!(settings->AlternateShell = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
WLog_WARN(TAG, "-s %s -> /shell:%s", arg->Value, arg->Value); WLog_WARN(TAG, "-s %s -> /shell:%s", arg->Value, arg->Value);
} }
CommandLineSwitchCase(arg, "t") CommandLineSwitchCase(arg, "t")
@ -538,7 +584,8 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
} }
CommandLineSwitchCase(arg, "u") CommandLineSwitchCase(arg, "u")
{ {
settings->Username = _strdup(arg->Value); if (!(settings->Username = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
WLog_WARN(TAG, "-u %s -> /u:%s", arg->Value, arg->Value); WLog_WARN(TAG, "-u %s -> /u:%s", arg->Value, arg->Value);
} }
CommandLineSwitchCase(arg, "x") CommandLineSwitchCase(arg, "x")

View File

@ -52,9 +52,16 @@ static WCHAR CR_LF_STR_W[] = { '\r', '\n', '\0' };
#define INVALID_INTEGER_VALUE 0xFFFFFFFF #define INVALID_INTEGER_VALUE 0xFFFFFFFF
BOOL freerdp_client_rdp_file_set_integer(rdpFile* file, const char* name, int value, int index) /*
* Set an integer in a rdpFile
*
* @return 0 if a standard name was set, 1 for a non-standard name, -1 on error
*
*/
static int freerdp_client_rdp_file_set_integer(rdpFile* file, const char* name, int value, int index)
{ {
BOOL bStandard = TRUE; int standard = 1;
#ifdef DEBUG_CLIENT_FILE #ifdef DEBUG_CLIENT_FILE
WLog_DBG(TAG, "%s:i:%d", name, value); WLog_DBG(TAG, "%s:i:%d", name, value);
@ -189,122 +196,161 @@ BOOL freerdp_client_rdp_file_set_integer(rdpFile* file, const char* name, int va
else if (_stricmp(name, "rdgiskdcproxy") == 0) else if (_stricmp(name, "rdgiskdcproxy") == 0)
file->RdgIsKdcProxy = value; file->RdgIsKdcProxy = value;
else else
bStandard = FALSE; standard = 1;
if (index >= 0) if (index >= 0)
{ {
file->lines[index].name = _strdup(name); file->lines[index].name = _strdup(name);
if (!file->lines[index].name)
return -1;
file->lines[index].iValue = (DWORD) value; file->lines[index].iValue = (DWORD) value;
file->lines[index].flags = RDP_FILE_LINE_FLAG_FORMATTED; file->lines[index].flags = RDP_FILE_LINE_FLAG_FORMATTED;
file->lines[index].flags |= RDP_FILE_LINE_FLAG_TYPE_INTEGER; file->lines[index].flags |= RDP_FILE_LINE_FLAG_TYPE_INTEGER;
if (bStandard) if (standard)
file->lines[index].flags |= RDP_FILE_LINE_FLAG_STANDARD; file->lines[index].flags |= RDP_FILE_LINE_FLAG_STANDARD;
file->lines[index].valueLength = 0; file->lines[index].valueLength = 0;
} }
return bStandard; return standard;
} }
void freerdp_client_parse_rdp_file_integer_unicode(rdpFile* file, WCHAR* name, WCHAR* value, int index) static BOOL freerdp_client_parse_rdp_file_integer_unicode(rdpFile* file, WCHAR* name, WCHAR* value, int index)
{ {
int length; int length;
int ivalue; int ivalue;
char* nameA; char* nameA;
char* valueA; char* valueA;
BOOL ret = TRUE;
length = (int) _wcslen(name); length = (int) _wcslen(name);
nameA = (char*) malloc(length + 1); nameA = (char*) malloc(length + 1);
if (!nameA)
return FALSE;
WideCharToMultiByte(CP_UTF8, 0, name, length, nameA, length, NULL, NULL); WideCharToMultiByte(CP_UTF8, 0, name, length, nameA, length, NULL, NULL);
nameA[length] = '\0'; nameA[length] = '\0';
length = (int) _wcslen(value); length = (int) _wcslen(value);
valueA = (char*) malloc(length + 1); valueA = (char*) malloc(length + 1);
if (!valueA)
{
free(nameA);
return FALSE;
}
WideCharToMultiByte(CP_UTF8, 0, value, length, valueA, length, NULL, NULL); WideCharToMultiByte(CP_UTF8, 0, value, length, valueA, length, NULL, NULL);
valueA[length] = '\0'; valueA[length] = '\0';
ivalue = atoi(valueA); ivalue = atoi(valueA);
freerdp_client_rdp_file_set_integer(file, nameA, ivalue, index); if (freerdp_client_rdp_file_set_integer(file, nameA, ivalue, index) < 0)
ret = FALSE;
free(nameA); free(nameA);
free(valueA); free(valueA);
return ret;
} }
void freerdp_client_parse_rdp_file_integer_ascii(rdpFile* file, const char* name, const char* value, int index) static BOOL freerdp_client_parse_rdp_file_integer_ascii(rdpFile* file, const char* name, const char* value, int index)
{ {
int ivalue = atoi(value); int ivalue = atoi(value);
freerdp_client_rdp_file_set_integer(file, name, ivalue, index); if (freerdp_client_rdp_file_set_integer(file, name, ivalue, index) < 0)
return FALSE;
return TRUE;
} }
BOOL freerdp_client_rdp_file_set_string(rdpFile* file, const char* name, const char* value, int index) /**
*
* @param file rdpFile
* @param name name of the string
* @param value value of the string to set
* @param index line index of the rdpFile
* @return 0 on success, 1 if the key wasn't found (not a standard key), -1 on error
*/
static int freerdp_client_rdp_file_set_string(rdpFile* file, const char* name, const char* value, int index)
{ {
BOOL bStandard = TRUE; int standard = 0;
LPSTR *tmp = NULL;
#ifdef DEBUG_CLIENT_FILE #ifdef DEBUG_CLIENT_FILE
WLog_DBG(TAG, "%s:s:%s", name, value); WLog_DBG(TAG, "%s:s:%s", name, value);
#endif #endif
if (!file)
return -1;
if (_stricmp(name, "username") == 0) if (_stricmp(name, "username") == 0)
file->Username = _strdup(value); tmp = &file->Username;
else if (_stricmp(name, "domain") == 0) else if (_stricmp(name, "domain") == 0)
file->Domain = _strdup(value); tmp = &file->Domain;
else if (_stricmp(name, "full address") == 0) else if (_stricmp(name, "full address") == 0)
file->FullAddress = _strdup(value); tmp = &file->FullAddress;
else if (_stricmp(name, "alternate full address") == 0) else if (_stricmp(name, "alternate full address") == 0)
file->AlternateFullAddress = _strdup(value); tmp = &file->AlternateFullAddress;
else if (_stricmp(name, "usbdevicestoredirect") == 0) else if (_stricmp(name, "usbdevicestoredirect") == 0)
file->UsbDevicesToRedirect = _strdup(value); tmp = &file->UsbDevicesToRedirect;
else if (_stricmp(name, "loadbalanceinfo") == 0) else if (_stricmp(name, "loadbalanceinfo") == 0)
file->LoadBalanceInfo = _strdup(value); tmp = &file->LoadBalanceInfo;
else if (_stricmp(name, "remoteapplicationname") == 0) else if (_stricmp(name, "remoteapplicationname") == 0)
file->RemoteApplicationName = _strdup(value); tmp = &file->RemoteApplicationName;
else if (_stricmp(name, "remoteapplicationicon") == 0) else if (_stricmp(name, "remoteapplicationicon") == 0)
file->RemoteApplicationIcon = _strdup(value); tmp = &file->RemoteApplicationIcon;
else if (_stricmp(name, "remoteapplicationprogram") == 0) else if (_stricmp(name, "remoteapplicationprogram") == 0)
file->RemoteApplicationProgram = _strdup(value); tmp = &file->RemoteApplicationProgram;
else if (_stricmp(name, "remoteapplicationfile") == 0) else if (_stricmp(name, "remoteapplicationfile") == 0)
file->RemoteApplicationFile = _strdup(value); tmp = &file->RemoteApplicationFile;
else if (_stricmp(name, "remoteapplicationguid") == 0) else if (_stricmp(name, "remoteapplicationguid") == 0)
file->RemoteApplicationGuid = _strdup(value); tmp = &file->RemoteApplicationGuid;
else if (_stricmp(name, "remoteapplicationcmdline") == 0) else if (_stricmp(name, "remoteapplicationcmdline") == 0)
file->RemoteApplicationCmdLine = _strdup(value); tmp = &file->RemoteApplicationCmdLine;
else if (_stricmp(name, "alternate shell") == 0) else if (_stricmp(name, "alternate shell") == 0)
file->AlternateShell = _strdup(value); tmp = &file->AlternateShell;
else if (_stricmp(name, "shell working directory") == 0) else if (_stricmp(name, "shell working directory") == 0)
file->ShellWorkingDirectory = _strdup(value); tmp = &file->ShellWorkingDirectory;
else if (_stricmp(name, "gatewayhostname") == 0) else if (_stricmp(name, "gatewayhostname") == 0)
file->GatewayHostname = _strdup(value); tmp = &file->GatewayHostname;
else if (_stricmp(name, "kdcproxyname") == 0) else if (_stricmp(name, "kdcproxyname") == 0)
file->KdcProxyName = _strdup(value); tmp = &file->KdcProxyName;
else if (_stricmp(name, "drivestoredirect") == 0) else if (_stricmp(name, "drivestoredirect") == 0)
file->DrivesToRedirect = _strdup(value); tmp = &file->DrivesToRedirect;
else if (_stricmp(name, "devicestoredirect") == 0) else if (_stricmp(name, "devicestoredirect") == 0)
file->DevicesToRedirect = _strdup(value); tmp = &file->DevicesToRedirect;
else if (_stricmp(name, "winposstr") == 0) else if (_stricmp(name, "winposstr") == 0)
file->WinPosStr = _strdup(value); tmp = &file->WinPosStr;
else else
bStandard = FALSE; standard = 1;
if (tmp && !(*tmp = _strdup(value)))
return -1;
if (index >= 0) if (index >= 0)
{ {
if (!file->lines)
return -1;
file->lines[index].name = _strdup(name); file->lines[index].name = _strdup(name);
file->lines[index].sValue = _strdup(value); file->lines[index].sValue = _strdup(value);
if (!file->lines[index].name || !file->lines[index].sValue)
{
free(file->lines[index].name);
free(file->lines[index].sValue);
return -1;
}
file->lines[index].flags = RDP_FILE_LINE_FLAG_FORMATTED; file->lines[index].flags = RDP_FILE_LINE_FLAG_FORMATTED;
file->lines[index].flags |= RDP_FILE_LINE_FLAG_TYPE_STRING; file->lines[index].flags |= RDP_FILE_LINE_FLAG_TYPE_STRING;
if (bStandard) if (standard == 0)
file->lines[index].flags |= RDP_FILE_LINE_FLAG_STANDARD; file->lines[index].flags |= RDP_FILE_LINE_FLAG_STANDARD;
file->lines[index].valueLength = 0; file->lines[index].valueLength = 0;
} }
return bStandard; return standard;
} }
void freerdp_client_add_option(rdpFile* file, char* option) static BOOL freerdp_client_add_option(rdpFile* file, char* option)
{ {
while ((file->argc + 1) > file->argSize) while ((file->argc + 1) > file->argSize)
{ {
@ -314,16 +360,19 @@ void freerdp_client_add_option(rdpFile* file, char* option)
new_size = file->argSize * 2; new_size = file->argSize * 2;
new_argv = (char**) realloc(file->argv, new_size * sizeof(char*)); new_argv = (char**) realloc(file->argv, new_size * sizeof(char*));
if (!new_argv) if (!new_argv)
return; return FALSE;
file->argv = new_argv; file->argv = new_argv;
file->argSize = new_size; file->argSize = new_size;
} }
file->argv[file->argc] = _strdup(option); file->argv[file->argc] = _strdup(option);
if (!file->argv[file->argc])
return FALSE;
(file->argc)++; (file->argc)++;
return TRUE;
} }
int freerdp_client_parse_rdp_file_add_line(rdpFile* file, char* line, int index) static int freerdp_client_parse_rdp_file_add_line(rdpFile* file, char* line, int index)
{ {
if (index < 0) if (index < 0)
index = file->lineCount; index = file->lineCount;
@ -343,72 +392,105 @@ int freerdp_client_parse_rdp_file_add_line(rdpFile* file, char* line, int index)
ZeroMemory(&(file->lines[file->lineCount]), sizeof(rdpFileLine)); ZeroMemory(&(file->lines[file->lineCount]), sizeof(rdpFileLine));
file->lines[file->lineCount].text = _strdup(line); file->lines[file->lineCount].text = _strdup(line);
if (!file->lines[file->lineCount].text)
return -1;
file->lines[file->lineCount].index = index; file->lines[file->lineCount].index = index;
(file->lineCount)++; (file->lineCount)++;
return index; return index;
} }
void freerdp_client_parse_rdp_file_add_line_unicode(rdpFile* file, WCHAR* line, int index) static BOOL freerdp_client_parse_rdp_file_add_line_unicode(rdpFile* file, WCHAR* line, int index)
{ {
char* lineA = NULL; char* lineA = NULL;
BOOL ret = TRUE;
ConvertFromUnicode(CP_UTF8, 0, line, -1, &lineA, 0, NULL, NULL); ConvertFromUnicode(CP_UTF8, 0, line, -1, &lineA, 0, NULL, NULL);
freerdp_client_parse_rdp_file_add_line(file, lineA, index); if (!lineA)
return FALSE;
if (freerdp_client_parse_rdp_file_add_line(file, lineA, index) == -1)
ret = FALSE;
free(lineA); free(lineA);
return ret;
} }
void freerdp_client_parse_rdp_file_add_line_ascii(rdpFile* file, char* line, int index) static BOOL freerdp_client_parse_rdp_file_add_line_ascii(rdpFile* file, char* line, int index)
{ {
freerdp_client_parse_rdp_file_add_line(file, line, index); if (freerdp_client_parse_rdp_file_add_line(file, line, index) == -1)
return FALSE;
return TRUE;
} }
void freerdp_client_parse_rdp_file_string_unicode(rdpFile* file, WCHAR* name, WCHAR* value, int index) static BOOL freerdp_client_parse_rdp_file_string_unicode(rdpFile* file, WCHAR* name, WCHAR* value, int index)
{ {
int length; int length;
char* nameA; char* nameA;
char* valueA; char* valueA;
BOOL ret = TRUE;
length = (int) _wcslen(name); length = (int) _wcslen(name);
nameA = (char*) malloc(length + 1); nameA = (char*) malloc(length + 1);
if (!nameA)
return FALSE;
WideCharToMultiByte(CP_UTF8, 0, name, length, nameA, length, NULL, NULL); WideCharToMultiByte(CP_UTF8, 0, name, length, nameA, length, NULL, NULL);
nameA[length] = '\0'; nameA[length] = '\0';
length = (int) _wcslen(value); length = (int) _wcslen(value);
valueA = (char*) malloc(length + 1); valueA = (char*) malloc(length + 1);
if (!valueA)
{
free(nameA);
return FALSE;
}
WideCharToMultiByte(CP_UTF8, 0, value, length, valueA, length, NULL, NULL); WideCharToMultiByte(CP_UTF8, 0, value, length, valueA, length, NULL, NULL);
valueA[length] = '\0'; valueA[length] = '\0';
freerdp_client_rdp_file_set_string(file, nameA, valueA, index); if (freerdp_client_rdp_file_set_string(file, nameA, valueA, index) == -1)
ret = FALSE;
free(nameA); free(nameA);
free(valueA); free(valueA);
return ret;
} }
void freerdp_client_parse_rdp_file_string_ascii(rdpFile* file, char* name, char* value, int index) static BOOL freerdp_client_parse_rdp_file_string_ascii(rdpFile* file, char* name, char* value, int index)
{ {
BOOL ret = TRUE;
char* valueA = _strdup(value); char* valueA = _strdup(value);
freerdp_client_rdp_file_set_string(file, name, valueA, index); if (!valueA)
return FALSE;
if (freerdp_client_rdp_file_set_string(file, name, valueA, index) == -1)
ret = FALSE;
free(valueA); free(valueA);
return ret;
} }
void freerdp_client_parse_rdp_file_option_unicode(rdpFile* file, WCHAR* option, int index) static BOOL freerdp_client_parse_rdp_file_option_unicode(rdpFile* file, WCHAR* option, int index)
{ {
char* optionA = NULL; char* optionA = NULL;
BOOL ret;
ConvertFromUnicode(CP_UTF8, 0, option, -1, &optionA, 0, NULL, NULL); ConvertFromUnicode(CP_UTF8, 0, option, -1, &optionA, 0, NULL, NULL);
freerdp_client_add_option(file, optionA); if (!optionA)
return FALSE;
ret = freerdp_client_add_option(file, optionA);
free(optionA); free(optionA);
return ret;
} }
void freerdp_client_parse_rdp_file_option_ascii(rdpFile* file, char* option, int index) static BOOL freerdp_client_parse_rdp_file_option_ascii(rdpFile* file, char* option, int index)
{ {
freerdp_client_add_option(file, option); return freerdp_client_add_option(file, option);
} }
BOOL freerdp_client_parse_rdp_file_buffer_ascii(rdpFile* file, const BYTE* buffer, size_t size) static BOOL freerdp_client_parse_rdp_file_buffer_ascii(rdpFile* file, const BYTE* buffer, size_t size)
{ {
int index; int index;
int length; int length;
@ -431,11 +513,14 @@ BOOL freerdp_client_parse_rdp_file_buffer_ascii(rdpFile* file, const BYTE* buffe
beg = line; beg = line;
end = &line[length - 1]; end = &line[length - 1];
freerdp_client_parse_rdp_file_add_line_ascii(file, line, index); if (!freerdp_client_parse_rdp_file_add_line_ascii(file, line, index))
return FALSE;
if (beg[0] == '/') if (beg[0] == '/')
{ {
freerdp_client_parse_rdp_file_option_ascii(file, line, index); if (!freerdp_client_parse_rdp_file_option_ascii(file, line, index))
return FALSE;
goto next_line; /* FreeRDP option */ goto next_line; /* FreeRDP option */
} }
@ -462,12 +547,14 @@ BOOL freerdp_client_parse_rdp_file_buffer_ascii(rdpFile* file, const BYTE* buffe
if (*type == 'i') if (*type == 'i')
{ {
/* integer type */ /* integer type */
freerdp_client_parse_rdp_file_integer_ascii(file, name, value, index); if (!freerdp_client_parse_rdp_file_integer_ascii(file, name, value, index))
return FALSE;
} }
else if (*type == 's') else if (*type == 's')
{ {
/* string type */ /* string type */
freerdp_client_parse_rdp_file_string_ascii(file, name, value, index); if (!freerdp_client_parse_rdp_file_string_ascii(file, name, value, index))
return FALSE;
} }
else if (*type == 'b') else if (*type == 'b')
{ {
@ -483,7 +570,7 @@ next_line:
return TRUE; return TRUE;
} }
BOOL freerdp_client_parse_rdp_file_buffer_unicode(rdpFile* file, const BYTE* buffer, size_t size) static BOOL freerdp_client_parse_rdp_file_buffer_unicode(rdpFile* file, const BYTE* buffer, size_t size)
{ {
int index; int index;
int length; int length;
@ -506,7 +593,8 @@ BOOL freerdp_client_parse_rdp_file_buffer_unicode(rdpFile* file, const BYTE* buf
beg = line; beg = line;
end = &line[length - 1]; end = &line[length - 1];
freerdp_client_parse_rdp_file_add_line_unicode(file, line, index); if (!freerdp_client_parse_rdp_file_add_line_unicode(file, line, index))
return FALSE;
if (beg[0] == '/') if (beg[0] == '/')
{ {
@ -538,12 +626,14 @@ BOOL freerdp_client_parse_rdp_file_buffer_unicode(rdpFile* file, const BYTE* buf
if (*type == 'i') if (*type == 'i')
{ {
/* integer type */ /* integer type */
freerdp_client_parse_rdp_file_integer_unicode(file, name, value, index); if (!freerdp_client_parse_rdp_file_integer_unicode(file, name, value, index))
return FALSE;
} }
else if (*type == 's') else if (*type == 's')
{ {
/* string type */ /* string type */
freerdp_client_parse_rdp_file_string_unicode(file, name, value, index); if (!freerdp_client_parse_rdp_file_string_unicode(file, name, value, index))
return FALSE;
} }
else if (*type == 'b') else if (*type == 'b')
{ {
@ -594,6 +684,11 @@ BOOL freerdp_client_parse_rdp_file(rdpFile* file, const char* name)
} }
buffer = (BYTE*) malloc(file_size + 2); buffer = (BYTE*) malloc(file_size + 2);
if (!buffer)
{
fclose(fp);
return FALSE;
}
read_size = fread(buffer, file_size, 1, fp); read_size = fread(buffer, file_size, 1, fp);
if (!read_size) if (!read_size)
@ -606,7 +701,6 @@ BOOL freerdp_client_parse_rdp_file(rdpFile* file, const char* name)
if (read_size < 1) if (read_size < 1)
{ {
free(buffer); free(buffer);
buffer = NULL;
return FALSE; return FALSE;
} }
@ -623,7 +717,9 @@ BOOL freerdp_client_parse_rdp_file(rdpFile* file, const char* name)
#define WRITE_ALL_SETTINGS TRUE #define WRITE_ALL_SETTINGS TRUE
#define SETTING_MODIFIED(_settings, _field) (WRITE_ALL_SETTINGS || _settings->SettingsModified[FreeRDP_##_field]) #define SETTING_MODIFIED(_settings, _field) (WRITE_ALL_SETTINGS || _settings->SettingsModified[FreeRDP_##_field])
#define SETTING_MODIFIED_SET(_target, _settings, _field) if SETTING_MODIFIED(_settings, _field) _target = _settings->_field #define SETTING_MODIFIED_SET(_target, _settings, _field) if SETTING_MODIFIED(_settings, _field) _target = _settings->_field
#define SETTING_MODIFIED_SET_STRING(_target, _settings, _field) if SETTING_MODIFIED(_settings, _field) _target = _strdup(_settings->_field) #define SETTING_MODIFIED_SET_STRING(_target, _settings, _field) do { if SETTING_MODIFIED(_settings, _field) _target = _strdup(_settings->_field); \
if (!_target) return FALSE; \
} while (0)
BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, const rdpSettings* settings) BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, const rdpSettings* settings)
{ {
@ -704,17 +800,28 @@ BOOL freerdp_client_write_rdp_file(const rdpFile* file, const char* name, BOOL u
ConvertToUnicode(CP_UTF8, 0, buffer, length, &unicodestr, 0); ConvertToUnicode(CP_UTF8, 0, buffer, length, &unicodestr, 0);
/* Write multi-byte header */ /* Write multi-byte header */
fwrite(BOM_UTF16_LE, sizeof(BYTE), 2, fp); if (fwrite(BOM_UTF16_LE, sizeof(BYTE), 2, fp) != 2 ||
fwrite(unicodestr, 2, length, fp); fwrite(unicodestr, 2, length, fp) != length)
{
free(buffer);
free(unicodestr);
fclose(fp);
return FALSE;
}
free(unicodestr); free(unicodestr);
} }
else else
{ {
fwrite(buffer, 1, length, fp); if (fwrite(buffer, 1, length, fp) != length)
{
free(buffer);
fclose(fp);
return FALSE;
}
} }
status = fflush(fp); fflush(fp);
status = fclose(fp); status = fclose(fp);
} }
@ -763,18 +870,26 @@ size_t freerdp_client_write_rdp_file_buffer(const rdpFile* file, char* buffer, s
BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* settings) BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* settings)
{ {
if (~((size_t) file->Domain)) if (~((size_t) file->Domain))
freerdp_set_param_string(settings, FreeRDP_Domain, file->Domain); {
if (freerdp_set_param_string(settings, FreeRDP_Domain, file->Domain) != 0)
return FALSE;
}
if (~((size_t) file->Username)) if (~((size_t) file->Username))
{ {
char* user = NULL; char* user = NULL;
char* domain = NULL; char* domain = NULL;
freerdp_parse_username(file->Username, &user, &domain); if (freerdp_parse_username(file->Username, &user, &domain) != 0)
freerdp_set_param_string(settings, FreeRDP_Username, user); return FALSE;
if (freerdp_set_param_string(settings, FreeRDP_Username, user) != 0)
return FALSE;
if (domain) if (domain)
freerdp_set_param_string(settings, FreeRDP_Domain, domain); {
if (freerdp_set_param_string(settings, FreeRDP_Domain, domain) != 0)
return FALSE;
}
free(user); free(user);
free(domain); free(domain);
@ -785,9 +900,11 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
int port = -1; int port = -1;
char* host = NULL; char* host = NULL;
freerdp_parse_hostname(file->FullAddress, &host, &port); if (freerdp_parse_hostname(file->FullAddress, &host, &port) != 0)
return FALSE;
freerdp_set_param_string(settings, FreeRDP_ServerHostname, host); if (freerdp_set_param_string(settings, FreeRDP_ServerHostname, host) != 0)
return FALSE;
if (port > 0) if (port > 0)
freerdp_set_param_uint32(settings, FreeRDP_ServerPort, (UINT32) port); freerdp_set_param_uint32(settings, FreeRDP_ServerPort, (UINT32) port);
@ -813,9 +930,15 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
if (~file->EnableCredSSPSupport) if (~file->EnableCredSSPSupport)
freerdp_set_param_bool(settings, FreeRDP_NlaSecurity, file->EnableCredSSPSupport); freerdp_set_param_bool(settings, FreeRDP_NlaSecurity, file->EnableCredSSPSupport);
if (~((size_t) file->AlternateShell)) if (~((size_t) file->AlternateShell))
freerdp_set_param_string(settings, FreeRDP_AlternateShell, file->AlternateShell); {
if(freerdp_set_param_string(settings, FreeRDP_AlternateShell, file->AlternateShell) != 0)
return FALSE;
}
if (~((size_t) file->ShellWorkingDirectory)) if (~((size_t) file->ShellWorkingDirectory))
freerdp_set_param_string(settings, FreeRDP_ShellWorkingDirectory, file->ShellWorkingDirectory); {
if (freerdp_set_param_string(settings, FreeRDP_ShellWorkingDirectory, file->ShellWorkingDirectory) != 0)
return FALSE;
}
if (~file->ScreenModeId) if (~file->ScreenModeId)
{ {
@ -845,6 +968,8 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
if (~((size_t) file->LoadBalanceInfo)) if (~((size_t) file->LoadBalanceInfo))
{ {
settings->LoadBalanceInfo = (BYTE*) _strdup(file->LoadBalanceInfo); settings->LoadBalanceInfo = (BYTE*) _strdup(file->LoadBalanceInfo);
if (!settings->LoadBalanceInfo)
return FALSE;
settings->LoadBalanceInfoLength = (int) strlen((char*) settings->LoadBalanceInfo); settings->LoadBalanceInfoLength = (int) strlen((char*) settings->LoadBalanceInfo);
} }
@ -897,9 +1022,11 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
int port = -1; int port = -1;
char* host = NULL; char* host = NULL;
freerdp_parse_hostname(file->GatewayHostname, &host, &port); if (freerdp_parse_hostname(file->GatewayHostname, &host, &port) != 0)
return FALSE;
freerdp_set_param_string(settings, FreeRDP_GatewayHostname, host); if (freerdp_set_param_string(settings, FreeRDP_GatewayHostname, host) != 0)
return FALSE;
if (port > 0) if (port > 0)
freerdp_set_param_uint32(settings, FreeRDP_GatewayPort, (UINT32) port); freerdp_set_param_uint32(settings, FreeRDP_GatewayPort, (UINT32) port);
@ -916,15 +1043,30 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
if (~file->RemoteApplicationMode) if (~file->RemoteApplicationMode)
freerdp_set_param_bool(settings, FreeRDP_RemoteApplicationMode, file->RemoteApplicationMode); freerdp_set_param_bool(settings, FreeRDP_RemoteApplicationMode, file->RemoteApplicationMode);
if (~((size_t) file->RemoteApplicationProgram)) if (~((size_t) file->RemoteApplicationProgram))
freerdp_set_param_string(settings, FreeRDP_RemoteApplicationProgram, file->RemoteApplicationProgram); {
if (freerdp_set_param_string(settings, FreeRDP_RemoteApplicationProgram, file->RemoteApplicationProgram) != 0)
return FALSE;
}
if (~((size_t) file->RemoteApplicationName)) if (~((size_t) file->RemoteApplicationName))
freerdp_set_param_string(settings, FreeRDP_RemoteApplicationName, file->RemoteApplicationName); {
if (freerdp_set_param_string(settings, FreeRDP_RemoteApplicationName, file->RemoteApplicationName) != 0)
return FALSE;
}
if (~((size_t) file->RemoteApplicationIcon)) if (~((size_t) file->RemoteApplicationIcon))
freerdp_set_param_string(settings, FreeRDP_RemoteApplicationIcon, file->RemoteApplicationIcon); {
if (freerdp_set_param_string(settings, FreeRDP_RemoteApplicationIcon, file->RemoteApplicationIcon) != 0)
return FALSE;
}
if (~((size_t) file->RemoteApplicationFile)) if (~((size_t) file->RemoteApplicationFile))
freerdp_set_param_string(settings, FreeRDP_RemoteApplicationGuid, file->RemoteApplicationGuid); {
if (freerdp_set_param_string(settings, FreeRDP_RemoteApplicationGuid, file->RemoteApplicationGuid) != 0)
return FALSE;
}
if (~((size_t) file->RemoteApplicationCmdLine)) if (~((size_t) file->RemoteApplicationCmdLine))
freerdp_set_param_string(settings, FreeRDP_RemoteApplicationCmdLine, file->RemoteApplicationCmdLine); {
if (freerdp_set_param_string(settings, FreeRDP_RemoteApplicationCmdLine, file->RemoteApplicationCmdLine) != 0)
return FALSE;
}
if (~file->SpanMonitors) if (~file->SpanMonitors)
freerdp_set_param_bool(settings, FreeRDP_SpanMonitors, file->SpanMonitors); freerdp_set_param_bool(settings, FreeRDP_SpanMonitors, file->SpanMonitors);
@ -1036,14 +1178,15 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
char* ConnectionFile = settings->ConnectionFile; char* ConnectionFile = settings->ConnectionFile;
settings->ConnectionFile = NULL; settings->ConnectionFile = NULL;
freerdp_client_settings_parse_command_line(settings, file->argc, file->argv, FALSE); if (freerdp_client_settings_parse_command_line(settings, file->argc, file->argv, FALSE) < 0)
return FALSE;
settings->ConnectionFile = ConnectionFile; settings->ConnectionFile = ConnectionFile;
} }
return TRUE; return TRUE;
} }
rdpFileLine* freerdp_client_rdp_file_find_line_index(rdpFile* file, int index) static rdpFileLine* freerdp_client_rdp_file_find_line_index(rdpFile* file, int index)
{ {
rdpFileLine* line; rdpFileLine* line;
@ -1052,7 +1195,7 @@ rdpFileLine* freerdp_client_rdp_file_find_line_index(rdpFile* file, int index)
return line; return line;
} }
rdpFileLine* freerdp_client_rdp_file_find_line_by_name(rdpFile* file, const char* name) static rdpFileLine* freerdp_client_rdp_file_find_line_by_name(rdpFile* file, const char* name)
{ {
int index; int index;
BOOL bFound = FALSE; BOOL bFound = FALSE;
@ -1075,6 +1218,14 @@ rdpFileLine* freerdp_client_rdp_file_find_line_by_name(rdpFile* file, const char
return (bFound) ? line : NULL; return (bFound) ? line : NULL;
} }
/**
* Set a string option to a rdpFile
* @param file rdpFile
* @param name name of the option
* @param value value of the option
* @return 0 on success
*/
int freerdp_client_rdp_file_set_string_option(rdpFile* file, const char* name, const char* value) int freerdp_client_rdp_file_set_string_option(rdpFile* file, const char* name, const char* value)
{ {
int index; int index;
@ -1082,17 +1233,20 @@ int freerdp_client_rdp_file_set_string_option(rdpFile* file, const char* name, c
char* text; char* text;
rdpFileLine* line; rdpFileLine* line;
line = freerdp_client_rdp_file_find_line_by_name(file, name);
length = _scprintf("%s:s:%s", name, value); length = _scprintf("%s:s:%s", name, value);
text = (char*) malloc(length + 1); text = (char*) malloc(length + 1);
if (!text)
return -1;
sprintf_s(text, length + 1, "%s:s:%s", name, value ? value : ""); sprintf_s(text, length + 1, "%s:s:%s", name, value ? value : "");
text[length] = '\0'; text[length] = '\0';
line = freerdp_client_rdp_file_find_line_by_name(file, name);
if (line) if (line)
{ {
free(line->sValue); free(line->sValue);
line->sValue = _strdup(value); line->sValue = _strdup(value);
if (!line->sValue)
goto out_fail;
free(line->text); free(line->text);
line->text = text; line->text = text;
@ -1100,14 +1254,24 @@ int freerdp_client_rdp_file_set_string_option(rdpFile* file, const char* name, c
else else
{ {
index = freerdp_client_parse_rdp_file_add_line(file, text, -1); index = freerdp_client_parse_rdp_file_add_line(file, text, -1);
line = freerdp_client_rdp_file_find_line_index(file, index); if (index == -1)
goto out_fail;
freerdp_client_rdp_file_set_string(file, name, value, index); if (!(line = freerdp_client_rdp_file_find_line_index(file, index)))
goto out_fail;
if (freerdp_client_rdp_file_set_string(file, name, value, index) == -1)
goto out_fail;
free(text); free(text);
} }
return 0; return 0;
out_fail:
free(text);
return -1;
} }
const char* freerdp_client_rdp_file_get_string_option(rdpFile* file, const char* name) const char* freerdp_client_rdp_file_get_string_option(rdpFile* file, const char* name)
@ -1149,9 +1313,18 @@ int freerdp_client_rdp_file_set_integer_option(rdpFile* file, const char* name,
else else
{ {
index = freerdp_client_parse_rdp_file_add_line(file, text, -1); index = freerdp_client_parse_rdp_file_add_line(file, text, -1);
if (index < 0)
{
free(text);
return -1;
}
line = freerdp_client_rdp_file_find_line_index(file, index); line = freerdp_client_rdp_file_find_line_index(file, index);
freerdp_client_rdp_file_set_integer(file, (char*) name, value, index); if (freerdp_client_rdp_file_set_integer(file, (char*) name, value, index) < 0)
{
free(text);
return -1;
}
free(text); free(text);
} }
@ -1174,7 +1347,7 @@ int freerdp_client_rdp_file_get_integer_option(rdpFile* file, const char* name)
return line->iValue; return line->iValue;
} }
void freerdp_client_file_string_check_free(LPSTR str) static void freerdp_client_file_string_check_free(LPSTR str)
{ {
if (~((size_t) str)) if (~((size_t) str))
free(str); free(str);
@ -1193,12 +1366,30 @@ rdpFile* freerdp_client_rdp_file_new()
file->lineCount = 0; file->lineCount = 0;
file->lineSize = 32; file->lineSize = 32;
file->lines = (rdpFileLine*) malloc(file->lineSize * sizeof(rdpFileLine)); file->lines = (rdpFileLine*) malloc(file->lineSize * sizeof(rdpFileLine));
if (!file->lines)
{
free(file);
return NULL;
}
file->argc = 0; file->argc = 0;
file->argSize = 32; file->argSize = 32;
file->argv = (char**) malloc(file->argSize * sizeof(char*)); file->argv = (char**) malloc(file->argSize * sizeof(char*));
if (!file->argv)
{
free(file->lines);
free(file);
return NULL;
}
freerdp_client_add_option(file, "freerdp"); if (!freerdp_client_add_option(file, "freerdp"))
{
free(file->argv);
free(file->lines);
free(file);
return NULL;
}
} }
return file; return file;

View File

@ -271,6 +271,11 @@ int TestClientRdpFile(int argc, char* argv[])
/* Unicode */ /* Unicode */
file = freerdp_client_rdp_file_new(); file = freerdp_client_rdp_file_new();
if (!file)
{
printf("rdp_file_new failed\n");
return -1;
}
freerdp_client_parse_rdp_file_buffer(file, testRdpFileUTF16, sizeof(testRdpFileUTF16)); freerdp_client_parse_rdp_file_buffer(file, testRdpFileUTF16, sizeof(testRdpFileUTF16));
if (file->UseMultiMon != 0) if (file->UseMultiMon != 0)
@ -331,7 +336,12 @@ int TestClientRdpFile(int argc, char* argv[])
} }
iValue = freerdp_client_rdp_file_get_integer_option(file, "vendor integer"); iValue = freerdp_client_rdp_file_get_integer_option(file, "vendor integer");
freerdp_client_rdp_file_set_integer_option(file, "vendor integer", 456); if (freerdp_client_rdp_file_set_integer_option(file, "vendor integer", 456) == -1)
{
printf("failed to set integer: vendor integer");
return -1;
}
iValue = freerdp_client_rdp_file_get_integer_option(file, "vendor integer"); iValue = freerdp_client_rdp_file_get_integer_option(file, "vendor integer");
sValue = (char*) freerdp_client_rdp_file_get_string_option(file, "vendor string"); sValue = (char*) freerdp_client_rdp_file_get_string_option(file, "vendor string");
@ -339,7 +349,11 @@ int TestClientRdpFile(int argc, char* argv[])
sValue = (char*) freerdp_client_rdp_file_get_string_option(file, "vendor string"); sValue = (char*) freerdp_client_rdp_file_get_string_option(file, "vendor string");
freerdp_client_rdp_file_set_string_option(file, "fruits", "banana,oranges"); freerdp_client_rdp_file_set_string_option(file, "fruits", "banana,oranges");
freerdp_client_rdp_file_set_integer_option(file, "numbers", 123456789); if (freerdp_client_rdp_file_set_integer_option(file, "numbers", 123456789) == -1)
{
printf("failed to set integer: numbers");
return -1;
}
for (index = 0; index < file->lineCount; index++) for (index = 0; index < file->lineCount; index++)
{ {

View File

@ -11,6 +11,7 @@
#import <freerdp/channels/channels.h> #import <freerdp/channels/channels.h>
#import <freerdp/client/channels.h> #import <freerdp/client/channels.h>
#import <freerdp/client/cmdline.h> #import <freerdp/client/cmdline.h>
#import <freerdp/freerdp.h>
#import "ios_freerdp.h" #import "ios_freerdp.h"
#import "ios_freerdp_ui.h" #import "ios_freerdp_ui.h"
@ -19,7 +20,6 @@
#import "RDPSession.h" #import "RDPSession.h"
#import "Utils.h" #import "Utils.h"
#pragma mark Connection helpers #pragma mark Connection helpers
static BOOL ios_pre_connect(freerdp* instance) static BOOL ios_pre_connect(freerdp* instance)
@ -279,6 +279,8 @@ void ios_context_free(freerdp* instance, rdpContext* context)
freerdp* ios_freerdp_new() freerdp* ios_freerdp_new()
{ {
freerdp* inst = freerdp_new(); freerdp* inst = freerdp_new();
if (!inst)
return NULL;
inst->PreConnect = ios_pre_connect; inst->PreConnect = ios_pre_connect;
inst->PostConnect = ios_post_connect; inst->PostConnect = ios_post_connect;
@ -297,6 +299,14 @@ freerdp* ios_freerdp_new()
free(inst->settings->ConfigPath); free(inst->settings->ConfigPath);
inst->settings->HomePath = strdup([home_path UTF8String]); inst->settings->HomePath = strdup([home_path UTF8String]);
inst->settings->ConfigPath = strdup([[home_path stringByAppendingPathComponent:@".freerdp"] UTF8String]); inst->settings->ConfigPath = strdup([[home_path stringByAppendingPathComponent:@".freerdp"] UTF8String]);
if (!inst->settings->HomePath || !inst->settings->ConfigPath)
{
free(inst->settings->HomePath);
free(inst->settings->ConfigPath);
freerdp_context_free(inst);
freerdp_free(inst);
return NULL;
}
return inst; return inst;
} }

View File

@ -52,6 +52,14 @@ BOOL ios_ui_authenticate(freerdp * instance, char** username, char** password, c
*password = strdup([[params objectForKey:@"password"] UTF8String]); *password = strdup([[params objectForKey:@"password"] UTF8String]);
*domain = strdup([[params objectForKey:@"domain"] UTF8String]); *domain = strdup([[params objectForKey:@"domain"] UTF8String]);
if (!(*username) || !(*password) || !(*domain))
{
free(*username);
free(*password);
free(*domain);
return FALSE;
}
return TRUE; return TRUE;
} }

View File

@ -75,31 +75,46 @@ NSString* TSXSessionDidFailToConnectNotification = @"TSXSessionDidFailToConnect"
settings->ConsoleSession = 1; settings->ConsoleSession = 1;
// connection info // connection info
settings->ServerHostname = strdup([_params UTF8StringForKey:@"hostname"]); if (!(settings->ServerHostname = strdup([_params UTF8StringForKey:@"hostname"])))
goto out_free;
// String settings // String settings
if ([[_params StringForKey:@"username"] length]) if ([[_params StringForKey:@"username"] length])
{
settings->Username = strdup([_params UTF8StringForKey:@"username"]); settings->Username = strdup([_params UTF8StringForKey:@"username"]);
if (!settings->Username)
goto out_free;
}
if ([[_params StringForKey:@"password"] length]) if ([[_params StringForKey:@"password"] length])
{
settings->Password = strdup([_params UTF8StringForKey:@"password"]); settings->Password = strdup([_params UTF8StringForKey:@"password"]);
if (!settings->Password)
goto out_free;
}
if ([[_params StringForKey:@"domain"] length]) if ([[_params StringForKey:@"domain"] length])
{
settings->Domain = strdup([_params UTF8StringForKey:@"domain"]); settings->Domain = strdup([_params UTF8StringForKey:@"domain"]);
if (!settings->Domain)
goto out_free;
}
settings->ShellWorkingDirectory = strdup([_params UTF8StringForKey:@"working_directory"]); settings->ShellWorkingDirectory = strdup([_params UTF8StringForKey:@"working_directory"]);
settings->AlternateShell = strdup([_params UTF8StringForKey:@"remote_program"]); settings->AlternateShell = strdup([_params UTF8StringForKey:@"remote_program"]);
if (!settings->ShellWorkingDirectory || !settings->AlternateShell)
goto out_free;
// RemoteFX // RemoteFX
if ([_params boolForKey:@"perf_remotefx" with3GEnabled:connected_via_3g]) if ([_params boolForKey:@"perf_remotefx" with3GEnabled:connected_via_3g])
{ {
settings->RemoteFxCodec = TRUE; settings->RemoteFxCodec = TRUE;
settings->FastPathOutput = TRUE; settings->FastPathOutput = TRUE;
settings->ColorDepth = 32; settings->ColorDepth = 32;
settings->LargePointerFlag = TRUE; settings->LargePointerFlag = TRUE;
settings->FrameMarkerCommandEnabled = TRUE; settings->FrameMarkerCommandEnabled = TRUE;
settings->FrameAcknowledge = 10; settings->FrameAcknowledge = 10;
} }
else else
{ {
@ -176,6 +191,12 @@ NSString* TSXSessionDidFailToConnectNotification = @"TSXSessionDidFailToConnect"
settings->GatewayUsageMethod = TSC_PROXY_MODE_DIRECT; settings->GatewayUsageMethod = TSC_PROXY_MODE_DIRECT;
settings->GatewayEnabled = TRUE; settings->GatewayEnabled = TRUE;
settings->GatewayUseSameCredentials = FALSE; settings->GatewayUseSameCredentials = FALSE;
if (!settings->GatewayHostname || !settings->GatewayUsername || !settings->GatewayPassword
|| !settings->GatewayDomain)
{
goto out_free;
}
} }
// Remote keyboard layout // Remote keyboard layout
@ -187,6 +208,10 @@ NSString* TSXSessionDidFailToConnectNotification = @"TSXSessionDidFailToConnect"
[self mfi]->session = self; [self mfi]->session = self;
return self; return self;
out_free:
[self release];
return nil;
} }
- (void)dealloc - (void)dealloc

View File

@ -28,6 +28,6 @@ option(ANDROID_BUILD_JAVA_DEBUG "Create a android debug package" ${JAVA_DEBUG_DE
set(ANDROID_APP_VERSION 3 CACHE STRING "Application version") set(ANDROID_APP_VERSION 3 CACHE STRING "Application version")
set(ANDROID_APP_TARGET_SDK 21 CACHE STRING "Application target android SDK") set(ANDROID_APP_TARGET_SDK 21 CACHE STRING "Application target android SDK")
set(ANDROID_APP_MIN_SDK 9 CACHE STRING "Application minimum android SDK requirement") set(ANDROID_APP_MIN_SDK 14 CACHE STRING "Application minimum android SDK requirement")
set(ANDROID_APP_GOOGLE_TARGET_SDK "16" CACHE STRING "Application target google SDK") set(ANDROID_APP_GOOGLE_TARGET_SDK "16" CACHE STRING "Application target google SDK")

31
cmake/FindDevD.cmake Normal file
View File

@ -0,0 +1,31 @@
# Configure devd environment
#
# DEVD_FOUND - system has a devd
# DEVD_BIN_DIR - devd bin dir
# DEVD_SKT_DIR - devd socket dir
#
# Copyright (c) 2015 Rozhuk Ivan <rozhuk.im@gmail.com>
# Redistribution and use is allowed according to the terms of the BSD license.
#
FIND_PATH(
DEVD_BIN_DIR
NAMES devd
PATHS /sbin /usr/sbin /usr/local/sbin
)
FIND_PATH(
DEVD_SKT_DIR
NAMES devd.seqpacket.pipe devd.pipe
PATHS /var/run/
)
if (DEVD_BIN_DIR)
set(DEVD_FOUND "YES")
message(STATUS "devd found")
if (NOT DEVD_SKT_DIR)
message(STATUS "devd not running!")
endif (NOT DEVD_SKT_DIR)
endif (DEVD_BIN_DIR)

View File

@ -20,6 +20,7 @@ set(UUID_FOUND TRUE)
else (UUID_LIBRARIES AND UUID_INCLUDE_DIRS) else (UUID_LIBRARIES AND UUID_INCLUDE_DIRS)
find_path(UUID_INCLUDE_DIR find_path(UUID_INCLUDE_DIR
NAMES NAMES
uuid.h
uuid/uuid.h uuid/uuid.h
PATHS PATHS
${UUID_DIR}/include ${UUID_DIR}/include
@ -85,26 +86,27 @@ $ENV{OSG_ROOT}/lib
/opt/lib /opt/lib
/usr/freeware/lib64 /usr/freeware/lib64
) )
if (NOT UUID_LIBRARY AND BSD)
set(UUID_LIBRARY "")
endif(NOT UUID_LIBRARY AND BSD)
set(UUID_INCLUDE_DIRS set(UUID_INCLUDE_DIRS ${UUID_INCLUDE_DIR})
${UUID_INCLUDE_DIR} set(UUID_LIBRARIES ${UUID_LIBRARY})
)
set(UUID_LIBRARIES
${UUID_LIBRARY}
)
if (UUID_INCLUDE_DIRS AND UUID_LIBRARIES) if (UUID_INCLUDE_DIRS)
set(UUID_FOUND TRUE) if (BSD OR UUID_LIBRARIES)
endif (UUID_INCLUDE_DIRS AND UUID_LIBRARIES) set(UUID_FOUND TRUE)
endif (BSD OR UUID_LIBRARIES)
endif (UUID_INCLUDE_DIRS)
if (UUID_FOUND) if (UUID_FOUND)
if (NOT UUID_FIND_QUIETLY) if (NOT UUID_FIND_QUIETLY)
message(STATUS "Found UUID: ${UUID_LIBRARIES}") message(STATUS "Found UUID: ${UUID_LIBRARIES}")
endif (NOT UUID_FIND_QUIETLY) endif (NOT UUID_FIND_QUIETLY)
else (UUID_FOUND) else (UUID_FOUND)
if (UUID_FIND_REQUIRED) if (UUID_FIND_REQUIRED)
message(FATAL_ERROR "Could not find UUID") message(FATAL_ERROR "Could not find UUID")
endif (UUID_FIND_REQUIRED) endif (UUID_FIND_REQUIRED)
endif (UUID_FOUND) endif (UUID_FOUND)
# show the UUID_INCLUDE_DIRS and UUID_LIBRARIES variables only in the advanced view # show the UUID_INCLUDE_DIRS and UUID_LIBRARIES variables only in the advanced view

View File

@ -209,6 +209,6 @@ After that FreeRDP and the Android package need to be rebuilt to include the lat
Android CMake related Variables Android CMake related Variables
------------------------------- -------------------------------
ANDROID_APP_TARGET_SDK ... specifies the desired android target SDK, currently 11 ANDROID_APP_TARGET_SDK ... specifies the desired android target SDK, currently 21
ANDROID_APP_MIN_SDK ... specifies the minimum android SDK version supported, currently 8 ANDROID_APP_MIN_SDK ... specifies the minimum android SDK version supported, currently 14
ANDROID_APP_GOOGLE_TARGET_SDK ... specifies the minimum google SDK requirement, currently 16 ANDROID_APP_GOOGLE_TARGET_SDK ... specifies the minimum google SDK requirement, currently 16

View File

@ -30,10 +30,8 @@ different install/build directory you specify it as first parameter:
In the example above the output can then be found in /tmp/openssl. In the example above the output can then be found in /tmp/openssl.
The script uses oldest iOS/iPhoneSimulator SDK found on the build machine per default. If you need to build against a different SDK you can set USER_OS_SDK The script uses oldest iOS/iPhoneSimulator SDK found on the build machine per default. If it is required to build against a specific SDK version
and/or USER_SIM_SDK in the top of the build script to the SDK version you need. E.g.: the variable SDK_VERSION can be used to specify it. The minimum SDK version that should be used can be set with MIN_SDK_VERSION within the script.
USER_SIM_SDK="iPhoneSimulator6.0.sdk"
When the script is finished you will find libcrypto.a and libssl.at, both universal libraries containing all openssl/lib When the script is finished you will find libcrypto.a and libssl.at, both universal libraries containing all openssl/lib
subfolder in the specified subfolder in the specified

View File

@ -104,7 +104,7 @@ struct _BITMAP_PLANAR_CONTEXT
FREERDP_API int freerdp_split_color_planes(BYTE* data, UINT32 format, int width, int height, int scanline, BYTE* planes[4]); FREERDP_API int freerdp_split_color_planes(BYTE* data, UINT32 format, int width, int height, int scanline, BYTE* planes[4]);
FREERDP_API BYTE* freerdp_bitmap_planar_compress_plane_rle(BYTE* plane, int width, int height, BYTE* outPlane, int* dstSize); FREERDP_API BYTE* freerdp_bitmap_planar_compress_plane_rle(BYTE* plane, int width, int height, BYTE* outPlane, int* dstSize);
FREERDP_API BYTE* freerdp_bitmap_planar_delta_encode_plane(BYTE* inPlane, int width, int height, BYTE* outPlane); FREERDP_API BYTE* freerdp_bitmap_planar_delta_encode_plane(BYTE* inPlane, int width, int height, BYTE* outPlane);
FREERDP_API int freerdp_bitmap_planar_delta_encode_planes(BYTE* inPlanes[4], int width, int height, BYTE* outPlanes[4]); FREERDP_API BOOL freerdp_bitmap_planar_delta_encode_planes(BYTE* inPlanes[4], int width, int height, BYTE* outPlanes[4]);
FREERDP_API BYTE* freerdp_bitmap_compress_planar(BITMAP_PLANAR_CONTEXT* context, BYTE* data, UINT32 format, FREERDP_API BYTE* freerdp_bitmap_compress_planar(BITMAP_PLANAR_CONTEXT* context, BYTE* data, UINT32 format,
int width, int height, int scanline, BYTE* dstData, int* pDstSize); int width, int height, int scanline, BYTE* dstData, int* pDstSize);

View File

@ -46,10 +46,6 @@ typedef struct _PROGRESSIVE_CONTEXT PROGRESSIVE_CONTEXT;
#define PROGRESSIVE_WBT_TILE_FIRST 0xCCC6 #define PROGRESSIVE_WBT_TILE_FIRST 0xCCC6
#define PROGRESSIVE_WBT_TILE_UPGRADE 0xCCC7 #define PROGRESSIVE_WBT_TILE_UPGRADE 0xCCC7
#define PROGRESSIVE_BLOCKS_ALL 0x0001
#define PROGRESSIVE_BLOCKS_REGION 0x0002
#define PROGRESSIVE_BLOCKS_TILE 0x0004
struct _RFX_COMPONENT_CODEC_QUANT struct _RFX_COMPONENT_CODEC_QUANT
{ {
BYTE LL3; BYTE LL3;
@ -102,77 +98,6 @@ struct _PROGRESSIVE_BLOCK_CONTEXT
}; };
typedef struct _PROGRESSIVE_BLOCK_CONTEXT PROGRESSIVE_BLOCK_CONTEXT; typedef struct _PROGRESSIVE_BLOCK_CONTEXT PROGRESSIVE_BLOCK_CONTEXT;
struct _PROGRESSIVE_BLOCK_TILE_SIMPLE
{
UINT16 blockType;
UINT32 blockLen;
BYTE quantIdxY;
BYTE quantIdxCb;
BYTE quantIdxCr;
UINT16 xIdx;
UINT16 yIdx;
BYTE flags;
UINT16 yLen;
UINT16 cbLen;
UINT16 crLen;
UINT16 tailLen;
BYTE* yData;
BYTE* cbData;
BYTE* crData;
BYTE* tailData;
};
typedef struct _PROGRESSIVE_BLOCK_TILE_SIMPLE PROGRESSIVE_BLOCK_TILE_SIMPLE;
struct _PROGRESSIVE_BLOCK_TILE_FIRST
{
UINT16 blockType;
UINT32 blockLen;
BYTE quantIdxY;
BYTE quantIdxCb;
BYTE quantIdxCr;
UINT16 xIdx;
UINT16 yIdx;
BYTE flags;
BYTE quality;
UINT16 yLen;
UINT16 cbLen;
UINT16 crLen;
UINT16 tailLen;
BYTE* yData;
BYTE* cbData;
BYTE* crData;
BYTE* tailData;
};
typedef struct _PROGRESSIVE_BLOCK_TILE_FIRST PROGRESSIVE_BLOCK_TILE_FIRST;
struct _PROGRESSIVE_BLOCK_TILE_UPGRADE
{
UINT16 blockType;
UINT32 blockLen;
BYTE quantIdxY;
BYTE quantIdxCb;
BYTE quantIdxCr;
UINT16 xIdx;
UINT16 yIdx;
BYTE quality;
UINT16 ySrlLen;
UINT16 yRawLen;
UINT16 cbSrlLen;
UINT16 cbRawLen;
UINT16 crSrlLen;
UINT16 crRawLen;
BYTE* ySrlData;
BYTE* yRawData;
BYTE* cbSrlData;
BYTE* cbRawData;
BYTE* crSrlData;
BYTE* crRawData;
};
typedef struct _PROGRESSIVE_BLOCK_TILE_UPGRADE PROGRESSIVE_BLOCK_TILE_UPGRADE;
struct _RFX_PROGRESSIVE_TILE struct _RFX_PROGRESSIVE_TILE
{ {
UINT16 blockType; UINT16 blockType;
@ -285,7 +210,6 @@ struct _PROGRESSIVE_CONTEXT
BOOL invert; BOOL invert;
wLog* log;
wBufferPool* bufferPool; wBufferPool* bufferPool;
UINT32 cRects; UINT32 cRects;

View File

@ -55,8 +55,8 @@ struct rdp_certificate_store
#endif #endif
FREERDP_API rdpCertificateData* certificate_data_new( FREERDP_API rdpCertificateData* certificate_data_new(
char* hostname, UINT16 port, char*subject, char* hostname, UINT16 port, char* subject,
char*issuer, char* fingerprint); char* issuer, char* fingerprint);
FREERDP_API void certificate_data_free( FREERDP_API void certificate_data_free(
rdpCertificateData* certificate_data); rdpCertificateData* certificate_data);
FREERDP_API rdpCertificateStore* certificate_store_new( FREERDP_API rdpCertificateStore* certificate_store_new(

View File

@ -24,7 +24,7 @@
#include <freerdp/freerdp.h> #include <freerdp/freerdp.h>
#include <freerdp/gdi/gdi.h> #include <freerdp/gdi/gdi.h>
typedef int (*pLineTo_16bpp)(HGDI_DC hdc, int nXEnd, int nYEnd); typedef BOOL (*pLineTo_16bpp)(HGDI_DC hdc, int nXEnd, int nYEnd);
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -32,10 +32,10 @@ typedef int (*pLineTo_16bpp)(HGDI_DC hdc, int nXEnd, int nYEnd);
FREERDP_API UINT16 gdi_get_color_16bpp(HGDI_DC hdc, GDI_COLOR color); FREERDP_API UINT16 gdi_get_color_16bpp(HGDI_DC hdc, GDI_COLOR color);
FREERDP_API int FillRect_16bpp(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr); FREERDP_API BOOL FillRect_16bpp(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr);
FREERDP_API int BitBlt_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop); FREERDP_API BOOL BitBlt_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, DWORD rop);
FREERDP_API int PatBlt_16bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop); FREERDP_API BOOL PatBlt_16bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, DWORD rop);
FREERDP_API int LineTo_16bpp(HGDI_DC hdc, int nXEnd, int nYEnd); FREERDP_API BOOL LineTo_16bpp(HGDI_DC hdc, int nXEnd, int nYEnd);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -24,7 +24,7 @@
#include <freerdp/freerdp.h> #include <freerdp/freerdp.h>
#include <freerdp/gdi/gdi.h> #include <freerdp/gdi/gdi.h>
typedef int (*pLineTo_32bpp)(HGDI_DC hdc, int nXEnd, int nYEnd); typedef BOOL (*pLineTo_32bpp)(HGDI_DC hdc, int nXEnd, int nYEnd);
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -32,10 +32,10 @@ typedef int (*pLineTo_32bpp)(HGDI_DC hdc, int nXEnd, int nYEnd);
FREERDP_API UINT32 gdi_get_color_32bpp(HGDI_DC hdc, GDI_COLOR color); FREERDP_API UINT32 gdi_get_color_32bpp(HGDI_DC hdc, GDI_COLOR color);
FREERDP_API int FillRect_32bpp(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr); FREERDP_API BOOL FillRect_32bpp(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr);
FREERDP_API int BitBlt_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop); FREERDP_API BOOL BitBlt_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, DWORD rop);
FREERDP_API int PatBlt_32bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop); FREERDP_API BOOL PatBlt_32bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, DWORD rop);
FREERDP_API int LineTo_32bpp(HGDI_DC hdc, int nXEnd, int nYEnd); FREERDP_API BOOL LineTo_32bpp(HGDI_DC hdc, int nXEnd, int nYEnd);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -24,7 +24,7 @@
#include <freerdp/freerdp.h> #include <freerdp/freerdp.h>
#include <freerdp/gdi/gdi.h> #include <freerdp/gdi/gdi.h>
typedef int (*pLineTo_8bpp)(HGDI_DC hdc, int nXEnd, int nYEnd); typedef BOOL (*pLineTo_8bpp)(HGDI_DC hdc, int nXEnd, int nYEnd);
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -32,10 +32,10 @@ typedef int (*pLineTo_8bpp)(HGDI_DC hdc, int nXEnd, int nYEnd);
FREERDP_API BYTE gdi_get_color_8bpp(HGDI_DC hdc, GDI_COLOR color); FREERDP_API BYTE gdi_get_color_8bpp(HGDI_DC hdc, GDI_COLOR color);
FREERDP_API int FillRect_8bpp(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr); FREERDP_API BOOL FillRect_8bpp(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr);
FREERDP_API int BitBlt_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop); FREERDP_API BOOL BitBlt_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, DWORD rop);
FREERDP_API int PatBlt_8bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop); FREERDP_API BOOL PatBlt_8bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, DWORD rop);
FREERDP_API int LineTo_8bpp(HGDI_DC hdc, int nXEnd, int nYEnd); FREERDP_API BOOL LineTo_8bpp(HGDI_DC hdc, int nXEnd, int nYEnd);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -40,9 +40,9 @@ FREERDP_API void gdi_SetPixel_16bpp(HGDI_BITMAP hBmp, int X, int Y, UINT16 pixel
FREERDP_API void gdi_SetPixel_32bpp(HGDI_BITMAP hBmp, int X, int Y, UINT32 pixel); FREERDP_API void gdi_SetPixel_32bpp(HGDI_BITMAP hBmp, int X, int Y, UINT32 pixel);
FREERDP_API HGDI_BITMAP gdi_CreateBitmap(int nWidth, int nHeight, int cBitsPerPixel, BYTE* data); FREERDP_API HGDI_BITMAP gdi_CreateBitmap(int nWidth, int nHeight, int cBitsPerPixel, BYTE* data);
FREERDP_API HGDI_BITMAP gdi_CreateCompatibleBitmap(HGDI_DC hdc, int nWidth, int nHeight); FREERDP_API HGDI_BITMAP gdi_CreateCompatibleBitmap(HGDI_DC hdc, int nWidth, int nHeight);
FREERDP_API int gdi_BitBlt(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop); FREERDP_API BOOL gdi_BitBlt(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, DWORD rop);
typedef int (*p_BitBlt)(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop); typedef BOOL (*p_BitBlt)(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, DWORD rop);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -30,12 +30,12 @@
FREERDP_API HGDI_BRUSH gdi_CreateSolidBrush(GDI_COLOR crColor); FREERDP_API HGDI_BRUSH gdi_CreateSolidBrush(GDI_COLOR crColor);
FREERDP_API HGDI_BRUSH gdi_CreatePatternBrush(HGDI_BITMAP hbmp); FREERDP_API HGDI_BRUSH gdi_CreatePatternBrush(HGDI_BITMAP hbmp);
FREERDP_API HGDI_BRUSH gdi_CreateHatchBrush(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); FREERDP_API BOOL gdi_PatBlt(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, DWORD rop);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
typedef int (*p_PatBlt)(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop); typedef BOOL (*p_PatBlt)(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, DWORD rop);
#endif /* FREERDP_GDI_BRUSH_H */ #endif /* FREERDP_GDI_BRUSH_H */

View File

@ -27,10 +27,10 @@
extern "C" { extern "C" {
#endif #endif
FREERDP_API int gdi_SetClipRgn(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight); FREERDP_API BOOL gdi_SetClipRgn(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight);
FREERDP_API HGDI_RGN gdi_GetClipRgn(HGDI_DC hdc); FREERDP_API HGDI_RGN gdi_GetClipRgn(HGDI_DC hdc);
FREERDP_API int gdi_SetNullClipRgn(HGDI_DC hdc); FREERDP_API BOOL gdi_SetNullClipRgn(HGDI_DC hdc);
FREERDP_API int gdi_ClipCoords(HGDI_DC hdc, int *x, int *y, int *w, int *h, int *srcx, int *srcy); FREERDP_API BOOL gdi_ClipCoords(HGDI_DC hdc, int *x, int *y, int *w, int *h, int *srcx, int *srcy);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -31,8 +31,8 @@ FREERDP_API HGDI_DC gdi_GetDC(void);
FREERDP_API HGDI_DC gdi_CreateDC(UINT32 flags, int bpp); FREERDP_API HGDI_DC gdi_CreateDC(UINT32 flags, int bpp);
FREERDP_API HGDI_DC gdi_CreateCompatibleDC(HGDI_DC hdc); FREERDP_API HGDI_DC gdi_CreateCompatibleDC(HGDI_DC hdc);
FREERDP_API HGDIOBJECT gdi_SelectObject(HGDI_DC hdc, HGDIOBJECT hgdiobject); FREERDP_API HGDIOBJECT gdi_SelectObject(HGDI_DC hdc, HGDIOBJECT hgdiobject);
FREERDP_API int gdi_DeleteObject(HGDIOBJECT hgdiobject); FREERDP_API BOOL gdi_DeleteObject(HGDIOBJECT hgdiobject);
FREERDP_API int gdi_DeleteDC(HGDI_DC hdc); FREERDP_API BOOL gdi_DeleteDC(HGDI_DC hdc);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -315,7 +315,7 @@ struct rdp_gdi
extern "C" { extern "C" {
#endif #endif
FREERDP_API UINT32 gdi_rop3_code(BYTE code); FREERDP_API DWORD gdi_rop3_code(BYTE code);
FREERDP_API UINT32 gdi_get_pixel_format(UINT32 bitsPerPixel, BOOL vFlip); FREERDP_API UINT32 gdi_get_pixel_format(UINT32 bitsPerPixel, BOOL vFlip);
FREERDP_API BYTE* gdi_get_bitmap_pointer(HGDI_DC hdcBmp, int x, int y); FREERDP_API BYTE* gdi_get_bitmap_pointer(HGDI_DC hdcBmp, int x, int y);
FREERDP_API BYTE* gdi_get_brush_pointer(HGDI_DC hdcBrush, int x, int y); FREERDP_API BYTE* gdi_get_brush_pointer(HGDI_DC hdcBrush, int x, int y);

View File

@ -27,16 +27,16 @@
extern "C" { extern "C" {
#endif #endif
FREERDP_API int gdi_LineTo(HGDI_DC hdc, int nXEnd, int nYEnd); FREERDP_API BOOL gdi_LineTo(HGDI_DC hdc, int nXEnd, int nYEnd);
FREERDP_API int gdi_PolylineTo(HGDI_DC hdc, GDI_POINT *lppt, int cCount); FREERDP_API BOOL gdi_PolylineTo(HGDI_DC hdc, GDI_POINT *lppt, DWORD cCount);
FREERDP_API int gdi_Polyline(HGDI_DC hdc, GDI_POINT *lppt, int cPoints); FREERDP_API BOOL gdi_Polyline(HGDI_DC hdc, GDI_POINT *lppt, int cPoints);
FREERDP_API int gdi_PolyPolyline(HGDI_DC hdc, GDI_POINT *lppt, int *lpdwPolyPoints, int cCount); FREERDP_API BOOL gdi_PolyPolyline(HGDI_DC hdc, GDI_POINT *lppt, int *lpdwPolyPoints, DWORD cCount);
FREERDP_API int gdi_MoveToEx(HGDI_DC hdc, int X, int Y, HGDI_POINT lpPoint); FREERDP_API BOOL gdi_MoveToEx(HGDI_DC hdc, int X, int Y, HGDI_POINT lpPoint);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
typedef int (*p_LineTo)(HGDI_DC hdc, int nXEnd, int nYEnd); typedef BOOL (*p_LineTo)(HGDI_DC hdc, int nXEnd, int nYEnd);
#endif /* FREERDP_GDI_LINE_H */ #endif /* FREERDP_GDI_LINE_H */

View File

@ -37,13 +37,13 @@ FREERDP_API void gdi_RgnToRect(HGDI_RGN rgn, HGDI_RECT rect);
FREERDP_API void gdi_CRgnToRect(int x, int y, int w, int h, HGDI_RECT rect); FREERDP_API void gdi_CRgnToRect(int x, int y, int w, int h, HGDI_RECT rect);
FREERDP_API void gdi_RgnToCRect(HGDI_RGN rgn, int *left, int *top, int *right, int *bottom); FREERDP_API void gdi_RgnToCRect(HGDI_RGN rgn, int *left, int *top, int *right, int *bottom);
FREERDP_API void gdi_CRgnToCRect(int x, int y, int w, int h, int *left, int *top, int *right, int *bottom); FREERDP_API void gdi_CRgnToCRect(int x, int y, int w, int h, int *left, int *top, int *right, int *bottom);
FREERDP_API int gdi_CopyOverlap(int x, int y, int width, int height, int srcx, int srcy); FREERDP_API BOOL gdi_CopyOverlap(int x, int y, int width, int height, int srcx, int srcy);
FREERDP_API int gdi_SetRect(HGDI_RECT rc, int xLeft, int yTop, int xRight, int yBottom); FREERDP_API BOOL gdi_SetRect(HGDI_RECT rc, int xLeft, int yTop, int xRight, int yBottom);
FREERDP_API int gdi_SetRgn(HGDI_RGN hRgn, int nXLeft, int nYLeft, int nWidth, int nHeight); FREERDP_API BOOL gdi_SetRgn(HGDI_RGN hRgn, int nXLeft, int nYLeft, int nWidth, int nHeight);
FREERDP_API int gdi_SetRectRgn(HGDI_RGN hRgn, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect); FREERDP_API BOOL gdi_SetRectRgn(HGDI_RGN hRgn, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
FREERDP_API int gdi_EqualRgn(HGDI_RGN hSrcRgn1, HGDI_RGN hSrcRgn2); FREERDP_API BOOL gdi_EqualRgn(HGDI_RGN hSrcRgn1, HGDI_RGN hSrcRgn2);
FREERDP_API int gdi_CopyRect(HGDI_RECT dst, HGDI_RECT src); FREERDP_API BOOL gdi_CopyRect(HGDI_RECT dst, HGDI_RECT src);
FREERDP_API int gdi_PtInRect(HGDI_RECT rc, int x, int y); FREERDP_API BOOL gdi_PtInRect(HGDI_RECT rc, int x, int y);
FREERDP_API BOOL gdi_InvalidateRegion(HGDI_DC hdc, int x, int y, int w, int h); FREERDP_API BOOL gdi_InvalidateRegion(HGDI_DC hdc, int x, int y, int w, int h);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -27,13 +27,13 @@
extern "C" { extern "C" {
#endif #endif
FREERDP_API int gdi_Ellipse(HGDI_DC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect); FREERDP_API BOOL gdi_Ellipse(HGDI_DC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
FREERDP_API int gdi_FillRect(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr); FREERDP_API BOOL gdi_FillRect(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr);
FREERDP_API int gdi_Polygon(HGDI_DC hdc, GDI_POINT *lpPoints, int nCount); FREERDP_API BOOL gdi_Polygon(HGDI_DC hdc, GDI_POINT *lpPoints, int nCount);
FREERDP_API int gdi_PolyPolygon(HGDI_DC hdc, GDI_POINT *lpPoints, int *lpPolyCounts, int nCount); FREERDP_API BOOL gdi_PolyPolygon(HGDI_DC hdc, GDI_POINT *lpPoints, int *lpPolyCounts, int nCount);
FREERDP_API int gdi_Rectangle(HGDI_DC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect); FREERDP_API BOOL gdi_Rectangle(HGDI_DC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
typedef int (*p_FillRect)(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr); typedef BOOL (*p_FillRect)(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -170,6 +170,7 @@ typedef struct _RDP_KEYBOARD_LAYOUT RDP_KEYBOARD_LAYOUT;
#define KBD_GREEK_LATIN 0x00050408 #define KBD_GREEK_LATIN 0x00050408
#define KBD_US_ENGLISH_TABLE_FOR_IBM_ARABIC_238_L 0x00050409 #define KBD_US_ENGLISH_TABLE_FOR_IBM_ARABIC_238_L 0x00050409
#define KBD_GREEK_POLYTONIC 0x00060408 #define KBD_GREEK_POLYTONIC 0x00060408
#define KBD_FRENCH_BEPO 0xa000040c
#define KBD_GERMAN_NEO 0xB0000407 #define KBD_GERMAN_NEO 0xB0000407
/* Global Input Method Editor (IME) IDs */ /* Global Input Method Editor (IME) IDs */

View File

@ -31,6 +31,8 @@
#include <freerdp/server/encomsp.h> #include <freerdp/server/encomsp.h>
#include <freerdp/server/remdesk.h> #include <freerdp/server/remdesk.h>
#include <freerdp/server/rdpsnd.h>
#include <freerdp/server/audin.h>
#include <freerdp/codec/color.h> #include <freerdp/codec/color.h>
#include <freerdp/codec/region.h> #include <freerdp/codec/region.h>
@ -64,6 +66,8 @@ typedef int (*pfnShadowEnumMonitors)(MONITOR_DEF* monitors, int maxMonitors);
typedef int (*pfnShadowAuthenticate)(rdpShadowSubsystem* subsystem, typedef int (*pfnShadowAuthenticate)(rdpShadowSubsystem* subsystem,
const char* user, const char* domain, const char* password); const char* user, const char* domain, const char* password);
typedef BOOL (*pfnShadowClientConnect)(rdpShadowSubsystem* subsystem, rdpShadowClient* client);
typedef void (*pfnShadowClientDisconnect)(rdpShadowSubsystem* subsystem, rdpShadowClient* client);
typedef int (*pfnShadowSynchronizeEvent)(rdpShadowSubsystem* subsystem, UINT32 flags); typedef int (*pfnShadowSynchronizeEvent)(rdpShadowSubsystem* subsystem, UINT32 flags);
typedef int (*pfnShadowKeyboardEvent)(rdpShadowSubsystem* subsystem, UINT16 flags, UINT16 code); typedef int (*pfnShadowKeyboardEvent)(rdpShadowSubsystem* subsystem, UINT16 flags, UINT16 code);
@ -71,6 +75,8 @@ typedef int (*pfnShadowUnicodeKeyboardEvent)(rdpShadowSubsystem* subsystem, UINT
typedef int (*pfnShadowMouseEvent)(rdpShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y); typedef int (*pfnShadowMouseEvent)(rdpShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y);
typedef int (*pfnShadowExtendedMouseEvent)(rdpShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y); typedef int (*pfnShadowExtendedMouseEvent)(rdpShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y);
typedef void (*pfnShadowChannelAudinServerReceiveSamples)(rdpShadowSubsystem* subsystem, const void* buf, int nframes);
struct rdp_shadow_client struct rdp_shadow_client
{ {
rdpContext context; rdpContext context;
@ -80,7 +86,7 @@ struct rdp_shadow_client
BOOL inLobby; BOOL inLobby;
BOOL mayView; BOOL mayView;
BOOL mayInteract; BOOL mayInteract;
HANDLE StopEvent; wMessageQueue* MsgQueue;
CRITICAL_SECTION lock; CRITICAL_SECTION lock;
REGION16 invalidRegion; REGION16 invalidRegion;
rdpShadowServer* server; rdpShadowServer* server;
@ -94,6 +100,8 @@ struct rdp_shadow_client
HANDLE vcm; HANDLE vcm;
EncomspServerContext* encomsp; EncomspServerContext* encomsp;
RemdeskServerContext* remdesk; RemdeskServerContext* remdesk;
RdpsndServerContext* rdpsnd;
audin_server_context* audin;
}; };
struct rdp_shadow_server struct rdp_shadow_server
@ -151,13 +159,21 @@ struct _RDP_SHADOW_ENTRY_POINTS
UINT32 pointerX; \ UINT32 pointerX; \
UINT32 pointerY; \ UINT32 pointerY; \
\ \
const AUDIO_FORMAT* rdpsndFormats; \
int nRdpsndFormats; \
const AUDIO_FORMAT* audinFormats; \
int nAudinFormats; \
\
pfnShadowSynchronizeEvent SynchronizeEvent; \ pfnShadowSynchronizeEvent SynchronizeEvent; \
pfnShadowKeyboardEvent KeyboardEvent; \ pfnShadowKeyboardEvent KeyboardEvent; \
pfnShadowUnicodeKeyboardEvent UnicodeKeyboardEvent; \ pfnShadowUnicodeKeyboardEvent UnicodeKeyboardEvent; \
pfnShadowMouseEvent MouseEvent; \ pfnShadowMouseEvent MouseEvent; \
pfnShadowExtendedMouseEvent ExtendedMouseEvent; \ pfnShadowExtendedMouseEvent ExtendedMouseEvent; \
pfnShadowChannelAudinServerReceiveSamples AudinServerReceiveSamples; \
\ \
pfnShadowAuthenticate Authenticate; \ pfnShadowAuthenticate Authenticate; \
pfnShadowClientConnect ClientConnect; \
pfnShadowClientDisconnect ClientDisconnect; \
\ \
rdpShadowServer* server rdpShadowServer* server
@ -166,10 +182,85 @@ struct rdp_shadow_subsystem
RDP_SHADOW_SUBSYSTEM_COMMON(); RDP_SHADOW_SUBSYSTEM_COMMON();
}; };
/* Definition of message between subsystem and clients */
#define SHADOW_MSG_IN_REFRESH_OUTPUT_ID 1001
#define SHADOW_MSG_IN_SUPPRESS_OUTPUT_ID 1002
struct _SHADOW_MSG_IN_REFRESH_OUTPUT
{
UINT32 numRects;
RECTANGLE_16* rects;
};
typedef struct _SHADOW_MSG_IN_REFRESH_OUTPUT SHADOW_MSG_IN_REFRESH_OUTPUT;
struct _SHADOW_MSG_IN_SUPPRESS_OUTPUT
{
BOOL allow;
RECTANGLE_16 rect;
};
typedef struct _SHADOW_MSG_IN_SUPPRESS_OUTPUT SHADOW_MSG_IN_SUPPRESS_OUTPUT;
typedef struct _SHADOW_MSG_OUT SHADOW_MSG_OUT;
typedef void (*MSG_OUT_FREE_FN)(UINT32 id, SHADOW_MSG_OUT* msg);
#define RDP_SHADOW_MSG_OUT_COMMON() \
int refCount; \
MSG_OUT_FREE_FN Free; /* function to free SHADOW_MSG_OUT */
struct _SHADOW_MSG_OUT
{
RDP_SHADOW_MSG_OUT_COMMON();
};
#define SHADOW_MSG_OUT_POINTER_POSITION_UPDATE_ID 2001
#define SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE_ID 2002
#define SHADOW_MSG_OUT_AUDIO_OUT_SAMPLES_ID 2003
#define SHADOW_MSG_OUT_AUDIO_OUT_VOLUME_ID 2004
struct _SHADOW_MSG_OUT_POINTER_POSITION_UPDATE
{
RDP_SHADOW_MSG_OUT_COMMON();
UINT32 xPos;
UINT32 yPos;
};
typedef struct _SHADOW_MSG_OUT_POINTER_POSITION_UPDATE SHADOW_MSG_OUT_POINTER_POSITION_UPDATE;
struct _SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE
{
RDP_SHADOW_MSG_OUT_COMMON();
UINT32 xHot;
UINT32 yHot;
UINT32 width;
UINT32 height;
BYTE* pixels;
int scanline;
BOOL premultiplied;
};
typedef struct _SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE;
struct _SHADOW_MSG_OUT_AUDIO_OUT_SAMPLES
{
RDP_SHADOW_MSG_OUT_COMMON();
AUDIO_FORMAT audio_format;
void* buf;
int nFrames;
UINT16 wTimestamp;
};
typedef struct _SHADOW_MSG_OUT_AUDIO_OUT_SAMPLES SHADOW_MSG_OUT_AUDIO_OUT_SAMPLES;
struct _SHADOW_MSG_OUT_AUDIO_OUT_VOLUME
{
RDP_SHADOW_MSG_OUT_COMMON();
int left;
int right;
};
typedef struct _SHADOW_MSG_OUT_AUDIO_OUT_VOLUME SHADOW_MSG_OUT_AUDIO_OUT_VOLUME;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
FREERDP_API void shadow_subsystem_set_entry(pfnShadowSubsystemEntry pEntry);
FREERDP_API int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** argv); FREERDP_API int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** argv);
FREERDP_API int shadow_server_command_line_status_print(rdpShadowServer* server, int argc, char** argv, int status); FREERDP_API int shadow_server_command_line_status_print(rdpShadowServer* server, int argc, char** argv, int status);
@ -179,11 +270,18 @@ FREERDP_API int shadow_server_stop(rdpShadowServer* server);
FREERDP_API int shadow_server_init(rdpShadowServer* server); FREERDP_API int shadow_server_init(rdpShadowServer* server);
FREERDP_API int shadow_server_uninit(rdpShadowServer* server); FREERDP_API int shadow_server_uninit(rdpShadowServer* server);
FREERDP_API int shadow_enum_monitors(MONITOR_DEF* monitors, int maxMonitors, const char* name); FREERDP_API int shadow_enum_monitors(MONITOR_DEF* monitors, int maxMonitors);
FREERDP_API rdpShadowServer* shadow_server_new(); FREERDP_API rdpShadowServer* shadow_server_new();
FREERDP_API void shadow_server_free(rdpShadowServer* server); FREERDP_API void shadow_server_free(rdpShadowServer* server);
FREERDP_API BOOL shadow_client_post_msg(rdpShadowClient* client, void* context, UINT32 type, SHADOW_MSG_OUT* msg, void* lParam);
FREERDP_API int shadow_client_boardcast_msg(rdpShadowServer* server, void* context, UINT32 type, SHADOW_MSG_OUT* msg, void* lParam);
FREERDP_API int shadow_client_boardcast_quit(rdpShadowServer* server, int nExitCode);
FREERDP_API int shadow_encoder_preferred_fps(rdpShadowEncoder* encoder);
FREERDP_API UINT32 shadow_encoder_inflight_frames(rdpShadowEncoder* encoder);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1435,17 +1435,17 @@ FREERDP_API int freerdp_addin_replace_argument(ADDIN_ARGV* args, char* previous,
FREERDP_API int freerdp_addin_set_argument_value(ADDIN_ARGV* args, char* option, char* value); FREERDP_API int freerdp_addin_set_argument_value(ADDIN_ARGV* args, char* option, char* value);
FREERDP_API int freerdp_addin_replace_argument_value(ADDIN_ARGV* args, char* previous, char* option, char* value); FREERDP_API int freerdp_addin_replace_argument_value(ADDIN_ARGV* args, char* previous, char* option, char* value);
FREERDP_API void freerdp_device_collection_add(rdpSettings* settings, RDPDR_DEVICE* device); FREERDP_API BOOL freerdp_device_collection_add(rdpSettings* settings, RDPDR_DEVICE* device);
FREERDP_API RDPDR_DEVICE* freerdp_device_collection_find(rdpSettings* settings, const char* name); FREERDP_API RDPDR_DEVICE* freerdp_device_collection_find(rdpSettings* settings, const char* name);
FREERDP_API RDPDR_DEVICE* freerdp_device_clone(RDPDR_DEVICE* device); FREERDP_API RDPDR_DEVICE* freerdp_device_clone(RDPDR_DEVICE* device);
FREERDP_API void freerdp_device_collection_free(rdpSettings* settings); FREERDP_API void freerdp_device_collection_free(rdpSettings* settings);
FREERDP_API void freerdp_static_channel_collection_add(rdpSettings* settings, ADDIN_ARGV* channel); FREERDP_API BOOL freerdp_static_channel_collection_add(rdpSettings* settings, ADDIN_ARGV* channel);
FREERDP_API ADDIN_ARGV* freerdp_static_channel_collection_find(rdpSettings* settings, const char* name); FREERDP_API ADDIN_ARGV* freerdp_static_channel_collection_find(rdpSettings* settings, const char* name);
FREERDP_API ADDIN_ARGV* freerdp_static_channel_clone(ADDIN_ARGV* channel); FREERDP_API ADDIN_ARGV* freerdp_static_channel_clone(ADDIN_ARGV* channel);
FREERDP_API void freerdp_static_channel_collection_free(rdpSettings* settings); FREERDP_API void freerdp_static_channel_collection_free(rdpSettings* settings);
FREERDP_API void freerdp_dynamic_channel_collection_add(rdpSettings* settings, ADDIN_ARGV* channel); FREERDP_API BOOL freerdp_dynamic_channel_collection_add(rdpSettings* settings, ADDIN_ARGV* channel);
FREERDP_API ADDIN_ARGV* freerdp_dynamic_channel_collection_find(rdpSettings* settings, const char* name); FREERDP_API ADDIN_ARGV* freerdp_dynamic_channel_collection_find(rdpSettings* settings, const char* name);
FREERDP_API ADDIN_ARGV* freerdp_dynamic_channel_clone(ADDIN_ARGV* channel); FREERDP_API ADDIN_ARGV* freerdp_dynamic_channel_clone(ADDIN_ARGV* channel);
FREERDP_API void freerdp_dynamic_channel_collection_free(rdpSettings* settings); FREERDP_API void freerdp_dynamic_channel_collection_free(rdpSettings* settings);

View File

@ -75,7 +75,7 @@ extern "C" {
FREERDP_API rdpPcap* pcap_open(char* name, BOOL write); FREERDP_API rdpPcap* pcap_open(char* name, BOOL write);
FREERDP_API void pcap_close(rdpPcap* pcap); FREERDP_API void pcap_close(rdpPcap* pcap);
FREERDP_API void pcap_add_record(rdpPcap* pcap, void* data, UINT32 length); FREERDP_API BOOL pcap_add_record(rdpPcap* pcap, void* data, UINT32 length);
FREERDP_API BOOL pcap_has_next_record(rdpPcap* pcap); FREERDP_API BOOL pcap_has_next_record(rdpPcap* pcap);
FREERDP_API BOOL pcap_get_next_record(rdpPcap* pcap, pcap_record* record); FREERDP_API BOOL pcap_get_next_record(rdpPcap* pcap, pcap_record* record);
FREERDP_API BOOL pcap_get_next_record_header(rdpPcap* pcap, pcap_record* record); FREERDP_API BOOL pcap_get_next_record_header(rdpPcap* pcap, pcap_record* record);

View File

@ -189,25 +189,31 @@ rdpBrushCache* brush_cache_new(rdpSettings* settings)
{ {
rdpBrushCache* brushCache; rdpBrushCache* brushCache;
brushCache = (rdpBrushCache*) malloc(sizeof(rdpBrushCache)); brushCache = (rdpBrushCache*) calloc(1, sizeof(rdpBrushCache));
if (brushCache) if (!brushCache)
{ return NULL;
ZeroMemory(brushCache, sizeof(rdpBrushCache));
brushCache->settings = settings; brushCache->settings = settings;
brushCache->maxEntries = 64; brushCache->maxEntries = 64;
brushCache->maxMonoEntries = 64; brushCache->maxMonoEntries = 64;
brushCache->entries = (BRUSH_ENTRY*) malloc(sizeof(BRUSH_ENTRY) * brushCache->maxEntries); brushCache->entries = (BRUSH_ENTRY*)calloc(brushCache->maxEntries, sizeof(BRUSH_ENTRY));
ZeroMemory(brushCache->entries, sizeof(BRUSH_ENTRY) * brushCache->maxEntries); if (!brushCache->entries)
goto error_entries;
brushCache->monoEntries = (BRUSH_ENTRY*) malloc(sizeof(BRUSH_ENTRY) * brushCache->maxMonoEntries); brushCache->monoEntries = (BRUSH_ENTRY*) calloc(brushCache->maxMonoEntries, sizeof(BRUSH_ENTRY));
ZeroMemory(brushCache->monoEntries, sizeof(BRUSH_ENTRY) * brushCache->maxMonoEntries); if (!brushCache->monoEntries)
} goto error_mono;
return brushCache; return brushCache;
error_mono:
free(brushCache->entries);
error_entries:
free(brushCache);
return NULL;
} }
void brush_cache_free(rdpBrushCache* brushCache) void brush_cache_free(rdpBrushCache* brushCache)

View File

@ -31,22 +31,50 @@ rdpCache* cache_new(rdpSettings* settings)
{ {
rdpCache* cache; rdpCache* cache;
cache = (rdpCache*) malloc(sizeof(rdpCache)); cache = (rdpCache*) calloc(1, sizeof(rdpCache));
ZeroMemory(cache, sizeof(rdpCache)); if (!cache)
return NULL;
if (cache != NULL) cache->settings = settings;
{ cache->glyph = glyph_cache_new(settings);
cache->settings = settings; if (!cache->glyph)
cache->glyph = glyph_cache_new(settings); goto error_glyph;
cache->brush = brush_cache_new(settings); cache->brush = brush_cache_new(settings);
cache->pointer = pointer_cache_new(settings); if (!cache->brush)
cache->bitmap = bitmap_cache_new(settings); goto error_brush;
cache->offscreen = offscreen_cache_new(settings); cache->pointer = pointer_cache_new(settings);
cache->palette = palette_cache_new(settings); if (!cache->pointer)
cache->nine_grid = nine_grid_cache_new(settings); goto error_pointer;
} cache->bitmap = bitmap_cache_new(settings);
if (!cache->bitmap)
goto error_bitmap;
cache->offscreen = offscreen_cache_new(settings);
if (!cache->offscreen)
goto error_offscreen;
cache->palette = palette_cache_new(settings);
if (!cache->palette)
goto error_palette;
cache->nine_grid = nine_grid_cache_new(settings);
if (!cache->nine_grid)
goto error_ninegrid;
return cache; return cache;
error_ninegrid:
palette_cache_free(cache->palette);
error_palette:
offscreen_cache_free(cache->offscreen);
error_offscreen:
bitmap_cache_free(cache->bitmap);
error_bitmap:
pointer_cache_free(cache->pointer);
error_pointer:
brush_cache_free(cache->brush);
error_brush:
glyph_cache_free(cache->glyph);
error_glyph:
free(cache);
return NULL;
} }
void cache_free(rdpCache* cache) void cache_free(rdpCache* cache)

View File

@ -57,7 +57,7 @@ void update_process_glyph(rdpContext* context, BYTE* data, int* index,
if (offset & 0x80) if (offset & 0x80)
{ {
offset = data[*index + 1] | (data[*index + 2] << 8); offset = data[*index + 1] | ((int)((char)data[*index + 2]) << 8);
(*index)++; (*index)++;
(*index)++; (*index)++;
} }
@ -77,7 +77,7 @@ void update_process_glyph(rdpContext* context, BYTE* data, int* index,
} }
} }
void update_process_glyph_fragments(rdpContext* context, BYTE* data, UINT32 length, BOOL update_process_glyph_fragments(rdpContext* context, BYTE* data, UINT32 length,
UINT32 cacheId, UINT32 ulCharInc, UINT32 flAccel, UINT32 bgcolor, UINT32 fgcolor, int x, int y, UINT32 cacheId, UINT32 ulCharInc, UINT32 flAccel, UINT32 bgcolor, UINT32 fgcolor, int x, int y,
int bkX, int bkY, int bkWidth, int bkHeight, int opX, int opY, int opWidth, int opHeight, BOOL fOpRedundant) int bkX, int bkY, int bkWidth, int bkHeight, int opX, int opY, int opWidth, int opHeight, BOOL fOpRedundant)
{ {
@ -108,17 +108,20 @@ void update_process_glyph_fragments(rdpContext* context, BYTE* data, UINT32 leng
if (opWidth > 0 && opHeight > 0) if (opWidth > 0 && opHeight > 0)
{ {
Glyph_BeginDraw(context, opX, opY, opWidth, opHeight, bgcolor, fgcolor, fOpRedundant); if (!Glyph_BeginDraw(context, opX, opY, opWidth, opHeight, bgcolor, fgcolor, fOpRedundant))
return FALSE;
} }
else else
{ {
if (fOpRedundant) if (fOpRedundant)
{ {
Glyph_BeginDraw(context, bkX, bkY, bkWidth, bkHeight, bgcolor, fgcolor, fOpRedundant); if (!Glyph_BeginDraw(context, bkX, bkY, bkWidth, bkHeight, bgcolor, fgcolor, fOpRedundant))
return FALSE;
} }
else else
{ {
Glyph_BeginDraw(context, 0, 0, 0, 0, bgcolor, fgcolor, fOpRedundant); if (!Glyph_BeginDraw(context, 0, 0, 0, 0, bgcolor, fgcolor, fOpRedundant))
return FALSE;
} }
} }
@ -175,6 +178,8 @@ void update_process_glyph_fragments(rdpContext* context, BYTE* data, UINT32 leng
size = data[index + 2]; size = data[index + 2];
fragments = (BYTE*) malloc(size); fragments = (BYTE*) malloc(size);
if (!fragments)
return FALSE;
CopyMemory(fragments, data, size); CopyMemory(fragments, data, size);
glyph_cache_fragment_put(glyph_cache, id, size, fragments); glyph_cache_fragment_put(glyph_cache, id, size, fragments);
@ -194,9 +199,9 @@ void update_process_glyph_fragments(rdpContext* context, BYTE* data, UINT32 leng
} }
if (opWidth > 0 && opHeight > 0) if (opWidth > 0 && opHeight > 0)
Glyph_EndDraw(context, opX, opY, opWidth, opHeight, bgcolor, fgcolor); return Glyph_EndDraw(context, opX, opY, opWidth, opHeight, bgcolor, fgcolor);
else
Glyph_EndDraw(context, bkX, bkY, bkWidth, bkHeight, bgcolor, fgcolor); return Glyph_EndDraw(context, bkX, bkY, bkWidth, bkHeight, bgcolor, fgcolor);
} }
BOOL update_gdi_glyph_index(rdpContext* context, GLYPH_INDEX_ORDER* glyphIndex) BOOL update_gdi_glyph_index(rdpContext* context, GLYPH_INDEX_ORDER* glyphIndex)
@ -211,14 +216,12 @@ BOOL update_gdi_glyph_index(rdpContext* context, GLYPH_INDEX_ORDER* glyphIndex)
bkHeight = glyphIndex->bkBottom - glyphIndex->bkTop; bkHeight = glyphIndex->bkBottom - glyphIndex->bkTop;
opHeight = glyphIndex->opBottom - glyphIndex->opTop; opHeight = glyphIndex->opBottom - glyphIndex->opTop;
update_process_glyph_fragments(context, glyphIndex->data, glyphIndex->cbData, return update_process_glyph_fragments(context, glyphIndex->data, glyphIndex->cbData,
glyphIndex->cacheId, glyphIndex->ulCharInc, glyphIndex->flAccel, glyphIndex->cacheId, glyphIndex->ulCharInc, glyphIndex->flAccel,
glyphIndex->backColor, glyphIndex->foreColor, glyphIndex->x, glyphIndex->y, glyphIndex->backColor, glyphIndex->foreColor, glyphIndex->x, glyphIndex->y,
glyphIndex->bkLeft, glyphIndex->bkTop, bkWidth, bkHeight, glyphIndex->bkLeft, glyphIndex->bkTop, bkWidth, bkHeight,
glyphIndex->opLeft, glyphIndex->opTop, opWidth, opHeight, glyphIndex->opLeft, glyphIndex->opTop, opWidth, opHeight,
glyphIndex->fOpRedundant); glyphIndex->fOpRedundant);
return TRUE;
} }
BOOL update_gdi_fast_index(rdpContext* context, FAST_INDEX_ORDER* fastIndex) BOOL update_gdi_fast_index(rdpContext* context, FAST_INDEX_ORDER* fastIndex)
@ -263,7 +266,7 @@ BOOL update_gdi_fast_index(rdpContext* context, FAST_INDEX_ORDER* fastIndex)
if (y == -32768) if (y == -32768)
y = fastIndex->bkTop; y = fastIndex->bkTop;
update_process_glyph_fragments(context, fastIndex->data, fastIndex->cbData, return update_process_glyph_fragments(context, fastIndex->data, fastIndex->cbData,
fastIndex->cacheId, fastIndex->ulCharInc, fastIndex->flAccel, fastIndex->cacheId, fastIndex->ulCharInc, fastIndex->flAccel,
fastIndex->backColor, fastIndex->foreColor, x, y, fastIndex->backColor, fastIndex->foreColor, x, y,
fastIndex->bkLeft, fastIndex->bkTop, fastIndex->bkLeft, fastIndex->bkTop,
@ -271,7 +274,6 @@ BOOL update_gdi_fast_index(rdpContext* context, FAST_INDEX_ORDER* fastIndex)
opLeft, opTop, opLeft, opTop,
opRight - opLeft, opBottom - opTop, opRight - opLeft, opBottom - opTop,
FALSE); FALSE);
return TRUE;
} }
BOOL update_gdi_fast_glyph(rdpContext* context, FAST_GLYPH_ORDER* fastGlyph) BOOL update_gdi_fast_glyph(rdpContext* context, FAST_GLYPH_ORDER* fastGlyph)
@ -323,14 +325,20 @@ BOOL update_gdi_fast_glyph(rdpContext* context, FAST_GLYPH_ORDER* fastGlyph)
glyphData = &fastGlyph->glyphData; glyphData = &fastGlyph->glyphData;
glyph = Glyph_Alloc(context); glyph = Glyph_Alloc(context);
if (!glyph)
return FALSE;
glyph->x = glyphData->x; glyph->x = glyphData->x;
glyph->y = glyphData->y; glyph->y = glyphData->y;
glyph->cx = glyphData->cx; glyph->cx = glyphData->cx;
glyph->cy = glyphData->cy; glyph->cy = glyphData->cy;
glyph->cb = glyphData->cb; glyph->cb = glyphData->cb;
glyph->aj = malloc(glyphData->cb); glyph->aj = malloc(glyphData->cb);
if (!glyph->aj)
goto error_aj;
CopyMemory(glyph->aj, glyphData->aj, glyph->cb); CopyMemory(glyph->aj, glyphData->aj, glyph->cb);
Glyph_New(context, glyph);
if (!Glyph_New(context, glyph))
goto error_glyph_new;
glyph_cache_put(cache->glyph, fastGlyph->cacheId, fastGlyph->data[0], glyph); glyph_cache_put(cache->glyph, fastGlyph->cacheId, fastGlyph->data[0], glyph);
} }
@ -338,7 +346,7 @@ BOOL update_gdi_fast_glyph(rdpContext* context, FAST_GLYPH_ORDER* fastGlyph)
text_data[0] = fastGlyph->data[0]; text_data[0] = fastGlyph->data[0];
text_data[1] = 0; text_data[1] = 0;
update_process_glyph_fragments(context, text_data, 1, return update_process_glyph_fragments(context, text_data, 1,
fastGlyph->cacheId, fastGlyph->ulCharInc, fastGlyph->flAccel, fastGlyph->cacheId, fastGlyph->ulCharInc, fastGlyph->flAccel,
fastGlyph->backColor, fastGlyph->foreColor, x, y, fastGlyph->backColor, fastGlyph->foreColor, x, y,
fastGlyph->bkLeft, fastGlyph->bkTop, fastGlyph->bkLeft, fastGlyph->bkTop,
@ -346,7 +354,13 @@ BOOL update_gdi_fast_glyph(rdpContext* context, FAST_GLYPH_ORDER* fastGlyph)
opLeft, opTop, opLeft, opTop,
opRight - opLeft, opBottom - opTop, opRight - opLeft, opBottom - opTop,
FALSE); FALSE);
return TRUE;
error_glyph_new:
free(glyph->aj);
glyph->aj = NULL;
error_aj:
Glyph_Free(context, glyph);
return FALSE;
} }
BOOL update_gdi_cache_glyph(rdpContext* context, CACHE_GLYPH_ORDER* cacheGlyph) BOOL update_gdi_cache_glyph(rdpContext* context, CACHE_GLYPH_ORDER* cacheGlyph)
@ -362,10 +376,7 @@ BOOL update_gdi_cache_glyph(rdpContext* context, CACHE_GLYPH_ORDER* cacheGlyph)
glyph = Glyph_Alloc(context); glyph = Glyph_Alloc(context);
if (!glyph) if (!glyph)
{
/* TODO: cleanup previously allocated memory */
return FALSE; return FALSE;
}
glyph->x = glyph_data->x; glyph->x = glyph_data->x;
glyph->y = glyph_data->y; glyph->y = glyph_data->y;
@ -373,7 +384,11 @@ BOOL update_gdi_cache_glyph(rdpContext* context, CACHE_GLYPH_ORDER* cacheGlyph)
glyph->cy = glyph_data->cy; glyph->cy = glyph_data->cy;
glyph->cb = glyph_data->cb; glyph->cb = glyph_data->cb;
glyph->aj = glyph_data->aj; glyph->aj = glyph_data->aj;
Glyph_New(context, glyph); if (!Glyph_New(context, glyph))
{
Glyph_Free(context, glyph);
return FALSE;
}
glyph_cache_put(cache->glyph, cacheGlyph->cacheId, glyph_data->cacheIndex, glyph); glyph_cache_put(cache->glyph, cacheGlyph->cacheId, glyph_data->cacheIndex, glyph);
} }

View File

@ -95,21 +95,23 @@ rdpNineGridCache* nine_grid_cache_new(rdpSettings* settings)
{ {
rdpNineGridCache* nine_grid; rdpNineGridCache* nine_grid;
nine_grid = (rdpNineGridCache*) malloc(sizeof(rdpNineGridCache)); nine_grid = (rdpNineGridCache*) calloc(1, sizeof(rdpNineGridCache));
ZeroMemory(nine_grid, sizeof(rdpNineGridCache)); if (!nine_grid)
return NULL;
if (nine_grid != NULL) nine_grid->settings = settings;
nine_grid->maxSize = 2560;
nine_grid->maxEntries = 256;
nine_grid->settings->DrawNineGridCacheSize = nine_grid->maxSize;
nine_grid->settings->DrawNineGridCacheEntries = nine_grid->maxEntries;
nine_grid->entries = (NINE_GRID_ENTRY*) calloc(nine_grid->maxEntries, sizeof(NINE_GRID_ENTRY));
if (!nine_grid->entries)
{ {
nine_grid->settings = settings; free(nine_grid);
return NULL;
nine_grid->maxSize = 2560;
nine_grid->maxEntries = 256;
nine_grid->settings->DrawNineGridCacheSize = nine_grid->maxSize;
nine_grid->settings->DrawNineGridCacheEntries = nine_grid->maxEntries;
nine_grid->entries = (NINE_GRID_ENTRY*) malloc(sizeof(NINE_GRID_ENTRY) * nine_grid->maxEntries);
ZeroMemory(nine_grid->entries, sizeof(NINE_GRID_ENTRY) * nine_grid->maxEntries);
} }
return nine_grid; return nine_grid;

View File

@ -146,26 +146,27 @@ rdpOffscreenCache* offscreen_cache_new(rdpSettings* settings)
{ {
rdpOffscreenCache* offscreenCache; rdpOffscreenCache* offscreenCache;
offscreenCache = (rdpOffscreenCache*) malloc(sizeof(rdpOffscreenCache)); offscreenCache = (rdpOffscreenCache*) calloc(1, sizeof(rdpOffscreenCache));
if (offscreenCache) if (!offscreenCache)
return NULL;
offscreenCache->settings = settings;
offscreenCache->update = ((freerdp*) settings->instance)->update;
offscreenCache->currentSurface = SCREEN_BITMAP_SURFACE;
offscreenCache->maxSize = 7680;
offscreenCache->maxEntries = 2000;
settings->OffscreenCacheSize = offscreenCache->maxSize;
settings->OffscreenCacheEntries = offscreenCache->maxEntries;
offscreenCache->entries = (rdpBitmap**) calloc(offscreenCache->maxEntries, sizeof(rdpBitmap*));
if (!offscreenCache->entries)
{ {
ZeroMemory(offscreenCache, sizeof(rdpOffscreenCache)); free(offscreenCache);
return NULL;
offscreenCache->settings = settings;
offscreenCache->update = ((freerdp*) settings->instance)->update;
offscreenCache->currentSurface = SCREEN_BITMAP_SURFACE;
offscreenCache->maxSize = 7680;
offscreenCache->maxEntries = 2000;
settings->OffscreenCacheSize = offscreenCache->maxSize;
settings->OffscreenCacheEntries = offscreenCache->maxEntries;
offscreenCache->entries = (rdpBitmap**) malloc(sizeof(rdpBitmap*) * offscreenCache->maxEntries);
ZeroMemory(offscreenCache->entries, sizeof(rdpBitmap*) * offscreenCache->maxEntries);
} }
return offscreenCache; return offscreenCache;
} }

View File

@ -109,39 +109,37 @@ BOOL update_pointer_new(rdpContext* context, POINTER_NEW_UPDATE* pointer_new)
rdpCache* cache = context->cache; rdpCache* cache = context->cache;
pointer = Pointer_Alloc(context); pointer = Pointer_Alloc(context);
if (!pointer)
return FALSE;
if (pointer != NULL) pointer->xorBpp = pointer_new->xorBpp;
pointer->xPos = pointer_new->colorPtrAttr.xPos;
pointer->yPos = pointer_new->colorPtrAttr.yPos;
pointer->width = pointer_new->colorPtrAttr.width;
pointer->height = pointer_new->colorPtrAttr.height;
pointer->lengthAndMask = pointer_new->colorPtrAttr.lengthAndMask;
pointer->lengthXorMask = pointer_new->colorPtrAttr.lengthXorMask;
if (pointer->lengthAndMask)
{ {
pointer->xorBpp = pointer_new->xorBpp; pointer->andMaskData = (BYTE*) malloc(pointer->lengthAndMask);
pointer->xPos = pointer_new->colorPtrAttr.xPos; if (!pointer->andMaskData)
pointer->yPos = pointer_new->colorPtrAttr.yPos; goto out_fail;
pointer->width = pointer_new->colorPtrAttr.width; CopyMemory(pointer->andMaskData, pointer_new->colorPtrAttr.andMaskData, pointer->lengthAndMask);
pointer->height = pointer_new->colorPtrAttr.height;
pointer->lengthAndMask = pointer_new->colorPtrAttr.lengthAndMask;
pointer->lengthXorMask = pointer_new->colorPtrAttr.lengthXorMask;
pointer->andMaskData = pointer->xorMaskData = NULL;
if (pointer->lengthAndMask)
{
pointer->andMaskData = (BYTE*) malloc(pointer->lengthAndMask);
if (!pointer->andMaskData)
goto out_fail;
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);
Pointer_Set(context, pointer);
return TRUE;
} }
return FALSE;
if (pointer->lengthXorMask)
{
pointer->xorMaskData = (BYTE*) malloc(pointer->lengthXorMask);
if (!pointer->xorMaskData)
goto out_fail;
CopyMemory(pointer->xorMaskData, pointer_new->colorPtrAttr.xorMaskData, pointer->lengthXorMask);
}
if (!pointer->New(context, pointer))
goto out_fail;
pointer_cache_put(cache->pointer, pointer_new->colorPtrAttr.cacheIndex, pointer);
return Pointer_Set(context, pointer);
out_fail: out_fail:
free(pointer->andMaskData); free(pointer->andMaskData);
@ -213,18 +211,19 @@ rdpPointerCache* pointer_cache_new(rdpSettings* settings)
{ {
rdpPointerCache* pointer_cache; rdpPointerCache* pointer_cache;
pointer_cache = (rdpPointerCache*) malloc(sizeof(rdpPointerCache)); pointer_cache = (rdpPointerCache*) calloc(1, sizeof(rdpPointerCache));
if (!pointer_cache)
return NULL;
if (pointer_cache != NULL) pointer_cache->settings = settings;
pointer_cache->cacheSize = settings->PointerCacheSize;
pointer_cache->update = ((freerdp*) settings->instance)->update;
pointer_cache->entries = (rdpPointer**) calloc(pointer_cache->cacheSize, sizeof(rdpPointer*));
if (!pointer_cache->entries)
{ {
ZeroMemory(pointer_cache, sizeof(rdpPointerCache)); free(pointer_cache);
return NULL;
pointer_cache->settings = settings;
pointer_cache->cacheSize = settings->PointerCacheSize;
pointer_cache->update = ((freerdp*) settings->instance)->update;
pointer_cache->entries = (rdpPointer**) malloc(sizeof(rdpPointer*) * pointer_cache->cacheSize);
ZeroMemory(pointer_cache->entries, sizeof(rdpPointer*) * pointer_cache->cacheSize);
} }
return pointer_cache; return pointer_cache;

View File

@ -377,12 +377,13 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize,
if (vBarShortEntry->count > vBarShortEntry->size) if (vBarShortEntry->count > vBarShortEntry->size)
{ {
UINT32 *tmp;
vBarShortEntry->size = vBarShortEntry->count; vBarShortEntry->size = vBarShortEntry->count;
if (!vBarShortEntry->pixels) tmp = (UINT32*) realloc(vBarShortEntry->pixels, vBarShortEntry->count * 4);
vBarShortEntry->pixels = (UINT32*) malloc(vBarShortEntry->count * 4); if (!tmp)
else return -1;
vBarShortEntry->pixels = (UINT32*) realloc(vBarShortEntry->pixels, vBarShortEntry->count * 4); vBarShortEntry->pixels = tmp;
} }
if (!vBarShortEntry->pixels && vBarShortEntry->size) if (!vBarShortEntry->pixels && vBarShortEntry->size)
@ -442,12 +443,13 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize,
if (vBarEntry->count > vBarEntry->size) if (vBarEntry->count > vBarEntry->size)
{ {
UINT32 *tmp;
vBarEntry->size = vBarEntry->count; vBarEntry->size = vBarEntry->count;
if (!vBarEntry->pixels) tmp = (UINT32*) realloc(vBarEntry->pixels, vBarEntry->count * 4);
vBarEntry->pixels = (UINT32*) malloc(vBarEntry->count * 4); if (!tmp)
else return -1;
vBarEntry->pixels = (UINT32*) realloc(vBarEntry->pixels, vBarEntry->count * 4); vBarEntry->pixels = tmp;
} }
if (!vBarEntry->pixels && vBarEntry->size) if (!vBarEntry->pixels && vBarEntry->size)
@ -791,12 +793,13 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize,
if (glyphEntry->count > glyphEntry->size) if (glyphEntry->count > glyphEntry->size)
{ {
UINT32 *tmp;
glyphEntry->size = glyphEntry->count; glyphEntry->size = glyphEntry->count;
if (!glyphEntry->pixels) tmp = (UINT32*) realloc(glyphEntry->pixels, glyphEntry->size * 4);
glyphEntry->pixels = (UINT32*) malloc(glyphEntry->size * 4); if (!tmp)
else return -1;
glyphEntry->pixels = (UINT32*) realloc(glyphEntry->pixels, glyphEntry->size * 4); glyphEntry->pixels = tmp;
} }
if (!glyphEntry->pixels) if (!glyphEntry->pixels)
@ -841,27 +844,31 @@ CLEAR_CONTEXT* clear_context_new(BOOL Compressor)
clear = (CLEAR_CONTEXT*) calloc(1, sizeof(CLEAR_CONTEXT)); clear = (CLEAR_CONTEXT*) calloc(1, sizeof(CLEAR_CONTEXT));
if (clear) if (!clear)
{ return NULL;
clear->Compressor = Compressor;
clear->nsc = nsc_context_new(); clear->Compressor = Compressor;
if (!clear->nsc) clear->nsc = nsc_context_new();
{ if (!clear->nsc)
free (clear); goto error_nsc;
return NULL;
}
nsc_context_set_pixel_format(clear->nsc, RDP_PIXEL_FORMAT_R8G8B8); nsc_context_set_pixel_format(clear->nsc, RDP_PIXEL_FORMAT_R8G8B8);
clear->TempSize = 512 * 512 * 4; clear->TempSize = 512 * 512 * 4;
clear->TempBuffer = (BYTE*) malloc(clear->TempSize); clear->TempBuffer = (BYTE*) malloc(clear->TempSize);
if (!clear->TempBuffer)
goto error_temp_buffer;
clear_context_reset(clear); clear_context_reset(clear);
}
return clear; return clear;
error_temp_buffer:
nsc_context_free(clear->nsc);
error_nsc:
free(clear);
return NULL;
} }
void clear_context_free(CLEAR_CONTEXT* clear) void clear_context_free(CLEAR_CONTEXT* clear)

View File

@ -679,7 +679,7 @@ int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize,
int h264_compress(H264_CONTEXT* h264, BYTE* pSrcData, DWORD SrcFormat, int h264_compress(H264_CONTEXT* h264, BYTE* pSrcData, DWORD SrcFormat,
int nSrcStep, int nSrcWidth, int nSrcHeight, BYTE** ppDstData, UINT32* pDstSize) int nSrcStep, int nSrcWidth, int nSrcHeight, BYTE** ppDstData, UINT32* pDstSize)
{ {
int status; int status = -1;
prim_size_t roi; prim_size_t roi;
int nWidth, nHeight; int nWidth, nHeight;
primitives_t *prims = primitives_get(); primitives_t *prims = primitives_get();
@ -691,12 +691,19 @@ int h264_compress(H264_CONTEXT* h264, BYTE* pSrcData, DWORD SrcFormat,
nWidth = (nSrcWidth + 1) & ~1; nWidth = (nSrcWidth + 1) & ~1;
nHeight = (nSrcHeight + 1) & ~1; nHeight = (nSrcHeight + 1) & ~1;
h264->pYUVData[0] = (BYTE*) malloc(nWidth * nHeight);
if (!(h264->pYUVData[0] = (BYTE*) malloc(nWidth * nHeight)))
return -1;
h264->iStride[0] = nWidth; h264->iStride[0] = nWidth;
h264->pYUVData[1] = (BYTE*) malloc(nWidth * nHeight / 4);
if (!(h264->pYUVData[1] = (BYTE*) malloc(nWidth * nHeight / 4)))
goto error_1;
h264->iStride[1] = nWidth / 2; h264->iStride[1] = nWidth / 2;
h264->pYUVData[2] = (BYTE*) malloc(nWidth * nHeight / 4);
if (!(h264->pYUVData[2] = (BYTE*) malloc(nWidth * nHeight / 4)))
goto error_2;
h264->iStride[2] = nWidth / 2; h264->iStride[2] = nWidth / 2;
h264->width = nWidth; h264->width = nWidth;
h264->height = nHeight; h264->height = nHeight;
roi.width = nSrcWidth; roi.width = nSrcWidth;
@ -706,12 +713,14 @@ int h264_compress(H264_CONTEXT* h264, BYTE* pSrcData, DWORD SrcFormat,
status = h264->subsystem->Compress(h264, ppDstData, pDstSize); status = h264->subsystem->Compress(h264, ppDstData, pDstSize);
free(h264->pYUVData[0]);
free(h264->pYUVData[1]);
free(h264->pYUVData[2]); free(h264->pYUVData[2]);
h264->pYUVData[0] = NULL;
h264->pYUVData[1] = NULL;
h264->pYUVData[2] = NULL; h264->pYUVData[2] = NULL;
error_2:
free(h264->pYUVData[1]);
h264->pYUVData[1] = NULL;
error_1:
free(h264->pYUVData[0]);
h264->pYUVData[0] = NULL;
return status; return status;
} }

View File

@ -873,6 +873,8 @@ BYTE* freerdp_bitmap_planar_compress_plane_rle(BYTE* inPlane, int width, int hei
{ {
outBufferSize = width * height; outBufferSize = width * height;
outPlane = malloc(outBufferSize); outPlane = malloc(outBufferSize);
if (!outPlane)
return NULL;
} }
else else
{ {
@ -968,7 +970,10 @@ BYTE* freerdp_bitmap_planar_delta_encode_plane(BYTE* inPlane, int width, int hei
BYTE *outPtr, *srcPtr, *prevLinePtr; BYTE *outPtr, *srcPtr, *prevLinePtr;
if (!outPlane) if (!outPlane)
outPlane = (BYTE*) malloc(width * height); {
if (!(outPlane = (BYTE*) malloc(width * height)))
return NULL;
}
// first line is copied as is // first line is copied as is
CopyMemory(outPlane, inPlane, width); CopyMemory(outPlane, inPlane, width);
@ -994,14 +999,18 @@ BYTE* freerdp_bitmap_planar_delta_encode_plane(BYTE* inPlane, int width, int hei
return outPlane; return outPlane;
} }
int freerdp_bitmap_planar_delta_encode_planes(BYTE* inPlanes[4], int width, int height, BYTE* outPlanes[4]) BOOL freerdp_bitmap_planar_delta_encode_planes(BYTE* inPlanes[4], int width, int height, BYTE* outPlanes[4])
{ {
outPlanes[0] = freerdp_bitmap_planar_delta_encode_plane(inPlanes[0], width, height, outPlanes[0]); int i;
outPlanes[1] = freerdp_bitmap_planar_delta_encode_plane(inPlanes[1], width, height, outPlanes[1]);
outPlanes[2] = freerdp_bitmap_planar_delta_encode_plane(inPlanes[2], width, height, outPlanes[2]);
outPlanes[3] = freerdp_bitmap_planar_delta_encode_plane(inPlanes[3], width, height, outPlanes[3]);
return 0; for (i = 0; i < 4; i++)
{
outPlanes[i] = freerdp_bitmap_planar_delta_encode_plane(inPlanes[i], width, height, outPlanes[i]);
if (!outPlanes[i])
return FALSE;
}
return TRUE;
} }
BYTE* freerdp_bitmap_compress_planar(BITMAP_PLANAR_CONTEXT* context, BYTE* data, UINT32 format, BYTE* freerdp_bitmap_compress_planar(BITMAP_PLANAR_CONTEXT* context, BYTE* data, UINT32 format,
@ -1025,7 +1034,8 @@ BYTE* freerdp_bitmap_compress_planar(BITMAP_PLANAR_CONTEXT* context, BYTE* data,
if (context->AllowRunLengthEncoding) if (context->AllowRunLengthEncoding)
{ {
freerdp_bitmap_planar_delta_encode_planes(context->planes, width, height, context->deltaPlanes); if (!freerdp_bitmap_planar_delta_encode_planes(context->planes, width, height, context->deltaPlanes))
return NULL;;
if (freerdp_bitmap_planar_compress_planes_rle(context->deltaPlanes, width, height, if (freerdp_bitmap_planar_compress_planes_rle(context->deltaPlanes, width, height,
context->rlePlanesBuffer, (int*) &dstSizes, context->AllowSkipAlpha) > 0) context->rlePlanesBuffer, (int*) &dstSizes, context->AllowSkipAlpha) > 0)
@ -1071,6 +1081,8 @@ BYTE* freerdp_bitmap_compress_planar(BITMAP_PLANAR_CONTEXT* context, BYTE* data,
size++; size++;
dstData = malloc(size); dstData = malloc(size);
if (!dstData)
return NULL;
*pDstSize = size; *pDstSize = size;
} }
@ -1157,13 +1169,10 @@ BITMAP_PLANAR_CONTEXT* freerdp_bitmap_planar_context_new(DWORD flags, int maxWid
{ {
BITMAP_PLANAR_CONTEXT* context; BITMAP_PLANAR_CONTEXT* context;
context = (BITMAP_PLANAR_CONTEXT*) malloc(sizeof(BITMAP_PLANAR_CONTEXT)); context = (BITMAP_PLANAR_CONTEXT*) calloc(1, sizeof(BITMAP_PLANAR_CONTEXT));
if (!context) if (!context)
return NULL; return NULL;
ZeroMemory(context, sizeof(BITMAP_PLANAR_CONTEXT));
if (flags & PLANAR_FORMAT_HEADER_NA) if (flags & PLANAR_FORMAT_HEADER_NA)
context->AllowSkipAlpha = TRUE; context->AllowSkipAlpha = TRUE;
@ -1183,20 +1192,34 @@ BITMAP_PLANAR_CONTEXT* freerdp_bitmap_planar_context_new(DWORD flags, int maxWid
context->maxPlaneSize = context->maxWidth * context->maxHeight; context->maxPlaneSize = context->maxWidth * context->maxHeight;
context->planesBuffer = malloc(context->maxPlaneSize * 4); context->planesBuffer = malloc(context->maxPlaneSize * 4);
if (!context->planesBuffer)
goto error_planesBuffer;
context->planes[0] = &context->planesBuffer[context->maxPlaneSize * 0]; context->planes[0] = &context->planesBuffer[context->maxPlaneSize * 0];
context->planes[1] = &context->planesBuffer[context->maxPlaneSize * 1]; context->planes[1] = &context->planesBuffer[context->maxPlaneSize * 1];
context->planes[2] = &context->planesBuffer[context->maxPlaneSize * 2]; context->planes[2] = &context->planesBuffer[context->maxPlaneSize * 2];
context->planes[3] = &context->planesBuffer[context->maxPlaneSize * 3]; context->planes[3] = &context->planesBuffer[context->maxPlaneSize * 3];
context->deltaPlanesBuffer = malloc(context->maxPlaneSize * 4); context->deltaPlanesBuffer = malloc(context->maxPlaneSize * 4);
if (!context->deltaPlanesBuffer)
goto error_deltaPlanesBuffer;
context->deltaPlanes[0] = &context->deltaPlanesBuffer[context->maxPlaneSize * 0]; context->deltaPlanes[0] = &context->deltaPlanesBuffer[context->maxPlaneSize * 0];
context->deltaPlanes[1] = &context->deltaPlanesBuffer[context->maxPlaneSize * 1]; context->deltaPlanes[1] = &context->deltaPlanesBuffer[context->maxPlaneSize * 1];
context->deltaPlanes[2] = &context->deltaPlanesBuffer[context->maxPlaneSize * 2]; context->deltaPlanes[2] = &context->deltaPlanesBuffer[context->maxPlaneSize * 2];
context->deltaPlanes[3] = &context->deltaPlanesBuffer[context->maxPlaneSize * 3]; context->deltaPlanes[3] = &context->deltaPlanesBuffer[context->maxPlaneSize * 3];
context->rlePlanesBuffer = malloc(context->maxPlaneSize * 4); context->rlePlanesBuffer = malloc(context->maxPlaneSize * 4);
if (!context->rlePlanesBuffer)
goto error_rlePlanesBuffer;
return context; return context;
error_rlePlanesBuffer:
free(context->deltaPlanesBuffer);
error_deltaPlanesBuffer:
free(context->planesBuffer);
error_planesBuffer:
free(context);
return NULL;
} }
void freerdp_bitmap_planar_context_free(BITMAP_PLANAR_CONTEXT* context) void freerdp_bitmap_planar_context_free(BITMAP_PLANAR_CONTEXT* context)

View File

@ -224,6 +224,12 @@ BOOL progressive_rfx_quant_cmp_equal(RFX_COMPONENT_CODEC_QUANT* q1, RFX_COMPONEN
return TRUE; return TRUE;
} }
void progressive_rfx_quant_print(RFX_COMPONENT_CODEC_QUANT* q, const char* name)
{
fprintf(stderr, "%s: HL1: %d LH1: %d HH1: %d HL2: %d LH2: %d HH2: %d HL3: %d LH3: %d HH3: %d LL3: %d\n",
name, q->HL1, q->LH1, q->HH1, q->HL2, q->LH2, q->HH2, q->HL3, q->LH3, q->HH3, q->LL3);
}
int progressive_set_surface_data(PROGRESSIVE_CONTEXT* progressive, UINT16 surfaceId, void* pData) int progressive_set_surface_data(PROGRESSIVE_CONTEXT* progressive, UINT16 surfaceId, void* pData)
{ {
ULONG_PTR key; ULONG_PTR key;
@ -270,7 +276,7 @@ PROGRESSIVE_SURFACE_CONTEXT* progressive_surface_context_new(UINT16 surfaceId, U
if (!surface->tiles) if (!surface->tiles)
{ {
free (surface); free(surface);
return NULL; return NULL;
} }
@ -727,10 +733,9 @@ int progressive_decompress_tile_first(PROGRESSIVE_CONTEXT* progressive, RFX_PROG
diff = tile->flags & RFX_TILE_DIFFERENCE; diff = tile->flags & RFX_TILE_DIFFERENCE;
#if 0 WLog_DBG(TAG, "ProgressiveTile%s: quantIdx Y: %d Cb: %d Cr: %d xIdx: %d yIdx: %d flags: 0x%02X quality: %d yLen: %d cbLen: %d crLen: %d tailLen: %d",
WLog_INFO(TAG, "ProgressiveTileFirst: quantIdx Y: %d Cb: %d Cr: %d xIdx: %d yIdx: %d flags: 0x%02X quality: %d yLen: %d cbLen: %d crLen: %d tailLen: %d", (tile->blockType == PROGRESSIVE_WBT_TILE_FIRST) ? "First" : "Simple",
tile->quantIdxY, tile->quantIdxCb, tile->quantIdxCr, tile->xIdx, tile->yIdx, tile->flags, tile->quality, tile->yLen, tile->cbLen, tile->crLen, tile->tailLen); tile->quantIdxY, tile->quantIdxCb, tile->quantIdxCr, tile->xIdx, tile->yIdx, tile->flags, tile->quality, tile->yLen, tile->cbLen, tile->crLen, tile->tailLen);
#endif
region = &(progressive->region); region = &(progressive->region);
@ -825,8 +830,6 @@ int progressive_decompress_tile_first(PROGRESSIVE_CONTEXT* progressive, RFX_PROG
BufferPool_Return(progressive->bufferPool, pBuffer); BufferPool_Return(progressive->bufferPool, pBuffer);
//WLog_Image(progressive->log, WLOG_TRACE, tile->data, 64, 64, 32);
return 1; return 1;
} }
@ -1134,10 +1137,8 @@ int progressive_decompress_tile_upgrade(PROGRESSIVE_CONTEXT* progressive, RFX_PR
tile->pass++; tile->pass++;
#if 0 WLog_DBG(TAG, "ProgressiveTileUpgrade: pass: %d quantIdx Y: %d Cb: %d Cr: %d xIdx: %d yIdx: %d quality: %d ySrlLen: %d yRawLen: %d cbSrlLen: %d cbRawLen: %d crSrlLen: %d crRawLen: %d",
WLog_INFO(TAG, "ProgressiveTileUpgrade: pass: %d quantIdx Y: %d Cb: %d Cr: %d xIdx: %d yIdx: %d quality: %d ySrlLen: %d yRawLen: %d cbSrlLen: %d cbRawLen: %d crSrlLen: %d crRawLen: %d",
tile->pass, tile->quantIdxY, tile->quantIdxCb, tile->quantIdxCr, tile->xIdx, tile->yIdx, tile->quality, tile->ySrlLen, tile->yRawLen, tile->cbSrlLen, tile->cbRawLen, tile->crSrlLen, tile->crRawLen); tile->pass, tile->quantIdxY, tile->quantIdxCb, tile->quantIdxCr, tile->xIdx, tile->yIdx, tile->quality, tile->ySrlLen, tile->yRawLen, tile->cbSrlLen, tile->cbRawLen, tile->crSrlLen, tile->crRawLen);
#endif
region = &(progressive->region); region = &(progressive->region);
@ -1246,8 +1247,6 @@ int progressive_decompress_tile_upgrade(PROGRESSIVE_CONTEXT* progressive, RFX_PR
BufferPool_Return(progressive->bufferPool, pBuffer); BufferPool_Return(progressive->bufferPool, pBuffer);
//WLog_Image(progressive->log, WLOG_TRACE, tile->data, 64, 64, 32);
return 1; return 1;
} }
@ -1281,7 +1280,7 @@ int progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive, BYTE* blocks, UI
blockLen = *((UINT32*) &block[boffset + 2]); /* blockLen (4 bytes) */ blockLen = *((UINT32*) &block[boffset + 2]); /* blockLen (4 bytes) */
boffset += 6; boffset += 6;
//WLog_INFO(TAG, "%s", progressive_get_block_type_string(blockType)); //WLog_DBG(TAG, "%s", progressive_get_block_type_string(blockType));
if ((blocksLen - offset) < blockLen) if ((blocksLen - offset) < blockLen)
return -1003; return -1003;
@ -1507,6 +1506,11 @@ int progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive, BYTE* blocks, UI
if (offset != blocksLen) if (offset != blocksLen)
return -1041; return -1041;
if (count != region->numTiles)
{
WLog_WARN(TAG, "numTiles inconsistency: actual: %d, expected: %d\n", count, region->numTiles);
}
for (index = 0; index < region->numTiles; index++) for (index = 0; index < region->numTiles; index++)
{ {
tile = tiles[index]; tile = tiles[index];
@ -1537,6 +1541,14 @@ int progressive_decompress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UIN
BYTE* block; BYTE* block;
BYTE* blocks; BYTE* blocks;
UINT16 index; UINT16 index;
UINT16 boxLeft;
UINT16 boxTop;
UINT16 boxRight;
UINT16 boxBottom;
UINT16 idxLeft;
UINT16 idxTop;
UINT16 idxRight;
UINT16 idxBottom;
UINT32 boffset; UINT32 boffset;
UINT16 blockType; UINT16 blockType;
UINT32 blockLen; UINT32 blockLen;
@ -1573,7 +1585,6 @@ int progressive_decompress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UIN
blockType = *((UINT16*) &block[boffset + 0]); /* blockType (2 bytes) */ blockType = *((UINT16*) &block[boffset + 0]); /* blockType (2 bytes) */
blockLen = *((UINT32*) &block[boffset + 2]); /* blockLen (4 bytes) */ blockLen = *((UINT32*) &block[boffset + 2]); /* blockLen (4 bytes) */
boffset += 6; boffset += 6;
//WLog_INFO(TAG, "%s", progressive_get_block_type_string(blockType));
if ((blocksLen - offset) < blockLen) if ((blocksLen - offset) < blockLen)
return -1003; return -1003;
@ -1582,6 +1593,8 @@ int progressive_decompress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UIN
{ {
case PROGRESSIVE_WBT_SYNC: case PROGRESSIVE_WBT_SYNC:
WLog_DBG(TAG, "ProgressiveSync");
sync.blockType = blockType; sync.blockType = blockType;
sync.blockLen = blockLen; sync.blockLen = blockLen;
@ -1612,6 +1625,9 @@ int progressive_decompress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UIN
frameBegin.regionCount = (UINT32) *((UINT16*) &block[boffset + 4]); /* regionCount (2 bytes) */ frameBegin.regionCount = (UINT32) *((UINT16*) &block[boffset + 4]); /* regionCount (2 bytes) */
boffset += 6; boffset += 6;
WLog_DBG(TAG, "ProgressiveFrameBegin: frameIndex: %d regionCount: %d",
frameBegin.frameIndex, frameBegin.regionCount);
/** /**
* If the number of elements specified by the regionCount field is * If the number of elements specified by the regionCount field is
* larger than the actual number of elements in the regions field, * larger than the actual number of elements in the regions field,
@ -1622,6 +1638,8 @@ int progressive_decompress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UIN
case PROGRESSIVE_WBT_FRAME_END: case PROGRESSIVE_WBT_FRAME_END:
WLog_DBG(TAG, "ProgressiveFrameEnd");
frameEnd.blockType = blockType; frameEnd.blockType = blockType;
frameEnd.blockLen = blockLen; frameEnd.blockLen = blockLen;
@ -1646,6 +1664,13 @@ int progressive_decompress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UIN
if (context.tileSize != 64) if (context.tileSize != 64)
return -1010; return -1010;
WLog_DBG(TAG, "ProgressiveContext: flags: 0x%02X", context.flags);
if (!(context.flags & RFX_SUBBAND_DIFFING))
{
WLog_WARN(TAG, "RFX_SUBBAND_DIFFING is not set");
}
break; break;
case PROGRESSIVE_WBT_REGION: case PROGRESSIVE_WBT_REGION:
@ -1755,11 +1780,11 @@ int progressive_decompress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UIN
if ((blockLen - boffset) < region->tileDataSize) if ((blockLen - boffset) < region->tileDataSize)
return -1021; return -1021;
if (region->numTiles > progressive->cTiles) if (progressive->cTiles < surface->gridSize)
{ {
progressive->tiles = (RFX_PROGRESSIVE_TILE**) realloc(progressive->tiles, progressive->tiles = (RFX_PROGRESSIVE_TILE**) realloc(progressive->tiles,
region->numTiles * sizeof(RFX_PROGRESSIVE_TILE*)); surface->gridSize * sizeof(RFX_PROGRESSIVE_TILE*));
progressive->cTiles = region->numTiles; progressive->cTiles = surface->gridSize;
} }
region->tiles = progressive->tiles; region->tiles = progressive->tiles;
@ -1767,14 +1792,67 @@ int progressive_decompress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UIN
if (!region->tiles) if (!region->tiles)
return -1; return -1;
//WLog_INFO(TAG, "numRects: %d numTiles: %d numQuant: %d numProgQuant: %d", WLog_DBG(TAG, "ProgressiveRegion: numRects: %d numTiles: %d tileDataSize: %d flags: 0x%02X numQuant: %d numProgQuant: %d",
// region->numRects, region->numTiles, region->numQuant, region->numProgQuant); region->numRects, region->numTiles, region->tileDataSize, region->flags, region->numQuant, region->numProgQuant);
if (!(region->flags & RFX_DWT_REDUCE_EXTRAPOLATE))
{
WLog_WARN(TAG, "RFX_DWT_REDUCE_EXTRAPOLATE is not set");
}
boxLeft = surface->gridWidth;
boxTop = surface->gridHeight;
boxRight = 0;
boxBottom = 0;
for (index = 0; index < region->numRects; index++)
{
rect = &(region->rects[index]);
idxLeft = rect->x / 64;
idxTop = rect->y / 64;
idxRight = (rect->x + rect->width + 63) / 64;
idxBottom = (rect->y + rect->height + 63) / 64;
if (idxLeft < boxLeft)
boxLeft = idxLeft;
if (idxTop < boxTop)
boxTop = idxTop;
if (idxRight > boxRight)
boxRight = idxRight;
if (idxBottom > boxBottom)
boxBottom = idxBottom;
WLog_DBG(TAG, "rect[%d]: x: %d y: %d w: %d h: %d",
index, rect->x, rect->y, rect->width, rect->height);
}
status = progressive_process_tiles(progressive, &block[boffset], region->tileDataSize, surface); status = progressive_process_tiles(progressive, &block[boffset], region->tileDataSize, surface);
if (status < 0) if (status < 0)
return status; return status;
region->numTiles = 0;
for (index = 0; index < surface->gridSize; index++)
{
RFX_PROGRESSIVE_TILE* tile = &(surface->tiles[index]);
if (!tile->data)
continue;
if ((tile->xIdx < boxLeft) || (tile->xIdx > boxRight))
continue;
if ((tile->yIdx < boxTop) || (tile->yIdx > boxBottom))
continue;
region->tiles[region->numTiles++] = tile;
}
boffset += (UINT32) status; boffset += (UINT32) status;
break; break;
@ -1817,8 +1895,6 @@ PROGRESSIVE_CONTEXT* progressive_context_new(BOOL Compressor)
{ {
progressive->Compressor = Compressor; progressive->Compressor = Compressor;
progressive->log = WLog_Get(TAG);
progressive->bufferPool = BufferPool_New(TRUE, (8192 + 32) * 3, 16); progressive->bufferPool = BufferPool_New(TRUE, (8192 + 32) * 3, 16);
progressive->cRects = 64; progressive->cRects = 64;

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