From 68e1ca324fecb522c649244fbfb2168ca1e32b9d Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Mon, 13 Sep 2021 22:31:48 +0200 Subject: [PATCH] New upstream version 2.4.0+dfsg1 --- CMakeLists.txt | 14 +- ChangeLog | 53 ++ channels/audin/client/mac/audin_mac.m | 55 +- channels/audin/client/winmm/audin_winmm.c | 174 ++++--- channels/geometry/client/CMakeLists.txt | 5 +- channels/printer/client/cups/printer_cups.c | 3 +- channels/printer/client/printer_main.c | 19 +- channels/rdpdr/client/rdpdr_main.c | 5 +- channels/rdpgfx/client/rdpgfx_main.c | 13 + channels/rdpsnd/client/mac/rdpsnd_mac.m | 2 +- channels/rdpsnd/server/rdpsnd_main.c | 2 +- channels/smartcard/client/smartcard_main.c | 25 +- channels/smartcard/client/smartcard_pack.c | 26 +- .../urbdrc/client/libusb/libusb_udevman.c | 2 +- channels/video/client/video_main.c | 4 +- client/Wayland/wlf_pointer.c | 4 +- client/X11/cli/xfreerdp.c | 4 +- client/X11/xf_cliprdr.c | 11 +- client/X11/xf_event.c | 31 ++ client/X11/xf_event.h | 1 + client/X11/xf_gdi.c | 4 +- client/X11/xf_gfx.c | 4 +- client/X11/xf_graphics.c | 23 +- client/X11/xf_keyboard.c | 2 +- client/X11/xf_rail.c | 4 +- client/common/CMakeLists.txt | 8 +- client/common/cmdline.c | 78 ++- client/common/cmdline.h | 8 +- client/common/compatibility.h | 10 +- client/common/file.c | 6 +- client/common/test/TestClientRdpFile.c | 6 +- cmake/ConfigOptions.cmake | 14 +- include/freerdp/channels/rdpei.h | 2 + include/freerdp/client.h | 18 +- include/freerdp/client/rdpsnd.h | 2 + include/freerdp/codec/nsc.h | 3 + include/freerdp/codec/progressive.h | 5 +- include/freerdp/codec/rfx.h | 2 + include/freerdp/crypto/crypto.h | 8 +- include/freerdp/error.h | 27 + include/freerdp/freerdp.h | 24 +- include/freerdp/gdi/gdi.h | 4 +- include/freerdp/rail.h | 8 + include/freerdp/server/rdpei.h | 2 + include/freerdp/settings.h | 8 +- libfreerdp/codec/clear.c | 4 +- libfreerdp/codec/color.c | 6 +- libfreerdp/codec/h264.c | 6 +- libfreerdp/codec/h264_ffmpeg.c | 3 + libfreerdp/codec/nsc_encode.c | 4 +- libfreerdp/codec/nsc_sse2.c | 4 +- libfreerdp/codec/planar.c | 29 +- libfreerdp/codec/progressive.c | 109 +++- .../codec/test/TestFreeRDPCodecPlanar.c | 116 +++++ .../codec/test/TestFreeRDPCodecProgressive.c | 5 +- libfreerdp/common/assistance.c | 3 +- libfreerdp/common/settings_getters.c | 7 + libfreerdp/common/settings_str.c | 1 + libfreerdp/core/certificate.c | 3 +- libfreerdp/core/errinfo.c | 4 + libfreerdp/core/freerdp.c | 62 +++ libfreerdp/core/gateway/rdg.c | 37 +- libfreerdp/core/gcc.c | 8 +- libfreerdp/core/license.c | 45 +- libfreerdp/core/test/TestConnect.c | 2 +- .../core/test/settings_property_lists.h | 1 + libfreerdp/crypto/crypto.c | 8 +- libfreerdp/crypto/test/CMakeLists.txt | 3 +- libfreerdp/crypto/test/TestKnownHosts.c | 6 +- libfreerdp/crypto/test/Test_x509_cert_info.c | 7 +- libfreerdp/crypto/tls.c | 4 + libfreerdp/gdi/bitmap.c | 3 +- libfreerdp/gdi/gdi.c | 2 +- libfreerdp/gdi/gfx.c | 41 +- libfreerdp/gdi/graphics.c | 2 +- libfreerdp/gdi/shape.c | 2 +- libfreerdp/gdi/video.c | 2 +- libfreerdp/primitives/prim_copy.c | 4 +- libfreerdp/primitives/primitives.c | 2 +- libfreerdp/utils/pcap.c | 3 +- rdtk/librdtk/rdtk_font.c | 7 +- scripts/android-build-32.conf | 2 +- scripts/android-build-64.conf | 2 +- scripts/android-build.conf | 2 +- server/Sample/sfreerdp.c | 3 +- server/shadow/X11/x11_shadow.c | 2 +- server/shadow/shadow_server.c | 19 +- uwac/libuwac/uwac-window.c | 9 +- winpr/CMakeLists.txt | 2 +- winpr/include/winpr/file.h | 2 + winpr/include/winpr/path.h | 6 + winpr/include/winpr/shell.h | 5 + winpr/include/winpr/synch.h | 4 +- winpr/include/winpr/thread.h | 3 + winpr/include/winpr/wlog.h | 2 + winpr/libwinpr/clipboard/posix.c | 23 +- winpr/libwinpr/error/error.c | 2 +- winpr/libwinpr/file/file.c | 31 +- winpr/libwinpr/file/test/TestFileCreateFile.c | 6 +- winpr/libwinpr/io/device.c | 4 +- winpr/libwinpr/path/shell.c | 111 +++- winpr/libwinpr/path/test/TestPathMakePath.c | 8 +- winpr/libwinpr/pipe/pipe.c | 8 +- winpr/libwinpr/registry/registry_reg.c | 7 +- winpr/libwinpr/sspi/NTLM/ntlm_message.c | 2 +- winpr/libwinpr/sspi/test/TestSchannel.c | 4 +- winpr/libwinpr/synch/CMakeLists.txt | 2 + winpr/libwinpr/synch/event.c | 197 +++---- winpr/libwinpr/synch/event.h | 56 ++ winpr/libwinpr/synch/pollset.c | 223 ++++++++ winpr/libwinpr/synch/pollset.h | 73 +++ winpr/libwinpr/synch/sleep.c | 66 ++- winpr/libwinpr/synch/synch.h | 38 +- winpr/libwinpr/synch/test/CMakeLists.txt | 3 +- winpr/libwinpr/synch/test/TestSynchAPC.c | 174 +++++++ .../synch/test/TestSynchMultipleThreads.c | 208 +++++--- .../synch/test/TestSynchWaitableTimerAPC.c | 31 +- winpr/libwinpr/synch/timer.c | 357 +++++++------ winpr/libwinpr/synch/wait.c | 482 ++++++++---------- winpr/libwinpr/thread/CMakeLists.txt | 2 + winpr/libwinpr/thread/apc.c | 244 +++++++++ winpr/libwinpr/thread/apc.h | 85 +++ winpr/libwinpr/thread/process.c | 2 +- winpr/libwinpr/thread/thread.c | 237 +++++---- winpr/libwinpr/thread/thread.h | 9 +- winpr/libwinpr/timezone/timezone.c | 5 +- winpr/libwinpr/utils/image.c | 6 +- winpr/libwinpr/utils/ini.c | 5 +- winpr/libwinpr/utils/lodepng/lodepng.c | 33 +- winpr/libwinpr/utils/print.c | 11 +- winpr/libwinpr/utils/sam.c | 186 +++---- winpr/libwinpr/utils/test/TestImage.c | 5 +- winpr/libwinpr/utils/test/TestWLog.c | 2 +- winpr/libwinpr/utils/wlog/BinaryAppender.c | 6 +- winpr/libwinpr/utils/wlog/DataMessage.c | 4 +- winpr/libwinpr/utils/wlog/FileAppender.c | 6 +- winpr/libwinpr/utils/wlog/Message.c | 4 +- winpr/libwinpr/utils/wlog/PacketMessage.c | 3 +- winpr/libwinpr/utils/wlog/wlog.c | 47 +- winpr/tools/makecert/makecert.c | 7 +- 140 files changed, 3096 insertions(+), 1280 deletions(-) create mode 100644 winpr/libwinpr/synch/event.h create mode 100644 winpr/libwinpr/synch/pollset.c create mode 100644 winpr/libwinpr/synch/pollset.h create mode 100644 winpr/libwinpr/synch/test/TestSynchAPC.c create mode 100644 winpr/libwinpr/thread/apc.c create mode 100644 winpr/libwinpr/thread/apc.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c22db2d..918d211 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,6 +74,10 @@ include(InstallFreeRDPMan) include(GetGitRevisionDescription) include(SetFreeRDPCMakeInstallDir) +if (DEFINE_NO_DEPRECATED) + add_definitions(-DDEFINE_NO_DEPRECATED) +endif() + # Soname versioning set(BUILD_NUMBER 0) if ($ENV{BUILD_NUMBER}) @@ -81,7 +85,7 @@ if ($ENV{BUILD_NUMBER}) endif() set(WITH_LIBRARY_VERSIONING "ON") -set(RAW_VERSION_STRING "2.3.0") +set(RAW_VERSION_STRING "2.4.0") if(EXISTS "${CMAKE_SOURCE_DIR}/.source_tag") file(READ ${CMAKE_SOURCE_DIR}/.source_tag RAW_VERSION_STRING) elseif(USE_VERSION_FROM_GIT_TAG) @@ -705,7 +709,7 @@ set(FFMPEG_FEATURE_DESCRIPTION "multimedia redirection, audio and video playback set(VAAPI_FEATURE_TYPE "OPTIONAL") set(VAAPI_FEATURE_PURPOSE "multimedia") -set(VAAPI_FEATURE_DESCRIPTION "VA-API hardware acceleration for video playback") +set(VAAPI_FEATURE_DESCRIPTION "[experimental] VA-API hardware acceleration for video playback") set(IPP_FEATURE_TYPE "OPTIONAL") set(IPP_FEATURE_PURPOSE "performance") @@ -725,7 +729,7 @@ set(OPENH264_FEATURE_DESCRIPTION "use OpenH264 library") set(OPENCL_FEATURE_TYPE "OPTIONAL") set(OPENCL_FEATURE_PURPOSE "codec") -set(OPENCL_FEATURE_DESCRIPTION "use OpenCL library") +set(OPENCL_FEATURE_DESCRIPTION "[experimental] use OpenCL library") set(GSM_FEATURE_TYPE "OPTIONAL") set(GSM_FEATURE_PURPOSE "codec") @@ -741,7 +745,7 @@ set(FAAD2_FEATURE_DESCRIPTION "FAAD2 AAC audio codec library") set(FAAC_FEATURE_TYPE "OPTIONAL") set(FAAC_FEATURE_PURPOSE "codec") -set(FAAC_FEATURE_DESCRIPTION "FAAC AAC audio codec library") +set(FAAC_FEATURE_DESCRIPTION "[experimental] FAAC AAC audio codec library") set(SOXR_FEATURE_TYPE "OPTIONAL") set(SOXR_FEATURE_PURPOSE "codec") @@ -749,7 +753,7 @@ set(SOXR_FEATURE_DESCRIPTION "SOX audio resample library") set(GSSAPI_FEATURE_TYPE "OPTIONAL") set(GSSAPI_FEATURE_PURPOSE "auth") -set(GSSAPI_FEATURE_DESCRIPTION "add kerberos support") +set(GSSAPI_FEATURE_DESCRIPTION "[experimental] add kerberos support") if(WIN32) set(X11_FEATURE_TYPE "DISABLED") diff --git a/ChangeLog b/ChangeLog index 27aa9a2..1389c23 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,56 @@ +# 2021-07-27 Version 2.4.0 + +Noteworthy changes: +* Backported multithreadded progressive decoder (#7036) +* Backported clipboard fixes (#6924) +* Fixed remote file read (#7185) + +Fixed issues: +* #6938: RAILS clipboard remote -> local +* #6985: Support newer FFMPEG builds +* #6989: Use OpenSSL default certificate store settings +* #7073: Planar alignment fixes + +# 2021-03-15 Version 2.3.2 + +For a complete and detailed change log since the last release run: +git log 2.3.2..2.4.0 + +Noteworthy changes: +* Fixed autoreconnect printer backend loading +* Fixed compilation on older mac os versions < 10.14 +* Fixed mouse pointer move with smart-sizing +* Added command line option to disable websocket gateway support +* Fixed drive hotplugging issues with windows +* Fixed smartcard issues on mac + +Fixed issues: +* #6900: Transparency issues with aFreeRDP +* #6848: Invalid format string in smartcard trace +* #6846: Fixed static builds +* #6888: Crash due to missing bounds checks +* #6882: Use default sound devoce on mac + +For a complete and detailed change log since the last release run: +git log 2.3.1..2.3.2 + +# 2021-03-01 Version 2.3.1 + +Noteworthy changes: +* This is a compatibility bugfix release readding some (deprecated) + symbols/defines +* Also add some more EXPERIMENTAL warnings to CMake flags as some were not + clear enough. +* Fixed a memory leak in xfreerdp (mouse pointer updates) +* No longer activating some compile time debug options with -DWITH_DEBUG_ALL=ON + which might leak sensitive information. +* Added -DDEFINE_NO_DEPRECATED for developers to detect use of deprecated + symbols + +For a complete and detailed change log since the last release run: +git log 2.3.0..2.3.1 + + # 2021-02-24 Version 2.3.0 Important notes: diff --git a/channels/audin/client/mac/audin_mac.m b/channels/audin/client/mac/audin_mac.m index a9742b3..ecf3c8c 100644 --- a/channels/audin/client/mac/audin_mac.m +++ b/channels/audin/client/mac/audin_mac.m @@ -420,33 +420,38 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn goto error_out; } - AVAuthorizationStatus status = - [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio]; - switch (status) +#if defined(MAC_OS_X_VERSION_10_14) + if (@available(macOS 10.14, *)) { - case AVAuthorizationStatusAuthorized: - mac->isAuthorized = TRUE; - break; - case AVAuthorizationStatusNotDetermined: - [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio - completionHandler:^(BOOL granted) { - if (granted == YES) - { - mac->isAuthorized = TRUE; - } - else - WLog_WARN(TAG, "Microphone access denied by user"); - }]; - break; - case AVAuthorizationStatusRestricted: - WLog_WARN(TAG, "Microphone access restricted by policy"); - break; - case AVAuthorizationStatusDenied: - WLog_WARN(TAG, "Microphone access denied by policy"); - break; - default: - break; + AVAuthorizationStatus status = + [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio]; + switch (status) + { + case AVAuthorizationStatusAuthorized: + mac->isAuthorized = TRUE; + break; + case AVAuthorizationStatusNotDetermined: + [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio + completionHandler:^(BOOL granted) { + if (granted == YES) + { + mac->isAuthorized = TRUE; + } + else + WLog_WARN(TAG, "Microphone access denied by user"); + }]; + break; + case AVAuthorizationStatusRestricted: + WLog_WARN(TAG, "Microphone access restricted by policy"); + break; + case AVAuthorizationStatusDenied: + WLog_WARN(TAG, "Microphone access denied by policy"); + break; + default: + break; + } } +#endif return CHANNEL_RC_OK; error_out: diff --git a/channels/audin/client/winmm/audin_winmm.c b/channels/audin/client/winmm/audin_winmm.c index bab9361..92a7785 100644 --- a/channels/audin/client/winmm/audin_winmm.c +++ b/channels/audin/client/winmm/audin_winmm.c @@ -110,27 +110,74 @@ static void CALLBACK waveInProc(HWAVEIN hWaveIn, UINT uMsg, DWORD_PTR dwInstance setChannelError(winmm->rdpcontext, error, "waveInProc reported an error"); } +static BOOL log_mmresult(AudinWinmmDevice* winmm, const char* what, MMRESULT result) +{ + if (result != MMSYSERR_NOERROR) + { + CHAR buffer[8192] = { 0 }; + CHAR msg[8192] = { 0 }; + CHAR cmsg[8192] = { 0 }; + waveInGetErrorTextA(result, buffer, sizeof(buffer)); + + _snprintf(msg, sizeof(msg) - 1, "%s failed. %" PRIu32 " [%s]", what, result, buffer); + _snprintf(cmsg, sizeof(cmsg) - 1, "audin_winmm_thread_func reported an error '%s'", msg); + WLog_Print(winmm->log, WLOG_DEBUG, "%s", msg); + if (winmm->rdpcontext) + setChannelError(winmm->rdpcontext, ERROR_INTERNAL_ERROR, cmsg); + return FALSE; + } + return TRUE; +} + +static BOOL test_format_supported(const PWAVEFORMATEX pwfx) +{ + MMRESULT rc; + WAVEINCAPSA caps = { 0 }; + + rc = waveInGetDevCapsA(WAVE_MAPPER, &caps, sizeof(caps)); + if (rc != MMSYSERR_NOERROR) + return FALSE; + + switch (pwfx->nChannels) + { + case 1: + if ((caps.dwFormats & + (WAVE_FORMAT_1M08 | WAVE_FORMAT_2M08 | WAVE_FORMAT_4M08 | WAVE_FORMAT_96M08 | + WAVE_FORMAT_1M16 | WAVE_FORMAT_2M16 | WAVE_FORMAT_4M16 | WAVE_FORMAT_96M16)) == 0) + return FALSE; + break; + case 2: + if ((caps.dwFormats & + (WAVE_FORMAT_1S08 | WAVE_FORMAT_2S08 | WAVE_FORMAT_4S08 | WAVE_FORMAT_96S08 | + WAVE_FORMAT_1S16 | WAVE_FORMAT_2S16 | WAVE_FORMAT_4S16 | WAVE_FORMAT_96S16)) == 0) + return FALSE; + break; + default: + return FALSE; + } + + rc = waveInOpen(NULL, WAVE_MAPPER, pwfx, 0, 0, + WAVE_FORMAT_QUERY | WAVE_MAPPED_DEFAULT_COMMUNICATION_DEVICE); + return (rc == MMSYSERR_NOERROR); +} + static DWORD WINAPI audin_winmm_thread_func(LPVOID arg) { AudinWinmmDevice* winmm = (AudinWinmmDevice*)arg; char* buffer; int size, i; - WAVEHDR waveHdr[4]; + WAVEHDR waveHdr[4] = { 0 }; DWORD status; MMRESULT rc; if (!winmm->hWaveIn) { - if (MMSYSERR_NOERROR != waveInOpen(&winmm->hWaveIn, WAVE_MAPPER, winmm->pwfx_cur, - (DWORD_PTR)waveInProc, (DWORD_PTR)winmm, - CALLBACK_FUNCTION)) - { - if (winmm->rdpcontext) - setChannelError(winmm->rdpcontext, ERROR_INTERNAL_ERROR, - "audin_winmm_thread_func reported an error"); - + MMRESULT rc; + rc = waveInOpen(&winmm->hWaveIn, WAVE_MAPPER, winmm->pwfx_cur, (DWORD_PTR)waveInProc, + (DWORD_PTR)winmm, + CALLBACK_FUNCTION | WAVE_MAPPED_DEFAULT_COMMUNICATION_DEVICE); + if (!log_mmresult(winmm, "waveInOpen", rc)) return ERROR_INTERNAL_ERROR; - } } size = @@ -150,36 +197,22 @@ static DWORD WINAPI audin_winmm_thread_func(LPVOID arg) waveHdr[i].lpData = buffer; rc = waveInPrepareHeader(winmm->hWaveIn, &waveHdr[i], sizeof(waveHdr[i])); - if (MMSYSERR_NOERROR != rc) + if (!log_mmresult(winmm, "waveInPrepareHeader", rc)) { - WLog_Print(winmm->log, WLOG_DEBUG, "waveInPrepareHeader failed. %" PRIu32 "", rc); - if (winmm->rdpcontext) - setChannelError(winmm->rdpcontext, ERROR_INTERNAL_ERROR, - "audin_winmm_thread_func reported an error"); } rc = waveInAddBuffer(winmm->hWaveIn, &waveHdr[i], sizeof(waveHdr[i])); - if (MMSYSERR_NOERROR != rc) + if (!log_mmresult(winmm, "waveInAddBuffer", rc)) { - WLog_Print(winmm->log, WLOG_DEBUG, "waveInAddBuffer failed. %" PRIu32 "", rc); - - if (winmm->rdpcontext) - setChannelError(winmm->rdpcontext, ERROR_INTERNAL_ERROR, - "audin_winmm_thread_func reported an error"); } } rc = waveInStart(winmm->hWaveIn); - if (MMSYSERR_NOERROR != rc) + if (!log_mmresult(winmm, "waveInStart", rc)) { - WLog_Print(winmm->log, WLOG_DEBUG, "waveInStart failed. %" PRIu32 "", rc); - - if (winmm->rdpcontext) - setChannelError(winmm->rdpcontext, ERROR_INTERNAL_ERROR, - "audin_winmm_thread_func reported an error"); } status = WaitForSingleObject(winmm->stopEvent, INFINITE); @@ -195,26 +228,17 @@ static DWORD WINAPI audin_winmm_thread_func(LPVOID arg) rc = waveInReset(winmm->hWaveIn); - if (MMSYSERR_NOERROR != rc) + if (!log_mmresult(winmm, "waveInReset", rc)) { - WLog_Print(winmm->log, WLOG_DEBUG, "waveInReset failed. %" PRIu32 "", rc); - - if (winmm->rdpcontext) - setChannelError(winmm->rdpcontext, ERROR_INTERNAL_ERROR, - "audin_winmm_thread_func reported an error"); } for (i = 0; i < 4; i++) { rc = waveInUnprepareHeader(winmm->hWaveIn, &waveHdr[i], sizeof(waveHdr[i])); - if (MMSYSERR_NOERROR != rc) + if (!log_mmresult(winmm, "waveInUnprepareHeader", rc)) { - WLog_Print(winmm->log, WLOG_DEBUG, "waveInUnprepareHeader failed. %" PRIu32 "", rc); - if (winmm->rdpcontext) - setChannelError(winmm->rdpcontext, ERROR_INTERNAL_ERROR, - "audin_winmm_thread_func reported an error"); } free(waveHdr[i].lpData); @@ -222,13 +246,8 @@ static DWORD WINAPI audin_winmm_thread_func(LPVOID arg) rc = waveInClose(winmm->hWaveIn); - if (MMSYSERR_NOERROR != rc) + if (!log_mmresult(winmm, "waveInClose", rc)) { - WLog_Print(winmm->log, WLOG_DEBUG, "waveInClose failed. %" PRIu32 "", rc); - - if (winmm->rdpcontext) - setChannelError(winmm->rdpcontext, ERROR_INTERNAL_ERROR, - "audin_winmm_thread_func reported an error"); } winmm->hWaveIn = NULL; @@ -311,16 +330,30 @@ static UINT audin_winmm_set_format(IAudinDevice* device, const AUDIO_FORMAT* for for (i = 0; i < winmm->cFormats; i++) { - if (winmm->ppwfx[i]->wFormatTag == format->wFormatTag && - winmm->ppwfx[i]->nChannels == format->nChannels && - winmm->ppwfx[i]->wBitsPerSample == format->wBitsPerSample) + const PWAVEFORMATEX ppwfx = winmm->ppwfx[i]; + if ((ppwfx->wFormatTag == format->wFormatTag) && (ppwfx->nChannels == format->nChannels) && + (ppwfx->wBitsPerSample == format->wBitsPerSample) && + (ppwfx->nSamplesPerSec == format->nSamplesPerSec)) { - winmm->pwfx_cur = winmm->ppwfx[i]; - break; + /* BUG: Many devices report to support stereo recording but fail here. + * Ensure we always use mono. */ + if (ppwfx->nChannels > 1) + { + ppwfx->nChannels = 1; + } + + if (ppwfx->nBlockAlign != 2) + { + ppwfx->nBlockAlign = 2; + } + if (!test_format_supported(ppwfx)) + return ERROR_INVALID_PARAMETER; + winmm->pwfx_cur = ppwfx; + return CHANNEL_RC_OK; } } - return CHANNEL_RC_OK; + return ERROR_INVALID_PARAMETER; } static BOOL audin_winmm_format_supported(IAudinDevice* device, const AUDIO_FORMAT* format) @@ -332,6 +365,9 @@ static BOOL audin_winmm_format_supported(IAudinDevice* device, const AUDIO_FORMA if (!winmm || !format) return FALSE; + if (format->wFormatTag != WAVE_FORMAT_PCM) + return FALSE; + pwfx = (PWAVEFORMATEX)malloc(sizeof(WAVEFORMATEX) + format->cbSize); if (!pwfx) @@ -346,29 +382,27 @@ static BOOL audin_winmm_format_supported(IAudinDevice* device, const AUDIO_FORMA data = (BYTE*)pwfx + sizeof(WAVEFORMATEX); memcpy(data, format->data, format->cbSize); - if (pwfx->wFormatTag == WAVE_FORMAT_PCM) + pwfx->nAvgBytesPerSec = pwfx->nSamplesPerSec * pwfx->nBlockAlign; + + if (!test_format_supported(pwfx)) + goto fail; + + if (winmm->cFormats >= winmm->ppwfx_size) { - pwfx->nAvgBytesPerSec = pwfx->nSamplesPerSec * pwfx->nBlockAlign; + PWAVEFORMATEX* tmp_ppwfx; + tmp_ppwfx = realloc(winmm->ppwfx, sizeof(PWAVEFORMATEX) * winmm->ppwfx_size * 2); - if (MMSYSERR_NOERROR == waveInOpen(NULL, WAVE_MAPPER, pwfx, 0, 0, WAVE_FORMAT_QUERY)) - { - if (winmm->cFormats >= winmm->ppwfx_size) - { - PWAVEFORMATEX* tmp_ppwfx; - tmp_ppwfx = realloc(winmm->ppwfx, sizeof(PWAVEFORMATEX) * winmm->ppwfx_size * 2); + if (!tmp_ppwfx) + goto fail; - if (!tmp_ppwfx) - return FALSE; - - winmm->ppwfx_size *= 2; - winmm->ppwfx = tmp_ppwfx; - } - - winmm->ppwfx[winmm->cFormats++] = pwfx; - return TRUE; - } + winmm->ppwfx_size *= 2; + winmm->ppwfx = tmp_ppwfx; } + winmm->ppwfx[winmm->cFormats++] = pwfx; + return TRUE; + +fail: free(pwfx); return FALSE; } @@ -507,7 +541,7 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn } winmm->ppwfx_size = 10; - winmm->ppwfx = malloc(sizeof(PWAVEFORMATEX) * winmm->ppwfx_size); + winmm->ppwfx = calloc(winmm->ppwfx_size, sizeof(PWAVEFORMATEX)); if (!winmm->ppwfx) { @@ -516,7 +550,7 @@ UINT freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEn goto error_out; } - if ((error = pEntryPoints->pRegisterAudinDevice(pEntryPoints->plugin, (IAudinDevice*)winmm))) + if ((error = pEntryPoints->pRegisterAudinDevice(pEntryPoints->plugin, &winmm->iface))) { WLog_Print(winmm->log, WLOG_ERROR, "RegisterAudinDevice failed with error %" PRIu32 "!", error); diff --git a/channels/geometry/client/CMakeLists.txt b/channels/geometry/client/CMakeLists.txt index ea28bff..ac9fdc4 100644 --- a/channels/geometry/client/CMakeLists.txt +++ b/channels/geometry/client/CMakeLists.txt @@ -25,9 +25,10 @@ include_directories(..) add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "DVCPluginEntry") - - set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} winpr) +if (NOT BUILTIN_CHANNELS OR NOT BUILD_SHARED_LIBS) + set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-client) +endif() target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) diff --git a/channels/printer/client/cups/printer_cups.c b/channels/printer/client/cups/printer_cups.c index 56cbace..baa46e5 100644 --- a/channels/printer/client/cups/printer_cups.c +++ b/channels/printer/client/cups/printer_cups.c @@ -33,6 +33,7 @@ #include #include +#include #include #include @@ -92,7 +93,7 @@ static UINT printer_cups_write_printjob(rdpPrintJob* printjob, const BYTE* data, { FILE* fp; - fp = fopen((const char*)cups_printjob->printjob_object, "a+b"); + fp = winpr_fopen((const char*)cups_printjob->printjob_object, "a+b"); if (!fp) return ERROR_INTERNAL_ERROR; diff --git a/channels/printer/client/printer_main.c b/channels/printer/client/printer_main.c index dbcc07d..8019968 100644 --- a/channels/printer/client/printer_main.c +++ b/channels/printer/client/printer_main.c @@ -82,9 +82,9 @@ static char* get_printer_config_path(const rdpSettings* settings, const WCHAR* n char* bname = crypto_base64_encode((const BYTE*)name, (int)length); char* config = GetCombinedPath(dir, bname); - if (config && !PathFileExistsA(config)) + if (config && !winpr_PathFileExists(config)) { - if (!PathMakePathA(config, NULL)) + if (!winpr_PathMakePath(config, NULL)) { free(config); config = NULL; @@ -145,7 +145,7 @@ static BOOL printer_config_valid(const char* path) if (!path) return FALSE; - if (!PathFileExistsA(path)) + if (!winpr_PathFileExists(path)) return FALSE; return TRUE; @@ -261,7 +261,7 @@ static BOOL printer_remove_config(const rdpSettings* settings, const WCHAR* name if (!printer_config_valid(path)) goto fail; - rc = RemoveDirectoryA(path); + rc = winpr_RemoveDirectory(path); fail: free(path); return rc; @@ -275,7 +275,7 @@ static BOOL printer_move_config(const rdpSettings* settings, const WCHAR* oldNam char* newPath = get_printer_config_path(settings, newName, newLength); if (printer_config_valid(oldPath)) - rc = MoveFileA(oldPath, newPath); + rc = winpr_MoveFile(oldPath, newPath); free(oldPath); free(newPath); @@ -979,7 +979,7 @@ printer_DeviceServiceEntry device = (RDPDR_PRINTER*)pEntryPoints->device; name = device->Name; - driver_name = device->DriverName; + driver_name = _strdup(device->DriverName); /* Secondary argument is one of the following: * @@ -1016,7 +1016,8 @@ printer_DeviceServiceEntry if (!driver) { WLog_ERR(TAG, "Could not get a printer driver!"); - return CHANNEL_RC_INITIALIZATION_ERROR; + error = CHANNEL_RC_INITIALIZATION_ERROR; + goto fail; } if (name && name[0]) @@ -1064,7 +1065,9 @@ printer_DeviceServiceEntry } fail: - driver->ReleaseRef(driver); + free(driver_name); + if (driver) + driver->ReleaseRef(driver); return error; } diff --git a/channels/rdpdr/client/rdpdr_main.c b/channels/rdpdr/client/rdpdr_main.c index e59bf0f..617ea42 100644 --- a/channels/rdpdr/client/rdpdr_main.c +++ b/channels/rdpdr/client/rdpdr_main.c @@ -129,7 +129,7 @@ static UINT drive_hotplug_thread_terminate(rdpdrPlugin* rdpdr) #elif _WIN32 -BOOL check_path(char* path) +BOOL check_path(const char* path) { UINT type = GetDriveTypeA(path); @@ -244,6 +244,9 @@ LRESULT CALLBACK hotplug_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) device_ext = (DEVICE_DRIVE_EXT*)ListDictionary_GetItemValue( rdpdr->devman->devices, (void*)keys[j]); + if (device_ext->device.type != RDPDR_DTYP_FILESYSTEM) + continue; + if (device_ext->path[0] == drive_name_upper || device_ext->path[0] == drive_name_lower) { diff --git a/channels/rdpgfx/client/rdpgfx_main.c b/channels/rdpgfx/client/rdpgfx_main.c index 94b5b68..67b3a7d 100644 --- a/channels/rdpgfx/client/rdpgfx_main.c +++ b/channels/rdpgfx/client/rdpgfx_main.c @@ -999,6 +999,19 @@ static UINT rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback, cmd.data = pdu.bitmapData; cmd.extra = NULL; + if (cmd.right < cmd.left) + { + WLog_Print(gfx->log, WLOG_ERROR, "RecvWireToSurface1Pdu right=%" PRIu32 " < left=%" PRIu32, + cmd.right, cmd.left); + return ERROR_INVALID_DATA; + } + if (cmd.bottom < cmd.top) + { + WLog_Print(gfx->log, WLOG_ERROR, "RecvWireToSurface1Pdu bottom=%" PRIu32 " < top=%" PRIu32, + cmd.bottom, cmd.top); + return ERROR_INVALID_DATA; + } + if ((error = rdpgfx_decode(gfx, &cmd))) WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_decode failed with error %" PRIu32 "!", error); diff --git a/channels/rdpsnd/client/mac/rdpsnd_mac.m b/channels/rdpsnd/client/mac/rdpsnd_mac.m index 5ccdbd6..8a01d9b 100644 --- a/channels/rdpsnd/client/mac/rdpsnd_mac.m +++ b/channels/rdpsnd/client/mac/rdpsnd_mac.m @@ -144,7 +144,7 @@ static BOOL rdpsnd_mac_open(rdpsndDevicePlugin *device, const AUDIO_FORMAT *form OSStatus err; NSError *error; rdpsndMacPlugin *mac = (rdpsndMacPlugin *)device; - AudioObjectPropertyAddress propertyAddress = { kAudioHardwarePropertyDefaultSystemOutputDevice, + AudioObjectPropertyAddress propertyAddress = { kAudioHardwarePropertyDefaultOutputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; diff --git a/channels/rdpsnd/server/rdpsnd_main.c b/channels/rdpsnd/server/rdpsnd_main.c index cb9f5fe..be0ca14 100644 --- a/channels/rdpsnd/server/rdpsnd_main.c +++ b/channels/rdpsnd/server/rdpsnd_main.c @@ -422,7 +422,7 @@ static UINT rdpsnd_server_send_wave_pdu(RdpsndServerContext* context, UINT16 wTi Stream_Seek(s, 3); /* bPad */ start = Stream_GetPosition(s); src = context->priv->out_buffer; - length = context->priv->out_pending_frames * context->priv->src_bytes_per_frame; + length = context->priv->out_pending_frames * context->priv->src_bytes_per_frame * 1ULL; if (!freerdp_dsp_encode(context->priv->dsp_context, context->src_format, src, length, s)) return ERROR_INTERNAL_ERROR; diff --git a/channels/smartcard/client/smartcard_main.c b/channels/smartcard/client/smartcard_main.c index 82fb587..2df4c14 100644 --- a/channels/smartcard/client/smartcard_main.c +++ b/channels/smartcard/client/smartcard_main.c @@ -180,6 +180,7 @@ void smartcard_context_free(void* pCtx) /* cancel blocking calls like SCardGetStatusChange */ SCardCancel(pContext->hContext); + SCardReleaseContext(pContext->hContext); if (MessageQueue_PostQuit(pContext->IrpQueue, 0) && (WaitForSingleObject(pContext->thread, INFINITE) == WAIT_FAILED)) @@ -237,7 +238,7 @@ static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard) /* Put thread to sleep so that PC/SC can process the cancel requests. This fixes a race * condition that sometimes caused the pc/sc daemon to crash on MacOS (_xpc_api_misuse) */ - Sleep(100); + SleepEx(100, FALSE); /** * Call SCardReleaseContext on remaining contexts and remove them from rgSCardContextList. @@ -251,27 +252,7 @@ static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard) for (index = 0; index < keyCount; index++) { - pContext = (SMARTCARD_CONTEXT*)ListDictionary_Remove(smartcard->rgSCardContextList, - (void*)pKeys[index]); - - if (!pContext) - continue; - - hContext = pContext->hContext; - - if (SCardIsValidContext(hContext) == SCARD_S_SUCCESS) - { - SCardReleaseContext(hContext); - - if (MessageQueue_PostQuit(pContext->IrpQueue, 0) && - (WaitForSingleObject(pContext->thread, INFINITE) == WAIT_FAILED)) - WLog_ERR(TAG, "WaitForSingleObject failed with error %" PRIu32 "!", - GetLastError()); - - CloseHandle(pContext->thread); - MessageQueue_Free(pContext->IrpQueue); - free(pContext); - } + ListDictionary_SetItemValue(smartcard->rgSCardContextList, (void*)pKeys[index], NULL); } free(pKeys); diff --git a/channels/smartcard/client/smartcard_pack.c b/channels/smartcard/client/smartcard_pack.c index f5987d4..f70eb4e 100644 --- a/channels/smartcard/client/smartcard_pack.c +++ b/channels/smartcard/client/smartcard_pack.c @@ -349,10 +349,16 @@ static char* smartcard_convert_string_list(const void* in, size_t bytes, BOOL un if (bytes < 1) return NULL; + if (in == NULL) + return NULL; + if (unicode) { - length = (bytes / 2); - if (ConvertFromUnicode(CP_UTF8, 0, string.wz, (int)length, &mszA, 0, NULL, NULL) != + length = (bytes / sizeof(WCHAR)) - 1; + mszA = (char*)calloc(length + 1, sizeof(WCHAR)); + if (!mszA) + return NULL; + if (ConvertFromUnicode(CP_UTF8, 0, string.wz, (int)length, &mszA, length + 1, NULL, NULL) != (int)length) { free(mszA); @@ -362,10 +368,11 @@ static char* smartcard_convert_string_list(const void* in, size_t bytes, BOOL un else { length = bytes; - mszA = (char*)malloc(length); + mszA = (char*)calloc(length, sizeof(char)); if (!mszA) return NULL; - CopyMemory(mszA, string.sz, length); + CopyMemory(mszA, string.sz, length - 1); + mszA[length - 1] = '\0'; } for (index = 0; index < length - 1; index++) @@ -1307,21 +1314,24 @@ static void smartcard_trace_status_return(SMARTCARD_DEVICE* smartcard, const Sta static void smartcard_trace_state_return(SMARTCARD_DEVICE* smartcard, const State_Return* ret) { char buffer[1024]; - + char* state; WINPR_UNUSED(smartcard); if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; + state = SCardGetReaderStateString(ret->dwState); WLog_LVL(TAG, g_LogLevel, "Reconnect_Return {"); WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")", SCardGetErrorString(ret->ReturnCode), ret->ReturnCode); - WLog_LVL(TAG, g_LogLevel, " dwState: %s (0x%08" PRIX32 ")", ret->dwState); - WLog_LVL(TAG, g_LogLevel, " dwProtocol: %s (0x%08" PRIX32 ")", ret->dwProtocol); - WLog_LVL(TAG, g_LogLevel, " cbAtrLen: %s (0x%08" PRIX32 ")", ret->cbAtrLen); + WLog_LVL(TAG, g_LogLevel, " dwState: %s (0x%08" PRIX32 ")", state, ret->dwState); + WLog_LVL(TAG, g_LogLevel, " dwProtocol: %s (0x%08" PRIX32 ")", + SCardGetProtocolString(ret->dwProtocol), ret->dwProtocol); + WLog_LVL(TAG, g_LogLevel, " cbAtrLen: (0x%08" PRIX32 ")", ret->cbAtrLen); WLog_LVL(TAG, g_LogLevel, " rgAtr: %s", smartcard_array_dump(ret->rgAtr, sizeof(ret->rgAtr), buffer, sizeof(buffer))); WLog_LVL(TAG, g_LogLevel, "}"); + free(state); } static void smartcard_trace_reconnect_return(SMARTCARD_DEVICE* smartcard, diff --git a/channels/urbdrc/client/libusb/libusb_udevman.c b/channels/urbdrc/client/libusb/libusb_udevman.c index ec7b0b3..1638b8c 100644 --- a/channels/urbdrc/client/libusb/libusb_udevman.c +++ b/channels/urbdrc/client/libusb/libusb_udevman.c @@ -536,7 +536,7 @@ static BOOL device_is_filtered(struct libusb_device* dev, for (x = 0; x < config->bNumInterfaces; x++) { - uint8_t y; + int y; const struct libusb_interface* ifc = &config->interface[x]; for (y = 0; y < ifc->num_altsetting; y++) { diff --git a/channels/video/client/video_main.c b/channels/video/client/video_main.c index 10fb30d..a21e7cd 100644 --- a/channels/video/client/video_main.c +++ b/channels/video/client/video_main.c @@ -666,7 +666,7 @@ static void video_timer(VideoClientContext* video, UINT64 now) presentation = frame->presentation; priv->publishedFrames++; - memcpy(presentation->surfaceData, frame->surfaceData, frame->w * frame->h * 4); + memcpy(presentation->surfaceData, frame->surfaceData, frame->w * frame->h * 4ULL); video->showSurface(video, presentation->surface); @@ -848,7 +848,7 @@ static UINT video_VideoData(VideoClientContext* context, TSMM_VIDEO_DATA* data) frame->w = presentation->SourceWidth; frame->h = presentation->SourceHeight; - frame->surfaceData = BufferPool_Take(priv->surfacePool, frame->w * frame->h * 4); + frame->surfaceData = BufferPool_Take(priv->surfacePool, frame->w * frame->h * 4ULL); if (!frame->surfaceData) { WLog_ERR(TAG, "unable to allocate frame data"); diff --git a/client/Wayland/wlf_pointer.c b/client/Wayland/wlf_pointer.c index 6416659..decde7f 100644 --- a/client/Wayland/wlf_pointer.c +++ b/client/Wayland/wlf_pointer.c @@ -42,7 +42,7 @@ static BOOL wlf_Pointer_New(rdpContext* context, rdpPointer* pointer) if (!ptr) return FALSE; - ptr->size = pointer->width * pointer->height * 4; + ptr->size = pointer->width * pointer->height * 4ULL; ptr->data = _aligned_malloc(ptr->size, 16); if (!ptr->data) @@ -92,7 +92,7 @@ static BOOL wlf_Pointer_Set(rdpContext* context, const rdpPointer* pointer) !wlf_scale_coordinates(context, &w, &h, FALSE)) return FALSE; - size = w * h * 4; + size = w * h * 4ULL; data = malloc(size); if (!data) diff --git a/client/X11/cli/xfreerdp.c b/client/X11/cli/xfreerdp.c index 5b70219..8db4d39 100644 --- a/client/X11/cli/xfreerdp.c +++ b/client/X11/cli/xfreerdp.c @@ -59,11 +59,9 @@ int main(int argc, char* argv[]) status = freerdp_client_settings_parse_command_line(context->settings, argc, argv, FALSE); if (status) { - BOOL list = settings->ListMonitors; - rc = freerdp_client_settings_command_line_status_print(settings, status, argc, argv); - if (list) + if (settings->ListMonitors) xf_list_monitors(xfc); goto out; diff --git a/client/X11/xf_cliprdr.c b/client/X11/xf_cliprdr.c index 0e6cd03..e08048f 100644 --- a/client/X11/xf_cliprdr.c +++ b/client/X11/xf_cliprdr.c @@ -1034,7 +1034,8 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, if (!delayRespond) { - union { + union + { XEvent* ev; XSelectionEvent* sev; } conv; @@ -1423,7 +1424,10 @@ static UINT xf_cliprdr_server_format_list(CliprdrClientContext* context, } ret = xf_cliprdr_send_client_format_list_response(clipboard, TRUE); - xf_cliprdr_prepare_to_set_selection_owner(xfc, clipboard); + if (xfc->remote_app) + xf_cliprdr_set_selection_owner(xfc, clipboard, CurrentTime); + else + xf_cliprdr_prepare_to_set_selection_owner(xfc, clipboard); return ret; } @@ -1611,7 +1615,8 @@ xf_cliprdr_server_format_data_response(CliprdrClientContext* context, xf_cliprdr_provide_data(clipboard, clipboard->respond, pDstData, DstSize); { - union { + union + { XEvent* ev; XSelectionEvent* sev; } conv; diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c index 60fe9c6..99577b1 100644 --- a/client/X11/xf_event.c +++ b/client/X11/xf_event.c @@ -262,6 +262,37 @@ static BOOL xf_event_execute_action_script(xfContext* xfc, const XEvent* event) return TRUE; } +void xf_adjust_coordinates_to_screen(xfContext* xfc, UINT32* x, UINT32* y) +{ + rdpSettings* settings; + INT64 tx, ty; + + if (!xfc || !xfc->context.settings || !y || !x) + return; + + settings = xfc->context.settings; + tx = *x; + ty = *y; + if (!xfc->remote_app) + { +#ifdef WITH_XRENDER + + if (xf_picture_transform_required(xfc)) + { + double xScalingFactor = xfc->scaledWidth / (double)settings->DesktopWidth; + double yScalingFactor = xfc->scaledHeight / (double)settings->DesktopHeight; + tx = ((tx + xfc->offset_x) * xScalingFactor); + ty = ((ty + xfc->offset_y) * yScalingFactor); + } + +#endif + } + + CLAMP_COORDINATES(tx, ty); + *x = tx; + *y = ty; +} + void xf_event_adjust_coordinates(xfContext* xfc, int* x, int* y) { rdpSettings* settings; diff --git a/client/X11/xf_event.h b/client/X11/xf_event.h index 185c83c..2269d3e 100644 --- a/client/X11/xf_event.h +++ b/client/X11/xf_event.h @@ -33,6 +33,7 @@ void xf_event_SendClientEvent(xfContext* xfc, xfWindow* window, Atom atom, unsig ...); void xf_event_adjust_coordinates(xfContext* xfc, int* x, int* y); +void xf_adjust_coordinates_to_screen(xfContext* xfc, UINT32* x, UINT32* y); BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state, Window window, BOOL app); BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button, Window window, BOOL app); diff --git a/client/X11/xf_gdi.c b/client/X11/xf_gdi.c index 949e62d..4f52853 100644 --- a/client/X11/xf_gdi.c +++ b/client/X11/xf_gdi.c @@ -231,7 +231,7 @@ static Pixmap xf_brush_new(xfContext* xfc, UINT32 width, UINT32 height, UINT32 b if (data) { brushFormat = gdi_get_pixel_format(bpp); - cdata = (BYTE*)_aligned_malloc(width * height * 4, 16); + cdata = (BYTE*)_aligned_malloc(width * height * 4ULL, 16); freerdp_image_copy(cdata, gdi->dstFormat, 0, 0, 0, width, height, data, brushFormat, 0, 0, 0, &xfc->context.gdi->palette, FREERDP_FLIP_NONE); image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, (char*)cdata, width, @@ -1066,7 +1066,7 @@ static BOOL xf_gdi_surface_bits(rdpContext* context, const SURFACE_BITS_COMMAND* case RDP_CODEC_ID_NONE: pSrcData = cmd->bmp.bitmapData; format = gdi_get_pixel_format(cmd->bmp.bpp); - size = cmd->bmp.width * cmd->bmp.height * GetBytesPerPixel(format); + size = cmd->bmp.width * cmd->bmp.height * GetBytesPerPixel(format) * 1ULL; if (size > cmd->bmp.bitmapDataLength) { WLog_ERR(TAG, "Short nocodec message: got %" PRIu32 " bytes, require %" PRIuz, diff --git a/client/X11/xf_gfx.c b/client/X11/xf_gfx.c index cb3423e..97d3ad3 100644 --- a/client/X11/xf_gfx.c +++ b/client/X11/xf_gfx.c @@ -288,7 +288,7 @@ static UINT xf_CreateSurface(RdpgfxClientContext* context, surface->gdi.scanline = surface->gdi.width * GetBytesPerPixel(surface->gdi.format); surface->gdi.scanline = x11_pad_scanline(surface->gdi.scanline, xfc->scanline_pad); - size = surface->gdi.scanline * surface->gdi.height; + size = surface->gdi.scanline * surface->gdi.height * 1ULL; surface->gdi.data = (BYTE*)_aligned_malloc(size, 16); if (!surface->gdi.data) @@ -312,7 +312,7 @@ static UINT xf_CreateSurface(RdpgfxClientContext* context, UINT32 bytes = GetBytesPerPixel(gdi->dstFormat); surface->stageScanline = width * bytes; surface->stageScanline = x11_pad_scanline(surface->stageScanline, xfc->scanline_pad); - size = surface->stageScanline * surface->gdi.height; + size = surface->stageScanline * surface->gdi.height * 1ULL; surface->stage = (BYTE*)_aligned_malloc(size, 16); if (!surface->stage) diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c index 20d54f5..8de32c5 100644 --- a/client/X11/xf_graphics.c +++ b/client/X11/xf_graphics.c @@ -37,6 +37,7 @@ #include "xf_graphics.h" #include "xf_gdi.h" +#include "xf_event.h" #include #define TAG CLIENT_TAG("x11") @@ -124,7 +125,7 @@ static BOOL xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap) if ((INT64)depth != xfc->depth) { - if (!(data = _aligned_malloc(bitmap->width * bitmap->height * 4, 16))) + if (!(data = _aligned_malloc(bitmap->width * bitmap->height * 4ULL, 16))) goto unlock; if (!freerdp_image_copy(data, gdi->dstFormat, 0, 0, 0, bitmap->width, bitmap->height, @@ -303,16 +304,16 @@ static BOOL _xf_Pointer_GetCursorForCurrentScale(rdpContext* context, const rdpP ci.height = yTargetSize; ci.xhot = pointer->xPos * xscale; ci.yhot = pointer->yPos * yscale; - size = ci.height * ci.width * GetBytesPerPixel(CursorFormat); - - if (!(ci.pixels = (XcursorPixel*)_aligned_malloc(size, 16))) - { - xf_unlock_x11(xfc); - return FALSE; - } + size = ci.height * ci.width * GetBytesPerPixel(CursorFormat) * 1ULL; if (xscale != 1 || yscale != 1) { + if (!(ci.pixels = (XcursorPixel*)_aligned_malloc(size, 16))) + { + xf_unlock_x11(xfc); + return FALSE; + } + if (!freerdp_image_scale((BYTE*)ci.pixels, CursorFormat, 0, 0, 0, ci.width, ci.height, (BYTE*)xpointer->cursorPixels, CursorFormat, 0, 0, 0, pointer->width, pointer->height)) @@ -390,7 +391,7 @@ static BOOL xf_Pointer_New(rdpContext* context, rdpPointer* pointer) xpointer->nCursors = 0; xpointer->mCursors = 0; - size = pointer->height * pointer->width * GetBytesPerPixel(CursorFormat); + size = pointer->height * pointer->width * GetBytesPerPixel(CursorFormat) * 1ULL; if (!(xpointer->cursorPixels = (XcursorPixel*)_aligned_malloc(size, 16))) return FALSE; @@ -521,6 +522,8 @@ static BOOL xf_Pointer_SetPosition(rdpContext* context, UINT32 x, UINT32 y) if (xfc->remote_app && !xfc->focused) return TRUE; + xf_adjust_coordinates_to_screen(xfc, &x, &y); + xf_lock_x11(xfc); rc = XGetWindowAttributes(xfc->display, handle, ¤t); @@ -541,7 +544,7 @@ static BOOL xf_Pointer_SetPosition(rdpContext* context, UINT32 x, UINT32 y) rc = XWarpPointer(xfc->display, None, handle, 0, 0, 0, 0, x, y); if (rc == 0) - WLog_WARN(TAG, "xf_Pointer_SetPosition: XWrapPointer==%d", rc); + WLog_WARN(TAG, "xf_Pointer_SetPosition: XWarpPointer==%d", rc); tmp.event_mask = current.your_event_mask; rc = XChangeWindowAttributes(xfc->display, handle, CWEventMask, &tmp); if (rc == 0) diff --git a/client/X11/xf_keyboard.c b/client/X11/xf_keyboard.c index 4c05e80..26a1fd2 100644 --- a/client/X11/xf_keyboard.c +++ b/client/X11/xf_keyboard.c @@ -60,7 +60,7 @@ static BOOL xf_keyboard_action_script_init(xfContext* xfc) char* keyCombination; char buffer[1024] = { 0 }; char command[1024] = { 0 }; - xfc->actionScriptExists = PathFileExistsA(xfc->context.settings->ActionScript); + xfc->actionScriptExists = winpr_PathFileExists(xfc->context.settings->ActionScript); if (!xfc->actionScriptExists) return FALSE; diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index 59d30b3..770234f 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -532,7 +532,7 @@ static xfRailIconCache* RailIconCache_New(rdpSettings* settings) cache->numCaches = settings->RemoteAppNumIconCaches; cache->numCacheEntries = settings->RemoteAppNumIconCacheEntries; - cache->entries = calloc(cache->numCaches * cache->numCacheEntries, sizeof(xfRailIcon)); + cache->entries = calloc(cache->numCaches * cache->numCacheEntries * 1ULL, sizeof(xfRailIcon)); if (!cache->entries) { @@ -602,7 +602,7 @@ static BOOL convert_rail_icon(const ICON_INFO* iconInfo, xfRailIcon* railIcon) long* pixels; int i; int nelements; - argbPixels = calloc(iconInfo->width * iconInfo->height, 4); + argbPixels = calloc(iconInfo->width * iconInfo->height * 1ULL, 4); if (!argbPixels) goto error; diff --git a/client/common/CMakeLists.txt b/client/common/CMakeLists.txt index d4588e1..b465a63 100644 --- a/client/common/CMakeLists.txt +++ b/client/common/CMakeLists.txt @@ -28,11 +28,15 @@ endif() set(${MODULE_PREFIX}_SRCS client.c cmdline.c - compatibility.c - compatibility.h file.c geometry.c) +if(NOT DEFINE_NO_DEPRECATED) + list(APPEND ${MODULE_PREFIX}_SRCS + compatibility.c + compatibility.h) +endif() + foreach(FREERDP_CHANNELS_CLIENT_SRC ${FREERDP_CHANNELS_CLIENT_SRCS}) get_filename_component(NINC ${FREERDP_CHANNELS_CLIENT_SRC} PATH) include_directories(${NINC}) diff --git a/client/common/cmdline.c b/client/common/cmdline.c index f17ba66..6982eef 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -93,7 +93,7 @@ static BOOL freerdp_path_valid(const char* path, BOOL* special) ? TRUE : FALSE; if (!isSpecial) - isPath = PathFileExistsA(path); + isPath = winpr_PathFileExists(path); if (special) *special = isSpecial; @@ -120,6 +120,23 @@ static BOOL freerdp_sanitize_drive_name(char* name, const char* invalid, const c return TRUE; } +static char* name_from_path(const char* path) +{ + const char* name = "NULL"; + if (path) + { + if (_strnicmp(path, "%", 2) == 0) + name = "home"; + else if (_strnicmp(path, "*", 2) == 0) + name = "hotplug-all"; + else if (_strnicmp(path, "DynamicDrives", 2) == 0) + name = "hotplug"; + else + name = path; + } + return _strdup(name); +} + static BOOL freerdp_client_add_drive(rdpSettings* settings, const char* path, const char* name) { RDPDR_DRIVE* drive; @@ -134,9 +151,9 @@ static BOOL freerdp_client_add_drive(rdpSettings* settings, const char* path, co if (name) { /* Path was entered as secondary argument, swap */ - if (PathFileExistsA(name)) + if (winpr_PathFileExists(name)) { - if (!PathFileExistsA(path) || (!PathIsRelativeA(name) && PathIsRelativeA(path))) + if (!winpr_PathFileExists(path) || (!PathIsRelativeA(name) && PathIsRelativeA(path))) { const char* tmp = path; path = name; @@ -151,8 +168,10 @@ static BOOL freerdp_client_add_drive(rdpSettings* settings, const char* path, co goto fail; } else /* We need a name to send to the server. */ - if (!(drive->Name = _strdup(path))) - goto fail; + { + if (!(drive->Name = name_from_path(path))) + goto fail; + } if (!path || !freerdp_sanitize_drive_name(drive->Name, "\\/", "__")) goto fail; @@ -1341,8 +1360,10 @@ static int freerdp_detect_posix_style_command_line_syntax(int argc, char** argv, static BOOL freerdp_client_detect_command_line(int argc, char** argv, DWORD* flags) { +#if !defined(DEFINE_NO_DEPRECATED) int old_cli_status; size_t old_cli_count; +#endif int posix_cli_status; size_t posix_cli_count; int windows_cli_status; @@ -1353,7 +1374,10 @@ static BOOL freerdp_client_detect_command_line(int argc, char** argv, DWORD* fla argc, argv, &windows_cli_count, ignoreUnknown); posix_cli_status = freerdp_detect_posix_style_command_line_syntax(argc, argv, &posix_cli_count, ignoreUnknown); +#if !defined(DEFINE_NO_DEPRECATED) old_cli_status = freerdp_detect_old_command_line_syntax(argc, argv, &old_cli_count); +#endif + /* Default is POSIX syntax */ *flags = COMMAND_LINE_SEPARATOR_SPACE; *flags |= COMMAND_LINE_SIGIL_DASH | COMMAND_LINE_SIGIL_DOUBLE_DASH; @@ -1370,6 +1394,7 @@ static BOOL freerdp_client_detect_command_line(int argc, char** argv, DWORD* fla *flags = COMMAND_LINE_SEPARATOR_COLON; *flags |= COMMAND_LINE_SIGIL_SLASH | COMMAND_LINE_SIGIL_PLUS_MINUS; } +#if !defined(DEFINE_NO_DEPRECATED) else if (old_cli_status >= 0) { /* Ignore legacy parsing in case there is an error in the command line. */ @@ -1380,9 +1405,13 @@ static BOOL freerdp_client_detect_command_line(int argc, char** argv, DWORD* fla compatibility = TRUE; } } - WLog_DBG(TAG, "windows: %d/%d posix: %d/%d compat: %d/%d", windows_cli_status, windows_cli_count, posix_cli_status, posix_cli_count, old_cli_status, old_cli_count); +#else + WLog_DBG(TAG, "windows: %d/%d posix: %d/%d", windows_cli_status, windows_cli_count, + posix_cli_status, posix_cli_count); +#endif + return compatibility; } @@ -1574,12 +1603,14 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, freerdp_settings_set_string(settings, FreeRDP_ProxyUsername, NULL); freerdp_settings_set_string(settings, FreeRDP_ProxyPassword, NULL); +#if !defined(DEFINE_NO_DEPRECATED) if (compatibility) { WLog_WARN(TAG, "Using deprecated command-line interface!"); return freerdp_client_parse_old_command_line_arguments(argc, argv, settings); } else +#endif { if (allowUnknown) flags |= COMMAND_LINE_IGN_UNKNOWN_KEYWORD; @@ -2234,15 +2265,29 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, settings->GatewayRpcTransport = TRUE; settings->GatewayHttpTransport = FALSE; } - else if (_stricmp(arg->Value, "http") == 0) + else { - settings->GatewayRpcTransport = FALSE; - settings->GatewayHttpTransport = TRUE; - } - else if (_stricmp(arg->Value, "auto") == 0) - { - settings->GatewayRpcTransport = TRUE; - settings->GatewayHttpTransport = TRUE; + char* c = strchr(arg->Value, ','); + if (c) + { + *c++ = '\0'; + if (_stricmp(c, "no-websockets") != 0) + { + return COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + } + freerdp_settings_set_bool(settings, FreeRDP_GatewayHttpUseWebsockets, FALSE); + } + + if (_stricmp(arg->Value, "http") == 0) + { + settings->GatewayRpcTransport = FALSE; + settings->GatewayHttpTransport = TRUE; + } + else if (_stricmp(arg->Value, "auto") == 0) + { + settings->GatewayRpcTransport = TRUE; + settings->GatewayHttpTransport = TRUE; + } } } CommandLineSwitchCase(arg, "gat") @@ -2582,6 +2627,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, if (enable) settings->SupportGraphicsPipeline = TRUE; } +#if !defined(DEFINE_NO_DEPRECATED) #ifdef WITH_GFX_H264 CommandLineSwitchCase(arg, "gfx-h264") { @@ -2631,6 +2677,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, return rc; } } +#endif #endif CommandLineSwitchCase(arg, "rfx") { @@ -2875,6 +2922,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, if (rc) return rc; } +#if !defined(DEFINE_NO_DEPRECATED) CommandLineSwitchCase(arg, "cert-name") { if (!copy_value(arg->Value, &settings->CertificateName)) @@ -2892,6 +2940,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, { settings->AutoDenyCertificate = enable; } +#endif CommandLineSwitchCase(arg, "authentication") { settings->Authentication = enable; @@ -3543,6 +3592,7 @@ BOOL freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings) /* Syntax: Comma seperated list of the following entries: * '*' ... Redirect all drives, including hotplug * 'DynamicDrives' ... hotplug + * '%' ... user home directory *