diff --git a/CMakeLists.txt b/CMakeLists.txt index b75d243e5..b050a3a1d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) 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 add_definitions("-DHAVE_CONFIG_H") @@ -722,10 +711,6 @@ add_subdirectory(include) add_subdirectory(libfreerdp) -if(WITH_CHANNELS) - add_subdirectory(channels) -endif() - if (IOS) set(CMAKE_OSX_DEPLOYMENT_TARGET "") if (IOS_PLATFORM MATCHES "SIMULATOR") @@ -741,6 +726,22 @@ include_directories("${CMAKE_BINARY_DIR}/rdtk/include") 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) add_subdirectory(client) endif() @@ -749,6 +750,7 @@ if(WITH_SERVER) add_subdirectory(server) endif() + # Exporting if(${CMAKE_VERSION} VERSION_GREATER "2.8.10") diff --git a/channels/audin/client/audin_main.c b/channels/audin/client/audin_main.c index e86233d46..53b18a905 100644 --- a/channels/audin/client/audin_main.c +++ b/channels/audin/client/audin_main.c @@ -97,7 +97,7 @@ static int audin_process_version(IWTSVirtualChannelCallback* pChannelCallback, w Stream_Read_UINT32(s, Version); - DEBUG_DVC("process_version: Version=%d", Version); + DEBUG_DVC("Version=%d", Version); out = Stream_New(NULL, 5); Stream_Write_UINT8(out, MSG_SNDIN_VERSION); @@ -130,7 +130,7 @@ static int audin_process_formats(IWTSVirtualChannelCallback* pChannelCallback, w UINT32 cbSizeFormatsPacket; Stream_Read_UINT32(s, NumFormats); - DEBUG_DVC("process_formats: NumFormats %d", NumFormats); + DEBUG_DVC("NumFormats %d", NumFormats); if ((NumFormats < 1) || (NumFormats > 1000)) { WLog_ERR(TAG, "bad NumFormats %d", NumFormats); @@ -158,7 +158,7 @@ static int audin_process_formats(IWTSVirtualChannelCallback* pChannelCallback, w format.data = Stream_Pointer(s); 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", format.wFormatTag, format.nChannels, format.nSamplesPerSec, format.nBlockAlign, format.wBitsPerSample, format.cbSize); @@ -171,7 +171,7 @@ static int audin_process_formats(IWTSVirtualChannelCallback* pChannelCallback, w continue; 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 */ callback->formats[callback->formats_count++] = format; @@ -264,7 +264,7 @@ static int audin_process_open(IWTSVirtualChannelCallback* pChannelCallback, wStr Stream_Read_UINT32(s, FramesPerPacket); Stream_Read_UINT32(s, initialFormat); - DEBUG_DVC("process_open: FramesPerPacket=%d initialFormat=%d", + DEBUG_DVC("FramesPerPacket=%d initialFormat=%d", FramesPerPacket, initialFormat); if (initialFormat >= (UINT32) callback->formats_count) @@ -296,7 +296,7 @@ static int audin_process_format_change(IWTSVirtualChannelCallback* pChannelCallb Stream_Read_UINT32(s, NewFormat); - DEBUG_DVC("process_format_change: NewFormat=%d", NewFormat); + DEBUG_DVC("NewFormat=%d", NewFormat); if (NewFormat >= (UINT32) callback->formats_count) { @@ -326,7 +326,7 @@ static int audin_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, Stream_Read_UINT8(data, MessageId); - DEBUG_DVC("on_data_received: MessageId=0x%x", MessageId); + DEBUG_DVC("MessageId=0x%x", MessageId); switch (MessageId) { @@ -360,7 +360,7 @@ static int audin_on_close(IWTSVirtualChannelCallback* pChannelCallback) AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback; AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) callback->plugin; - DEBUG_DVC("on_close"); + DEBUG_DVC("..."); if (audin->device) IFCALL(audin->device->Close, audin->device); @@ -378,7 +378,7 @@ static int audin_on_new_channel_connection(IWTSListenerCallback* pListenerCallba AUDIN_CHANNEL_CALLBACK* callback; AUDIN_LISTENER_CALLBACK* listener_callback = (AUDIN_LISTENER_CALLBACK*) pListenerCallback; - DEBUG_DVC("on_new_channel_connection"); + DEBUG_DVC("..."); callback = (AUDIN_CHANNEL_CALLBACK*) malloc(sizeof(AUDIN_CHANNEL_CALLBACK)); ZeroMemory(callback, sizeof(AUDIN_CHANNEL_CALLBACK)); @@ -398,7 +398,7 @@ static int audin_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManage { AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) pPlugin; - DEBUG_DVC("plugin_initialize"); + DEBUG_DVC("..."); audin->listener_callback = (AUDIN_LISTENER_CALLBACK*) malloc(sizeof(AUDIN_LISTENER_CALLBACK)); ZeroMemory(audin->listener_callback, sizeof(AUDIN_LISTENER_CALLBACK)); @@ -415,7 +415,7 @@ static int audin_plugin_terminated(IWTSPlugin* pPlugin) { AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) pPlugin; - DEBUG_DVC("plugin_terminated"); + DEBUG_DVC("..."); if (audin->device) { @@ -445,7 +445,7 @@ static void audin_register_device_plugin(IWTSPlugin* pPlugin, IAudinDevice* devi return; } - DEBUG_DVC("register_device_plugin: device registered."); + DEBUG_DVC("device registered."); audin->device = device; } diff --git a/channels/audin/client/oss/audin_oss.c b/channels/audin/client/oss/audin_oss.c index 6052fd55e..07c24ede3 100644 --- a/channels/audin/client/oss/audin_oss.c +++ b/channels/audin/client/oss/audin_oss.c @@ -37,9 +37,9 @@ #include #include #if defined(__OpenBSD__) - #include +#include #else - #include +#include #endif #include @@ -49,14 +49,15 @@ #include "audin_main.h" -typedef struct _AudinOSSDevice { +typedef struct _AudinOSSDevice +{ IAudinDevice iface; FREERDP_DSP_CONTEXT* dsp_context; HANDLE thread; HANDLE stopEvent; - + audinFormat format; UINT32 FramesPerPacket; int dev_unit; @@ -70,193 +71,259 @@ typedef struct _AudinOSSDevice { 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) { - case WAVE_FORMAT_PCM: - switch (format->wBitsPerSample) { - case 8: - return AFMT_S8; - case 16: - return AFMT_S16_LE; - } - break; - case WAVE_FORMAT_ALAW: - return AFMT_A_LAW; + switch (format->wBitsPerSample) + { + case 8: + return AFMT_S8; + case 16: + return AFMT_S16_LE; + } + + break; + case WAVE_FORMAT_ALAW: + return AFMT_A_LAW; #if 0 /* This does not work on my desktop. */ - case WAVE_FORMAT_MULAW: - return AFMT_MU_LAW; + case WAVE_FORMAT_MULAW: + return AFMT_MU_LAW; #endif - case WAVE_FORMAT_ADPCM: - case WAVE_FORMAT_DVI_ADPCM: - return AFMT_S16_LE; + case WAVE_FORMAT_ADPCM: + case WAVE_FORMAT_DVI_ADPCM: + return AFMT_S16_LE; } 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; if (device == NULL || format == NULL) return FALSE; - switch (format->wFormatTag) { - case WAVE_FORMAT_PCM: - if (format->cbSize != 0 || - format->nSamplesPerSec > 48000 || - (format->wBitsPerSample != 8 && format->wBitsPerSample != 16) || - (format->nChannels != 1 && format->nChannels != 2)) - return FALSE; - break; - case WAVE_FORMAT_ADPCM: - case WAVE_FORMAT_DVI_ADPCM: - if (format->nSamplesPerSec > 48000 || - format->wBitsPerSample != 4 || - (format->nChannels != 1 && format->nChannels != 2)) - return FALSE; - break; + switch (format->wFormatTag) + { + case WAVE_FORMAT_PCM: + + if (format->cbSize != 0 || + format->nSamplesPerSec > 48000 || + (format->wBitsPerSample != 8 && format->wBitsPerSample != 16) || + (format->nChannels != 1 && format->nChannels != 2)) + return FALSE; + + break; + case WAVE_FORMAT_ADPCM: + case WAVE_FORMAT_DVI_ADPCM: + + if (format->nSamplesPerSec > 48000 || + format->wBitsPerSample != 4 || + (format->nChannels != 1 && format->nChannels != 2)) + return FALSE; + + break; } - + req_fmt = audin_oss_get_format(format); + if (req_fmt == 0) return FALSE; return TRUE; } -static void audin_oss_set_format(IAudinDevice *device, audinFormat *format, UINT32 FramesPerPacket) { - AudinOSSDevice *oss = (AudinOSSDevice*)device; +static void audin_oss_set_format(IAudinDevice* device, audinFormat* format, UINT32 FramesPerPacket) +{ + AudinOSSDevice* oss = (AudinOSSDevice*)device; if (device == NULL || format == NULL) return; - + oss->FramesPerPacket = FramesPerPacket; CopyMemory(&(oss->format), format, sizeof(audinFormat)); - switch (format->wFormatTag) { - case WAVE_FORMAT_ADPCM: - case WAVE_FORMAT_DVI_ADPCM: - oss->FramesPerPacket *= 4; /* Compression ratio. */ - oss->format.wBitsPerSample *= 4; - break; + + switch (format->wFormatTag) + { + case WAVE_FORMAT_ADPCM: + case WAVE_FORMAT_DVI_ADPCM: + oss->FramesPerPacket *= 4; /* Compression ratio. */ + oss->format.wBitsPerSample *= 4; + break; } } -static void *audin_oss_thread_func(void *arg) +static void* audin_oss_thread_func(void* arg) { char dev_name[PATH_MAX] = "/dev/dsp"; - int pcm_handle = -1; - BYTE *buffer = NULL, *encoded_data; + char mixer_name[PATH_MAX] = "/dev/mixer"; + int pcm_handle = -1, mixer_handle; + BYTE* buffer = NULL, *encoded_data; int tmp, buffer_size, encoded_size; - AudinOSSDevice *oss = (AudinOSSDevice*)arg; + AudinOSSDevice* oss = (AudinOSSDevice*)arg; if (arg == NULL) goto err_out; if (oss->dev_unit != -1) + { snprintf(dev_name, (PATH_MAX - 1), "/dev/dsp%i", oss->dev_unit); + snprintf(mixer_name, PATH_MAX - 1, "/dev/mixer%i", oss->dev_unit); + } + 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); 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. */ 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); - } else if ((tmp & PCM_CAP_INPUT) == 0) { + } + else if ((tmp & PCM_CAP_INPUT) == 0) + { OSS_LOG_ERR("Device does not supports playback", EOPNOTSUPP); goto err_out; } + #endif /* Set format. */ tmp = audin_oss_get_format(&oss->format); + if (ioctl(pcm_handle, SNDCTL_DSP_SETFMT, &tmp) == -1) OSS_LOG_ERR("SNDCTL_DSP_SETFMT failed", errno); + tmp = oss->format.nChannels; + if (ioctl(pcm_handle, SNDCTL_DSP_CHANNELS, &tmp) == -1) OSS_LOG_ERR("SNDCTL_DSP_CHANNELS failed", errno); + tmp = oss->format.nSamplesPerSec; + if (ioctl(pcm_handle, SNDCTL_DSP_SPEED, &tmp) == -1) OSS_LOG_ERR("SNDCTL_DSP_SPEED failed", errno); + tmp = oss->format.nBlockAlign; + if (ioctl(pcm_handle, SNDCTL_DSP_SETFRAGMENT, &tmp) == -1) 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*)malloc((buffer_size + sizeof(void*))); - if (NULL == buffer) { + + if (NULL == buffer) + { OSS_LOG_ERR("malloc() fail", errno); goto err_out; } - ZeroMemory(buffer, buffer_size); + ZeroMemory(buffer, buffer_size); 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); - if (tmp < 0) { /* Error happen. */ + + /* Error happen. */ + if (tmp < 0) + { OSS_LOG_ERR("read() error", errno); continue; } + if (tmp < buffer_size) /* Not enouth data. */ continue; + /* Process. */ - switch (oss->format.wFormatTag) { - case WAVE_FORMAT_ADPCM: - oss->dsp_context->encode_ms_adpcm(oss->dsp_context, - buffer, buffer_size, oss->format.nChannels, oss->format.nBlockAlign); - encoded_data = oss->dsp_context->adpcm_buffer; - encoded_size = oss->dsp_context->adpcm_size; - break; - case WAVE_FORMAT_DVI_ADPCM: - oss->dsp_context->encode_ima_adpcm(oss->dsp_context, - buffer, buffer_size, oss->format.nChannels, oss->format.nBlockAlign); - encoded_data = oss->dsp_context->adpcm_buffer; - encoded_size = oss->dsp_context->adpcm_size; - break; - default: - encoded_data = buffer; - encoded_size = buffer_size; - break; + switch (oss->format.wFormatTag) + { + case WAVE_FORMAT_ADPCM: + oss->dsp_context->encode_ms_adpcm(oss->dsp_context, + buffer, buffer_size, oss->format.nChannels, oss->format.nBlockAlign); + encoded_data = oss->dsp_context->adpcm_buffer; + encoded_size = oss->dsp_context->adpcm_size; + break; + case WAVE_FORMAT_DVI_ADPCM: + oss->dsp_context->encode_ima_adpcm(oss->dsp_context, + buffer, buffer_size, oss->format.nChannels, oss->format.nBlockAlign); + encoded_data = oss->dsp_context->adpcm_buffer; + encoded_size = oss->dsp_context->adpcm_size; + break; + default: + encoded_data = buffer; + encoded_size = buffer_size; + break; } - if (0 != oss->receive(encoded_data, encoded_size, oss->user_data)) + + if (0 == oss->receive(encoded_data, encoded_size, oss->user_data)) break; } err_out: + if (pcm_handle != -1) + { + WLog_INFO(TAG, "close: %s", dev_name); close(pcm_handle); + } + free(buffer); - ExitThread(0); - return NULL; } -static void audin_oss_open(IAudinDevice *device, AudinReceive receive, void *user_data) { - AudinOSSDevice *oss = (AudinOSSDevice*)device; - +static void audin_oss_open(IAudinDevice* device, AudinReceive receive, void* user_data) +{ + AudinOSSDevice* oss = (AudinOSSDevice*)device; oss->receive = receive; oss->user_data = user_data; - oss->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); oss->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)audin_oss_thread_func, oss, 0, NULL); } -static void audin_oss_close(IAudinDevice *device) { - AudinOSSDevice *oss = (AudinOSSDevice*)device; +static void audin_oss_close(IAudinDevice* device) +{ + AudinOSSDevice* oss = (AudinOSSDevice*)device; if (device == NULL) return; - if (oss->stopEvent != NULL) { + if (oss->stopEvent != NULL) + { SetEvent(oss->stopEvent); WaitForSingleObject(oss->thread, INFINITE); - CloseHandle(oss->stopEvent); oss->stopEvent = NULL; - CloseHandle(oss->thread); oss->thread = NULL; } @@ -265,81 +332,79 @@ static void audin_oss_close(IAudinDevice *device) { oss->user_data = NULL; } -static void audin_oss_free(IAudinDevice *device) { - AudinOSSDevice *oss = (AudinOSSDevice*)device; +static void audin_oss_free(IAudinDevice* device) +{ + AudinOSSDevice* oss = (AudinOSSDevice*)device; if (device == NULL) return; audin_oss_close(device); freerdp_dsp_context_free(oss->dsp_context); - free(oss); } -COMMAND_LINE_ARGUMENT_A audin_oss_args[] = { +COMMAND_LINE_ARGUMENT_A audin_oss_args[] = +{ { "dev", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "audio device name" }, { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } }; -static void audin_oss_parse_addin_args(AudinOSSDevice *device, ADDIN_ARGV *args) { +static void audin_oss_parse_addin_args(AudinOSSDevice* device, ADDIN_ARGV* args) +{ int status; - char *str_num, *eptr; + char* str_num, *eptr; DWORD flags; - COMMAND_LINE_ARGUMENT_A *arg; - AudinOSSDevice *oss = (AudinOSSDevice*)device; - + COMMAND_LINE_ARGUMENT_A* arg; + AudinOSSDevice* oss = (AudinOSSDevice*)device; 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); + if (status < 0) return; arg = audin_oss_args; - do { + do + { if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT)) continue; CommandLineSwitchStart(arg) - - CommandLineSwitchCase(arg, "dev") { + CommandLineSwitchCase(arg, "dev") + { str_num = _strdup(arg->Value); oss->dev_unit = strtol(str_num, &eptr, 10); + if (oss->dev_unit < 0 || *eptr != '\0') oss->dev_unit = -1; + free(str_num); } - CommandLineSwitchEnd(arg) - } while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); + } + while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); } #ifdef STATIC_CHANNELS #define freerdp_audin_client_subsystem_entry oss_freerdp_audin_client_subsystem_entry #endif -int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints) { - ADDIN_ARGV *args; - AudinOSSDevice *oss; - +int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints) +{ + ADDIN_ARGV* args; + AudinOSSDevice* oss; oss = (AudinOSSDevice*)malloc(sizeof(AudinOSSDevice)); ZeroMemory(oss, sizeof(AudinOSSDevice)); - oss->iface.Open = audin_oss_open; oss->iface.FormatSupported = audin_oss_format_supported; oss->iface.SetFormat = audin_oss_set_format; oss->iface.Close = audin_oss_close; oss->iface.Free = audin_oss_free; - oss->dev_unit = -1; - args = pEntryPoints->args; audin_oss_parse_addin_args(oss, args); - oss->dsp_context = freerdp_dsp_context_new(); - pEntryPoints->pRegisterAudinDevice(pEntryPoints->plugin, (IAudinDevice*)oss); - return 0; } diff --git a/channels/rdpsnd/client/oss/rdpsnd_oss.c b/channels/rdpsnd/client/oss/rdpsnd_oss.c index 047d03813..82299b3be 100644 --- a/channels/rdpsnd/client/oss/rdpsnd_oss.c +++ b/channels/rdpsnd/client/oss/rdpsnd_oss.c @@ -37,9 +37,9 @@ #include #include #if defined(__OpenBSD__) - #include +#include #else - #include +#include #endif #include @@ -51,7 +51,8 @@ typedef struct rdpsnd_oss_plugin rdpsndOssPlugin; -struct rdpsnd_oss_plugin { +struct rdpsnd_oss_plugin +{ rdpsndDevicePlugin device; int pcm_handle; @@ -63,68 +64,85 @@ struct rdpsnd_oss_plugin { int latency; AUDIO_FORMAT format; - FREERDP_DSP_CONTEXT *dsp_context; + FREERDP_DSP_CONTEXT* dsp_context; }; #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) { - case WAVE_FORMAT_PCM: - switch (format->wBitsPerSample) { - case 8: - return AFMT_S8; - case 16: - return AFMT_S16_LE; - } - break; - case WAVE_FORMAT_ALAW: - return AFMT_A_LAW; + switch (format->wBitsPerSample) + { + case 8: + return AFMT_S8; + case 16: + return AFMT_S16_LE; + } + + break; + case WAVE_FORMAT_ALAW: + return AFMT_A_LAW; #if 0 /* This does not work on my desktop. */ - case WAVE_FORMAT_MULAW: - return AFMT_MU_LAW; + case WAVE_FORMAT_MULAW: + return AFMT_MU_LAW; #endif - case WAVE_FORMAT_ADPCM: - case WAVE_FORMAT_DVI_ADPCM: - return AFMT_S16_LE; + case WAVE_FORMAT_ADPCM: + case WAVE_FORMAT_DVI_ADPCM: + return AFMT_S16_LE; } 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; - rdpsndOssPlugin *oss = (rdpsndOssPlugin*)device; + rdpsndOssPlugin* oss = (rdpsndOssPlugin*)device; if (device == NULL || format == NULL) return FALSE; - switch (format->wFormatTag) { - case WAVE_FORMAT_PCM: - if (format->cbSize != 0 || - format->nSamplesPerSec > 48000 || - (format->wBitsPerSample != 8 && format->wBitsPerSample != 16) || - (format->nChannels != 1 && format->nChannels != 2)) - return FALSE; - break; - case WAVE_FORMAT_ADPCM: - case WAVE_FORMAT_DVI_ADPCM: - if (format->nSamplesPerSec > 48000 || - format->wBitsPerSample != 4 || - (format->nChannels != 1 && format->nChannels != 2)) - return FALSE; - break; + switch (format->wFormatTag) + { + case WAVE_FORMAT_PCM: + + if (format->cbSize != 0 || + format->nSamplesPerSec > 48000 || + (format->wBitsPerSample != 8 && format->wBitsPerSample != 16) || + (format->nChannels != 1 && format->nChannels != 2)) + return FALSE; + + break; + case WAVE_FORMAT_ADPCM: + case WAVE_FORMAT_DVI_ADPCM: + + if (format->nSamplesPerSec > 48000 || + format->wBitsPerSample != 4 || + (format->nChannels != 1 && format->nChannels != 2)) + return FALSE; + + break; } - + 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) return FALSE; - } else { + } + else + { if (req_fmt == 0) return FALSE; } @@ -132,45 +150,57 @@ static BOOL rdpsnd_oss_format_supported(rdpsndDevicePlugin *device, AUDIO_FORMAT return TRUE; } -static void rdpsnd_oss_set_format(rdpsndDevicePlugin *device, AUDIO_FORMAT *format, int latency) { +static void rdpsnd_oss_set_format(rdpsndDevicePlugin* device, AUDIO_FORMAT* format, int latency) +{ int tmp; - rdpsndOssPlugin *oss = (rdpsndOssPlugin*)device; + rdpsndOssPlugin* oss = (rdpsndOssPlugin*)device; if (device == NULL || oss->pcm_handle == -1 || format == NULL) return; - + oss->latency = latency; CopyMemory(&(oss->format), format, sizeof(AUDIO_FORMAT)); - tmp = rdpsnd_oss_get_format(format); + if (ioctl(oss->pcm_handle, SNDCTL_DSP_SETFMT, &tmp) == -1) OSS_LOG_ERR("SNDCTL_DSP_SETFMT failed", errno); + tmp = format->nChannels; + if (ioctl(oss->pcm_handle, SNDCTL_DSP_CHANNELS, &tmp) == -1) OSS_LOG_ERR("SNDCTL_DSP_CHANNELS failed", errno); + tmp = format->nSamplesPerSec; + if (ioctl(oss->pcm_handle, SNDCTL_DSP_SPEED, &tmp) == -1) OSS_LOG_ERR("SNDCTL_DSP_SPEED failed", errno); + tmp = format->nBlockAlign; + if (ioctl(oss->pcm_handle, SNDCTL_DSP_SETFRAGMENT, &tmp) == -1) OSS_LOG_ERR("SNDCTL_DSP_SETFRAGMENT failed", errno); } -static void rdpsnd_oss_open_mixer(rdpsndOssPlugin *oss) { +static void rdpsnd_oss_open_mixer(rdpsndOssPlugin* oss) +{ int devmask = 0; - char mixer[PATH_MAX] = "/dev/mixer"; + char mixer_name[PATH_MAX] = "/dev/mixer"; if (oss->mixer_handle != -1) return; if (oss->dev_unit != -1) - snprintf(mixer, PATH_MAX - 1, "/dev/mixer%i", oss->dev_unit); - if ((oss->mixer_handle = open(mixer, O_RDWR)) < 0) { + snprintf(mixer_name, PATH_MAX - 1, "/dev/mixer%i", oss->dev_unit); + + if ((oss->mixer_handle = open(mixer_name, O_RDWR)) < 0) + { OSS_LOG_ERR("mixer open failed", errno); oss->mixer_handle = -1; 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); close(oss->mixer_handle); oss->mixer_handle = -1; @@ -178,158 +208,172 @@ static void rdpsnd_oss_open_mixer(rdpsndOssPlugin *oss) { } } -static void rdpsnd_oss_open(rdpsndDevicePlugin *device, AUDIO_FORMAT *format, int latency) { +static void rdpsnd_oss_open(rdpsndDevicePlugin* device, AUDIO_FORMAT* format, int latency) +{ char dev_name[PATH_MAX] = "/dev/dsp"; - rdpsndOssPlugin *oss = (rdpsndOssPlugin*)device; + rdpsndOssPlugin* oss = (rdpsndOssPlugin*)device; if (device == NULL || oss->pcm_handle != -1) return; if (oss->dev_unit != -1) snprintf(dev_name, PATH_MAX - 1, "/dev/dsp%i", oss->dev_unit); + 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->pcm_handle = -1; return; } + #if 0 /* FreeBSD OSS implementation at this moment (2015.03) does not set PCM_CAP_OUTPUT flag. */ 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); - } else if ((mask & PCM_CAP_OUTPUT) == 0) { + } + 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; } + #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); close(oss->pcm_handle); oss->pcm_handle = -1; return; } + freerdp_dsp_context_reset_adpcm(oss->dsp_context); rdpsnd_oss_set_format(device, format, latency); rdpsnd_oss_open_mixer(oss); } -static void rdpsnd_oss_close(rdpsndDevicePlugin *device) { - rdpsndOssPlugin *oss = (rdpsndOssPlugin*)device; +static void rdpsnd_oss_close(rdpsndDevicePlugin* device) +{ + rdpsndOssPlugin* oss = (rdpsndOssPlugin*)device; if (device == NULL) return; - if (oss->pcm_handle != -1) { + if (oss->pcm_handle != -1) + { + WLog_INFO(TAG, "close: dsp"); close(oss->pcm_handle); oss->pcm_handle = -1; } - if (oss->mixer_handle != -1) { + if (oss->mixer_handle != -1) + { + WLog_INFO(TAG, "close: mixer"); close(oss->mixer_handle); oss->mixer_handle = -1; } } -static void rdpsnd_oss_free(rdpsndDevicePlugin *device) { - rdpsndOssPlugin *oss = (rdpsndOssPlugin*)device; +static void rdpsnd_oss_free(rdpsndDevicePlugin* device) +{ + rdpsndOssPlugin* oss = (rdpsndOssPlugin*)device; if (device == NULL) return; rdpsnd_oss_close(device); freerdp_dsp_context_free(oss->dsp_context); - free(oss); } -static UINT32 rdpsnd_oss_get_volume(rdpsndDevicePlugin *device) { +static UINT32 rdpsnd_oss_get_volume(rdpsndDevicePlugin* device) +{ int vol; UINT32 dwVolume; UINT16 dwVolumeLeft, dwVolumeRight; - rdpsndOssPlugin *oss = (rdpsndOssPlugin*)device; - + rdpsndOssPlugin* oss = (rdpsndOssPlugin*)device; /* On error return 50% volume. */ dwVolumeLeft = ((50 * 0xFFFF) / 100); /* 50% */ dwVolumeRight = ((50 * 0xFFFF) / 100); /* 50% */ dwVolume = ((dwVolumeLeft << 16) | dwVolumeRight); - + if (device == NULL || oss->mixer_handle == -1) 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); return dwVolume; } - + dwVolumeLeft = (((vol & 0x7f) * 0xFFFF) / 100); dwVolumeRight = ((((vol >> 8) & 0x7f) * 0xFFFF) / 100); dwVolume = ((dwVolumeLeft << 16) | dwVolumeRight); - return dwVolume; } -static void rdpsnd_oss_set_volume(rdpsndDevicePlugin *device, UINT32 value) { +static void rdpsnd_oss_set_volume(rdpsndDevicePlugin* device, UINT32 value) +{ int left, right; - rdpsndOssPlugin *oss = (rdpsndOssPlugin*)device; + rdpsndOssPlugin* oss = (rdpsndOssPlugin*)device; if (device == NULL || oss->mixer_handle == -1) return; - left = (value & 0xFFFF); - right = ((value >> 16) & 0xFFFF); + left = (((value & 0xFFFF) * 100) / 0xFFFF); + right = ((((value >> 16) & 0xFFFF) * 100) / 0xFFFF); if (left < 0) left = 0; else if (left > 100) left = 100; + if (right < 0) right = 0; else if (right > 100) right = 100; left |= (right << 8); + if (ioctl(oss->mixer_handle, MIXER_WRITE(SOUND_MIXER_VOLUME), &left) == -1) OSS_LOG_ERR("WRITE_MIXER", errno); } -static void rdpsnd_oss_wave_decode(rdpsndDevicePlugin *device, RDPSND_WAVE *wave) { - int size; - BYTE *data; - rdpsndOssPlugin *oss = (rdpsndOssPlugin*)device; +static void rdpsnd_oss_wave_decode(rdpsndDevicePlugin* device, RDPSND_WAVE* wave) +{ + rdpsndOssPlugin* oss = (rdpsndOssPlugin*)device; if (device == NULL || wave == NULL) return; - switch (oss->format.wFormatTag) { - case WAVE_FORMAT_ADPCM: - oss->dsp_context->decode_ms_adpcm(oss->dsp_context, - wave->data, wave->length, oss->format.nChannels, oss->format.nBlockAlign); - size = oss->dsp_context->adpcm_size; - data = oss->dsp_context->adpcm_buffer; - break; - case WAVE_FORMAT_DVI_ADPCM: - oss->dsp_context->decode_ima_adpcm(oss->dsp_context, - wave->data, wave->length, oss->format.nChannels, oss->format.nBlockAlign); - size = oss->dsp_context->adpcm_size; - data = oss->dsp_context->adpcm_buffer; - break; - default: - size = wave->length; - data = wave->data; + switch (oss->format.wFormatTag) + { + case WAVE_FORMAT_ADPCM: + oss->dsp_context->decode_ms_adpcm(oss->dsp_context, + wave->data, wave->length, oss->format.nChannels, oss->format.nBlockAlign); + wave->length = oss->dsp_context->adpcm_size; + wave->data = oss->dsp_context->adpcm_buffer; + break; + case WAVE_FORMAT_DVI_ADPCM: + oss->dsp_context->decode_ima_adpcm(oss->dsp_context, + wave->data, wave->length, oss->format.nChannels, oss->format.nBlockAlign); + wave->length = oss->dsp_context->adpcm_size; + wave->data = oss->dsp_context->adpcm_buffer; + break; } - - wave->data = (BYTE*)malloc(size); - CopyMemory(wave->data, data, size); - wave->length = size; } -static void rdpsnd_oss_wave_play(rdpsndDevicePlugin *device, RDPSND_WAVE *wave) { - BYTE *data; - int offset, size, status; - rdpsndOssPlugin *oss = (rdpsndOssPlugin*)device; +static void rdpsnd_oss_wave_play(rdpsndDevicePlugin* device, RDPSND_WAVE* wave) +{ + BYTE* data; + int offset, size, status, latency; + rdpsndOssPlugin* oss = (rdpsndOssPlugin*)device; if (device == NULL || wave == NULL) return; @@ -337,61 +381,69 @@ static void rdpsnd_oss_wave_play(rdpsndDevicePlugin *device, RDPSND_WAVE *wave) offset = 0; data = wave->data; size = wave->length; + latency = oss->latency; - while (offset < size) { + while (offset < size) + { status = write(oss->pcm_handle, &data[offset], (size - offset)); - if (status < 0) { + + if (status < 0) + { OSS_LOG_ERR("write fail", errno); rdpsnd_oss_close(device); - rdpsnd_oss_open(device, NULL, 0); + rdpsnd_oss_open(device, NULL, latency); break; } + 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, "", NULL, NULL, -1, NULL, "device" }, { 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; - char *str_num, *eptr; + char* str_num, *eptr; DWORD flags; - COMMAND_LINE_ARGUMENT_A *arg; - rdpsndOssPlugin *oss = (rdpsndOssPlugin*)device; - + COMMAND_LINE_ARGUMENT_A* arg; + rdpsndOssPlugin* oss = (rdpsndOssPlugin*)device; 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); + if (status < 0) return status; arg = rdpsnd_oss_args; - do { + do + { if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT)) continue; CommandLineSwitchStart(arg) - - CommandLineSwitchCase(arg, "dev") { + CommandLineSwitchCase(arg, "dev") + { str_num = _strdup(arg->Value); oss->dev_unit = strtol(str_num, &eptr, 10); + if (oss->dev_unit < 0 || *eptr != '\0') oss->dev_unit = -1; + free(str_num); } - CommandLineSwitchEnd(arg) - } while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); + } + while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); return status; } @@ -400,13 +452,12 @@ static int rdpsnd_oss_parse_addin_args(rdpsndDevicePlugin *device, ADDIN_ARGV *a #define freerdp_rdpsnd_client_subsystem_entry oss_freerdp_rdpsnd_client_subsystem_entry #endif -int freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints) { - ADDIN_ARGV *args; - rdpsndOssPlugin *oss; - +int freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints) +{ + ADDIN_ARGV* args; + rdpsndOssPlugin* oss; oss = (rdpsndOssPlugin*)malloc(sizeof(rdpsndOssPlugin)); ZeroMemory(oss, sizeof(rdpsndOssPlugin)); - oss->device.Open = rdpsnd_oss_open; oss->device.FormatSupported = rdpsnd_oss_format_supported; oss->device.SetFormat = rdpsnd_oss_set_format; @@ -416,17 +467,12 @@ int freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pE oss->device.WavePlay = rdpsnd_oss_wave_play; oss->device.Close = rdpsnd_oss_close; oss->device.Free = rdpsnd_oss_free; - oss->pcm_handle = -1; oss->mixer_handle = -1; oss->dev_unit = -1; - args = pEntryPoints->args; rdpsnd_oss_parse_addin_args((rdpsndDevicePlugin*)oss, args); - oss->dsp_context = freerdp_dsp_context_new(); - pEntryPoints->pRegisterRdpsndDevice(pEntryPoints->rdpsnd, (rdpsndDevicePlugin*)oss); - return 0; } diff --git a/channels/tsmf/client/CMakeLists.txt b/channels/tsmf/client/CMakeLists.txt index 462ce246c..b47a616a2 100644 --- a/channels/tsmf/client/CMakeLists.txt +++ b/channels/tsmf/client/CMakeLists.txt @@ -62,6 +62,10 @@ if(WITH_GSTREAMER_0_10 OR WITH_GSTREAMER_1_0) endif() endif() +if(WITH_OSS) + add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "oss" "audio") +endif() + if(WITH_ALSA) add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "alsa" "audio") endif() diff --git a/channels/tsmf/client/alsa/tsmf_alsa.c b/channels/tsmf/client/alsa/tsmf_alsa.c index dec1e3443..c595f8162 100644 --- a/channels/tsmf/client/alsa/tsmf_alsa.c +++ b/channels/tsmf/client/alsa/tsmf_alsa.c @@ -68,8 +68,7 @@ static BOOL tsmf_alsa_open(ITSMFAudioDevice *audio, const char *device) TSMFAlsaAudioDevice *alsa = (TSMFAlsaAudioDevice *) audio; if(!device) { - if(!alsa->device[0]) - strncpy(alsa->device, "default", sizeof(alsa->device)); + strncpy(alsa->device, "default", sizeof(alsa->device)); } else { diff --git a/channels/tsmf/client/gstreamer/tsmf_X11.c b/channels/tsmf/client/gstreamer/tsmf_X11.c index e678f88a5..6c1d570e1 100644 --- a/channels/tsmf/client/gstreamer/tsmf_X11.c +++ b/channels/tsmf/client/gstreamer/tsmf_X11.c @@ -25,6 +25,9 @@ #include #include +#include +#include +#include #include #include @@ -61,8 +64,8 @@ struct X11Handle static const char* get_shm_id() { - static char shm_id[64]; - snprintf(shm_id, sizeof(shm_id), "com.freerdp.xfreerdp.tsmf_%016X", GetCurrentProcessId()); + static char shm_id[128]; + snprintf(shm_id, sizeof(shm_id), "/com.freerdp.xfreerdp.tsmf_%016X", GetCurrentProcessId()); return shm_id; } @@ -87,7 +90,6 @@ int tsmf_platform_create(TSMFGstreamerDecoder* decoder) return -1; hdl = calloc(1, sizeof(struct X11Handle)); - if (!hdl) { WLog_ERR(TAG, "Could not allocate handle."); @@ -95,26 +97,21 @@ int tsmf_platform_create(TSMFGstreamerDecoder* decoder) } decoder->platform = hdl; - hdl->shmid = shm_open(get_shm_id(), O_RDWR, PROT_READ | PROT_WRITE);; - - if (hdl->shmid < 0) + hdl->shmid = shm_open(get_shm_id(), (O_RDWR | O_CREAT), (PROT_READ | PROT_WRITE)); + if (hdl->shmid == -1) { - 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; } - 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!"); return -3; } hdl->disp = XOpenDisplay(NULL); - if (!hdl->disp) { WLog_ERR(TAG, "Failed to open display"); diff --git a/channels/tsmf/client/oss/CMakeLists.txt b/channels/tsmf/client/oss/CMakeLists.txt new file mode 100644 index 000000000..b0d39b6a9 --- /dev/null +++ b/channels/tsmf/client/oss/CMakeLists.txt @@ -0,0 +1,32 @@ +# FreeRDP: A Remote Desktop Protocol Implementation +# FreeRDP cmake build script +# +# Copyright (c) 2015 Rozhuk Ivan +# +# 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) diff --git a/channels/tsmf/client/oss/tsmf_oss.c b/channels/tsmf/client/oss/tsmf_oss.c new file mode 100644 index 000000000..2ae4713b8 --- /dev/null +++ b/channels/tsmf/client/oss/tsmf_oss.c @@ -0,0 +1,251 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Video Redirection Virtual Channel - OSS Audio Device + * + * Copyright (c) 2015 Rozhuk Ivan + * + * 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 +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#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; +} diff --git a/channels/tsmf/client/tsmf_audio.c b/channels/tsmf/client/tsmf_audio.c index 5b4e7fdb9..a71b016b3 100644 --- a/channels/tsmf/client/tsmf_audio.c +++ b/channels/tsmf/client/tsmf_audio.c @@ -49,6 +49,11 @@ static ITSMFAudioDevice* tsmf_load_audio_device_by_name(const char* name, const { audio->Free(audio); 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; @@ -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* audio; + ITSMFAudioDevice* audio = NULL; if (name) { @@ -64,10 +69,29 @@ ITSMFAudioDevice* tsmf_load_audio_device(const char* name, const char* device) } 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) 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; diff --git a/channels/tsmf/client/tsmf_main.c b/channels/tsmf/client/tsmf_main.c index 0a31a3417..9545349b0 100644 --- a/channels/tsmf/client/tsmf_main.c +++ b/channels/tsmf/client/tsmf_main.c @@ -362,8 +362,8 @@ static int tsmf_plugin_terminated(IWTSPlugin* pPlugin) COMMAND_LINE_ARGUMENT_A tsmf_args[] = { - { "audio", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "audio subsystem" }, - { "audio-dev", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "audio device name" }, + { "sys", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "audio subsystem" }, + { "dev", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "audio device name" }, { "decoder", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "decoder subsystem" }, { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } }; @@ -386,11 +386,11 @@ static void tsmf_process_addin_args(IWTSPlugin *pPlugin, ADDIN_ARGV *args) if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT)) continue; CommandLineSwitchStart(arg) - CommandLineSwitchCase(arg, "audio") + CommandLineSwitchCase(arg, "sys") { tsmf->audio_name = _strdup(arg->Value); } - CommandLineSwitchCase(arg, "audio-dev") + CommandLineSwitchCase(arg, "dev") { tsmf->audio_device = _strdup(arg->Value); } diff --git a/channels/tsmf/client/tsmf_media.c b/channels/tsmf/client/tsmf_media.c index 40155655b..15c612a08 100644 --- a/channels/tsmf/client/tsmf_media.c +++ b/channels/tsmf/client/tsmf_media.c @@ -424,13 +424,13 @@ static void tsmf_sample_playback_audio(TSMF_SAMPLE* sample) DEBUG_TSMF("MessageId %d EndTime %d consumed.", sample->sample_id, (int)sample->end_time); - if (sample->stream->audio && sample->data) + if (stream->audio && sample->data) { - sample->stream->audio->Play(sample->stream->audio, sample->data, sample->decoded_size); + stream->audio->Play(stream->audio, sample->data, sample->decoded_size); sample->data = NULL; sample->decoded_size = 0; - if (stream->audio && stream->audio->GetLatency) + if (stream->audio->GetLatency) latency = stream->audio->GetLatency(stream->audio); } else diff --git a/channels/urbdrc/CMakeLists.txt b/channels/urbdrc/CMakeLists.txt index 2e10bd89b..995c63b71 100644 --- a/channels/urbdrc/CMakeLists.txt +++ b/channels/urbdrc/CMakeLists.txt @@ -18,15 +18,28 @@ define_channel("urbdrc") if(NOT WIN32) + find_package(DevD) find_package(UDev) find_package(UUID) find_package(DbusGlib) find_package(libusb-1.0) endif() -if(UDEV_FOUND AND UUID_FOUND AND DBUS_GLIB_FOUND AND LIBUSB_1_FOUND) - set(URBDRC_DEPENDENCIES_FOUND TRUE) - message(STATUS "Found all URBDRC dependencies") +if(DEVD_FOUND OR UDEV_FOUND) + if(UUID_FOUND AND DBUS_GLIB_FOUND AND LIBUSB_1_FOUND) + 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() if(WITH_CLIENT_CHANNELS) diff --git a/channels/urbdrc/client/CMakeLists.txt b/channels/urbdrc/client/CMakeLists.txt index 4ad1f27c0..5b0bc314a 100644 --- a/channels/urbdrc/client/CMakeLists.txt +++ b/channels/urbdrc/client/CMakeLists.txt @@ -39,8 +39,10 @@ add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE set(${MODULE_PREFIX}_LIBS ${DBUS_GLIB_LIBRARIES} - ${UDEV_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) diff --git a/channels/urbdrc/client/data_transfer.c b/channels/urbdrc/client/data_transfer.c index b0a37fd25..47ded1889 100644 --- a/channels/urbdrc/client/data_transfer.c +++ b/channels/urbdrc/client/data_transfer.c @@ -1281,7 +1281,7 @@ static int urb_os_feature_descriptor_request(URBDRC_CHANNEL_CALLBACK * callback, data_read_UINT32(data + 0, RequestId); 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 + 6, Ms_PageIndex); /** Ms_PageIndex */ data_read_UINT16(data + 7, Ms_featureDescIndex); /** Ms_featureDescIndex */ diff --git a/channels/urbdrc/client/libusb/libusb_udevice.c b/channels/urbdrc/client/libusb/libusb_udevice.c index d7cf55ff1..b7d17b2e5 100644 --- a/channels/urbdrc/client/libusb/libusb_udevice.c +++ b/channels/urbdrc/client/libusb/libusb_udevice.c @@ -22,7 +22,9 @@ #include #include #include +#if defined(__linux__) #include +#endif #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) { - int i; - ssize_t total_device; + ssize_t i, total_device; LIBUSB_DEVICE** 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; } - /* 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) { struct udev* udev; @@ -627,6 +690,7 @@ static int udev_get_hub_handle(UDEVICE* pdev, UINT16 bus_number, UINT16 dev_numb /* Success! */ return 0; } +#endif 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; int success = 0, ret; + WLog_DBG(TAG,"..."); if (pdev->hub_handle != NULL) { 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; UINT16 bus_number; UINT16 dev_number; - ssize_t total_device; - int i, status, num = 0; + ssize_t i, total_device; + 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*)); @@ -1839,7 +1904,7 @@ int udev_new_by_id(UINT16 idVendor, UINT16 idProduct, IUDEVICE*** devArray) 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(array[num]); continue; diff --git a/channels/urbdrc/client/libusb/libusb_udevice.h b/channels/urbdrc/client/libusb/libusb_udevice.h index 5f8e9004b..d753039ce 100644 --- a/channels/urbdrc/client/libusb/libusb_udevice.h +++ b/channels/urbdrc/client/libusb/libusb_udevice.h @@ -23,7 +23,11 @@ #ifndef __LIBUSB_UDEVICE_H #define __LIBUSB_UDEVICE_H +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +#include +#else #include +#endif #include "urbdrc_types.h" #include "request_queue.h" diff --git a/channels/urbdrc/client/libusb/libusb_udevman.c b/channels/urbdrc/client/libusb/libusb_udevman.c index f8ce71503..e99b95da2 100644 --- a/channels/urbdrc/client/libusb/libusb_udevman.c +++ b/channels/urbdrc/client/libusb/libusb_udevman.c @@ -610,5 +610,7 @@ int freerdp_urbdrc_client_subsystem_entry(PFREERDP_URBDRC_SERVICE_ENTRY_POINTS p pEntryPoints->pRegisterUDEVMAN(pEntryPoints->plugin, (IUDEVMAN*) udevman); + WLog_DBG(TAG, "UDEVMAN device registered."); + return 0; } diff --git a/channels/urbdrc/client/urbdrc_main.c b/channels/urbdrc/client/urbdrc_main.c index a3e1fce5c..21aea896a 100644 --- a/channels/urbdrc/client/urbdrc_main.c +++ b/channels/urbdrc/client/urbdrc_main.c @@ -24,7 +24,16 @@ #include #include #include +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +#include +#include +#include +#include +#include +#endif +#if defined(__linux__) #include +#endif #include #include @@ -435,6 +444,266 @@ static int urbdrc_exchange_capabilities(URBDRC_CHANNEL_CALLBACK* callback, char* 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) { USB_SEARCHMAN* searchman = (USB_SEARCHMAN*) arg; @@ -658,6 +927,7 @@ fail_create_monfd_event: return 0; } +#endif void* urbdrc_new_device_create(void* arg) { @@ -674,8 +944,10 @@ void* urbdrc_new_device_create(void* arg) UINT32 FunctionId; int i = 0, found = 0; + WLog_DBG(TAG, "..."); + 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 + 4, FunctionId); @@ -743,6 +1015,8 @@ static int urbdrc_process_channel_notification(URBDRC_CHANNEL_CALLBACK* callback UINT32 FunctionId; URBDRC_PLUGIN* urbdrc = (URBDRC_PLUGIN*) callback->plugin; + WLog_DBG(TAG, "..."); + data_read_UINT32(pBuffer + 0, MessageId); data_read_UINT32(pBuffer + 4, FunctionId); @@ -793,7 +1067,7 @@ static int urbdrc_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, UINT32 Mask; int error = 0; char* pBuffer = (char*)Stream_Pointer(data); - UINT32 cbSize = Stream_GetRemainingLength(data); + UINT32 cbSize = Stream_GetRemainingLength(data); if (callback == NULL) return 0; diff --git a/channels/urbdrc/client/urbdrc_types.h b/channels/urbdrc/client/urbdrc_types.h index 641478eea..a3219d7f4 100644 --- a/channels/urbdrc/client/urbdrc_types.h +++ b/channels/urbdrc/client/urbdrc_types.h @@ -30,7 +30,11 @@ #include #include +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +#include +#else #include +#endif #include #include diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index 4c9e19d4f..b03f202ea 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -335,7 +335,7 @@ static void xf_SetWindowPID(xfContext* xfc, Window window, pid_t pid) static const char* get_shm_id() { static char shm_id[64]; - snprintf(shm_id, sizeof(shm_id), "com.freerdp.xfreerdp.tsmf_%016X", GetCurrentProcessId()); + snprintf(shm_id, sizeof(shm_id), "/com.freerdp.xfreerdp.tsmf_%016X", GetCurrentProcessId()); return shm_id; } @@ -368,7 +368,7 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap | 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) { @@ -382,7 +382,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); - if (mem == ((int*) -1)) + if (mem == MAP_FAILED) { DEBUG_X11("xf_CreateDesktopWindow: failed to assign pointer to the memory address - shmat()\n"); } diff --git a/client/common/cmdline.c b/client/common/cmdline.c index f5b7e5f44..65087ab38 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -91,10 +91,10 @@ COMMAND_LINE_ARGUMENT_A args[] = { "compression-level", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Compression level (0,1,2)" }, { "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" }, - { "sound", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, "audio", "Audio output (sound)" }, - { "microphone", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, "mic", "Audio input (microphone)" }, + { "sound", COMMAND_LINE_VALUE_OPTIONAL, "[sys][dev][format][rate][channel][latency][quality]", NULL, NULL, -1, "audio", "Audio output (sound)" }, + { "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" }, - { "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" }, { "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" }, @@ -104,7 +104,7 @@ COMMAND_LINE_ARGUMENT_A args[] = { "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" }, { "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" }, { "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" }, @@ -268,10 +268,13 @@ int freerdp_client_print_command_line_help(int argc, char** argv) printf("Printer Redirection: /printer:,\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 Input Redirection: /microphone:sys:oss,dev:1,format:1\n"); printf("Audio Input Redirection: /microphone:sys:alsa\n"); printf("\n"); + printf("Multimedia Redirection: /multimedia:sys:oss,dev:/dev/dsp1,decoder:ffmpeg\n"); printf("Multimedia Redirection: /multimedia:sys:alsa\n"); printf("USB Device Redirection: /usb:id,dev:054c:0268\n"); printf("\n"); diff --git a/cmake/FindDevD.cmake b/cmake/FindDevD.cmake new file mode 100644 index 000000000..5c5b606f9 --- /dev/null +++ b/cmake/FindDevD.cmake @@ -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 +# 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) diff --git a/cmake/FindUUID.cmake b/cmake/FindUUID.cmake index 330e5caba..88083df9d 100644 --- a/cmake/FindUUID.cmake +++ b/cmake/FindUUID.cmake @@ -20,6 +20,7 @@ set(UUID_FOUND TRUE) else (UUID_LIBRARIES AND UUID_INCLUDE_DIRS) find_path(UUID_INCLUDE_DIR NAMES +uuid.h uuid/uuid.h PATHS ${UUID_DIR}/include @@ -85,26 +86,27 @@ $ENV{OSG_ROOT}/lib /opt/lib /usr/freeware/lib64 ) +if (NOT UUID_LIBRARY AND BSD) + set(UUID_LIBRARY "") +endif(NOT UUID_LIBRARY AND BSD) -set(UUID_INCLUDE_DIRS -${UUID_INCLUDE_DIR} -) -set(UUID_LIBRARIES -${UUID_LIBRARY} -) +set(UUID_INCLUDE_DIRS ${UUID_INCLUDE_DIR}) +set(UUID_LIBRARIES ${UUID_LIBRARY}) -if (UUID_INCLUDE_DIRS AND UUID_LIBRARIES) -set(UUID_FOUND TRUE) -endif (UUID_INCLUDE_DIRS AND UUID_LIBRARIES) +if (UUID_INCLUDE_DIRS) + if (BSD OR UUID_LIBRARIES) + set(UUID_FOUND TRUE) + endif (BSD OR UUID_LIBRARIES) +endif (UUID_INCLUDE_DIRS) if (UUID_FOUND) -if (NOT UUID_FIND_QUIETLY) -message(STATUS "Found UUID: ${UUID_LIBRARIES}") -endif (NOT UUID_FIND_QUIETLY) + if (NOT UUID_FIND_QUIETLY) + message(STATUS "Found UUID: ${UUID_LIBRARIES}") + endif (NOT UUID_FIND_QUIETLY) else (UUID_FOUND) -if (UUID_FIND_REQUIRED) -message(FATAL_ERROR "Could not find UUID") -endif (UUID_FIND_REQUIRED) + if (UUID_FIND_REQUIRED) + message(FATAL_ERROR "Could not find UUID") + endif (UUID_FIND_REQUIRED) endif (UUID_FOUND) # show the UUID_INCLUDE_DIRS and UUID_LIBRARIES variables only in the advanced view diff --git a/libfreerdp/core/fastpath.c b/libfreerdp/core/fastpath.c index 905639372..79fa00d6e 100644 --- a/libfreerdp/core/fastpath.c +++ b/libfreerdp/core/fastpath.c @@ -263,13 +263,19 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s { case FASTPATH_UPDATETYPE_ORDERS: if (!fastpath_recv_orders(fastpath, s)) + { + WLog_ERR(TAG, "FASTPATH_UPDATETYPE_ORDERS - fastpath_recv_orders()"); return -1; + } break; case FASTPATH_UPDATETYPE_BITMAP: case FASTPATH_UPDATETYPE_PALETTE: if (!fastpath_recv_update_common(fastpath, s)) + { + WLog_ERR(TAG, "FASTPATH_UPDATETYPE_ORDERS - fastpath_recv_orders()"); return -1; + } break; case FASTPATH_UPDATETYPE_SYNCHRONIZE: @@ -281,6 +287,8 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s case FASTPATH_UPDATETYPE_SURFCMDS: status = update_recv_surfcmds(update, size, s); + if (status < 0) + WLog_ERR(TAG, "FASTPATH_UPDATETYPE_SURFCMDS - update_recv_surfcmds() - %i", status); break; case FASTPATH_UPDATETYPE_PTR_NULL: @@ -291,30 +299,41 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s case FASTPATH_UPDATETYPE_PTR_DEFAULT: update->pointer->pointer_system.type = SYSPTR_DEFAULT; IFCALL(pointer->PointerSystem, context, &pointer->pointer_system); - break; case FASTPATH_UPDATETYPE_PTR_POSITION: if (!update_read_pointer_position(s, &pointer->pointer_position)) + { + WLog_ERR(TAG, "FASTPATH_UPDATETYPE_PTR_POSITION - update_read_pointer_position()"); return -1; + } IFCALL(pointer->PointerPosition, context, &pointer->pointer_position); break; case FASTPATH_UPDATETYPE_COLOR: if (!update_read_pointer_color(s, &pointer->pointer_color, 24)) + { + WLog_ERR(TAG, "FASTPATH_UPDATETYPE_COLOR - update_read_pointer_color()"); return -1; + } IFCALL(pointer->PointerColor, context, &pointer->pointer_color); break; case FASTPATH_UPDATETYPE_CACHED: if (!update_read_pointer_cached(s, &pointer->pointer_cached)) + { + WLog_ERR(TAG, "FASTPATH_UPDATETYPE_CACHED - update_read_pointer_cached()"); return -1; + } IFCALL(pointer->PointerCached, context, &pointer->pointer_cached); break; case FASTPATH_UPDATETYPE_POINTER: if (!update_read_pointer_new(s, &pointer->pointer_new)) + { + WLog_ERR(TAG, "FASTPATH_UPDATETYPE_POINTER - update_read_pointer_new()"); return -1; + } IFCALL(pointer->PointerNew, context, &pointer->pointer_new); break; @@ -371,7 +390,10 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) Stream_Read_UINT16(s, size); if (Stream_GetRemainingLength(s) < size) + { + WLog_ERR(TAG, "Stream_GetRemainingLength() < size"); return -1; + } cs = s; next_pos = Stream_GetPosition(s) + size; @@ -380,7 +402,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) if (bulkStatus < 0) { - WLog_ERR(TAG, "bulk_decompress() failed"); + WLog_ERR(TAG, "bulk_decompress() failed"); return -1; } @@ -402,7 +424,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) { if (fastpath->fragmentation != -1) { - WLog_ERR(TAG, "Unexpected FASTPATH_FRAGMENT_SINGLE"); + WLog_ERR(TAG, "Unexpected FASTPATH_FRAGMENT_SINGLE"); goto out_fail; } @@ -410,7 +432,10 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) status = fastpath_recv_update(fastpath, updateCode, totalSize, cs); if (status < 0) + { + WLog_ERR(TAG, "fastpath_recv_update() - %i", status); goto out_fail; + } } else { @@ -418,7 +443,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) { if (fastpath->fragmentation != -1) { - WLog_ERR(TAG, "Unexpected FASTPATH_FRAGMENT_FIRST"); + WLog_ERR(TAG, "fastpath_recv_update_data: Unexpected FASTPATH_FRAGMENT_FIRST"); goto out_fail; } @@ -428,7 +453,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) if (totalSize > transport->settings->MultifragMaxRequestSize) { - WLog_ERR(TAG, "Total size (%d) exceeds MultifragMaxRequestSize (%d)", + WLog_ERR(TAG, "Total size (%d) exceeds MultifragMaxRequestSize (%d)", totalSize, transport->settings->MultifragMaxRequestSize); goto out_fail; } @@ -445,7 +470,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) if ((fastpath->fragmentation != FASTPATH_FRAGMENT_FIRST) && (fastpath->fragmentation != FASTPATH_FRAGMENT_NEXT)) { - WLog_ERR(TAG, "Unexpected FASTPATH_FRAGMENT_NEXT"); + WLog_ERR(TAG, "fastpath_recv_update_data: Unexpected FASTPATH_FRAGMENT_NEXT"); goto out_fail; } @@ -455,7 +480,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) if (totalSize > transport->settings->MultifragMaxRequestSize) { - WLog_ERR(TAG, "Total size (%d) exceeds MultifragMaxRequestSize (%d)", + WLog_ERR(TAG, "Total size (%d) exceeds MultifragMaxRequestSize (%d)", totalSize, transport->settings->MultifragMaxRequestSize); goto out_fail; } @@ -473,7 +498,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) if ((fastpath->fragmentation != FASTPATH_FRAGMENT_FIRST) && (fastpath->fragmentation != FASTPATH_FRAGMENT_NEXT)) { - WLog_ERR(TAG, "Unexpected FASTPATH_FRAGMENT_LAST"); + WLog_ERR(TAG, "fastpath_recv_update_data: Unexpected FASTPATH_FRAGMENT_LAST"); goto out_fail; } @@ -483,7 +508,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) if (totalSize > transport->settings->MultifragMaxRequestSize) { - WLog_ERR(TAG, "Total size (%d) exceeds MultifragMaxRequestSize (%d)", + WLog_ERR(TAG, "Total size (%d) exceeds MultifragMaxRequestSize (%d)", totalSize, transport->settings->MultifragMaxRequestSize); goto out_fail; } @@ -504,7 +529,10 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) Stream_Release(fastpath->updateData); if (status < 0) + { + WLog_ERR(TAG, "fastpath_recv_update_data: fastpath_recv_update() - %i", status); goto out_fail; + } } } @@ -526,7 +554,6 @@ out_fail: int fastpath_recv_updates(rdpFastPath* fastpath, wStream* s) { - int status = 0; rdpUpdate* update = fastpath->rdp->update; IFCALL(update->BeginPaint, update->context); @@ -534,12 +561,15 @@ int fastpath_recv_updates(rdpFastPath* fastpath, wStream* s) while (Stream_GetRemainingLength(s) >= 3) { if (fastpath_recv_update_data(fastpath, s) < 0) + { + WLog_ERR(TAG, "fastpath_recv_update_data() fail"); return -1; + } } IFCALL(update->EndPaint, update->context); - return status; + return 0; } static BOOL fastpath_read_input_event_header(wStream* s, BYTE* eventFlags, BYTE* eventCode) @@ -683,7 +713,7 @@ static BOOL fastpath_recv_input_event(rdpFastPath* fastpath, wStream* s) break; default: - WLog_ERR(TAG, "Unknown eventCode %d", eventCode); + WLog_ERR(TAG, "Unknown eventCode %d", eventCode); break; } @@ -794,7 +824,7 @@ BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, int iNu if (length >= (2 << 14)) { - WLog_ERR(TAG, "Maximum FastPath PDU length is 32767"); + WLog_ERR(TAG, "Maximum FastPath PDU length is 32767"); return FALSE; } diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index a220b9bd8..aef2ae8d9 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -210,6 +210,7 @@ BOOL freerdp_check_fds(freerdp* instance) TerminateEventArgs e; rdpContext* context = instance->context; + WLog_DBG(TAG, "rdp_check_fds() - %i", status); EventArgsInit(&e, "freerdp"); e.code = 0; PubSub_OnTerminate(context->pubSub, context, &e); @@ -244,9 +245,17 @@ BOOL freerdp_check_event_handles(rdpContext* context) status = freerdp_check_fds(context->instance); if (!status) + { + WLog_ERR(TAG, "freerdp_check_fds() failed - %i", status); return FALSE; + } status = freerdp_channels_check_fds(context->channels, context->instance); + if (!status) + { + WLog_ERR(TAG, "freerdp_channels_check_fds() failed - %i", status); + return FALSE; + } return status; } diff --git a/libfreerdp/core/orders.c b/libfreerdp/core/orders.c index fbfa7ac5d..60aed90b8 100644 --- a/libfreerdp/core/orders.c +++ b/libfreerdp/core/orders.c @@ -500,7 +500,10 @@ static INLINE BOOL update_read_delta(wStream* s, INT32* value) BYTE byte; if (Stream_GetRemainingLength(s) < 1) + { + WLog_ERR(TAG, "Stream_GetRemainingLength(s) < 1"); return FALSE; + } Stream_Read_UINT8(s, byte); if (byte & 0x40) @@ -511,7 +514,10 @@ static INLINE BOOL update_read_delta(wStream* s, INT32* value) if (byte & 0x80) { if (Stream_GetRemainingLength(s) < 1) + { + WLog_ERR(TAG, "Stream_GetRemainingLength(s) < 1"); return FALSE; + } Stream_Read_UINT8(s, byte); *value = (*value << 8) | byte; } @@ -723,7 +729,10 @@ static INLINE BOOL update_read_delta_points(wStream* s, DELTA_POINT* points, int zeroBitsSize = ((number + 3) / 4); if (Stream_GetRemainingLength(s) < zeroBitsSize) + { + WLog_ERR(TAG, "Stream_GetRemainingLength(s) < %i", zeroBitsSize); return FALSE; + } Stream_GetPointer(s, zeroBits); Stream_Seek(s, zeroBitsSize); @@ -736,10 +745,16 @@ static INLINE BOOL update_read_delta_points(wStream* s, DELTA_POINT* points, int flags = zeroBits[i / 4]; if ((~flags & 0x80) && !update_read_delta(s, &points[i].x)) + { + WLog_ERR(TAG, "update_read_delta(x) failed"); return FALSE; + } if ((~flags & 0x40) && !update_read_delta(s, &points[i].y)) + { + WLog_ERR(TAG, "update_read_delta(y) failed"); return FALSE; + } flags <<= 2; } @@ -1336,12 +1351,18 @@ BOOL update_read_polyline_order(wStream* s, ORDER_INFO* orderInfo, POLYLINE_ORDE DELTA_POINT *new_points; if (Stream_GetRemainingLength(s) < 1) + { + WLog_ERR(TAG, "Stream_GetRemainingLength(s) < 1"); return FALSE; + } Stream_Read_UINT8(s, polyline->cbData); new_points = (DELTA_POINT*) realloc(polyline->points, sizeof(DELTA_POINT) * new_num); if (!new_points) + { + WLog_ERR(TAG, "realloc(%i) failed", new_num); return FALSE; + } polyline->points = new_points; polyline->numDeltaEntries = new_num; @@ -3139,14 +3160,20 @@ BOOL update_recv_primary_order(rdpUpdate* update, wStream* s, BYTE flags) if (!update_read_field_flags(s, &(orderInfo->fieldFlags), flags, PRIMARY_DRAWING_ORDER_FIELD_BYTES[orderInfo->orderType])) + { + WLog_ERR(TAG, "update_read_field_flags() failed"); return FALSE; + } if (flags & ORDER_BOUNDS) { if (!(flags & ORDER_ZERO_BOUNDS_DELTAS)) { if (!update_read_bounds(s, &orderInfo->bounds)) + { + WLog_ERR(TAG, "update_read_bounds() failed"); return FALSE; + } } IFCALL(update->SetBounds, context, &orderInfo->bounds); @@ -3162,154 +3189,220 @@ BOOL update_recv_primary_order(rdpUpdate* update, wStream* s, BYTE flags) { case ORDER_TYPE_DSTBLT: if (!update_read_dstblt_order(s, orderInfo, &(primary->dstblt))) + { + WLog_ERR(TAG, "ORDER_TYPE_DSTBLT - update_read_dstblt_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "DstBlt"); IFCALL(primary->DstBlt, context, &primary->dstblt); break; case ORDER_TYPE_PATBLT: if (!update_read_patblt_order(s, orderInfo, &(primary->patblt))) + { + WLog_ERR(TAG, "ORDER_TYPE_PATBLT - update_read_patblt_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "PatBlt"); IFCALL(primary->PatBlt, context, &primary->patblt); break; case ORDER_TYPE_SCRBLT: if (!update_read_scrblt_order(s, orderInfo, &(primary->scrblt))) + { + WLog_ERR(TAG, "ORDER_TYPE_SCRBLT - update_read_scrblt_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "ScrBlt"); IFCALL(primary->ScrBlt, context, &primary->scrblt); break; case ORDER_TYPE_OPAQUE_RECT: if (!update_read_opaque_rect_order(s, orderInfo, &(primary->opaque_rect))) + { + WLog_ERR(TAG, "ORDER_TYPE_OPAQUE_RECT - update_read_opaque_rect_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "OpaqueRect"); IFCALL(primary->OpaqueRect, context, &primary->opaque_rect); break; case ORDER_TYPE_DRAW_NINE_GRID: if (!update_read_draw_nine_grid_order(s, orderInfo, &(primary->draw_nine_grid))) + { + WLog_ERR(TAG, "ORDER_TYPE_DRAW_NINE_GRID - update_read_draw_nine_grid_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "DrawNineGrid"); IFCALL(primary->DrawNineGrid, context, &primary->draw_nine_grid); break; case ORDER_TYPE_MULTI_DSTBLT: if (!update_read_multi_dstblt_order(s, orderInfo, &(primary->multi_dstblt))) + { + WLog_ERR(TAG, "ORDER_TYPE_MULTI_DSTBLT - update_read_multi_dstblt_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "MultiDstBlt"); IFCALL(primary->MultiDstBlt, context, &primary->multi_dstblt); break; case ORDER_TYPE_MULTI_PATBLT: if (!update_read_multi_patblt_order(s, orderInfo, &(primary->multi_patblt))) + { + WLog_ERR(TAG, "ORDER_TYPE_MULTI_PATBLT - update_read_multi_patblt_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "MultiPatBlt"); IFCALL(primary->MultiPatBlt, context, &primary->multi_patblt); break; case ORDER_TYPE_MULTI_SCRBLT: if (!update_read_multi_scrblt_order(s, orderInfo, &(primary->multi_scrblt))) + { + WLog_ERR(TAG, "ORDER_TYPE_MULTI_SCRBLT - update_read_multi_scrblt_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "MultiScrBlt"); IFCALL(primary->MultiScrBlt, context, &primary->multi_scrblt); break; case ORDER_TYPE_MULTI_OPAQUE_RECT: if (!update_read_multi_opaque_rect_order(s, orderInfo, &(primary->multi_opaque_rect))) + { + WLog_ERR(TAG, "ORDER_TYPE_MULTI_OPAQUE_RECT - update_read_multi_opaque_rect_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "MultiOpaqueRect"); IFCALL(primary->MultiOpaqueRect, context, &primary->multi_opaque_rect); break; case ORDER_TYPE_MULTI_DRAW_NINE_GRID: if (!update_read_multi_draw_nine_grid_order(s, orderInfo, &(primary->multi_draw_nine_grid))) + { + WLog_ERR(TAG, "ORDER_TYPE_MULTI_DRAW_NINE_GRID - update_read_multi_draw_nine_grid_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "MultiDrawNineGrid"); IFCALL(primary->MultiDrawNineGrid, context, &primary->multi_draw_nine_grid); break; case ORDER_TYPE_LINE_TO: if (!update_read_line_to_order(s, orderInfo, &(primary->line_to))) + { + WLog_ERR(TAG, "ORDER_TYPE_LINE_TO - update_read_line_to_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "LineTo"); IFCALL(primary->LineTo, context, &primary->line_to); break; case ORDER_TYPE_POLYLINE: if (!update_read_polyline_order(s, orderInfo, &(primary->polyline))) + { + WLog_ERR(TAG, "ORDER_TYPE_POLYLINE - update_read_polyline_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "Polyline"); IFCALL(primary->Polyline, context, &primary->polyline); break; case ORDER_TYPE_MEMBLT: if (!update_read_memblt_order(s, orderInfo, &(primary->memblt))) + { + WLog_ERR(TAG, "ORDER_TYPE_MEMBLT - update_read_memblt_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "MemBlt"); IFCALL(primary->MemBlt, context, &primary->memblt); break; case ORDER_TYPE_MEM3BLT: if (!update_read_mem3blt_order(s, orderInfo, &(primary->mem3blt))) + { + WLog_ERR(TAG, "ORDER_TYPE_MEM3BLT - update_read_mem3blt_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "Mem3Blt"); IFCALL(primary->Mem3Blt, context, &primary->mem3blt); break; case ORDER_TYPE_SAVE_BITMAP: if (!update_read_save_bitmap_order(s, orderInfo, &(primary->save_bitmap))) + { + WLog_ERR(TAG, "ORDER_TYPE_SAVE_BITMAP - update_read_save_bitmap_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "SaveBitmap"); IFCALL(primary->SaveBitmap, context, &primary->save_bitmap); break; case ORDER_TYPE_GLYPH_INDEX: if (!update_read_glyph_index_order(s, orderInfo, &(primary->glyph_index))) + { + WLog_ERR(TAG, "ORDER_TYPE_GLYPH_INDEX - update_read_glyph_index_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "GlyphIndex"); IFCALL(primary->GlyphIndex, context, &primary->glyph_index); break; case ORDER_TYPE_FAST_INDEX: if (!update_read_fast_index_order(s, orderInfo, &(primary->fast_index))) + { + WLog_ERR(TAG, "ORDER_TYPE_FAST_INDEX - update_read_fast_index_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "FastIndex"); IFCALL(primary->FastIndex, context, &primary->fast_index); break; case ORDER_TYPE_FAST_GLYPH: if (!update_read_fast_glyph_order(s, orderInfo, &(primary->fast_glyph))) + { + WLog_ERR(TAG, "ORDER_TYPE_FAST_GLYPH - update_read_fast_glyph_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "FastGlyph"); IFCALL(primary->FastGlyph, context, &primary->fast_glyph); break; case ORDER_TYPE_POLYGON_SC: if (!update_read_polygon_sc_order(s, orderInfo, &(primary->polygon_sc))) + { + WLog_ERR(TAG, "ORDER_TYPE_POLYGON_SC - update_read_polygon_sc_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "PolygonSC"); IFCALL(primary->PolygonSC, context, &primary->polygon_sc); break; case ORDER_TYPE_POLYGON_CB: if (!update_read_polygon_cb_order(s, orderInfo, &(primary->polygon_cb))) + { + WLog_ERR(TAG, "ORDER_TYPE_POLYGON_CB - update_read_polygon_cb_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "PolygonCB"); IFCALL(primary->PolygonCB, context, &primary->polygon_cb); break; case ORDER_TYPE_ELLIPSE_SC: if (!update_read_ellipse_sc_order(s, orderInfo, &(primary->ellipse_sc))) + { + WLog_ERR(TAG, "ORDER_TYPE_ELLIPSE_SC - update_read_ellipse_sc_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "EllipseSC"); IFCALL(primary->EllipseSC, context, &primary->ellipse_sc); break; case ORDER_TYPE_ELLIPSE_CB: if (!update_read_ellipse_cb_order(s, orderInfo, &(primary->ellipse_cb))) + { + WLog_ERR(TAG, "ORDER_TYPE_ELLIPSE_CB - update_read_ellipse_cb_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "EllipseCB"); IFCALL(primary->EllipseCB, context, &primary->ellipse_cb); break; @@ -3336,7 +3429,10 @@ BOOL update_recv_secondary_order(rdpUpdate* update, wStream* s, BYTE flags) rdpSecondaryUpdate* secondary = update->secondary; if (Stream_GetRemainingLength(s) < 5) + { + WLog_ERR(TAG, "Stream_GetRemainingLength(s) < 5"); return FALSE; + } Stream_Read_UINT16(s, orderLength); /* orderLength (2 bytes) */ Stream_Read_UINT16(s, extraFlags); /* extraFlags (2 bytes) */ @@ -3355,42 +3451,60 @@ BOOL update_recv_secondary_order(rdpUpdate* update, wStream* s, BYTE flags) { case ORDER_TYPE_BITMAP_UNCOMPRESSED: if (!update_read_cache_bitmap_order(s, &(secondary->cache_bitmap_order), FALSE, extraFlags)) + { + WLog_ERR(TAG, "ORDER_TYPE_BITMAP_UNCOMPRESSED - update_read_cache_bitmap_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "CacheBitmapUncompressed"); IFCALL(secondary->CacheBitmap, context, &(secondary->cache_bitmap_order)); break; case ORDER_TYPE_CACHE_BITMAP_COMPRESSED: if (!update_read_cache_bitmap_order(s, &(secondary->cache_bitmap_order), TRUE, extraFlags)) + { + WLog_ERR(TAG, "ORDER_TYPE_CACHE_BITMAP_COMPRESSED - update_read_cache_bitmap_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "CacheBitmapCompressed"); IFCALL(secondary->CacheBitmap, context, &(secondary->cache_bitmap_order)); break; case ORDER_TYPE_BITMAP_UNCOMPRESSED_V2: if (!update_read_cache_bitmap_v2_order(s, &(secondary->cache_bitmap_v2_order), FALSE, extraFlags)) + { + WLog_ERR(TAG, "ORDER_TYPE_BITMAP_UNCOMPRESSED_V2 - update_read_cache_bitmap_v2_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "CacheBitmapUncompressedV2"); IFCALL(secondary->CacheBitmapV2, context, &(secondary->cache_bitmap_v2_order)); break; case ORDER_TYPE_BITMAP_COMPRESSED_V2: if (!update_read_cache_bitmap_v2_order(s, &(secondary->cache_bitmap_v2_order), TRUE, extraFlags)) + { + WLog_ERR(TAG, "ORDER_TYPE_BITMAP_COMPRESSED_V2 - update_read_cache_bitmap_v2_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "CacheBitmapCompressedV2"); IFCALL(secondary->CacheBitmapV2, context, &(secondary->cache_bitmap_v2_order)); break; case ORDER_TYPE_BITMAP_COMPRESSED_V3: if (!update_read_cache_bitmap_v3_order(s, &(secondary->cache_bitmap_v3_order), extraFlags)) + { + WLog_ERR(TAG, "ORDER_TYPE_BITMAP_COMPRESSED_V3 - update_read_cache_bitmap_v3_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "CacheBitmapCompressedV3"); IFCALL(secondary->CacheBitmapV3, context, &(secondary->cache_bitmap_v3_order)); break; case ORDER_TYPE_CACHE_COLOR_TABLE: if (!update_read_cache_color_table_order(s, &(secondary->cache_color_table_order), extraFlags)) + { + WLog_ERR(TAG, "ORDER_TYPE_CACHE_COLOR_TABLE - update_read_cache_color_table_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "CacheColorTable"); IFCALL(secondary->CacheColorTable, context, &(secondary->cache_color_table_order)); break; @@ -3399,14 +3513,20 @@ BOOL update_recv_secondary_order(rdpUpdate* update, wStream* s, BYTE flags) if (secondary->glyph_v2) { if (!update_read_cache_glyph_v2_order(s, &(secondary->cache_glyph_v2_order), extraFlags)) + { + WLog_ERR(TAG, "ORDER_TYPE_CACHE_GLYPH - update_read_cache_glyph_v2_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "CacheGlyphV2"); IFCALL(secondary->CacheGlyphV2, context, &(secondary->cache_glyph_v2_order)); } else { if (!update_read_cache_glyph_order(s, &(secondary->cache_glyph_order), extraFlags)) + { + WLog_ERR(TAG, "ORDER_TYPE_CACHE_GLYPH - update_read_cache_glyph_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "CacheGlyph"); IFCALL(secondary->CacheGlyph, context, &(secondary->cache_glyph_order)); } @@ -3414,7 +3534,10 @@ BOOL update_recv_secondary_order(rdpUpdate* update, wStream* s, BYTE flags) case ORDER_TYPE_CACHE_BRUSH: if (!update_read_cache_brush_order(s, &(secondary->cache_brush_order), extraFlags)) + { + WLog_ERR(TAG, "ORDER_TYPE_CACHE_BRUSH - update_read_cache_brush_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "CacheBrush"); IFCALL(secondary->CacheBrush, context, &(secondary->cache_brush_order)); break; @@ -3438,37 +3561,49 @@ BOOL update_recv_altsec_order(rdpUpdate* update, wStream* s, BYTE flags) #ifdef WITH_DEBUG_ORDERS if (orderType < ALTSEC_DRAWING_ORDER_COUNT) - WLog_DBG(TAG, "%s Alternate Secondary Drawing Order (0x%02X)", ALTSEC_DRAWING_ORDER_STRINGS[orderType], orderType); + WLog_DBG(TAG, "%s Alternate Secondary Drawing Order (0x%02X)", ALTSEC_DRAWING_ORDER_STRINGS[orderType], orderType); else - WLog_DBG(TAG, "Unknown Alternate Secondary Drawing Order: 0x%02X", orderType); + WLog_DBG(TAG, "Unknown Alternate Secondary Drawing Order: 0x%02X", orderType); #endif switch (orderType) { case ORDER_TYPE_CREATE_OFFSCREEN_BITMAP: if (!update_read_create_offscreen_bitmap_order(s, &(altsec->create_offscreen_bitmap))) + { + WLog_ERR(TAG, "ORDER_TYPE_CREATE_OFFSCREEN_BITMAP - update_read_create_offscreen_bitmap_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "CreateOffscreenBitmap"); IFCALL(altsec->CreateOffscreenBitmap, context, &(altsec->create_offscreen_bitmap)); break; case ORDER_TYPE_SWITCH_SURFACE: if (!update_read_switch_surface_order(s, &(altsec->switch_surface))) + { + WLog_ERR(TAG, "ORDER_TYPE_SWITCH_SURFACE - update_read_switch_surface_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "SwitchSurface"); IFCALL(altsec->SwitchSurface, context, &(altsec->switch_surface)); break; case ORDER_TYPE_CREATE_NINE_GRID_BITMAP: if (!update_read_create_nine_grid_bitmap_order(s, &(altsec->create_nine_grid_bitmap))) + { + WLog_ERR(TAG, "ORDER_TYPE_CREATE_NINE_GRID_BITMAP - update_read_create_nine_grid_bitmap_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "CreateNineGridBitmap"); IFCALL(altsec->CreateNineGridBitmap, context, &(altsec->create_nine_grid_bitmap)); break; case ORDER_TYPE_FRAME_MARKER: if (!update_read_frame_marker_order(s, &(altsec->frame_marker))) + { + WLog_ERR(TAG, "ORDER_TYPE_FRAME_MARKER - update_read_frame_marker_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "AltSecFrameMarker: action: %s (%d)", (!altsec->frame_marker.action) ? "Begin" : "End", altsec->frame_marker.action); IFCALL(altsec->FrameMarker, context, &(altsec->frame_marker)); @@ -3476,56 +3611,80 @@ BOOL update_recv_altsec_order(rdpUpdate* update, wStream* s, BYTE flags) case ORDER_TYPE_STREAM_BITMAP_FIRST: if (!update_read_stream_bitmap_first_order(s, &(altsec->stream_bitmap_first))) + { + WLog_ERR(TAG, "ORDER_TYPE_STREAM_BITMAP_FIRST - update_read_stream_bitmap_first_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "StreamBitmapFirst"); IFCALL(altsec->StreamBitmapFirst, context, &(altsec->stream_bitmap_first)); break; case ORDER_TYPE_STREAM_BITMAP_NEXT: if (!update_read_stream_bitmap_next_order(s, &(altsec->stream_bitmap_next))) + { + WLog_ERR(TAG, "ORDER_TYPE_STREAM_BITMAP_NEXT - update_read_stream_bitmap_next_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "StreamBitmapNext"); IFCALL(altsec->StreamBitmapNext, context, &(altsec->stream_bitmap_next)); break; case ORDER_TYPE_GDIPLUS_FIRST: if (!update_read_draw_gdiplus_first_order(s, &(altsec->draw_gdiplus_first))) + { + WLog_ERR(TAG, "ORDER_TYPE_GDIPLUS_FIRST - update_read_draw_gdiplus_first_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "DrawGdiPlusFirst"); IFCALL(altsec->DrawGdiPlusFirst, context, &(altsec->draw_gdiplus_first)); break; case ORDER_TYPE_GDIPLUS_NEXT: if (!update_read_draw_gdiplus_next_order(s, &(altsec->draw_gdiplus_next))) + { + WLog_ERR(TAG, "ORDER_TYPE_GDIPLUS_NEXT - update_read_draw_gdiplus_next_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "DrawGdiPlusNext"); IFCALL(altsec->DrawGdiPlusNext, context, &(altsec->draw_gdiplus_next)); break; case ORDER_TYPE_GDIPLUS_END: if (update_read_draw_gdiplus_end_order(s, &(altsec->draw_gdiplus_end))) + { + WLog_ERR(TAG, "ORDER_TYPE_GDIPLUS_END - update_read_draw_gdiplus_end_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "DrawGdiPlusEnd"); IFCALL(altsec->DrawGdiPlusEnd, context, &(altsec->draw_gdiplus_end)); break; case ORDER_TYPE_GDIPLUS_CACHE_FIRST: if (!update_read_draw_gdiplus_cache_first_order(s, &(altsec->draw_gdiplus_cache_first))) + { + WLog_ERR(TAG, "ORDER_TYPE_GDIPLUS_CACHE_FIRST - update_read_draw_gdiplus_cache_first_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "DrawGdiPlusCacheFirst"); IFCALL(altsec->DrawGdiPlusCacheFirst, context, &(altsec->draw_gdiplus_cache_first)); break; case ORDER_TYPE_GDIPLUS_CACHE_NEXT: if (!update_read_draw_gdiplus_cache_next_order(s, &(altsec->draw_gdiplus_cache_next))) + { + WLog_ERR(TAG, "ORDER_TYPE_GDIPLUS_CACHE_NEXT - update_read_draw_gdiplus_cache_next_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "DrawGdiPlusCacheNext"); IFCALL(altsec->DrawGdiPlusCacheNext, context, &(altsec->draw_gdiplus_cache_next)); break; case ORDER_TYPE_GDIPLUS_CACHE_END: if (!update_read_draw_gdiplus_cache_end_order(s, &(altsec->draw_gdiplus_cache_end))) + { + WLog_ERR(TAG, "ORDER_TYPE_GDIPLUS_CACHE_END - update_read_draw_gdiplus_cache_end_order() failed"); return FALSE; + } WLog_Print(update->log, WLOG_DEBUG, "DrawGdiPlusCacheEnd"); IFCALL(altsec->DrawGdiPlusCacheEnd, context, &(altsec->draw_gdiplus_cache_end)); break; @@ -3548,7 +3707,10 @@ BOOL update_recv_order(rdpUpdate* update, wStream* s) BYTE controlFlags; if (Stream_GetRemainingLength(s) < 1) + { + WLog_ERR(TAG, "Stream_GetRemainingLength(s) < 1"); return FALSE; + } Stream_Read_UINT8(s, controlFlags); /* controlFlags (1 byte) */ diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c index a88b1e856..f4c41ff97 100644 --- a/libfreerdp/core/peer.c +++ b/libfreerdp/core/peer.c @@ -331,7 +331,7 @@ static BOOL peer_recv_data_pdu(freerdp_peer* client, wStream* s) break; default: - WLog_ERR(TAG, "Data PDU type %d", type); + WLog_ERR(TAG, "Data PDU type %d", type); break; } @@ -352,7 +352,7 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s) if (!rdp_read_header(rdp, s, &length, &channelId)) { - WLog_ERR(TAG, "Incorrect RDP header."); + WLog_ERR(TAG, "Incorrect RDP header."); return -1; } @@ -368,7 +368,7 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s) { if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) { - WLog_ERR(TAG, "rdp_decrypt failed"); + WLog_ERR(TAG, "rdp_decrypt failed"); return -1; } } @@ -399,7 +399,7 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s) break; default: - WLog_ERR(TAG, "Client sent pduType %d", pduType); + WLog_ERR(TAG, "Client sent pduType %d", pduType); return -1; } } @@ -433,7 +433,7 @@ static int peer_recv_fastpath_pdu(freerdp_peer* client, wStream* s) if ((length == 0) || (length > Stream_GetRemainingLength(s))) { - WLog_ERR(TAG, "incorrect FastPath PDU header length %d", length); + WLog_ERR(TAG, "incorrect FastPath PDU header length %d", length); return -1; } @@ -463,7 +463,10 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra) { case CONNECTION_STATE_INITIAL: if (!rdp_server_accept_nego(rdp, s)) + { + WLog_ERR(TAG, "peer_recv_callback: CONNECTION_STATE_INITIAL - rdp_server_accept_nego() fail"); return -1; + } if (rdp->nego->SelectedProtocol & PROTOCOL_NLA) { @@ -481,29 +484,44 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra) case CONNECTION_STATE_NEGO: if (!rdp_server_accept_mcs_connect_initial(rdp, s)) + { + WLog_ERR(TAG, "peer_recv_callback: CONNECTION_STATE_NEGO - rdp_server_accept_mcs_connect_initial() fail"); return -1; + } break; case CONNECTION_STATE_MCS_CONNECT: if (!rdp_server_accept_mcs_erect_domain_request(rdp, s)) + { + WLog_ERR(TAG, "peer_recv_callback: CONNECTION_STATE_MCS_CONNECT - rdp_server_accept_mcs_erect_domain_request() fail"); return -1; + } break; case CONNECTION_STATE_MCS_ERECT_DOMAIN: if (!rdp_server_accept_mcs_attach_user_request(rdp, s)) + { + WLog_ERR(TAG, "peer_recv_callback: CONNECTION_STATE_MCS_ERECT_DOMAIN - rdp_server_accept_mcs_attach_user_request() fail"); return -1; + } break; case CONNECTION_STATE_MCS_ATTACH_USER: if (!rdp_server_accept_mcs_channel_join_request(rdp, s)) + { + WLog_ERR(TAG, "peer_recv_callback: CONNECTION_STATE_MCS_ATTACH_USER - rdp_server_accept_mcs_channel_join_request() fail"); return -1; + } break; case CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT: if (rdp->settings->UseRdpSecurityLayer) { if (!rdp_server_establish_keys(rdp, s)) + { + WLog_ERR(TAG, "peer_recv_callback: CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT - rdp_server_establish_keys() fail"); return -1; + } } rdp_server_transition_to_state(rdp, CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE); @@ -512,9 +530,11 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra) break; case CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE: - if (!rdp_recv_client_info(rdp, s)) + { + WLog_ERR(TAG, "peer_recv_callback: CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE - rdp_recv_client_info() fail"); return -1; + } rdp_server_transition_to_state(rdp, CONNECTION_STATE_LICENSING); return peer_recv_callback(transport, NULL, extra); @@ -522,9 +542,11 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra) break; case CONNECTION_STATE_LICENSING: - if (!license_send_valid_client_error_packet(rdp->license)) + { + WLog_ERR(TAG, "peer_recv_callback: CONNECTION_STATE_LICENSING - license_send_valid_client_error_packet() fail"); return FALSE; + } rdp_server_transition_to_state(rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE); return peer_recv_callback(transport, NULL, extra); @@ -538,14 +560,20 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra) IFCALL(client->Capabilities, client); if (!rdp_send_demand_active(rdp)) + { + WLog_ERR(TAG, "peer_recv_callback: CONNECTION_STATE_CAPABILITIES_EXCHANGE - rdp_send_demand_active() fail"); return -1; + } rdp->AwaitCapabilities = TRUE; if (s) { if (peer_recv_pdu(client, s) < 0) + { + WLog_ERR(TAG, "peer_recv_callback: CONNECTION_STATE_CAPABILITIES_EXCHANGE - peer_recv_pdu() fail"); return -1; + } } } else @@ -556,23 +584,32 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra) */ if (peer_recv_pdu(client, s) < 0) + { + WLog_ERR(TAG, "peer_recv_callback: CONNECTION_STATE_CAPABILITIES_EXCHANGE - peer_recv_pdu() fail"); return -1; + } } break; case CONNECTION_STATE_FINALIZATION: if (peer_recv_pdu(client, s) < 0) + { + WLog_ERR(TAG, "peer_recv_callback: CONNECTION_STATE_FINALIZATION - peer_recv_pdu() fail"); return -1; + } break; case CONNECTION_STATE_ACTIVE: if (peer_recv_pdu(client, s) < 0) + { + WLog_ERR(TAG, "peer_recv_callback: CONNECTION_STATE_ACTIVE - peer_recv_pdu() fail"); return -1; + } break; default: - WLog_ERR(TAG, "Invalid state %d", rdp->state); + WLog_ERR(TAG, "Invalid state %d", rdp->state); return -1; } diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index 74c4af9cb..fac827aab 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -768,7 +768,10 @@ int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) UINT16 compressedLength; if (!rdp_read_share_data_header(s, &length, &type, &shareId, &compressedType, &compressedLength)) + { + WLog_ERR(TAG, "rdp_read_share_data_header() failed"); return -1; + } cs = s; @@ -815,72 +818,114 @@ int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) { case DATA_PDU_TYPE_UPDATE: if (!update_recv(rdp->update, cs)) + { + WLog_ERR(TAG, "DATA_PDU_TYPE_UPDATE - update_recv() failed"); goto out_fail; + } break; case DATA_PDU_TYPE_CONTROL: if (!rdp_recv_server_control_pdu(rdp, cs)) + { + WLog_ERR(TAG, "DATA_PDU_TYPE_CONTROL - rdp_recv_server_control_pdu() failed"); goto out_fail; + } break; case DATA_PDU_TYPE_POINTER: if (!update_recv_pointer(rdp->update, cs)) + { + WLog_ERR(TAG, "DATA_PDU_TYPE_POINTER - update_recv_pointer() failed"); goto out_fail; + } break; case DATA_PDU_TYPE_SYNCHRONIZE: if (!rdp_recv_synchronize_pdu(rdp, cs)) + { + WLog_ERR(TAG, "DATA_PDU_TYPE_SYNCHRONIZE - rdp_recv_synchronize_pdu() failed"); goto out_fail; + } break; case DATA_PDU_TYPE_PLAY_SOUND: if (!update_recv_play_sound(rdp->update, cs)) + { + WLog_ERR(TAG, "DATA_PDU_TYPE_PLAY_SOUND - update_recv_play_sound() failed"); goto out_fail; + } break; case DATA_PDU_TYPE_SHUTDOWN_DENIED: if (!rdp_recv_server_shutdown_denied_pdu(rdp, cs)) + { + WLog_ERR(TAG, "DATA_PDU_TYPE_SHUTDOWN_DENIED - rdp_recv_server_shutdown_denied_pdu() failed"); goto out_fail; + } break; case DATA_PDU_TYPE_SAVE_SESSION_INFO: if (!rdp_recv_save_session_info(rdp, cs)) + { + WLog_ERR(TAG, "DATA_PDU_TYPE_SAVE_SESSION_INFO - rdp_recv_save_session_info() failed"); goto out_fail; + } break; case DATA_PDU_TYPE_FONT_MAP: if (!rdp_recv_font_map_pdu(rdp, cs)) + { + WLog_ERR(TAG, "DATA_PDU_TYPE_FONT_MAP - rdp_recv_font_map_pdu() failed"); goto out_fail; + } break; case DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS: if (!rdp_recv_server_set_keyboard_indicators_pdu(rdp, cs)) + { + WLog_ERR(TAG, "DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS - rdp_recv_server_set_keyboard_indicators_pdu() failed"); goto out_fail; + } break; case DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS: if (!rdp_recv_server_set_keyboard_ime_status_pdu(rdp, cs)) + { + WLog_ERR(TAG, "DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS - rdp_recv_server_set_keyboard_ime_status_pdu() failed"); goto out_fail; + } break; case DATA_PDU_TYPE_SET_ERROR_INFO: if (!rdp_recv_set_error_info_data_pdu(rdp, cs)) + { + WLog_ERR(TAG, "DATA_PDU_TYPE_SET_ERROR_INFO - rdp_recv_set_error_info_data_pdu() failed"); goto out_fail; + } break; case DATA_PDU_TYPE_ARC_STATUS: if (!rdp_recv_server_auto_reconnect_status_pdu(rdp, cs)) + { + WLog_ERR(TAG, "DATA_PDU_TYPE_ARC_STATUS - rdp_recv_server_auto_reconnect_status_pdu() failed"); goto out_fail; + } break; case DATA_PDU_TYPE_STATUS_INFO: if (!rdp_recv_server_status_info_pdu(rdp, cs)) + { + WLog_ERR(TAG, "DATA_PDU_TYPE_STATUS_INFO - rdp_recv_server_status_info_pdu() failed"); goto out_fail; + } break; case DATA_PDU_TYPE_MONITOR_LAYOUT: if (!rdp_recv_monitor_layout_pdu(rdp, cs)) + { + WLog_ERR(TAG, "DATA_PDU_TYPE_MONITOR_LAYOUT - rdp_recv_monitor_layout_pdu() failed"); goto out_fail; + } break; default: @@ -1087,7 +1132,10 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s) if (rdp->settings->UseRdpSecurityLayer) { if (!rdp_read_security_header(s, &securityFlags)) + { + WLog_ERR(TAG, "rdp_recv_tpkt_pdu: rdp_read_security_header() fail"); return -1; + } if (securityFlags & (SEC_ENCRYPT | SEC_REDIRECTION_PKT)) { @@ -1117,7 +1165,10 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s) nextPosition = Stream_GetPosition(s); if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource)) + { + WLog_ERR(TAG, "rdp_recv_tpkt_pdu: rdp_read_share_control_header() fail"); return -1; + } nextPosition += pduLength; @@ -1128,14 +1179,17 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s) case PDU_TYPE_DATA: if (rdp_recv_data_pdu(rdp, s) < 0) { - WLog_ERR(TAG, "rdp_recv_data_pdu failed"); + WLog_ERR(TAG, "rdp_recv_data_pdu() failed"); return -1; } break; case PDU_TYPE_DEACTIVATE_ALL: if (!rdp_recv_deactivate_all(rdp, s)) + { + WLog_ERR(TAG, "rdp_recv_tpkt_pdu: rdp_recv_deactivate_all() fail"); return -1; + } break; case PDU_TYPE_SERVER_REDIRECTION: @@ -1166,7 +1220,10 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s) else { if (!freerdp_channel_process(rdp->instance, s, channelId)) + { + WLog_ERR(TAG, "rdp_recv_tpkt_pdu: freerdp_channel_process() fail"); return -1; + } } return 0; @@ -1180,7 +1237,10 @@ static int rdp_recv_fastpath_pdu(rdpRdp* rdp, wStream* s) fastpath = rdp->fastpath; if (!fastpath_read_header_rdp(fastpath, s, &length)) + { + WLog_ERR(TAG, "rdp_recv_fastpath_pdu: fastpath_read_header_rdp() fail"); return -1; + } if ((length == 0) || (length > Stream_GetRemainingLength(s))) { @@ -1198,7 +1258,10 @@ static int rdp_recv_fastpath_pdu(rdpRdp* rdp, wStream* s) UINT16 flags = (fastpath->encryptionFlags & FASTPATH_OUTPUT_SECURE_CHECKSUM) ? SEC_SECURE_CHECKSUM : 0; if (!rdp_decrypt(rdp, s, length, flags)) + { + WLog_ERR(TAG, "rdp_recv_fastpath_pdu: rdp_decrypt() fail"); return -1; + } } return fastpath_recv_updates(rdp->fastpath, s); @@ -1233,7 +1296,10 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra) { case CONNECTION_STATE_NLA: if (nla_recv_pdu(rdp->nla, s) < 1) + { + WLog_ERR(TAG, "rdp_recv_callback: CONNECTION_STATE_NLA - nla_recv_pdu() fail"); return -1; + } if (rdp->nla->state == NLA_STATE_AUTH_INFO) { @@ -1243,7 +1309,10 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra) rdp->nla = NULL; if (!mcs_client_begin(rdp->mcs)) + { + WLog_ERR(TAG, "rdp_recv_callback: CONNECTION_STATE_NLA - mcs_client_begin() fail"); return -1; + } } break; @@ -1288,15 +1357,22 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra) case CONNECTION_STATE_MCS_CHANNEL_JOIN: if (!rdp_client_connect_mcs_channel_join_confirm(rdp, s)) + { + WLog_ERR(TAG, "rdp_recv_callback: CONNECTION_STATE_MCS_CHANNEL_JOIN - rdp_client_connect_mcs_channel_join_confirm() fail"); status = -1; + } break; case CONNECTION_STATE_LICENSING: status = rdp_client_connect_license(rdp, s); + if (status < 0) + WLog_DBG(TAG, "CONNECTION_STATE_LICENSING - rdp_client_connect_license() - %i", status); break; case CONNECTION_STATE_CAPABILITIES_EXCHANGE: status = rdp_client_connect_demand_active(rdp, s); + if (status < 0) + WLog_DBG(TAG, "CONNECTION_STATE_CAPABILITIES_EXCHANGE - rdp_client_connect_demand_active() - %i", status); break; case CONNECTION_STATE_FINALIZATION: @@ -1307,10 +1383,14 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra) rdp_client_transition_to_state(rdp, CONNECTION_STATE_ACTIVE); return 2; } + if (status < 0) + WLog_DBG(TAG, "CONNECTION_STATE_FINALIZATION - rdp_recv_pdu() - %i", status); break; case CONNECTION_STATE_ACTIVE: status = rdp_recv_pdu(rdp, s); + if (status < 0) + WLog_DBG(TAG, "CONNECTION_STATE_ACTIVE - rdp_recv_pdu() - %i", status); break; default: @@ -1356,7 +1436,10 @@ int rdp_check_fds(rdpRdp* rdp) status = tsg_check_event_handles(tsg); if (status < 0) + { + WLog_ERR(TAG, "rdp_check_fds: tsg_check_event_handles() - %i", status); return -1; + } if (tsg->state != TSG_STATE_PIPE_CREATED) return status; @@ -1368,6 +1451,8 @@ int rdp_check_fds(rdpRdp* rdp) { status = rdp_client_redirect(rdp); /* session redirection */ } + if (status < 0) + WLog_DBG(TAG, "transport_check_fds() - %i", status); return status; } diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 9097a4477..808264091 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -768,6 +768,9 @@ int transport_check_fds(rdpTransport* transport) */ if ((status = transport_read_pdu(transport, transport->ReceiveBuffer)) <= 0) { + if (status < 0) + WLog_DBG(TAG, "transport_check_fds: transport_read_pdu() - %i", status); + return status; } @@ -790,7 +793,10 @@ int transport_check_fds(rdpTransport* transport) } if (recv_status < 0) + { + WLog_ERR(TAG, "transport_check_fds: transport->ReceiveCallback() - %i", recv_status); return -1; + } } return 0; @@ -921,6 +927,7 @@ static void* transport_client_thread(void* arg) if (transport->layer == TRANSPORT_LAYER_CLOSED) { + WLog_DBG(TAG, "TRANSPORT_LAYER_CLOSED"); rdp_set_error_info(rdp, ERRINFO_PEER_DISCONNECTED); break; } @@ -934,6 +941,7 @@ static void* transport_client_thread(void* arg) { if (!freerdp_check_event_handles(context)) { + WLog_ERR(TAG, "freerdp_check_event_handles()"); rdp_set_error_info(rdp, ERRINFO_PEER_DISCONNECTED); break; } diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c index 21442cd10..90e183e1c 100644 --- a/libfreerdp/core/update.c +++ b/libfreerdp/core/update.c @@ -52,7 +52,10 @@ BOOL update_recv_orders(rdpUpdate* update, wStream* s) UINT16 numberOrders; if (Stream_GetRemainingLength(s) < 6) + { + WLog_ERR(TAG, "Stream_GetRemainingLength(s) < 6"); return FALSE; + } Stream_Seek_UINT16(s); /* pad2OctetsA (2 bytes) */ Stream_Read_UINT16(s, numberOrders); /* numberOrders (2 bytes) */ @@ -61,7 +64,10 @@ BOOL update_recv_orders(rdpUpdate* update, wStream* s) while (numberOrders > 0) { if (!update_recv_order(update, s)) + { + WLog_ERR(TAG, "update_recv_order() failed"); return FALSE; + } numberOrders--; } @@ -488,7 +494,10 @@ BOOL update_recv(rdpUpdate* update, wStream* s) rdpContext* context = update->context; if (Stream_GetRemainingLength(s) < 2) + { + WLog_ERR(TAG, "Stream_GetRemainingLength(s) < 2"); return FALSE; + } Stream_Read_UINT16(s, updateType); /* updateType (2 bytes) */ //WLog_DBG(TAG, "%s Update Data PDU", UPDATE_TYPE_STRINGS[updateType]); @@ -501,19 +510,26 @@ BOOL update_recv(rdpUpdate* update, wStream* s) if (!update_recv_orders(update, s)) { /* XXX: Do we have to call EndPaint? */ + WLog_ERR(TAG, "UPDATE_TYPE_ORDERS - update_recv_orders() failed"); return FALSE; } break; case UPDATE_TYPE_BITMAP: if (!update_read_bitmap_update(update, s, &update->bitmap_update)) + { + WLog_ERR(TAG, "UPDATE_TYPE_BITMAP - update_read_bitmap_update() failed"); return FALSE; + } IFCALL(update->BitmapUpdate, context, &update->bitmap_update); break; case UPDATE_TYPE_PALETTE: if (!update_read_palette(update, s, &update->palette_update)) + { + WLog_ERR(TAG, "UPDATE_TYPE_PALETTE - update_read_palette() failed"); return FALSE; + } IFCALL(update->Palette, context, &update->palette_update); break;