New upstream version 2.11.2+dfsg1
This commit is contained in:
parent
2d5b821574
commit
4bb5bc077f
@ -34,9 +34,9 @@ if(NOT DEFINED FREERDP_VENDOR)
|
||||
set(FREERDP_VENDOR 1)
|
||||
endif()
|
||||
|
||||
set(CMAKE_COLOR_MAKEFILE ON)
|
||||
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
option(CMAKE_COLOR_MAKEFILE "colorful CMake makefile" ON)
|
||||
option(CMAKE_VERBOSE_MAKEFILE "verbose CMake makefile" ON)
|
||||
option(CMAKE_POSITION_INDEPENDENT_CODE "build with position independent code (-fPIC or -fPIE)" ON)
|
||||
|
||||
# Include our extra modules
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/)
|
||||
@ -85,7 +85,7 @@ if ($ENV{BUILD_NUMBER})
|
||||
endif()
|
||||
set(WITH_LIBRARY_VERSIONING "ON")
|
||||
|
||||
set(RAW_VERSION_STRING "2.10.0")
|
||||
set(RAW_VERSION_STRING "2.11.2")
|
||||
if(EXISTS "${CMAKE_SOURCE_DIR}/.source_tag")
|
||||
file(READ ${CMAKE_SOURCE_DIR}/.source_tag RAW_VERSION_STRING)
|
||||
elseif(USE_VERSION_FROM_GIT_TAG)
|
||||
@ -225,7 +225,7 @@ endif()
|
||||
if(MSVC)
|
||||
include(MSVCRuntime)
|
||||
if(NOT DEFINED MSVC_RUNTIME)
|
||||
set(MSVC_RUNTIME "dynamic")
|
||||
set(MSVC_RUNTIME "dynamic" CACHE STRING "MSVC runtime type [dynamic|static]")
|
||||
endif()
|
||||
if(MSVC_RUNTIME STREQUAL "static")
|
||||
if(BUILD_SHARED_LIBS)
|
||||
|
||||
42
ChangeLog
42
ChangeLog
@ -1,6 +1,42 @@
|
||||
# 2023-09-20 Version 2.11.2
|
||||
|
||||
Notworthy changes:
|
||||
* Backported #9378: backported wArrayList (optional) copy on insert
|
||||
* Backported #9360: backported certificate algorithm detection
|
||||
|
||||
For a complete and detailed change log since the last release run:
|
||||
git log 2.11.2..2.11.1
|
||||
|
||||
# 2023-09-04 Version 2.11.1
|
||||
|
||||
Notworthy changes:
|
||||
* Backported #9356: Fix issues with order updates
|
||||
|
||||
For a complete and detailed change log since the last release run:
|
||||
git log 2.11.1..2.11.0
|
||||
|
||||
# 2023-08-28 Version 2.11.0
|
||||
|
||||
Noteworthy changes:
|
||||
* Various input validation fixes
|
||||
* Added various CMake options #9317
|
||||
* LibreSSL build fixes #8709
|
||||
|
||||
Fixed issues:
|
||||
* Backported #9233: Big endian support
|
||||
* Backported #9099: Mouse grabbing support
|
||||
* Backported #6851: wayland scrolling fix
|
||||
* Backported #8690: Update h264 to use new FFMPEG API
|
||||
* Backported #7306: early bail from update_read_window_state_order breaks protocol
|
||||
* Backported #8903: rdpecam/server: Remove wrong assertion
|
||||
* Backported #8994: bounds checks for gdi/gfx rectangles
|
||||
* Backported #9023: enforce rdpdr client side state checks
|
||||
* Backported #6331: deactivate mouse grabbing by default
|
||||
* Cherry-pick out of #9172: channels/cliprdr: Fix writing incorrect PDU type for unlock PDUs
|
||||
|
||||
# 2023-02-16 Version 2.10.0
|
||||
|
||||
Notewhorth changes:
|
||||
Noteworthy changes:
|
||||
* Fix android build scripts, use CMake from SDK
|
||||
* Fix connection negotiation with mstsc/msrdc #8426
|
||||
* [ntlm]: use rfc5929 binding hash algorithm #8430
|
||||
@ -23,7 +59,7 @@ Fixed issues:
|
||||
|
||||
# 2022-11-16 Version 2.9.0
|
||||
|
||||
Notewhorth changes:
|
||||
Noteworthy changes:
|
||||
* Backported #8252: Support sending server redirection PDU
|
||||
* Backported #8406: Ensure X11 client cursor is never smaller 1x1
|
||||
* Backported #8403: Fixed multiple client side input validation issues
|
||||
@ -49,7 +85,7 @@ git log 2.8.1..2.9.0
|
||||
|
||||
# 2022-10-12 Version 2.8.1
|
||||
|
||||
Notewhorth changes:
|
||||
Noteworthy changes:
|
||||
* Fixed CVE-2022-39282
|
||||
* Fixed CVE-2022-39283
|
||||
* Added missing commit for backported #8041: Remove ALAW/ULAW codecs from linux backends (unreliable)
|
||||
|
||||
@ -138,7 +138,7 @@ cliprdr_packet_unlock_clipdata_new(const CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockCl
|
||||
if (!unlockClipboardData)
|
||||
return NULL;
|
||||
|
||||
s = cliprdr_packet_new(CB_LOCK_CLIPDATA, 0, 4);
|
||||
s = cliprdr_packet_new(CB_UNLOCK_CLIPDATA, 0, 4);
|
||||
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
@ -41,6 +41,8 @@
|
||||
|
||||
#include "devman.h"
|
||||
|
||||
#define TAG CHANNELS_TAG("rdpdr.client")
|
||||
|
||||
static void devman_device_free(void* obj)
|
||||
{
|
||||
DEVICE* device = (DEVICE*)obj;
|
||||
@ -62,7 +64,7 @@ DEVMAN* devman_new(rdpdrPlugin* rdpdr)
|
||||
|
||||
if (!devman)
|
||||
{
|
||||
WLog_INFO(TAG, "calloc failed!");
|
||||
WLog_Print(rdpdr->log, WLOG_INFO, "calloc failed!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -72,7 +74,7 @@ DEVMAN* devman_new(rdpdrPlugin* rdpdr)
|
||||
|
||||
if (!devman->devices)
|
||||
{
|
||||
WLog_INFO(TAG, "ListDictionary_New failed!");
|
||||
WLog_Print(rdpdr->log, WLOG_INFO, "ListDictionary_New failed!");
|
||||
free(devman);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -76,13 +76,13 @@ static UINT irp_complete(IRP* irp)
|
||||
return irp_free(irp);
|
||||
}
|
||||
|
||||
IRP* irp_new(DEVMAN* devman, wStream* s, UINT* error)
|
||||
IRP* irp_new(DEVMAN* devman, wStream* s, wLog* log, UINT* error)
|
||||
{
|
||||
IRP* irp;
|
||||
DEVICE* device;
|
||||
UINT32 DeviceId;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 20)
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 20))
|
||||
{
|
||||
if (error)
|
||||
*error = ERROR_INVALID_DATA;
|
||||
@ -94,7 +94,7 @@ IRP* irp_new(DEVMAN* devman, wStream* s, UINT* error)
|
||||
|
||||
if (!device)
|
||||
{
|
||||
WLog_WARN(TAG, "devman_get_device_by_id failed!");
|
||||
WLog_Print(log, WLOG_WARN, "devman_get_device_by_id failed!");
|
||||
if (error)
|
||||
*error = CHANNEL_RC_OK;
|
||||
|
||||
@ -105,7 +105,7 @@ IRP* irp_new(DEVMAN* devman, wStream* s, UINT* error)
|
||||
|
||||
if (!irp)
|
||||
{
|
||||
WLog_ERR(TAG, "_aligned_malloc failed!");
|
||||
WLog_Print(log, WLOG_ERROR, "_aligned_malloc failed!");
|
||||
if (error)
|
||||
*error = CHANNEL_RC_NO_MEMORY;
|
||||
return NULL;
|
||||
@ -125,7 +125,7 @@ IRP* irp_new(DEVMAN* devman, wStream* s, UINT* error)
|
||||
irp->output = Stream_New(NULL, 256);
|
||||
if (!irp->output)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
WLog_Print(log, WLOG_ERROR, "Stream_New failed!");
|
||||
_aligned_free(irp);
|
||||
if (error)
|
||||
*error = CHANNEL_RC_NO_MEMORY;
|
||||
|
||||
@ -21,8 +21,9 @@
|
||||
#ifndef FREERDP_CHANNEL_RDPDR_CLIENT_IRP_H
|
||||
#define FREERDP_CHANNEL_RDPDR_CLIENT_IRP_H
|
||||
|
||||
#include <winpr/wlog.h>
|
||||
#include "rdpdr_main.h"
|
||||
|
||||
IRP* irp_new(DEVMAN* devman, wStream* s, UINT* error);
|
||||
IRP* irp_new(DEVMAN* devman, wStream* s, wLog* log, UINT* error);
|
||||
|
||||
#endif /* FREERDP_CHANNEL_RDPDR_CLIENT_IRP_H */
|
||||
|
||||
@ -69,7 +69,7 @@ static UINT rdpdr_process_general_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
UINT16 capabilityLength;
|
||||
WINPR_UNUSED(rdpdr);
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, 2))
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, capabilityLength);
|
||||
@ -77,7 +77,7 @@ static UINT rdpdr_process_general_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
if (capabilityLength < 4)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < capabilityLength - 4U)
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, capabilityLength - 4U))
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Seek(s, capabilityLength - 4U);
|
||||
@ -97,7 +97,7 @@ static UINT rdpdr_process_printer_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
UINT16 capabilityLength;
|
||||
WINPR_UNUSED(rdpdr);
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, 2))
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, capabilityLength);
|
||||
@ -105,7 +105,7 @@ static UINT rdpdr_process_printer_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
if (capabilityLength < 4)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < capabilityLength - 4U)
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, capabilityLength - 4U))
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Seek(s, capabilityLength - 4U);
|
||||
@ -125,7 +125,7 @@ static UINT rdpdr_process_port_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
UINT16 capabilityLength;
|
||||
WINPR_UNUSED(rdpdr);
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, 2))
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, capabilityLength);
|
||||
@ -133,7 +133,7 @@ static UINT rdpdr_process_port_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
if (capabilityLength < 4U)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < capabilityLength - 4U)
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, capabilityLength - 4U))
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Seek(s, capabilityLength - 4U);
|
||||
@ -153,7 +153,7 @@ static UINT rdpdr_process_drive_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
UINT16 capabilityLength;
|
||||
WINPR_UNUSED(rdpdr);
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, 2))
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, capabilityLength);
|
||||
@ -161,7 +161,7 @@ static UINT rdpdr_process_drive_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
if (capabilityLength < 4)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < capabilityLength - 4U)
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, capabilityLength - 4U))
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Seek(s, capabilityLength - 4U);
|
||||
@ -181,7 +181,7 @@ static UINT rdpdr_process_smartcard_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
UINT16 capabilityLength;
|
||||
WINPR_UNUSED(rdpdr);
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, 2))
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, capabilityLength);
|
||||
@ -189,7 +189,7 @@ static UINT rdpdr_process_smartcard_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
if (capabilityLength < 4)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < capabilityLength - 4U)
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, capabilityLength - 4U))
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Seek(s, capabilityLength - 4U);
|
||||
@ -206,7 +206,10 @@ UINT rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s)
|
||||
if (!rdpdr || !s)
|
||||
return CHANNEL_RC_NULL_DATA;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
WINPR_ASSERT(rdpdr->state == RDPDR_CHANNEL_STATE_SERVER_CAPS);
|
||||
rdpdr_state_advance(rdpdr, RDPDR_CHANNEL_STATE_CLIENT_CAPS);
|
||||
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, 4))
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, numCapabilities);
|
||||
@ -214,7 +217,7 @@ UINT rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s)
|
||||
|
||||
for (i = 0; i < numCapabilities; i++)
|
||||
{
|
||||
if (Stream_GetRemainingLength(s) < sizeof(UINT16))
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, sizeof(UINT16)))
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, capabilityType);
|
||||
@ -264,7 +267,7 @@ UINT rdpdr_send_capability_response(rdpdrPlugin* rdpdr)
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "Stream_New failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
@ -79,12 +79,50 @@ struct _DEVICE_DRIVE_EXT
|
||||
BOOL automount;
|
||||
};
|
||||
|
||||
static const char* rdpdr_state_str(enum RDPDR_CHANNEL_STATE state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case RDPDR_CHANNEL_STATE_INITIAL:
|
||||
return "RDPDR_CHANNEL_STATE_INITIAL";
|
||||
case RDPDR_CHANNEL_STATE_ANNOUNCE:
|
||||
return "RDPDR_CHANNEL_STATE_ANNOUNCE";
|
||||
case RDPDR_CHANNEL_STATE_ANNOUNCE_REPLY:
|
||||
return "RDPDR_CHANNEL_STATE_ANNOUNCE_REPLY";
|
||||
case RDPDR_CHANNEL_STATE_NAME_REQUEST:
|
||||
return "RDPDR_CHANNEL_STATE_NAME_REQUEST";
|
||||
case RDPDR_CHANNEL_STATE_SERVER_CAPS:
|
||||
return "RDPDR_CHANNEL_STATE_SERVER_CAPS";
|
||||
case RDPDR_CHANNEL_STATE_CLIENT_CAPS:
|
||||
return "RDPDR_CHANNEL_STATE_CLIENT_CAPS";
|
||||
case RDPDR_CHANNEL_STATE_CLIENTID_CONFIRM:
|
||||
return "RDPDR_CHANNEL_STATE_CLIENTID_CONFIRM";
|
||||
case RDPDR_CHANNEL_STATE_READY:
|
||||
return "RDPDR_CHANNEL_STATE_READY";
|
||||
case RDPDR_CHANNEL_STATE_USER_LOGGEDON:
|
||||
return "RDPDR_CHANNEL_STATE_USER_LOGGEDON";
|
||||
default:
|
||||
return "RDPDR_CHANNEL_STATE_UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
BOOL rdpdr_state_advance(rdpdrPlugin* rdpdr, enum RDPDR_CHANNEL_STATE next)
|
||||
{
|
||||
WINPR_ASSERT(rdpdr);
|
||||
|
||||
if (next != rdpdr->state)
|
||||
WLog_Print(rdpdr->log, WLOG_DEBUG, "[RDPDR] transition from %s to %s",
|
||||
rdpdr_state_str(rdpdr->state), rdpdr_state_str(next));
|
||||
rdpdr->state = next;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL userLoggedOn);
|
||||
static UINT rdpdr_try_send_device_list_announce_request(rdpdrPlugin* rdpdr);
|
||||
|
||||
/**
|
||||
* Function description
|
||||
@ -99,7 +137,7 @@ static UINT rdpdr_send_device_list_remove_request(rdpdrPlugin* rdpdr, UINT32 cou
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "Stream_New failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
@ -212,7 +250,7 @@ LRESULT CALLBACK hotplug_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
devman_load_device_service(rdpdr->devman,
|
||||
(const RDPDR_DEVICE*)&drive,
|
||||
rdpdr->rdpcontext);
|
||||
rdpdr_send_device_list_announce_request(rdpdr, TRUE);
|
||||
rdpdr_try_send_device_list_announce_request(rdpdr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,8 +299,8 @@ LRESULT CALLBACK hotplug_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
rdpdr, 1, ids)))
|
||||
{
|
||||
// dont end on error, just report ?
|
||||
WLog_ERR(
|
||||
TAG,
|
||||
WLog_Print(
|
||||
rdpdr->log, WLOG_ERROR,
|
||||
"rdpdr_send_device_list_remove_request failed "
|
||||
"with error %" PRIu32 "!",
|
||||
error);
|
||||
@ -358,7 +396,7 @@ static UINT drive_hotplug_thread_terminate(rdpdrPlugin* rdpdr)
|
||||
if (rdpdr->hotplug_wnd && !PostMessage(rdpdr->hotplug_wnd, WM_QUIT, 0, 0))
|
||||
{
|
||||
error = GetLastError();
|
||||
WLog_ERR(TAG, "PostMessage failed with error %" PRIu32 "", error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "PostMessage failed with error %" PRIu32 "", error);
|
||||
}
|
||||
|
||||
return error;
|
||||
@ -475,9 +513,9 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr)
|
||||
|
||||
if ((error = rdpdr_send_device_list_remove_request(rdpdr, 1, ids)))
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"rdpdr_send_device_list_remove_request failed with error %" PRIu32 "!",
|
||||
error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR,
|
||||
"rdpdr_send_device_list_remove_request failed with error %" PRIu32 "!",
|
||||
error);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
@ -506,7 +544,7 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr)
|
||||
if ((error = devman_load_device_service(rdpdr->devman, (RDPDR_DEVICE*)&drive,
|
||||
rdpdr->rdpcontext)))
|
||||
{
|
||||
WLog_ERR(TAG, "devman_load_device_service failed!");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "devman_load_device_service failed!");
|
||||
error = CHANNEL_RC_NO_MEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
@ -540,10 +578,11 @@ static void drive_hotplug_fsevent_callback(ConstFSEventStreamRef streamRef,
|
||||
{
|
||||
if ((error = handle_hotplug(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "handle_hotplug failed with error %" PRIu32 "!", error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "handle_hotplug failed with error %" PRIu32 "!",
|
||||
error);
|
||||
}
|
||||
else
|
||||
rdpdr_send_device_list_announce_request(rdpdr, TRUE);
|
||||
rdpdr_try_send_device_list_announce_request(rdpdr);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -556,7 +595,7 @@ void first_hotplug(rdpdrPlugin* rdpdr)
|
||||
|
||||
if ((error = handle_hotplug(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "handle_hotplug failed with error %" PRIu32 "!", error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "handle_hotplug failed with error %" PRIu32 "!", error);
|
||||
}
|
||||
}
|
||||
|
||||
@ -661,14 +700,14 @@ static void handle_mountpoint(hotplug_dev* dev_array, size_t* size, const char*
|
||||
|
||||
#ifdef __sun
|
||||
#include <sys/mnttab.h>
|
||||
static UINT handle_platform_mounts_sun(hotplug_dev* dev_array, size_t* size)
|
||||
static UINT handle_platform_mounts_sun(wLog* log, hotplug_dev* dev_array, size_t* size)
|
||||
{
|
||||
FILE* f;
|
||||
struct mnttab ent;
|
||||
f = fopen("/etc/mnttab", "r");
|
||||
if (f == NULL)
|
||||
{
|
||||
WLog_ERR(TAG, "fopen failed!");
|
||||
WLog_Print(log, WLOG_ERROR, "fopen failed!");
|
||||
return ERROR_OPEN_FAILED;
|
||||
}
|
||||
while (getmntent(f, &ent) == 0)
|
||||
@ -682,7 +721,7 @@ static UINT handle_platform_mounts_sun(hotplug_dev* dev_array, size_t* size)
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
#include <sys/mount.h>
|
||||
static UINT handle_platform_mounts_bsd(hotplug_dev* dev_array, size_t* size)
|
||||
static UINT handle_platform_mounts_bsd(wLog* log, hotplug_dev* dev_array, size_t* size)
|
||||
{
|
||||
int mntsize;
|
||||
size_t idx;
|
||||
@ -692,7 +731,7 @@ static UINT handle_platform_mounts_bsd(hotplug_dev* dev_array, size_t* size)
|
||||
if (!mntsize)
|
||||
{
|
||||
/* TODO: handle 'errno' */
|
||||
WLog_ERR(TAG, "getmntinfo failed!");
|
||||
WLog_Print(log, WLOG_ERROR, "getmntinfo failed!");
|
||||
return ERROR_OPEN_FAILED;
|
||||
}
|
||||
for (idx = 0; idx < (size_t)mntsize; idx++)
|
||||
@ -706,14 +745,14 @@ static UINT handle_platform_mounts_bsd(hotplug_dev* dev_array, size_t* size)
|
||||
|
||||
#if defined(__LINUX__) || defined(__linux__)
|
||||
#include <mntent.h>
|
||||
static UINT handle_platform_mounts_linux(hotplug_dev* dev_array, size_t* size)
|
||||
static UINT handle_platform_mounts_linux(wLog* log, hotplug_dev* dev_array, size_t* size)
|
||||
{
|
||||
FILE* f;
|
||||
struct mntent* ent;
|
||||
f = fopen("/proc/mounts", "r");
|
||||
if (f == NULL)
|
||||
{
|
||||
WLog_ERR(TAG, "fopen failed!");
|
||||
WLog_Print(log, WLOG_ERROR, "fopen failed!");
|
||||
return ERROR_OPEN_FAILED;
|
||||
}
|
||||
while ((ent = getmntent(f)) != NULL)
|
||||
@ -725,14 +764,14 @@ static UINT handle_platform_mounts_linux(hotplug_dev* dev_array, size_t* size)
|
||||
}
|
||||
#endif
|
||||
|
||||
static UINT handle_platform_mounts(hotplug_dev* dev_array, size_t* size)
|
||||
static UINT handle_platform_mounts(wLog* log, hotplug_dev* dev_array, size_t* size)
|
||||
{
|
||||
#ifdef __sun
|
||||
return handle_platform_mounts_sun(dev_array, size);
|
||||
return handle_platform_mounts_sun(log, dev_array, size);
|
||||
#elif defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
return handle_platform_mounts_bsd(dev_array, size);
|
||||
return handle_platform_mounts_bsd(log, dev_array, size);
|
||||
#elif defined(__LINUX__) || defined(__linux__)
|
||||
return handle_platform_mounts_linux(dev_array, size);
|
||||
return handle_platform_mounts_linux(log, dev_array, size);
|
||||
#endif
|
||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||
}
|
||||
@ -790,7 +829,7 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr)
|
||||
UINT32 ids[1];
|
||||
UINT error = ERROR_SUCCESS;
|
||||
|
||||
error = handle_platform_mounts(dev_array, &size);
|
||||
error = handle_platform_mounts(rdpdr->log, dev_array, &size);
|
||||
|
||||
/* delete removed devices */
|
||||
count = ListDictionary_GetKeys(rdpdr->devman->devices, &keys);
|
||||
@ -834,9 +873,9 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr)
|
||||
|
||||
if ((error = rdpdr_send_device_list_remove_request(rdpdr, 1, ids)))
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"rdpdr_send_device_list_remove_request failed with error %" PRIu32 "!",
|
||||
error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR,
|
||||
"rdpdr_send_device_list_remove_request failed with error %" PRIu32 "!",
|
||||
error);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
@ -858,7 +897,7 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr)
|
||||
|
||||
if (!drive.Name)
|
||||
{
|
||||
WLog_ERR(TAG, "_strdup failed!");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "_strdup failed!");
|
||||
error = CHANNEL_RC_NO_MEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
@ -866,7 +905,7 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr)
|
||||
if ((error = devman_load_device_service(rdpdr->devman, (const RDPDR_DEVICE*)&drive,
|
||||
rdpdr->rdpcontext)))
|
||||
{
|
||||
WLog_ERR(TAG, "devman_load_device_service failed!");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "devman_load_device_service failed!");
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
@ -887,7 +926,7 @@ static void first_hotplug(rdpdrPlugin* rdpdr)
|
||||
|
||||
if ((error = handle_hotplug(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "handle_hotplug failed with error %" PRIu32 "!", error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "handle_hotplug failed with error %" PRIu32 "!", error);
|
||||
}
|
||||
}
|
||||
|
||||
@ -905,7 +944,7 @@ static DWORD WINAPI drive_hotplug_thread_func(LPVOID arg)
|
||||
|
||||
if (mfd < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "ERROR: Unable to open /proc/mounts.");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "ERROR: Unable to open /proc/mounts.");
|
||||
error = ERROR_INTERNAL_ERROR;
|
||||
goto out;
|
||||
}
|
||||
@ -922,7 +961,8 @@ static DWORD WINAPI drive_hotplug_thread_func(LPVOID arg)
|
||||
if (status == WAIT_FAILED)
|
||||
{
|
||||
error = GetLastError();
|
||||
WLog_ERR(TAG, "WaitForSingleObject failed with error %" PRIu32 "!", error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "WaitForSingleObject failed with error %" PRIu32 "!",
|
||||
error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -934,11 +974,12 @@ static DWORD WINAPI drive_hotplug_thread_func(LPVOID arg)
|
||||
/* file /proc/mounts changed, handle this */
|
||||
if ((error = handle_hotplug(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "handle_hotplug failed with error %" PRIu32 "!", error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "handle_hotplug failed with error %" PRIu32 "!",
|
||||
error);
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
rdpdr_send_device_list_announce_request(rdpdr, TRUE);
|
||||
rdpdr_try_send_device_list_announce_request(rdpdr);
|
||||
}
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
@ -978,7 +1019,8 @@ static UINT drive_hotplug_thread_terminate(rdpdrPlugin* rdpdr)
|
||||
if (WaitForSingleObject(rdpdr->hotplugThread, INFINITE) == WAIT_FAILED)
|
||||
{
|
||||
error = GetLastError();
|
||||
WLog_ERR(TAG, "WaitForSingleObject failed with error %" PRIu32 "!", error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "WaitForSingleObject failed with error %" PRIu32 "!",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -1007,7 +1049,7 @@ static UINT rdpdr_process_connect(rdpdrPlugin* rdpdr)
|
||||
|
||||
if (!rdpdr->devman)
|
||||
{
|
||||
WLog_ERR(TAG, "devman_new failed!");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "devman_new failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
@ -1036,7 +1078,7 @@ static UINT rdpdr_process_connect(rdpdrPlugin* rdpdr)
|
||||
|
||||
if (!(rdpdr->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
{
|
||||
WLog_ERR(TAG, "CreateEvent failed!");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "CreateEvent failed!");
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
@ -1045,7 +1087,7 @@ static UINT rdpdr_process_connect(rdpdrPlugin* rdpdr)
|
||||
if (!(rdpdr->hotplugThread =
|
||||
CreateThread(NULL, 0, drive_hotplug_thread_func, rdpdr, 0, NULL)))
|
||||
{
|
||||
WLog_ERR(TAG, "CreateThread failed!");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "CreateThread failed!");
|
||||
#ifndef _WIN32
|
||||
CloseHandle(rdpdr->stopEvent);
|
||||
rdpdr->stopEvent = NULL;
|
||||
@ -1059,7 +1101,8 @@ static UINT rdpdr_process_connect(rdpdrPlugin* rdpdr)
|
||||
|
||||
if ((error = devman_load_device_service(rdpdr->devman, device, rdpdr->rdpcontext)))
|
||||
{
|
||||
WLog_ERR(TAG, "devman_load_device_service failed with error %" PRIu32 "!", error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR,
|
||||
"devman_load_device_service failed with error %" PRIu32 "!", error);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
@ -1087,11 +1130,16 @@ static UINT rdpdr_process_server_announce_request(rdpdrPlugin* rdpdr, wStream* s
|
||||
static UINT rdpdr_send_client_announce_reply(rdpdrPlugin* rdpdr)
|
||||
{
|
||||
wStream* s;
|
||||
|
||||
WINPR_ASSERT(rdpdr);
|
||||
WINPR_ASSERT(rdpdr->state == RDPDR_CHANNEL_STATE_ANNOUNCE);
|
||||
rdpdr_state_advance(rdpdr, RDPDR_CHANNEL_STATE_ANNOUNCE_REPLY);
|
||||
|
||||
s = Stream_New(NULL, 12);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "Stream_New failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
@ -1114,6 +1162,10 @@ static UINT rdpdr_send_client_name_request(rdpdrPlugin* rdpdr)
|
||||
WCHAR* computerNameW = NULL;
|
||||
size_t computerNameLenW;
|
||||
|
||||
WINPR_ASSERT(rdpdr);
|
||||
WINPR_ASSERT(rdpdr->state == RDPDR_CHANNEL_STATE_ANNOUNCE_REPLY);
|
||||
rdpdr_state_advance(rdpdr, RDPDR_CHANNEL_STATE_NAME_REQUEST);
|
||||
|
||||
if (!rdpdr->computerName[0])
|
||||
{
|
||||
DWORD size = sizeof(rdpdr->computerName) - 1;
|
||||
@ -1126,7 +1178,7 @@ static UINT rdpdr_send_client_name_request(rdpdrPlugin* rdpdr)
|
||||
if (!s)
|
||||
{
|
||||
free(computerNameW);
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "Stream_New failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
@ -1147,7 +1199,10 @@ static UINT rdpdr_process_server_clientid_confirm(rdpdrPlugin* rdpdr, wStream* s
|
||||
UINT16 versionMinor;
|
||||
UINT32 clientID;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 8)
|
||||
WINPR_ASSERT(rdpdr);
|
||||
WINPR_ASSERT(s);
|
||||
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, 8))
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, versionMajor);
|
||||
@ -1184,11 +1239,23 @@ static UINT rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use
|
||||
DEVICE* device;
|
||||
int keyCount;
|
||||
ULONG_PTR* pKeys = NULL;
|
||||
|
||||
if (userLoggedOn)
|
||||
{
|
||||
WINPR_ASSERT(rdpdr->state >= RDPDR_CHANNEL_STATE_READY);
|
||||
rdpdr_state_advance(rdpdr, RDPDR_CHANNEL_STATE_USER_LOGGEDON);
|
||||
}
|
||||
else
|
||||
{
|
||||
WINPR_ASSERT(rdpdr->state >= RDPDR_CHANNEL_STATE_CLIENTID_CONFIRM);
|
||||
rdpdr_state_advance(rdpdr, RDPDR_CHANNEL_STATE_READY);
|
||||
}
|
||||
|
||||
s = Stream_New(NULL, 256);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "Stream_New failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
@ -1220,7 +1287,7 @@ static UINT rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use
|
||||
{
|
||||
free(pKeys);
|
||||
Stream_Free(s, TRUE);
|
||||
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "Stream_EnsureRemainingCapacity failed!");
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
@ -1244,8 +1311,9 @@ static UINT rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use
|
||||
Stream_Write(s, Stream_Buffer(device->data), data_len);
|
||||
|
||||
count++;
|
||||
WLog_INFO(TAG, "registered device #%" PRIu32 ": %s (type=%" PRIu32 " id=%" PRIu32 ")",
|
||||
count, device->name, device->type, device->id);
|
||||
WLog_Print(rdpdr->log, WLOG_INFO,
|
||||
"registered device #%" PRIu32 ": %s (type=%" PRIu32 " id=%" PRIu32 ")",
|
||||
count, device->name, device->type, device->id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1258,6 +1326,19 @@ static UINT rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use
|
||||
return rdpdr_send(rdpdr, s);
|
||||
}
|
||||
|
||||
UINT rdpdr_try_send_device_list_announce_request(rdpdrPlugin* rdpdr)
|
||||
{
|
||||
WINPR_ASSERT(rdpdr);
|
||||
if (rdpdr->state != RDPDR_CHANNEL_STATE_USER_LOGGEDON)
|
||||
{
|
||||
WLog_Print(rdpdr->log, WLOG_DEBUG,
|
||||
"hotplug event received, but channel [RDPDR] is not ready (state %s), ignoring.",
|
||||
rdpdr_state_str(rdpdr->state));
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
return rdpdr_send_device_list_announce_request(rdpdr, TRUE);
|
||||
}
|
||||
|
||||
static UINT dummy_irp_response(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
|
||||
@ -1268,7 +1349,7 @@ static UINT dummy_irp_response(rdpdrPlugin* rdpdr, wStream* s)
|
||||
wStream* output = Stream_New(NULL, 256); // RDPDR_DEVICE_IO_RESPONSE_LENGTH
|
||||
if (!output)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "Stream_New failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
@ -1301,11 +1382,11 @@ static UINT rdpdr_process_irp(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
IRP* irp;
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
irp = irp_new(rdpdr->devman, s, &error);
|
||||
irp = irp_new(rdpdr->devman, s, rdpdr->log, &error);
|
||||
|
||||
if (!irp)
|
||||
{
|
||||
WLog_ERR(TAG, "irp_new failed with %" PRIu32 "!", error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "irp_new failed with %" PRIu32 "!", error);
|
||||
|
||||
if (error == CHANNEL_RC_OK)
|
||||
{
|
||||
@ -1317,8 +1398,11 @@ static UINT rdpdr_process_irp(rdpdrPlugin* rdpdr, wStream* s)
|
||||
|
||||
IFCALLRET(irp->device->IRPRequest, error, irp->device, irp);
|
||||
|
||||
if (error)
|
||||
WLog_ERR(TAG, "device->IRPRequest failed with error %" PRIu32 "", error);
|
||||
if (error != CHANNEL_RC_OK)
|
||||
{
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "device->IRPRequest failed with error %" PRIu32 "",
|
||||
error);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
@ -1370,7 +1454,7 @@ static UINT rdpdr_process_init(rdpdrPlugin* rdpdr)
|
||||
|
||||
if (error != CHANNEL_RC_OK)
|
||||
{
|
||||
WLog_ERR(TAG, "Init failed!");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "Init failed!");
|
||||
free(pKeys);
|
||||
return error;
|
||||
}
|
||||
@ -1380,6 +1464,58 @@ static UINT rdpdr_process_init(rdpdrPlugin* rdpdr)
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
static BOOL rdpdr_state_check(rdpdrPlugin* rdpdr, UINT16 packetid,
|
||||
enum RDPDR_CHANNEL_STATE expected, enum RDPDR_CHANNEL_STATE next)
|
||||
{
|
||||
WINPR_ASSERT(rdpdr);
|
||||
|
||||
const char* strstate = rdpdr_state_str(rdpdr->state);
|
||||
if (rdpdr->state != expected)
|
||||
{
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR,
|
||||
"channel [RDPDR] received %" PRIu16
|
||||
", expected state %s but have state %s, aborting.",
|
||||
packetid, rdpdr_state_str(expected), strstate);
|
||||
|
||||
rdpdr_state_advance(rdpdr, RDPDR_CHANNEL_STATE_INITIAL);
|
||||
return FALSE;
|
||||
}
|
||||
return rdpdr_state_advance(rdpdr, next);
|
||||
}
|
||||
|
||||
static BOOL rdpdr_check_channel_state(rdpdrPlugin* rdpdr, UINT16 packetid)
|
||||
{
|
||||
WINPR_ASSERT(rdpdr);
|
||||
|
||||
switch (packetid)
|
||||
{
|
||||
case PAKID_CORE_SERVER_ANNOUNCE:
|
||||
/* windows servers sometimes send this message.
|
||||
* it seems related to session login (e.g. first initialization for RDP/TLS style login,
|
||||
* then reinitialize the channel after login successful
|
||||
*/
|
||||
rdpdr_state_advance(rdpdr, RDPDR_CHANNEL_STATE_INITIAL);
|
||||
return rdpdr_state_check(rdpdr, packetid, RDPDR_CHANNEL_STATE_INITIAL,
|
||||
RDPDR_CHANNEL_STATE_ANNOUNCE);
|
||||
case PAKID_CORE_SERVER_CAPABILITY:
|
||||
return rdpdr_state_check(rdpdr, packetid, RDPDR_CHANNEL_STATE_NAME_REQUEST,
|
||||
RDPDR_CHANNEL_STATE_SERVER_CAPS);
|
||||
case PAKID_CORE_CLIENTID_CONFIRM:
|
||||
return rdpdr_state_check(rdpdr, packetid, RDPDR_CHANNEL_STATE_CLIENT_CAPS,
|
||||
RDPDR_CHANNEL_STATE_CLIENTID_CONFIRM);
|
||||
case PAKID_CORE_USER_LOGGEDON:
|
||||
return rdpdr_state_check(rdpdr, packetid, RDPDR_CHANNEL_STATE_READY,
|
||||
RDPDR_CHANNEL_STATE_USER_LOGGEDON);
|
||||
default:
|
||||
{
|
||||
enum RDPDR_CHANNEL_STATE state = RDPDR_CHANNEL_STATE_READY;
|
||||
if (rdpdr->state == RDPDR_CHANNEL_STATE_USER_LOGGEDON)
|
||||
state = RDPDR_CHANNEL_STATE_USER_LOGGEDON;
|
||||
return rdpdr_state_check(rdpdr, packetid, state, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
@ -1403,6 +1539,9 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
||||
|
||||
if (component == RDPDR_CTYP_CORE)
|
||||
{
|
||||
if (!rdpdr_check_channel_state(rdpdr, packetId))
|
||||
return CHANNEL_RC_OK;
|
||||
|
||||
switch (packetId)
|
||||
{
|
||||
case PAKID_CORE_SERVER_ANNOUNCE:
|
||||
@ -1411,19 +1550,20 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
||||
}
|
||||
else if ((error = rdpdr_send_client_announce_reply(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"rdpdr_send_client_announce_reply failed with error %" PRIu32 "",
|
||||
error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR,
|
||||
"rdpdr_send_client_announce_reply failed with error %" PRIu32 "",
|
||||
error);
|
||||
}
|
||||
else if ((error = rdpdr_send_client_name_request(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"rdpdr_send_client_name_request failed with error %" PRIu32 "",
|
||||
error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR,
|
||||
"rdpdr_send_client_name_request failed with error %" PRIu32 "",
|
||||
error);
|
||||
}
|
||||
else if ((error = rdpdr_process_init(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_process_init failed with error %" PRIu32 "", error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR,
|
||||
"rdpdr_process_init failed with error %" PRIu32 "", error);
|
||||
}
|
||||
|
||||
break;
|
||||
@ -1434,9 +1574,9 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
||||
}
|
||||
else if ((error = rdpdr_send_capability_response(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"rdpdr_send_capability_response failed with error %" PRIu32 "",
|
||||
error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR,
|
||||
"rdpdr_send_capability_response failed with error %" PRIu32 "",
|
||||
error);
|
||||
}
|
||||
|
||||
break;
|
||||
@ -1447,8 +1587,8 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
||||
}
|
||||
else if ((error = rdpdr_send_device_list_announce_request(rdpdr, FALSE)))
|
||||
{
|
||||
WLog_ERR(
|
||||
TAG,
|
||||
WLog_Print(
|
||||
rdpdr->log, WLOG_ERROR,
|
||||
"rdpdr_send_device_list_announce_request failed with error %" PRIu32 "",
|
||||
error);
|
||||
}
|
||||
@ -1458,8 +1598,8 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
||||
case PAKID_CORE_USER_LOGGEDON:
|
||||
if ((error = rdpdr_send_device_list_announce_request(rdpdr, TRUE)))
|
||||
{
|
||||
WLog_ERR(
|
||||
TAG,
|
||||
WLog_Print(
|
||||
rdpdr->log, WLOG_ERROR,
|
||||
"rdpdr_send_device_list_announce_request failed with error %" PRIu32 "",
|
||||
error);
|
||||
}
|
||||
@ -1481,7 +1621,8 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
||||
case PAKID_CORE_DEVICE_IOREQUEST:
|
||||
if ((error = rdpdr_process_irp(rdpdr, s)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_process_irp failed with error %" PRIu32 "", error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR,
|
||||
"rdpdr_process_irp failed with error %" PRIu32 "", error);
|
||||
return error;
|
||||
}
|
||||
else
|
||||
@ -1490,7 +1631,8 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "RDPDR_CTYP_CORE unknown PacketId: 0x%04" PRIX16 "", packetId);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR,
|
||||
"RDPDR_CTYP_CORE unknown PacketId: 0x%04" PRIX16 "", packetId);
|
||||
error = ERROR_INVALID_DATA;
|
||||
break;
|
||||
}
|
||||
@ -1501,9 +1643,10 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
||||
|
||||
if (error != CHANNEL_RC_OK)
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"Unknown message: Component: 0x%04" PRIX16 " PacketId: 0x%04" PRIX16 "",
|
||||
component, packetId);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR,
|
||||
"Unknown message: Component: [0x%04" PRIX16 "] PacketId: [0x%04" PRIX16
|
||||
"]",
|
||||
component, packetId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1543,8 +1686,8 @@ UINT rdpdr_send(rdpdrPlugin* rdpdr, wStream* s)
|
||||
if (status != CHANNEL_RC_OK)
|
||||
{
|
||||
Stream_Free(s, TRUE);
|
||||
WLog_ERR(TAG, "pVirtualChannelWriteEx failed with %s [%08" PRIX32 "]",
|
||||
WTSErrorToString(status), status);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "pVirtualChannelWriteEx failed with %s [%08" PRIX32 "]",
|
||||
WTSErrorToString(status), status);
|
||||
}
|
||||
|
||||
return status;
|
||||
@ -1581,7 +1724,7 @@ static UINT rdpdr_virtual_channel_event_data_received(rdpdrPlugin* rdpdr, void*
|
||||
|
||||
if (!rdpdr->data_in)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "Stream_New failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
@ -1590,7 +1733,7 @@ static UINT rdpdr_virtual_channel_event_data_received(rdpdrPlugin* rdpdr, void*
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(data_in, dataLength))
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "Stream_EnsureRemainingCapacity failed!");
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
@ -1600,7 +1743,8 @@ static UINT rdpdr_virtual_channel_event_data_received(rdpdrPlugin* rdpdr, void*
|
||||
{
|
||||
if (Stream_Capacity(data_in) != Stream_GetPosition(data_in))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_virtual_channel_event_data_received: read error");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR,
|
||||
"rdpdr_virtual_channel_event_data_received: read error");
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
@ -1610,7 +1754,7 @@ static UINT rdpdr_virtual_channel_event_data_received(rdpdrPlugin* rdpdr, void*
|
||||
|
||||
if (!MessageQueue_Post(rdpdr->queue, NULL, 0, (void*)data_in, NULL))
|
||||
{
|
||||
WLog_ERR(TAG, "MessageQueue_Post failed!");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "MessageQueue_Post failed!");
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
@ -1631,14 +1775,15 @@ static VOID VCAPITYPE rdpdr_virtual_channel_open_event_ex(LPVOID lpUserParam, DW
|
||||
case CHANNEL_EVENT_DATA_RECEIVED:
|
||||
if (!rdpdr || !pData || (rdpdr->OpenHandle != openHandle))
|
||||
{
|
||||
WLog_ERR(TAG, "error no match");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "error no match");
|
||||
return;
|
||||
}
|
||||
if ((error = rdpdr_virtual_channel_event_data_received(rdpdr, pData, dataLength,
|
||||
totalLength, dataFlags)))
|
||||
WLog_ERR(TAG,
|
||||
"rdpdr_virtual_channel_event_data_received failed with error %" PRIu32 "!",
|
||||
error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR,
|
||||
"rdpdr_virtual_channel_event_data_received failed with error %" PRIu32
|
||||
"!",
|
||||
error);
|
||||
|
||||
break;
|
||||
|
||||
@ -1676,7 +1821,8 @@ static DWORD WINAPI rdpdr_virtual_channel_client_thread(LPVOID arg)
|
||||
|
||||
if ((error = rdpdr_process_connect(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_process_connect failed with error %" PRIu32 "!", error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "rdpdr_process_connect failed with error %" PRIu32 "!",
|
||||
error);
|
||||
|
||||
if (rdpdr->rdpcontext)
|
||||
setChannelError(rdpdr->rdpcontext, error,
|
||||
@ -1702,7 +1848,8 @@ static DWORD WINAPI rdpdr_virtual_channel_client_thread(LPVOID arg)
|
||||
|
||||
if ((error = rdpdr_process_receive(rdpdr, data)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_process_receive failed with error %" PRIu32 "!", error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR,
|
||||
"rdpdr_process_receive failed with error %" PRIu32 "!", error);
|
||||
|
||||
if (rdpdr->rdpcontext)
|
||||
setChannelError(rdpdr->rdpcontext, error,
|
||||
@ -1740,8 +1887,8 @@ static UINT rdpdr_virtual_channel_event_connected(rdpdrPlugin* rdpdr, LPVOID pDa
|
||||
|
||||
if (status != CHANNEL_RC_OK)
|
||||
{
|
||||
WLog_ERR(TAG, "pVirtualChannelOpenEx failed with %s [%08" PRIX32 "]",
|
||||
WTSErrorToString(status), status);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "pVirtualChannelOpenEx failed with %s [%08" PRIX32 "]",
|
||||
WTSErrorToString(status), status);
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -1749,7 +1896,7 @@ static UINT rdpdr_virtual_channel_event_connected(rdpdrPlugin* rdpdr, LPVOID pDa
|
||||
|
||||
if (!rdpdr->queue)
|
||||
{
|
||||
WLog_ERR(TAG, "MessageQueue_New failed!");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "MessageQueue_New failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
@ -1758,7 +1905,7 @@ static UINT rdpdr_virtual_channel_event_connected(rdpdrPlugin* rdpdr, LPVOID pDa
|
||||
if (!(rdpdr->thread =
|
||||
CreateThread(NULL, 0, rdpdr_virtual_channel_client_thread, (void*)rdpdr, 0, NULL)))
|
||||
{
|
||||
WLog_ERR(TAG, "CreateThread failed!");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "CreateThread failed!");
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
@ -1781,7 +1928,8 @@ static UINT rdpdr_virtual_channel_event_disconnected(rdpdrPlugin* rdpdr)
|
||||
(WaitForSingleObject(rdpdr->thread, INFINITE) == WAIT_FAILED))
|
||||
{
|
||||
error = GetLastError();
|
||||
WLog_ERR(TAG, "WaitForSingleObject failed with error %" PRIu32 "!", error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "WaitForSingleObject failed with error %" PRIu32 "!",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -1792,7 +1940,8 @@ static UINT rdpdr_virtual_channel_event_disconnected(rdpdrPlugin* rdpdr)
|
||||
|
||||
if ((error = drive_hotplug_thread_terminate(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "drive_hotplug_thread_terminate failed with error %" PRIu32 "!", error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR,
|
||||
"drive_hotplug_thread_terminate failed with error %" PRIu32 "!", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -1800,8 +1949,8 @@ static UINT rdpdr_virtual_channel_event_disconnected(rdpdrPlugin* rdpdr)
|
||||
|
||||
if (CHANNEL_RC_OK != error)
|
||||
{
|
||||
WLog_ERR(TAG, "pVirtualChannelCloseEx failed with %s [%08" PRIX32 "]",
|
||||
WTSErrorToString(error), error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "pVirtualChannelCloseEx failed with %s [%08" PRIX32 "]",
|
||||
WTSErrorToString(error), error);
|
||||
}
|
||||
|
||||
rdpdr->OpenHandle = 0;
|
||||
@ -1835,7 +1984,7 @@ static VOID VCAPITYPE rdpdr_virtual_channel_init_event_ex(LPVOID lpUserParam, LP
|
||||
|
||||
if (!rdpdr || (rdpdr->InitHandle != pInitHandle))
|
||||
{
|
||||
WLog_ERR(TAG, "error no match");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "error no match");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1846,17 +1995,18 @@ static VOID VCAPITYPE rdpdr_virtual_channel_init_event_ex(LPVOID lpUserParam, LP
|
||||
|
||||
case CHANNEL_EVENT_CONNECTED:
|
||||
if ((error = rdpdr_virtual_channel_event_connected(rdpdr, pData, dataLength)))
|
||||
WLog_ERR(TAG,
|
||||
"rdpdr_virtual_channel_event_connected failed with error %" PRIu32 "!",
|
||||
error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR,
|
||||
"rdpdr_virtual_channel_event_connected failed with error %" PRIu32 "!",
|
||||
error);
|
||||
|
||||
break;
|
||||
|
||||
case CHANNEL_EVENT_DISCONNECTED:
|
||||
if ((error = rdpdr_virtual_channel_event_disconnected(rdpdr)))
|
||||
WLog_ERR(TAG,
|
||||
"rdpdr_virtual_channel_event_disconnected failed with error %" PRIu32 "!",
|
||||
error);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR,
|
||||
"rdpdr_virtual_channel_event_disconnected failed with error %" PRIu32
|
||||
"!",
|
||||
error);
|
||||
|
||||
break;
|
||||
|
||||
@ -1867,7 +2017,7 @@ static VOID VCAPITYPE rdpdr_virtual_channel_init_event_ex(LPVOID lpUserParam, LP
|
||||
case CHANNEL_EVENT_ATTACHED:
|
||||
case CHANNEL_EVENT_DETACHED:
|
||||
default:
|
||||
WLog_ERR(TAG, "unknown event %" PRIu32 "!", event);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "unknown event %" PRIu32 "!", event);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1877,6 +2027,7 @@ static VOID VCAPITYPE rdpdr_virtual_channel_init_event_ex(LPVOID lpUserParam, LP
|
||||
}
|
||||
|
||||
/* rdpdr is always built-in */
|
||||
#define TAG CHANNELS_TAG("rdpdr.client")
|
||||
#define VirtualChannelEntryEx rdpdr_VirtualChannelEntryEx
|
||||
|
||||
BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID pInitHandle)
|
||||
@ -1888,9 +2039,11 @@ BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID p
|
||||
|
||||
if (!rdpdr)
|
||||
{
|
||||
WLog_ERR(TAG, "calloc failed!");
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "calloc failed!");
|
||||
return FALSE;
|
||||
}
|
||||
rdpdr->log = WLog_Get(TAG);
|
||||
WINPR_ASSERT(rdpdr->log);
|
||||
|
||||
rdpdr->channelDef.options =
|
||||
CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP | CHANNEL_OPTION_COMPRESS_RDP;
|
||||
@ -1912,8 +2065,8 @@ BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID p
|
||||
|
||||
if (CHANNEL_RC_OK != rc)
|
||||
{
|
||||
WLog_ERR(TAG, "pVirtualChannelInitEx failed with %s [%08" PRIX32 "]", WTSErrorToString(rc),
|
||||
rc);
|
||||
WLog_Print(rdpdr->log, WLOG_ERROR, "pVirtualChannelInitEx failed with %s [%08" PRIX32 "]",
|
||||
WTSErrorToString(rc), rc);
|
||||
free(rdpdr);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -42,15 +42,33 @@
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#endif
|
||||
|
||||
#define TAG CHANNELS_TAG("rdpdr.client")
|
||||
#if !defined(Stream_CheckAndLogRequiredLengthWLog)
|
||||
#define Stream_CheckAndLogRequiredLengthWLog(log, s, len) \
|
||||
Stream_CheckAndLogRequiredLengthWLogEx(log, WLOG_WARN, s, len, "%s(%s:%d)", __FUNCTION__, \
|
||||
__FILE__, __LINE__)
|
||||
#endif
|
||||
|
||||
typedef struct rdpdr_plugin rdpdrPlugin;
|
||||
|
||||
enum RDPDR_CHANNEL_STATE
|
||||
{
|
||||
RDPDR_CHANNEL_STATE_INITIAL = 0,
|
||||
RDPDR_CHANNEL_STATE_ANNOUNCE,
|
||||
RDPDR_CHANNEL_STATE_ANNOUNCE_REPLY,
|
||||
RDPDR_CHANNEL_STATE_NAME_REQUEST,
|
||||
RDPDR_CHANNEL_STATE_SERVER_CAPS,
|
||||
RDPDR_CHANNEL_STATE_CLIENT_CAPS,
|
||||
RDPDR_CHANNEL_STATE_CLIENTID_CONFIRM,
|
||||
RDPDR_CHANNEL_STATE_READY,
|
||||
RDPDR_CHANNEL_STATE_USER_LOGGEDON
|
||||
};
|
||||
|
||||
struct rdpdr_plugin
|
||||
{
|
||||
CHANNEL_DEF channelDef;
|
||||
CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints;
|
||||
|
||||
enum RDPDR_CHANNEL_STATE state;
|
||||
HANDLE thread;
|
||||
wStream* data_in;
|
||||
void* InitHandle;
|
||||
@ -78,8 +96,10 @@ struct rdpdr_plugin
|
||||
HANDLE stopEvent;
|
||||
#endif
|
||||
rdpContext* rdpcontext;
|
||||
wLog* log;
|
||||
};
|
||||
|
||||
BOOL rdpdr_state_advance(rdpdrPlugin* rdpdr, enum RDPDR_CHANNEL_STATE next);
|
||||
UINT rdpdr_send(rdpdrPlugin* rdpdr, wStream* s);
|
||||
|
||||
#endif /* FREERDP_CHANNEL_RDPDR_CLIENT_MAIN_H */
|
||||
|
||||
@ -686,8 +686,6 @@ static wStream* device_server_packet_new(size_t size, BYTE version, BYTE message
|
||||
{
|
||||
wStream* s;
|
||||
|
||||
WINPR_ASSERT(size > 0);
|
||||
|
||||
/* Allocate what we need plus header bytes */
|
||||
s = Stream_New(NULL, size + CAM_HEADER_SIZE);
|
||||
if (!s)
|
||||
|
||||
@ -523,7 +523,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 * 1ULL;
|
||||
length = 1ull * context->priv->out_pending_frames * context->priv->src_bytes_per_frame;
|
||||
|
||||
if (!freerdp_dsp_encode(context->priv->dsp_context, context->src_format, src, length, s))
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
|
||||
@ -235,8 +235,10 @@ static BOOL tsmf_ffmpeg_init_stream(ITSMFDecoder* decoder, const TS_AM_MEDIA_TYP
|
||||
}
|
||||
}
|
||||
|
||||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 18, 100)
|
||||
if (mdecoder->codec->capabilities & AV_CODEC_CAP_TRUNCATED)
|
||||
mdecoder->codec_context->flags |= AV_CODEC_FLAG_TRUNCATED;
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -134,26 +134,44 @@ BOOL wlf_handle_pointer_buttons(freerdp* instance, const UwacPointerButtonEvent*
|
||||
}
|
||||
|
||||
BOOL wlf_handle_pointer_axis(freerdp* instance, const UwacPointerAxisEvent* ev)
|
||||
{
|
||||
wlfContext* context;
|
||||
if (!instance || !instance->context || !ev)
|
||||
return FALSE;
|
||||
|
||||
context = (wlfContext*)instance->context;
|
||||
ArrayList_Add(context->events, ev);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL wlf_handle_pointer_axis_discrete(freerdp* instance, const UwacPointerAxisEvent* ev)
|
||||
{
|
||||
wlfContext* context;
|
||||
if (!instance || !instance->context || !ev)
|
||||
return FALSE;
|
||||
|
||||
context = (wlfContext*)instance->context;
|
||||
ArrayList_Add(context->events, ev);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL wlf_handle_wheel(freerdp* instance, uint32_t x, uint32_t y, uint32_t axis,
|
||||
int32_t value)
|
||||
{
|
||||
rdpInput* input;
|
||||
UINT16 flags = 0;
|
||||
int32_t direction;
|
||||
uint32_t x, y;
|
||||
uint32_t i;
|
||||
uint32_t avalue = abs(value);
|
||||
|
||||
if (!instance || !ev || !instance->input)
|
||||
return FALSE;
|
||||
|
||||
x = ev->x;
|
||||
y = ev->y;
|
||||
input = instance->input;
|
||||
|
||||
if (!wlf_scale_coordinates(instance->context, &x, &y, TRUE))
|
||||
return FALSE;
|
||||
|
||||
input = instance->input;
|
||||
|
||||
direction = ev->value;
|
||||
switch (ev->axis)
|
||||
direction = value;
|
||||
switch (axis)
|
||||
{
|
||||
case WL_POINTER_AXIS_VERTICAL_SCROLL:
|
||||
flags |= PTR_FLAGS_WHEEL;
|
||||
@ -176,16 +194,102 @@ BOOL wlf_handle_pointer_axis(freerdp* instance, const UwacPointerAxisEvent* ev)
|
||||
* positive: 0 ... 0xFF -> slow ... fast
|
||||
* negative: 0 ... 0xFF -> fast ... slow
|
||||
*/
|
||||
for (i = 0; i < abs(direction); i++)
|
||||
|
||||
while (avalue > 0)
|
||||
{
|
||||
uint32_t cflags = flags | 0x78;
|
||||
const uint32_t cval = avalue > 0xFF ? 0xFF : avalue;
|
||||
uint32_t cflags = flags | cval;
|
||||
/* Convert negative values to 9bit twos complement */
|
||||
if (flags & PTR_FLAGS_WHEEL_NEGATIVE)
|
||||
cflags = (flags & 0xFF00) | (0x100 - (cflags & 0xFF));
|
||||
cflags = (flags & 0xFF00) | (0x100 - cval);
|
||||
if (!freerdp_input_send_mouse_event(input, cflags, (UINT16)x, (UINT16)y))
|
||||
return FALSE;
|
||||
|
||||
avalue -= cval;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL wlf_handle_pointer_frame(freerdp* instance, const UwacPointerFrameEvent* ev)
|
||||
{
|
||||
BOOL success = TRUE;
|
||||
BOOL handle = FALSE;
|
||||
size_t x;
|
||||
wlfContext* context;
|
||||
enum wl_pointer_axis_source source;
|
||||
|
||||
if (!instance || !ev || !instance->input || !instance->context)
|
||||
return FALSE;
|
||||
|
||||
context = (wlfContext*)instance->context;
|
||||
|
||||
for (x = 0; x < ArrayList_Count(context->events); x++)
|
||||
{
|
||||
UwacEvent* ev = ArrayList_GetItem(context->events, x);
|
||||
if (!ev)
|
||||
continue;
|
||||
if (ev->type == UWAC_EVENT_POINTER_SOURCE)
|
||||
{
|
||||
handle = TRUE;
|
||||
source = ev->mouse_source.axis_source;
|
||||
}
|
||||
}
|
||||
|
||||
/* We need source events to determine how to interpret the data */
|
||||
if (handle)
|
||||
{
|
||||
for (x = 0; x < ArrayList_Count(context->events); x++)
|
||||
{
|
||||
UwacEvent* ev = ArrayList_GetItem(context->events, x);
|
||||
if (!ev)
|
||||
continue;
|
||||
|
||||
switch (source)
|
||||
{
|
||||
/* If we have a mouse wheel, just use discrete data */
|
||||
case WL_POINTER_AXIS_SOURCE_WHEEL:
|
||||
#if defined(WL_POINTER_AXIS_SOURCE_WHEEL_TILT_SINCE_VERSION)
|
||||
case WL_POINTER_AXIS_SOURCE_WHEEL_TILT:
|
||||
#endif
|
||||
if (ev->type == UWAC_EVENT_POINTER_AXIS_DISCRETE)
|
||||
{
|
||||
/* Get the number of steps, multiply by default step width of 120 */
|
||||
int32_t val = ev->mouse_axis.value * 0x78;
|
||||
/* No wheel event received, success! */
|
||||
if (!wlf_handle_wheel(instance, ev->mouse_axis.x, ev->mouse_axis.y,
|
||||
ev->mouse_axis.axis, val))
|
||||
success = FALSE;
|
||||
}
|
||||
break;
|
||||
/* If we have a touch pad we get actual data, scale */
|
||||
case WL_POINTER_AXIS_SOURCE_FINGER:
|
||||
case WL_POINTER_AXIS_SOURCE_CONTINUOUS:
|
||||
if (ev->type == UWAC_EVENT_POINTER_AXIS)
|
||||
{
|
||||
double dval = wl_fixed_to_double(ev->mouse_axis.value);
|
||||
int32_t val = dval * 0x78 / 10.0;
|
||||
if (!wlf_handle_wheel(instance, ev->mouse_axis.x, ev->mouse_axis.y,
|
||||
ev->mouse_axis.axis, val))
|
||||
success = FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ArrayList_Clear(context->events);
|
||||
return success;
|
||||
}
|
||||
|
||||
BOOL wlf_handle_pointer_source(freerdp* instance, const UwacPointerSourceEvent* ev)
|
||||
{
|
||||
wlfContext* context;
|
||||
if (!instance || !instance->context || !ev)
|
||||
return FALSE;
|
||||
|
||||
context = (wlfContext*)instance->context;
|
||||
ArrayList_Add(context->events, ev);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@ -30,6 +30,9 @@ BOOL wlf_handle_pointer_enter(freerdp* instance, const UwacPointerEnterLeaveEven
|
||||
BOOL wlf_handle_pointer_motion(freerdp* instance, const UwacPointerMotionEvent* ev);
|
||||
BOOL wlf_handle_pointer_buttons(freerdp* instance, const UwacPointerButtonEvent* ev);
|
||||
BOOL wlf_handle_pointer_axis(freerdp* instance, const UwacPointerAxisEvent* ev);
|
||||
BOOL wlf_handle_pointer_axis_discrete(freerdp* instance, const UwacPointerAxisEvent* ev);
|
||||
BOOL wlf_handle_pointer_frame(freerdp* instance, const UwacPointerFrameEvent* ev);
|
||||
BOOL wlf_handle_pointer_source(freerdp* instance, const UwacPointerSourceEvent* ev);
|
||||
BOOL wlf_handle_touch_up(freerdp* instance, const UwacTouchUp* ev);
|
||||
BOOL wlf_handle_touch_down(freerdp* instance, const UwacTouchDown* ev);
|
||||
BOOL wlf_handle_touch_motion(freerdp* instance, const UwacTouchMotion* ev);
|
||||
|
||||
@ -362,12 +362,22 @@ static BOOL handle_uwac_events(freerdp* instance, UwacDisplay* display)
|
||||
break;
|
||||
|
||||
case UWAC_EVENT_POINTER_AXIS:
|
||||
if (!wlf_handle_pointer_axis(instance, &event.mouse_axis))
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case UWAC_EVENT_POINTER_AXIS_DISCRETE:
|
||||
if (!wlf_handle_pointer_axis(instance, &event.mouse_axis))
|
||||
if (!wlf_handle_pointer_axis_discrete(instance, &event.mouse_axis))
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case UWAC_EVENT_POINTER_FRAME:
|
||||
if (!wlf_handle_pointer_frame(instance, &event.mouse_frame))
|
||||
return FALSE;
|
||||
break;
|
||||
case UWAC_EVENT_POINTER_SOURCE:
|
||||
if (!wlf_handle_pointer_source(instance, &event.mouse_source))
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case UWAC_EVENT_KEY:
|
||||
@ -561,8 +571,37 @@ static int wlf_logon_error_info(freerdp* instance, UINT32 data, UINT32 type)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void wlf_client_free(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
wlfContext* wlf = (wlfContext*)instance->context;
|
||||
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
if (wlf->display)
|
||||
UwacCloseDisplay(&wlf->display);
|
||||
|
||||
if (wlf->displayHandle)
|
||||
CloseHandle(wlf->displayHandle);
|
||||
ArrayList_Free(wlf->events);
|
||||
DeleteCriticalSection(&wlf->critical);
|
||||
}
|
||||
|
||||
static void* uwac_event_clone(const void* val)
|
||||
{
|
||||
UwacEvent* copy;
|
||||
UwacEvent* ev = (UwacEvent*)val;
|
||||
|
||||
copy = calloc(1, sizeof(UwacEvent));
|
||||
if (!copy)
|
||||
return NULL;
|
||||
*copy = *ev;
|
||||
return copy;
|
||||
}
|
||||
|
||||
static BOOL wlf_client_new(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
wObject* obj;
|
||||
UwacReturnCode status;
|
||||
wlfContext* wfl = (wlfContext*)context;
|
||||
|
||||
@ -590,26 +629,19 @@ static BOOL wlf_client_new(freerdp* instance, rdpContext* context)
|
||||
if (!wfl->displayHandle)
|
||||
return FALSE;
|
||||
|
||||
wfl->events = ArrayList_New(FALSE);
|
||||
if (!wfl->events)
|
||||
return FALSE;
|
||||
|
||||
obj = ArrayList_Object(wfl->events);
|
||||
obj->fnObjectNew = uwac_event_clone;
|
||||
obj->fnObjectFree = free;
|
||||
|
||||
InitializeCriticalSection(&wfl->critical);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void wlf_client_free(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
wlfContext* wlf = (wlfContext*)instance->context;
|
||||
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
if (wlf->display)
|
||||
UwacCloseDisplay(&wlf->display);
|
||||
|
||||
if (wlf->displayHandle)
|
||||
CloseHandle(wlf->displayHandle);
|
||||
DeleteCriticalSection(&wlf->critical);
|
||||
}
|
||||
|
||||
static int wfl_client_start(rdpContext* context)
|
||||
{
|
||||
WINPR_UNUSED(context);
|
||||
|
||||
@ -53,6 +53,7 @@ struct wlf_context
|
||||
wlfDispContext* disp;
|
||||
wLog* log;
|
||||
CRITICAL_SECTION critical;
|
||||
wArrayList* events;
|
||||
};
|
||||
|
||||
BOOL wlf_scale_coordinates(rdpContext* context, UINT32* px, UINT32* py, BOOL fromLocalToRDP);
|
||||
|
||||
@ -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) * 1ULL;
|
||||
size = 1ull * cmd->bmp.width * cmd->bmp.height * GetBytesPerPixel(format);
|
||||
if (size > cmd->bmp.bitmapDataLength)
|
||||
{
|
||||
WLog_ERR(TAG, "Short nocodec message: got %" PRIu32 " bytes, require %" PRIuz,
|
||||
|
||||
@ -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 * 1ULL;
|
||||
size = 1ull * surface->gdi.scanline * surface->gdi.height;
|
||||
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 * 1ULL;
|
||||
size = 1ull * surface->stageScanline * surface->gdi.height;
|
||||
surface->stage = (BYTE*)_aligned_malloc(size, 16);
|
||||
|
||||
if (!surface->stage)
|
||||
|
||||
@ -311,7 +311,7 @@ static BOOL xf_Pointer_GetCursorForCurrentScale(rdpContext* context, const rdpPo
|
||||
ci.height = yTargetSize;
|
||||
ci.xhot = pointer->xPos * xscale;
|
||||
ci.yhot = pointer->yPos * yscale;
|
||||
size = ci.height * ci.width * GetBytesPerPixel(CursorFormat) * 1ULL;
|
||||
size = 1ull * ci.height * ci.width * GetBytesPerPixel(CursorFormat);
|
||||
|
||||
if (!(ci.pixels = (XcursorPixel*)_aligned_malloc(size, 16)))
|
||||
{
|
||||
@ -421,7 +421,7 @@ static BOOL xf_Pointer_New(rdpContext* context, rdpPointer* pointer)
|
||||
xpointer->nCursors = 0;
|
||||
xpointer->mCursors = 0;
|
||||
|
||||
size = pointer->height * pointer->width * GetBytesPerPixel(CursorFormat) * 1ULL;
|
||||
size = 1ull * pointer->height * pointer->width * GetBytesPerPixel(CursorFormat);
|
||||
|
||||
if (!(xpointer->cursorPixels = (XcursorPixel*)_aligned_malloc(size, 16)))
|
||||
goto fail;
|
||||
@ -560,7 +560,7 @@ static BOOL xf_Pointer_SetPosition(rdpContext* context, UINT32 x, UINT32 y)
|
||||
}
|
||||
|
||||
WLog_DBG(TAG, "%s: %" PRIu32 "x%" PRIu32, __func__, x, y);
|
||||
if (xfc->remote_app && !xfc->focused)
|
||||
if (!xfc->focused)
|
||||
return TRUE;
|
||||
|
||||
xf_adjust_coordinates_to_screen(xfc, &x, &y);
|
||||
@ -583,7 +583,7 @@ static BOOL xf_Pointer_SetPosition(rdpContext* context, UINT32 x, UINT32 y)
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = XWarpPointer(xfc->display, None, handle, 0, 0, 0, 0, x, y);
|
||||
rc = XWarpPointer(xfc->display, handle, handle, 0, 0, 0, 0, x, y);
|
||||
if (rc == 0)
|
||||
WLog_WARN(TAG, "%s: XWarpPointer==%d", __func__, rc);
|
||||
tmp.event_mask = current.your_event_mask;
|
||||
|
||||
@ -544,7 +544,7 @@ static xfRailIconCache* RailIconCache_New(rdpSettings* settings)
|
||||
|
||||
cache->numCaches = settings->RemoteAppNumIconCaches;
|
||||
cache->numCacheEntries = settings->RemoteAppNumIconCacheEntries;
|
||||
cache->entries = calloc(cache->numCaches * cache->numCacheEntries * 1ULL, sizeof(xfRailIcon));
|
||||
cache->entries = calloc(1ull * cache->numCaches * cache->numCacheEntries, sizeof(xfRailIcon));
|
||||
|
||||
if (!cache->entries)
|
||||
{
|
||||
@ -614,7 +614,7 @@ static BOOL convert_rail_icon(const ICON_INFO* iconInfo, xfRailIcon* railIcon)
|
||||
long* pixels;
|
||||
int i;
|
||||
int nelements;
|
||||
argbPixels = calloc(iconInfo->width * iconInfo->height * 1ULL, 4);
|
||||
argbPixels = calloc(1ull * iconInfo->width * iconInfo->height, 4);
|
||||
|
||||
if (!argbPixels)
|
||||
goto error;
|
||||
|
||||
@ -2996,6 +2996,10 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
|
||||
{
|
||||
settings->GrabKeyboard = enable;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "grab-mouse")
|
||||
{
|
||||
settings->GrabMouse = enable;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "unmap-buttons")
|
||||
{
|
||||
settings->UnmapButtons = enable;
|
||||
|
||||
@ -184,6 +184,7 @@ static const COMMAND_LINE_ARGUMENT_A args[] = {
|
||||
{ "gp", COMMAND_LINE_VALUE_REQUIRED, "<password>", NULL, NULL, -1, NULL, "Gateway password" },
|
||||
{ "grab-keyboard", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
|
||||
"Grab keyboard" },
|
||||
{ "grab-mouse", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Grab mouse" },
|
||||
{ "gt", COMMAND_LINE_VALUE_REQUIRED, "[rpc|http[,no-websockets]|auto[,no-websockets]]", NULL,
|
||||
NULL, -1, NULL, "Gateway transport type" },
|
||||
{ "gu", COMMAND_LINE_VALUE_REQUIRED, "[[<domain>\\]<user>|<user>[@<domain>]]", NULL, NULL, -1,
|
||||
|
||||
@ -55,7 +55,7 @@ FIND_PATH(OPENSSL_INCLUDE_DIR
|
||||
NAMES
|
||||
openssl/ssl.h
|
||||
PATH_SUFFIXES
|
||||
"include"
|
||||
"include"
|
||||
HINTS
|
||||
${_OPENSSL_INCLUDEDIR}
|
||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
||||
@ -172,8 +172,8 @@ ELSEIF(WIN32 AND NOT CYGWIN)
|
||||
)
|
||||
|
||||
set( OPENSSL_DEBUG_LIBRARIES ${SSL_EAY_DEBUG} ${LIB_EAY_DEBUG} )
|
||||
set( OPENSSL_RELEASE_LIBRARIES ${SSL_EAY_RELEASE} ${LIB_EAY_RELEASE} )
|
||||
set( OPENSSL_LIBRARIES ${OPENSSL_RELEASE_LIBRARIES} )
|
||||
set( OPENSSL_RELEASE_LIBRARIES ${SSL_EAY_RELEASE} ${LIB_EAY_RELEASE} )
|
||||
set( OPENSSL_LIBRARIES ${OPENSSL_RELEASE_LIBRARIES} )
|
||||
|
||||
MARK_AS_ADVANCED(SSL_EAY_DEBUG SSL_EAY_RELEASE)
|
||||
MARK_AS_ADVANCED(LIB_EAY_DEBUG LIB_EAY_RELEASE)
|
||||
@ -313,25 +313,50 @@ if (OPENSSL_INCLUDE_DIR)
|
||||
|
||||
string(REGEX REPLACE "^.*OPENSSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F]).*$"
|
||||
"\\1;\\2;\\3;\\4;\\5" OPENSSL_VERSION_LIST "${openssl_version_str}")
|
||||
list(GET OPENSSL_VERSION_LIST 0 OPENSSL_VERSION_MAJOR)
|
||||
list(GET OPENSSL_VERSION_LIST 1 OPENSSL_VERSION_MINOR)
|
||||
from_hex("${OPENSSL_VERSION_MINOR}" OPENSSL_VERSION_MINOR)
|
||||
list(GET OPENSSL_VERSION_LIST 2 OPENSSL_VERSION_FIX)
|
||||
from_hex("${OPENSSL_VERSION_FIX}" OPENSSL_VERSION_FIX)
|
||||
list(GET OPENSSL_VERSION_LIST 3 OPENSSL_VERSION_PATCH)
|
||||
if (OPENSSL_VERSION_LIST)
|
||||
list(GET OPENSSL_VERSION_LIST 0 OPENSSL_VERSION_MAJOR)
|
||||
list(GET OPENSSL_VERSION_LIST 1 OPENSSL_VERSION_MINOR)
|
||||
from_hex("${OPENSSL_VERSION_MINOR}" OPENSSL_VERSION_MINOR)
|
||||
list(GET OPENSSL_VERSION_LIST 2 OPENSSL_VERSION_FIX)
|
||||
from_hex("${OPENSSL_VERSION_FIX}" OPENSSL_VERSION_FIX)
|
||||
list(GET OPENSSL_VERSION_LIST 3 OPENSSL_VERSION_PATCH)
|
||||
|
||||
if (NOT OPENSSL_VERSION_PATCH STREQUAL "00")
|
||||
from_hex("${OPENSSL_VERSION_PATCH}" _tmp)
|
||||
# 96 is the ASCII code of 'a' minus 1
|
||||
math(EXPR OPENSSL_VERSION_PATCH_ASCII "${_tmp} + 96")
|
||||
unset(_tmp)
|
||||
# Once anyone knows how OpenSSL would call the patch versions beyond 'z'
|
||||
# this should be updated to handle that, too. This has not happened yet
|
||||
# so it is simply ignored here for now.
|
||||
string(ASCII "${OPENSSL_VERSION_PATCH_ASCII}" OPENSSL_VERSION_PATCH_STRING)
|
||||
endif (NOT OPENSSL_VERSION_PATCH STREQUAL "00")
|
||||
if (NOT OPENSSL_VERSION_PATCH STREQUAL "00")
|
||||
from_hex("${OPENSSL_VERSION_PATCH}" _tmp)
|
||||
# 96 is the ASCII code of 'a' minus 1
|
||||
math(EXPR OPENSSL_VERSION_PATCH_ASCII "${_tmp} + 96")
|
||||
unset(_tmp)
|
||||
# Once anyone knows how OpenSSL would call the patch versions beyond 'z'
|
||||
# this should be updated to handle that, too. This has not happened yet
|
||||
# so it is simply ignored here for now.
|
||||
string(ASCII "${OPENSSL_VERSION_PATCH_ASCII}" OPENSSL_VERSION_PATCH_STRING)
|
||||
endif (NOT OPENSSL_VERSION_PATCH STREQUAL "00")
|
||||
|
||||
set(OPENSSL_VERSION "${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_MINOR}.${OPENSSL_VERSION_FIX}${OPENSSL_VERSION_PATCH_STRING}")
|
||||
set(OPENSSL_VERSION "${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_MINOR}.${OPENSSL_VERSION_FIX}${OPENSSL_VERSION_PATCH_STRING}")
|
||||
endif()
|
||||
|
||||
if (NOT OPENSSL_VERSION_LIST)
|
||||
file(STRINGS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h" openssl_version_str_str
|
||||
REGEX "^#[\t ]*define[\t ]+OPENSSL_VERSION_STR[\t ]\"([0-9a-fA-F]+)\\.([0-9a-fA-F]+)\\.([0-9a-fA-F]+).*\".*$")
|
||||
string(REGEX REPLACE "^.*OPENSSL_VERSION_STR[\t ]+\"([0-9a-fA-F]+)\\.([0-9a-fA-F]+)\\.([0-9a-fA-F]+).*\".*$"
|
||||
"\\1.\\2.\\3" OPENSSL_VERSION "${openssl_version_str_str}")
|
||||
endif()
|
||||
|
||||
if (NOT OPENSSL_VERSION_LIST)
|
||||
file(STRINGS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h" openssl_version_major_str
|
||||
REGEX "^#[\t ]*define[\t ]+OPENSSL_VERSION_MAJOR[\t ]+([0-9a-fA-F]+).*$")
|
||||
string(REGEX REPLACE "^#[\t ]*define[\t ]+OPENSSL_VERSION_MAJOR[\t ]+([0-9a-fA-F]+).*$"
|
||||
"\\1" OPENSSL_VERSION_MAJOR "${openssl_version_major_str}")
|
||||
file(STRINGS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h" openssl_version_minor_str
|
||||
REGEX "^#[\t ]*define[\t ]+OPENSSL_VERSION_MINOR[\t ]+([0-9a-fA-F]+).*$")
|
||||
string(REGEX REPLACE "^#[\t ]*define[\t ]+OPENSSL_VERSION_MINOR[\t ]+([0-9a-fA-F]+).*$"
|
||||
"\\1" OPENSSL_VERSION_MINOR "${openssl_version_minor_str}")
|
||||
file(STRINGS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h" openssl_version_patch_str
|
||||
REGEX "^#[\t ]*define[\t ]+OPENSSL_VERSION_PATCH[\t ]+([0-9a-fA-F]+).*$")
|
||||
string(REGEX REPLACE "^#[\t ]*define[\t ]+OPENSSL_VERSION_PATCH[\t ]+([0-9a-fA-F]+).*$"
|
||||
"\\1" OPENSSL_VERSION_PATCH "${openssl_version_patch_str}")
|
||||
set(OPENSSL_VERSION "${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_MINOR}.${OPENSSL_VERSION_PATCH}")
|
||||
endif()
|
||||
endif (_OPENSSL_VERSION)
|
||||
endif (OPENSSL_INCLUDE_DIR)
|
||||
|
||||
|
||||
@ -730,6 +730,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
|
||||
#define FreeRDP_PercentScreenUseWidth (1556)
|
||||
#define FreeRDP_PercentScreenUseHeight (1557)
|
||||
#define FreeRDP_DynamicResolutionUpdate (1558)
|
||||
#define FreeRDP_GrabMouse (1559)
|
||||
#define FreeRDP_SoftwareGdi (1601)
|
||||
#define FreeRDP_LocalConnection (1602)
|
||||
#define FreeRDP_AuthenticationOnly (1603)
|
||||
@ -1216,7 +1217,8 @@ struct rdp_settings
|
||||
ALIGN64 BOOL PercentScreenUseWidth; /* 1556 */
|
||||
ALIGN64 BOOL PercentScreenUseHeight; /* 1557 */
|
||||
ALIGN64 BOOL DynamicResolutionUpdate; /* 1558 */
|
||||
UINT64 padding1601[1601 - 1559]; /* 1559 */
|
||||
ALIGN64 BOOL GrabMouse; /* 1559 */
|
||||
UINT64 padding1601[1601 - 1560]; /* 1560 */
|
||||
|
||||
/* Miscellaneous */
|
||||
ALIGN64 BOOL SoftwareGdi; /* 1601 */
|
||||
|
||||
3
libfreerdp/cache/pointer.c
vendored
3
libfreerdp/cache/pointer.c
vendored
@ -68,6 +68,9 @@ static BOOL update_pointer_position(rdpContext* context,
|
||||
!pointer_position)
|
||||
return FALSE;
|
||||
|
||||
if (!context->settings->GrabMouse)
|
||||
return TRUE;
|
||||
|
||||
pointer = context->graphics->Pointer_Prototype;
|
||||
return IFCALLRESULT(TRUE, pointer->SetPosition, context, pointer_position->xPos,
|
||||
pointer_position->yPos);
|
||||
|
||||
@ -566,7 +566,7 @@ static BOOL resize_vbar_entry(CLEAR_CONTEXT* clear, CLEAR_VBAR_ENTRY* vBarEntry)
|
||||
const UINT32 diffSize = (vBarEntry->count - vBarEntry->size) * bpp;
|
||||
BYTE* tmp;
|
||||
vBarEntry->size = vBarEntry->count;
|
||||
tmp = (BYTE*)realloc(vBarEntry->pixels, vBarEntry->count * bpp * 1ULL);
|
||||
tmp = (BYTE*)realloc(vBarEntry->pixels, 1ull * vBarEntry->count * bpp);
|
||||
|
||||
if (!tmp)
|
||||
{
|
||||
@ -591,13 +591,9 @@ static BOOL resize_vbar_entry(CLEAR_CONTEXT* clear, CLEAR_VBAR_ENTRY* vBarEntry)
|
||||
static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32 bandsByteCount,
|
||||
UINT32 nWidth, UINT32 nHeight, BYTE* pDstData,
|
||||
UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst,
|
||||
UINT32 nYDst)
|
||||
UINT32 nYDst, UINT32 nDstWidth, UINT32 nDstHeight)
|
||||
{
|
||||
UINT32 i, y;
|
||||
UINT32 count;
|
||||
UINT32 suboffset;
|
||||
UINT32 nXDstRel;
|
||||
UINT32 nYDstRel;
|
||||
UINT32 suboffset = 0;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < bandsByteCount)
|
||||
{
|
||||
@ -605,22 +601,20 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
suboffset = 0;
|
||||
|
||||
while (suboffset < bandsByteCount)
|
||||
{
|
||||
BYTE r, g, b;
|
||||
BYTE cr, cg, cb;
|
||||
UINT16 xStart;
|
||||
UINT16 xEnd;
|
||||
UINT16 yStart;
|
||||
UINT16 yEnd;
|
||||
UINT32 colorBkg;
|
||||
UINT16 vBarHeader;
|
||||
UINT16 vBarYOn;
|
||||
UINT16 vBarYOn = 0;
|
||||
UINT16 vBarYOff;
|
||||
UINT32 vBarCount;
|
||||
UINT32 vBarPixelCount;
|
||||
UINT32 vBarShortPixelCount;
|
||||
UINT32 vBarShortPixelCount = 0;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 11)
|
||||
{
|
||||
@ -632,11 +626,11 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32
|
||||
Stream_Read_UINT16(s, xEnd);
|
||||
Stream_Read_UINT16(s, yStart);
|
||||
Stream_Read_UINT16(s, yEnd);
|
||||
Stream_Read_UINT8(s, b);
|
||||
Stream_Read_UINT8(s, g);
|
||||
Stream_Read_UINT8(s, r);
|
||||
Stream_Read_UINT8(s, cb);
|
||||
Stream_Read_UINT8(s, cg);
|
||||
Stream_Read_UINT8(s, cr);
|
||||
suboffset += 11;
|
||||
colorBkg = FreeRDPGetColor(clear->format, r, g, b, 0xFF);
|
||||
colorBkg = FreeRDPGetColor(clear->format, cr, cg, cb, 0xFF);
|
||||
|
||||
if (xEnd < xStart)
|
||||
{
|
||||
@ -652,13 +646,13 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32
|
||||
|
||||
vBarCount = (xEnd - xStart) + 1;
|
||||
|
||||
for (i = 0; i < vBarCount; i++)
|
||||
for (UINT32 i = 0; i < vBarCount; i++)
|
||||
{
|
||||
UINT32 vBarHeight;
|
||||
CLEAR_VBAR_ENTRY* vBarEntry = NULL;
|
||||
CLEAR_VBAR_ENTRY* vBarShortEntry;
|
||||
CLEAR_VBAR_ENTRY* vBarShortEntry = NULL;
|
||||
BOOL vBarUpdate = FALSE;
|
||||
const BYTE* pSrcPixel;
|
||||
const BYTE* cpSrcPixel;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
{
|
||||
@ -740,11 +734,11 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32
|
||||
if (!resize_vbar_entry(clear, vBarShortEntry))
|
||||
return FALSE;
|
||||
|
||||
for (y = 0; y < vBarShortPixelCount; y++)
|
||||
for (UINT32 y = 0; y < vBarShortPixelCount; y++)
|
||||
{
|
||||
BYTE r, g, b;
|
||||
BYTE r = 0, g = 0, b = 0;
|
||||
BYTE* dstBuffer = &vBarShortEntry->pixels[y * GetBytesPerPixel(clear->format)];
|
||||
UINT32 color;
|
||||
UINT32 color = 0;
|
||||
Stream_Read_UINT8(s, b);
|
||||
Stream_Read_UINT8(s, g);
|
||||
Stream_Read_UINT8(s, r);
|
||||
@ -804,8 +798,8 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32
|
||||
|
||||
dstBuffer = vBarEntry->pixels;
|
||||
/* if (y < vBarYOn), use colorBkg */
|
||||
y = 0;
|
||||
count = vBarYOn;
|
||||
UINT32 y = 0;
|
||||
UINT32 count = vBarYOn;
|
||||
|
||||
if ((y + count) > vBarPixelCount)
|
||||
count = (vBarPixelCount > y) ? (vBarPixelCount - y) : 0;
|
||||
@ -868,28 +862,31 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
nXDstRel = nXDst + xStart;
|
||||
nYDstRel = nYDst + yStart;
|
||||
pSrcPixel = vBarEntry->pixels;
|
||||
const UINT32 nXDstRel = nXDst + xStart;
|
||||
const UINT32 nYDstRel = nYDst + yStart;
|
||||
cpSrcPixel = vBarEntry->pixels;
|
||||
|
||||
if (i < nWidth)
|
||||
{
|
||||
count = vBarEntry->count;
|
||||
UINT32 count = vBarEntry->count;
|
||||
|
||||
if (count > nHeight)
|
||||
count = nHeight;
|
||||
|
||||
for (y = 0; y < count; y++)
|
||||
if (nXDstRel + i > nDstWidth)
|
||||
return FALSE;
|
||||
|
||||
for (UINT32 y = 0; y < count; y++)
|
||||
{
|
||||
BYTE* pDstPixel8 = &pDstData[((nYDstRel + y) * nDstStep) +
|
||||
((nXDstRel + i) * GetBytesPerPixel(DstFormat))];
|
||||
UINT32 color = ReadColor(pSrcPixel, clear->format);
|
||||
UINT32 color = ReadColor(cpSrcPixel, clear->format);
|
||||
color = FreeRDPConvertColor(color, clear->format, DstFormat, NULL);
|
||||
|
||||
if (!WriteColor(pDstPixel8, DstFormat, color))
|
||||
return FALSE;
|
||||
|
||||
pSrcPixel += GetBytesPerPixel(clear->format);
|
||||
cpSrcPixel += GetBytesPerPixel(clear->format);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -980,7 +977,7 @@ static BOOL clear_decompress_glyph_data(CLEAR_CONTEXT* clear, wStream* s, UINT32
|
||||
if (glyphEntry->count > glyphEntry->size)
|
||||
{
|
||||
BYTE* tmp;
|
||||
tmp = realloc(glyphEntry->pixels, glyphEntry->count * bpp * 1ULL);
|
||||
tmp = realloc(glyphEntry->pixels, 1ull * glyphEntry->count * bpp);
|
||||
|
||||
if (!tmp)
|
||||
{
|
||||
@ -1117,7 +1114,7 @@ INT32 clear_decompress(CLEAR_CONTEXT* clear, const BYTE* pSrcData, UINT32 SrcSiz
|
||||
if (bandsByteCount > 0)
|
||||
{
|
||||
if (!clear_decompress_bands_data(clear, s, bandsByteCount, nWidth, nHeight, pDstData,
|
||||
DstFormat, nDstStep, nXDst, nYDst))
|
||||
DstFormat, nDstStep, nXDst, nYDst, nDstWidth, nDstHeight))
|
||||
{
|
||||
WLog_ERR(TAG, "clear_decompress_bands_data failed!");
|
||||
goto fail;
|
||||
|
||||
@ -56,7 +56,7 @@ BYTE* freerdp_glyph_convert(UINT32 width, UINT32 height, const BYTE* data)
|
||||
* means of accessing individual pixels in blitting operations
|
||||
*/
|
||||
scanline = (width + 7) / 8;
|
||||
dstData = (BYTE*)_aligned_malloc(width * height * 1ULL, 16);
|
||||
dstData = (BYTE*)_aligned_malloc(1ull * width * height, 16);
|
||||
|
||||
if (!dstData)
|
||||
return NULL;
|
||||
@ -545,7 +545,7 @@ BOOL freerdp_image_copy_from_pointer_data(BYTE* pDstData, UINT32 DstFormat, UINT
|
||||
for (y = nYDst; y < nHeight; y++)
|
||||
{
|
||||
BYTE* pDstLine = &pDstData[y * nDstStep + nXDst * dstBytesPerPixel];
|
||||
memset(pDstLine, 0, dstBytesPerPixel * (nWidth - nXDst) * 1ULL);
|
||||
memset(pDstLine, 0, 1ull * dstBytesPerPixel * (nWidth - nXDst));
|
||||
}
|
||||
|
||||
switch (xorBpp)
|
||||
@ -728,21 +728,22 @@ BOOL freerdp_image_copy(BYTE* pDstData, DWORD DstFormat, UINT32 nDstStep, UINT32
|
||||
BOOL freerdp_image_fill(BYTE* pDstData, DWORD DstFormat, UINT32 nDstStep, UINT32 nXDst,
|
||||
UINT32 nYDst, UINT32 nWidth, UINT32 nHeight, UINT32 color)
|
||||
{
|
||||
UINT32 x, y;
|
||||
if ((nWidth == 0) || (nHeight == 0))
|
||||
return TRUE;
|
||||
const UINT32 bpp = GetBytesPerPixel(DstFormat);
|
||||
BYTE* pFirstDstLine = &pDstData[nYDst * nDstStep];
|
||||
BYTE* pFirstDstLineXOffset = &pFirstDstLine[nXDst * bpp];
|
||||
|
||||
for (x = 0; x < nWidth; x++)
|
||||
for (UINT32 x = 0; x < nWidth; x++)
|
||||
{
|
||||
BYTE* pDst = &pFirstDstLine[(x + nXDst) * bpp];
|
||||
WriteColor(pDst, DstFormat, color);
|
||||
}
|
||||
|
||||
for (y = 1; y < nHeight; y++)
|
||||
for (UINT32 y = 1; y < nHeight; y++)
|
||||
{
|
||||
BYTE* pDstLine = &pDstData[(y + nYDst) * nDstStep + nXDst * bpp];
|
||||
memcpy(pDstLine, pFirstDstLineXOffset, nWidth * bpp * 1ULL);
|
||||
memcpy(pDstLine, pFirstDstLineXOffset, 1ull * nWidth * bpp);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
@ -63,9 +63,9 @@ BOOL avc420_ensure_buffer(H264_CONTEXT* h264, UINT32 stride, UINT32 width, UINT3
|
||||
_aligned_free(h264->pYUVData[0]);
|
||||
_aligned_free(h264->pYUVData[1]);
|
||||
_aligned_free(h264->pYUVData[2]);
|
||||
h264->pYUVData[0] = _aligned_malloc(h264->iStride[0] * height * 1ULL, 16);
|
||||
h264->pYUVData[1] = _aligned_malloc(h264->iStride[1] * height * 1ULL, 16);
|
||||
h264->pYUVData[2] = _aligned_malloc(h264->iStride[2] * height * 1ULL, 16);
|
||||
h264->pYUVData[0] = _aligned_malloc(1ull * h264->iStride[0] * height, 16);
|
||||
h264->pYUVData[1] = _aligned_malloc(1ull * h264->iStride[1] * height, 16);
|
||||
h264->pYUVData[2] = _aligned_malloc(1ull * h264->iStride[2] * height, 16);
|
||||
|
||||
if (!h264->pYUVData[0] || !h264->pYUVData[1] || !h264->pYUVData[2])
|
||||
return FALSE;
|
||||
|
||||
@ -529,10 +529,12 @@ static BOOL libavcodec_init(H264_CONTEXT* h264)
|
||||
goto EXCEPTION;
|
||||
}
|
||||
|
||||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 18, 100)
|
||||
if (sys->codecDecoder->capabilities & AV_CODEC_CAP_TRUNCATED)
|
||||
{
|
||||
sys->codecDecoderContext->flags |= AV_CODEC_FLAG_TRUNCATED;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_VAAPI
|
||||
|
||||
|
||||
@ -1994,15 +1994,9 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
UINT32* pDstSize, UINT32 flags)
|
||||
{
|
||||
UINT32 index;
|
||||
UINT32 bits;
|
||||
INT32 nbits;
|
||||
const BYTE* SrcPtr;
|
||||
const BYTE* SrcEnd;
|
||||
UINT16 Mask;
|
||||
BYTE Literal;
|
||||
UINT32 IndexLEC;
|
||||
UINT32 BitLength;
|
||||
UINT32 MaskedBits;
|
||||
UINT32 CopyOffset;
|
||||
UINT32 CopyLength;
|
||||
UINT32 OldCopyOffset;
|
||||
@ -2010,9 +2004,6 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
UINT32 LengthOfMatch;
|
||||
UINT32 CopyOffsetIndex;
|
||||
UINT32 OffsetCacheIndex;
|
||||
BYTE* HistoryPtr;
|
||||
BYTE* HistoryBuffer;
|
||||
BYTE* HistoryBufferEnd;
|
||||
UINT32 CopyOffsetBits;
|
||||
UINT32 CopyOffsetBase;
|
||||
UINT32 LengthOfMatchBits;
|
||||
@ -2021,8 +2012,8 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
if (ncrush->HistoryEndOffset != 65535)
|
||||
return -1001;
|
||||
|
||||
HistoryBuffer = ncrush->HistoryBuffer;
|
||||
HistoryBufferEnd = &HistoryBuffer[ncrush->HistoryEndOffset];
|
||||
BYTE* HistoryBuffer = ncrush->HistoryBuffer;
|
||||
const BYTE* HistoryBufferEnd = &HistoryBuffer[ncrush->HistoryEndOffset];
|
||||
|
||||
if (flags & PACKET_AT_FRONT)
|
||||
{
|
||||
@ -2041,7 +2032,7 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
ZeroMemory(&(ncrush->OffsetCache), sizeof(ncrush->OffsetCache));
|
||||
}
|
||||
|
||||
HistoryPtr = ncrush->HistoryPtr;
|
||||
BYTE* HistoryPtr = ncrush->HistoryPtr;
|
||||
|
||||
if (!(flags & PACKET_COMPRESSED))
|
||||
{
|
||||
@ -2050,17 +2041,19 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
return 1;
|
||||
}
|
||||
|
||||
SrcEnd = &pSrcData[SrcSize];
|
||||
nbits = 32;
|
||||
bits = get_dword(pSrcData);
|
||||
SrcPtr = pSrcData + 4;
|
||||
const BYTE* SrcEnd = &pSrcData[SrcSize];
|
||||
const BYTE* SrcPtr = pSrcData + 4;
|
||||
|
||||
INT32 nbits = 32;
|
||||
UINT32 bits = get_dword(pSrcData);
|
||||
while (1)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
Mask = get_word(&HuffTableMask[29]);
|
||||
MaskedBits = bits & Mask;
|
||||
const UINT16 Mask = get_word(&HuffTableMask[29]);
|
||||
const UINT32 MaskedBits = bits & Mask;
|
||||
if (MaskedBits >= ARRAYSIZE(HuffTableLEC))
|
||||
return -1;
|
||||
IndexLEC = HuffTableLEC[MaskedBits] & 0xFFF;
|
||||
BitLength = HuffTableLEC[MaskedBits] >> 12;
|
||||
bits >>= BitLength;
|
||||
@ -2096,8 +2089,10 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
return -1004;
|
||||
|
||||
CopyOffset = ncrush->OffsetCache[OffsetCacheIndex];
|
||||
Mask = get_word(&HuffTableMask[21]);
|
||||
MaskedBits = bits & Mask;
|
||||
const UINT16 Mask = get_word(&HuffTableMask[21]);
|
||||
const UINT32 MaskedBits = bits & Mask;
|
||||
if (MaskedBits > ARRAYSIZE(HuffTableLOM))
|
||||
return -1;
|
||||
LengthOfMatch = HuffTableLOM[MaskedBits] & 0xFFF;
|
||||
BitLength = HuffTableLOM[MaskedBits] >> 12;
|
||||
bits >>= BitLength;
|
||||
@ -2106,13 +2101,23 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
if (!NCrushFetchBits(&SrcPtr, &SrcEnd, &nbits, &bits))
|
||||
return -1;
|
||||
|
||||
if (LengthOfMatch >= ARRAYSIZE(LOMBitsLUT))
|
||||
return -1;
|
||||
|
||||
LengthOfMatchBits = LOMBitsLUT[LengthOfMatch];
|
||||
|
||||
if (LengthOfMatch >= ARRAYSIZE(LOMBaseLUT))
|
||||
return -1;
|
||||
LengthOfMatchBase = LOMBaseLUT[LengthOfMatch];
|
||||
|
||||
if (LengthOfMatchBits)
|
||||
{
|
||||
Mask = get_word(&HuffTableMask[(2 * LengthOfMatchBits) + 3]);
|
||||
MaskedBits = bits & Mask;
|
||||
const size_t idx = (2ull * LengthOfMatchBits) + 3ull;
|
||||
if (idx >= ARRAYSIZE(HuffTableMask))
|
||||
return -1;
|
||||
|
||||
const UINT16 Mask = get_word(&HuffTableMask[idx]);
|
||||
const UINT32 MaskedBits = bits & Mask;
|
||||
bits >>= LengthOfMatchBits;
|
||||
nbits -= LengthOfMatchBits;
|
||||
LengthOfMatchBase += MaskedBits;
|
||||
@ -2127,15 +2132,28 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CopyOffsetIndex >= ARRAYSIZE(CopyOffsetBitsLUT))
|
||||
return -1;
|
||||
|
||||
CopyOffsetBits = CopyOffsetBitsLUT[CopyOffsetIndex];
|
||||
|
||||
if (CopyOffsetIndex >= ARRAYSIZE(CopyOffsetBaseLUT))
|
||||
return -1;
|
||||
CopyOffsetBase = CopyOffsetBaseLUT[CopyOffsetIndex];
|
||||
CopyOffset = CopyOffsetBase - 1;
|
||||
|
||||
if (CopyOffsetBits)
|
||||
{
|
||||
Mask = get_word(&HuffTableMask[(2 * CopyOffsetBits) + 3]);
|
||||
MaskedBits = bits & Mask;
|
||||
CopyOffset = CopyOffsetBase + MaskedBits - 1;
|
||||
const size_t idx = (2ull * CopyOffsetBits) + 3ull;
|
||||
if (idx >= ARRAYSIZE(HuffTableMask))
|
||||
return -1;
|
||||
|
||||
const UINT16 Mask = get_word(&HuffTableMask[idx]);
|
||||
const UINT32 MaskedBits = bits & Mask;
|
||||
const UINT32 tmp = CopyOffsetBase + MaskedBits;
|
||||
if (tmp < 1)
|
||||
return -1;
|
||||
CopyOffset = tmp - 1;
|
||||
bits >>= CopyOffsetBits;
|
||||
nbits -= CopyOffsetBits;
|
||||
|
||||
@ -2143,8 +2161,11 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
return -1;
|
||||
}
|
||||
|
||||
Mask = get_word(&HuffTableMask[21]);
|
||||
MaskedBits = bits & Mask;
|
||||
const UINT16 Mask = get_word(&HuffTableMask[21]);
|
||||
const UINT32 MaskedBits = bits & Mask;
|
||||
if (MaskedBits >= ARRAYSIZE(HuffTableLOM))
|
||||
return -1;
|
||||
|
||||
LengthOfMatch = HuffTableLOM[MaskedBits] & 0xFFF;
|
||||
BitLength = HuffTableLOM[MaskedBits] >> 12;
|
||||
bits >>= BitLength;
|
||||
@ -2153,13 +2174,23 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
||||
if (!NCrushFetchBits(&SrcPtr, &SrcEnd, &nbits, &bits))
|
||||
return -1;
|
||||
|
||||
if (LengthOfMatch >= ARRAYSIZE(LOMBitsLUT))
|
||||
return -1;
|
||||
|
||||
LengthOfMatchBits = LOMBitsLUT[LengthOfMatch];
|
||||
|
||||
if (LengthOfMatch >= ARRAYSIZE(LOMBaseLUT))
|
||||
return -1;
|
||||
LengthOfMatchBase = LOMBaseLUT[LengthOfMatch];
|
||||
|
||||
if (LengthOfMatchBits)
|
||||
{
|
||||
Mask = get_word(&HuffTableMask[(2 * LengthOfMatchBits) + 3]);
|
||||
MaskedBits = bits & Mask;
|
||||
const size_t idx = (2ull * LengthOfMatchBits) + 3ull;
|
||||
if (idx >= ARRAYSIZE(HuffTableMask))
|
||||
return -1;
|
||||
|
||||
const UINT16 Mask = get_word(&HuffTableMask[idx]);
|
||||
const UINT32 MaskedBits = bits & Mask;
|
||||
bits >>= LengthOfMatchBits;
|
||||
nbits -= LengthOfMatchBits;
|
||||
LengthOfMatchBase += MaskedBits;
|
||||
@ -2583,7 +2614,12 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE
|
||||
}
|
||||
|
||||
IndexLEC = Literal;
|
||||
if (IndexLEC >= ARRAYSIZE(HuffLengthLEC))
|
||||
return -1;
|
||||
BitLength = HuffLengthLEC[IndexLEC];
|
||||
|
||||
if (IndexLEC * 2ull >= ARRAYSIZE(HuffCodeLEC))
|
||||
return -1;
|
||||
CodeLEC = get_word(&HuffCodeLEC[IndexLEC * 2]);
|
||||
|
||||
if (BitLength > 15)
|
||||
@ -2666,9 +2702,18 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE
|
||||
bits = CopyOffset;
|
||||
|
||||
CopyOffsetIndex = ncrush->HuffTableCopyOffset[bits + 2];
|
||||
|
||||
if (CopyOffsetIndex >= ARRAYSIZE(CopyOffsetBitsLUT))
|
||||
return -1;
|
||||
|
||||
CopyOffsetBits = CopyOffsetBitsLUT[CopyOffsetIndex];
|
||||
IndexLEC = 257 + CopyOffsetIndex;
|
||||
if (IndexLEC >= ARRAYSIZE(HuffLengthLEC))
|
||||
return -1;
|
||||
BitLength = HuffLengthLEC[IndexLEC];
|
||||
|
||||
if (IndexLEC * 2ull >= ARRAYSIZE(HuffCodeLEC))
|
||||
return -1;
|
||||
CodeLEC = get_word(&HuffCodeLEC[IndexLEC * 2]);
|
||||
|
||||
if (BitLength > 15)
|
||||
@ -2687,13 +2732,23 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE
|
||||
else
|
||||
IndexCO = ncrush->HuffTableLOM[MatchLength];
|
||||
|
||||
if (IndexCO >= ARRAYSIZE(HuffLengthLOM))
|
||||
return -1;
|
||||
BitLength = HuffLengthLOM[IndexCO];
|
||||
|
||||
if (IndexCO >= ARRAYSIZE(LOMBitsLUT))
|
||||
return -1;
|
||||
IndexLOM = LOMBitsLUT[IndexCO];
|
||||
|
||||
if (IndexCO >= ARRAYSIZE(HuffCodeLOM))
|
||||
return -1;
|
||||
NCrushWriteBits(&DstPtr, &accumulator, &offset, HuffCodeLOM[IndexCO], BitLength);
|
||||
Mask = ((1 << IndexLOM) - 1);
|
||||
MaskedBits = (MatchLength - 2) & Mask;
|
||||
NCrushWriteBits(&DstPtr, &accumulator, &offset, MaskedBits, IndexLOM);
|
||||
|
||||
if (IndexCO >= ARRAYSIZE(LOMBaseLUT))
|
||||
return -1;
|
||||
if ((MaskedBits + LOMBaseLUT[IndexCO]) != MatchLength)
|
||||
return -1010;
|
||||
}
|
||||
@ -2701,7 +2756,11 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE
|
||||
{
|
||||
/* CopyOffset in OffsetCache */
|
||||
IndexLEC = 289 + OffsetCacheIndex;
|
||||
if (IndexLEC >= ARRAYSIZE(HuffLengthLEC))
|
||||
return -1;
|
||||
BitLength = HuffLengthLEC[IndexLEC];
|
||||
if (IndexLEC * 2ull >= ARRAYSIZE(HuffCodeLEC))
|
||||
return -1;
|
||||
CodeLEC = get_word(&HuffCodeLEC[IndexLEC * 2]);
|
||||
|
||||
if (BitLength >= 15)
|
||||
@ -2714,13 +2773,24 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE
|
||||
else
|
||||
IndexCO = ncrush->HuffTableLOM[MatchLength];
|
||||
|
||||
if (IndexCO >= ARRAYSIZE(HuffLengthLOM))
|
||||
return -1;
|
||||
|
||||
BitLength = HuffLengthLOM[IndexCO];
|
||||
|
||||
if (IndexCO >= ARRAYSIZE(LOMBitsLUT))
|
||||
return -1;
|
||||
IndexLOM = LOMBitsLUT[IndexCO];
|
||||
|
||||
if (IndexCO >= ARRAYSIZE(HuffCodeLOM))
|
||||
return -1;
|
||||
NCrushWriteBits(&DstPtr, &accumulator, &offset, HuffCodeLOM[IndexCO], BitLength);
|
||||
Mask = ((1 << IndexLOM) - 1);
|
||||
MaskedBits = (MatchLength - 2) & Mask;
|
||||
NCrushWriteBits(&DstPtr, &accumulator, &offset, MaskedBits, IndexLOM);
|
||||
|
||||
if (IndexCO >= ARRAYSIZE(LOMBaseLUT))
|
||||
return -1;
|
||||
if ((MaskedBits + LOMBaseLUT[IndexCO]) != MatchLength)
|
||||
return -1012;
|
||||
}
|
||||
@ -2745,6 +2815,10 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE
|
||||
Literal = *SrcPtr++;
|
||||
HistoryPtr++;
|
||||
IndexLEC = Literal;
|
||||
if (IndexLEC >= ARRAYSIZE(HuffLengthLEC))
|
||||
return -1;
|
||||
if (IndexLEC * 2ull >= ARRAYSIZE(HuffCodeLEC))
|
||||
return -1;
|
||||
BitLength = HuffLengthLEC[IndexLEC];
|
||||
CodeLEC = get_word(&HuffCodeLEC[IndexLEC * 2]);
|
||||
|
||||
@ -2817,6 +2891,11 @@ static int ncrush_generate_tables(NCRUSH_CONTEXT* context)
|
||||
else
|
||||
i = context->HuffTableLOM[k];
|
||||
|
||||
if (i >= ARRAYSIZE(LOMBitsLUT))
|
||||
return -1;
|
||||
if (i >= ARRAYSIZE(LOMBaseLUT))
|
||||
return -1;
|
||||
|
||||
if (((((1 << LOMBitsLUT[i]) - 1) & (k - 2)) + LOMBaseLUT[i]) != k)
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -29,6 +29,8 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/assert.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
#include <freerdp/codec/nsc.h>
|
||||
#include <freerdp/codec/color.h>
|
||||
@ -38,6 +40,12 @@
|
||||
|
||||
#include "nsc_sse2.h"
|
||||
|
||||
#if !defined(Stream_CheckAndLogRequiredLengthWLog)
|
||||
#define Stream_CheckAndLogRequiredLengthWLog(log, s, len) \
|
||||
Stream_CheckAndLogRequiredLengthWLogEx(log, WLOG_WARN, s, len, "%s(%s:%d)", __FUNCTION__, \
|
||||
__FILE__, __LINE__)
|
||||
#endif
|
||||
|
||||
#ifndef NSC_INIT_SIMD
|
||||
#define NSC_INIT_SIMD(_nsc_context) \
|
||||
do \
|
||||
@ -111,12 +119,17 @@ static BOOL nsc_decode(NSC_CONTEXT* context)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL nsc_rle_decode(BYTE* in, BYTE* out, UINT32 outSize, UINT32 originalSize)
|
||||
static BOOL nsc_rle_decode(const BYTE* in, size_t inSize, BYTE* out, UINT32 outSize,
|
||||
UINT32 originalSize)
|
||||
{
|
||||
UINT32 left = originalSize;
|
||||
|
||||
while (left > 4)
|
||||
{
|
||||
if (inSize < 1)
|
||||
return FALSE;
|
||||
inSize--;
|
||||
|
||||
const BYTE value = *in++;
|
||||
UINT32 len = 0;
|
||||
|
||||
@ -129,17 +142,26 @@ static BOOL nsc_rle_decode(BYTE* in, BYTE* out, UINT32 outSize, UINT32 originalS
|
||||
*out++ = value;
|
||||
left--;
|
||||
}
|
||||
else if (inSize < 1)
|
||||
return FALSE;
|
||||
else if (value == *in)
|
||||
{
|
||||
inSize--;
|
||||
in++;
|
||||
|
||||
if (*in < 0xFF)
|
||||
if (inSize < 1)
|
||||
return FALSE;
|
||||
else if (*in < 0xFF)
|
||||
{
|
||||
inSize--;
|
||||
len = (UINT32)*in++;
|
||||
len += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inSize < 5)
|
||||
return FALSE;
|
||||
inSize -= 5;
|
||||
in++;
|
||||
len = ((UINT32)(*in++));
|
||||
len |= ((UINT32)(*in++)) << 8U;
|
||||
@ -169,26 +191,28 @@ static BOOL nsc_rle_decode(BYTE* in, BYTE* out, UINT32 outSize, UINT32 originalS
|
||||
if ((outSize < 4) || (left < 4))
|
||||
return FALSE;
|
||||
|
||||
if (inSize < 4)
|
||||
return FALSE;
|
||||
memcpy(out, in, 4);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL nsc_rle_decompress_data(NSC_CONTEXT* context)
|
||||
{
|
||||
UINT16 i;
|
||||
BYTE* rle;
|
||||
UINT32 planeSize;
|
||||
UINT32 originalSize;
|
||||
|
||||
if (!context)
|
||||
return FALSE;
|
||||
|
||||
rle = context->Planes;
|
||||
const BYTE* rle = context->Planes;
|
||||
size_t rleSize = context->PlanesSize;
|
||||
WINPR_ASSERT(rle);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
{
|
||||
originalSize = context->OrgByteCount[i];
|
||||
planeSize = context->PlaneByteCount[i];
|
||||
const UINT32 originalSize = context->OrgByteCount[i];
|
||||
const UINT32 planeSize = context->PlaneByteCount[i];
|
||||
|
||||
if (rleSize < planeSize)
|
||||
return FALSE;
|
||||
|
||||
if (planeSize == 0)
|
||||
{
|
||||
@ -199,7 +223,7 @@ static BOOL nsc_rle_decompress_data(NSC_CONTEXT* context)
|
||||
}
|
||||
else if (planeSize < originalSize)
|
||||
{
|
||||
if (!nsc_rle_decode(rle, context->priv->PlaneBuffers[i],
|
||||
if (!nsc_rle_decode(rle, rleSize, context->priv->PlaneBuffers[i],
|
||||
context->priv->PlaneBuffersLength, originalSize))
|
||||
return FALSE;
|
||||
}
|
||||
@ -208,6 +232,9 @@ static BOOL nsc_rle_decompress_data(NSC_CONTEXT* context)
|
||||
if (context->priv->PlaneBuffersLength < originalSize)
|
||||
return FALSE;
|
||||
|
||||
if (rleSize < originalSize)
|
||||
return FALSE;
|
||||
|
||||
CopyMemory(context->priv->PlaneBuffers[i], rle, originalSize);
|
||||
}
|
||||
|
||||
@ -219,64 +246,64 @@ static BOOL nsc_rle_decompress_data(NSC_CONTEXT* context)
|
||||
|
||||
static BOOL nsc_stream_initialize(NSC_CONTEXT* context, wStream* s)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 20)
|
||||
WINPR_ASSERT(context);
|
||||
WINPR_ASSERT(context->priv);
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(context->priv->log, s, 20))
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
size_t total = 0;
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
{
|
||||
Stream_Read_UINT32(s, context->PlaneByteCount[i]);
|
||||
total += context->PlaneByteCount[i];
|
||||
}
|
||||
|
||||
Stream_Read_UINT8(s, context->ColorLossLevel); /* ColorLossLevel (1 byte) */
|
||||
Stream_Read_UINT8(s, context->ChromaSubsamplingLevel); /* ChromaSubsamplingLevel (1 byte) */
|
||||
Stream_Seek(s, 2); /* Reserved (2 bytes) */
|
||||
context->Planes = Stream_Pointer(s);
|
||||
return TRUE;
|
||||
context->PlanesSize = total;
|
||||
return Stream_CheckAndLogRequiredLengthWLog(context->priv->log, s, total);
|
||||
}
|
||||
|
||||
static BOOL nsc_context_initialize(NSC_CONTEXT* context, wStream* s)
|
||||
{
|
||||
int i;
|
||||
UINT32 length;
|
||||
UINT32 tempWidth;
|
||||
UINT32 tempHeight;
|
||||
|
||||
if (!nsc_stream_initialize(context, s))
|
||||
return FALSE;
|
||||
|
||||
length = context->width * context->height * 4;
|
||||
const size_t blength = context->width * context->height * 4ull;
|
||||
|
||||
if (!context->BitmapData)
|
||||
{
|
||||
context->BitmapData = calloc(1, length + 16);
|
||||
context->BitmapData = calloc(1, blength + 16);
|
||||
|
||||
if (!context->BitmapData)
|
||||
return FALSE;
|
||||
|
||||
context->BitmapDataLength = length;
|
||||
context->BitmapDataLength = blength;
|
||||
}
|
||||
else if (length > context->BitmapDataLength)
|
||||
else if (blength > context->BitmapDataLength)
|
||||
{
|
||||
void* tmp;
|
||||
tmp = realloc(context->BitmapData, length + 16);
|
||||
tmp = realloc(context->BitmapData, blength + 16);
|
||||
|
||||
if (!tmp)
|
||||
return FALSE;
|
||||
|
||||
context->BitmapData = tmp;
|
||||
context->BitmapDataLength = length;
|
||||
context->BitmapDataLength = blength;
|
||||
}
|
||||
|
||||
tempWidth = ROUND_UP_TO(context->width, 8);
|
||||
tempHeight = ROUND_UP_TO(context->height, 2);
|
||||
const UINT32 tempWidth = ROUND_UP_TO(context->width, 8);
|
||||
const UINT32 tempHeight = ROUND_UP_TO(context->height, 2);
|
||||
/* The maximum length a decoded plane can reach in all cases */
|
||||
length = tempWidth * tempHeight;
|
||||
const size_t plength = 1ull * tempWidth * tempHeight;
|
||||
|
||||
if (length > context->priv->PlaneBuffersLength)
|
||||
if (plength > context->priv->PlaneBuffersLength)
|
||||
{
|
||||
for (i = 0; i < 4; i++)
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
{
|
||||
void* tmp = (BYTE*)realloc(context->priv->PlaneBuffers[i], length);
|
||||
void* tmp = (BYTE*)realloc(context->priv->PlaneBuffers[i], plength);
|
||||
|
||||
if (!tmp)
|
||||
return FALSE;
|
||||
@ -284,13 +311,11 @@ static BOOL nsc_context_initialize(NSC_CONTEXT* context, wStream* s)
|
||||
context->priv->PlaneBuffers[i] = tmp;
|
||||
}
|
||||
|
||||
context->priv->PlaneBuffersLength = length;
|
||||
context->priv->PlaneBuffersLength = plength;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
context->OrgByteCount[i] = context->width * context->height;
|
||||
}
|
||||
|
||||
if (context->ChromaSubsamplingLevel)
|
||||
{
|
||||
|
||||
@ -119,6 +119,8 @@ static BOOL nsc_encode_argb_to_aycocg(NSC_CONTEXT* context, const BYTE* data, UI
|
||||
UINT16 rw;
|
||||
BYTE ccl;
|
||||
const BYTE* src;
|
||||
const UINT32* src_32;
|
||||
const UINT16* src_16;
|
||||
BYTE* yplane = NULL;
|
||||
BYTE* coplane = NULL;
|
||||
BYTE* cgplane = NULL;
|
||||
@ -140,69 +142,85 @@ static BOOL nsc_encode_argb_to_aycocg(NSC_CONTEXT* context, const BYTE* data, UI
|
||||
coplane = context->priv->PlaneBuffers[1] + y * rw;
|
||||
cgplane = context->priv->PlaneBuffers[2] + y * rw;
|
||||
aplane = context->priv->PlaneBuffers[3] + y * context->width;
|
||||
src_32 = (UINT32*)src;
|
||||
src_16 = (UINT16*)src;
|
||||
|
||||
for (x = 0; x < context->width; x++)
|
||||
{
|
||||
switch (context->format)
|
||||
{
|
||||
case PIXEL_FORMAT_BGRX32:
|
||||
b_val = *src++;
|
||||
g_val = *src++;
|
||||
r_val = *src++;
|
||||
src++;
|
||||
b_val = (INT16)(*src_32 & 0xFF);
|
||||
g_val = (INT16)((*src_32 >> 8) & 0xFF);
|
||||
r_val = (INT16)((*src_32 >> 16) & 0xFF);
|
||||
a_val = 0xFF;
|
||||
src_32++;
|
||||
break;
|
||||
|
||||
case PIXEL_FORMAT_BGRA32:
|
||||
b_val = *src++;
|
||||
g_val = *src++;
|
||||
r_val = *src++;
|
||||
a_val = *src++;
|
||||
b_val = (INT16)(*src_32 & 0xFF);
|
||||
g_val = (INT16)((*src_32 >> 8) & 0xFF);
|
||||
r_val = (INT16)((*src_32 >> 16) & 0xFF);
|
||||
a_val = (INT16)((*src_32 >> 24) & 0xFF);
|
||||
src_32++;
|
||||
break;
|
||||
|
||||
case PIXEL_FORMAT_RGBX32:
|
||||
r_val = *src++;
|
||||
g_val = *src++;
|
||||
b_val = *src++;
|
||||
src++;
|
||||
r_val = (INT16)(*src_32 & 0xFF);
|
||||
g_val = (INT16)((*src_32 >> 8) & 0xFF);
|
||||
b_val = (INT16)((*src_32 >> 16) & 0xFF);
|
||||
a_val = 0xFF;
|
||||
src_32++;
|
||||
break;
|
||||
|
||||
case PIXEL_FORMAT_RGBA32:
|
||||
r_val = *src++;
|
||||
g_val = *src++;
|
||||
b_val = *src++;
|
||||
a_val = *src++;
|
||||
r_val = (INT16)(*src_32 & 0xFF);
|
||||
g_val = (INT16)((*src_32 >> 8) & 0xFF);
|
||||
b_val = (INT16)((*src_32 >> 16) & 0xFF);
|
||||
a_val = (INT16)((*src_32 >> 24) & 0xFF);
|
||||
src_32++;
|
||||
break;
|
||||
|
||||
case PIXEL_FORMAT_BGR24:
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
b_val = *src++;
|
||||
g_val = *src++;
|
||||
r_val = *src++;
|
||||
#else
|
||||
r_val = *src++;
|
||||
g_val = *src++;
|
||||
b_val = *src++;
|
||||
#endif
|
||||
a_val = 0xFF;
|
||||
break;
|
||||
|
||||
case PIXEL_FORMAT_RGB24:
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
r_val = *src++;
|
||||
g_val = *src++;
|
||||
b_val = *src++;
|
||||
#else
|
||||
b_val = *src++;
|
||||
g_val = *src++;
|
||||
r_val = *src++;
|
||||
#endif
|
||||
a_val = 0xFF;
|
||||
break;
|
||||
|
||||
case PIXEL_FORMAT_BGR16:
|
||||
b_val = (INT16)(((*(src + 1)) & 0xF8) | ((*(src + 1)) >> 5));
|
||||
g_val = (INT16)((((*(src + 1)) & 0x07) << 5) | (((*src) & 0xE0) >> 3));
|
||||
r_val = (INT16)((((*src) & 0x1F) << 3) | (((*src) >> 2) & 0x07));
|
||||
b_val = (INT16)((*src_16) & 0x1F);
|
||||
g_val = (INT16)((*src_16 >> 5) & 0x3F);
|
||||
r_val = (INT16)((*src_16 >> 11) & 0x1F);
|
||||
a_val = 0xFF;
|
||||
src += 2;
|
||||
src_16++;
|
||||
break;
|
||||
|
||||
case PIXEL_FORMAT_RGB16:
|
||||
r_val = (INT16)(((*(src + 1)) & 0xF8) | ((*(src + 1)) >> 5));
|
||||
g_val = (INT16)((((*(src + 1)) & 0x07) << 5) | (((*src) & 0xE0) >> 3));
|
||||
b_val = (INT16)((((*src) & 0x1F) << 3) | (((*src) >> 2) & 0x07));
|
||||
r_val = (INT16)((*src_16) & 0x1F);
|
||||
g_val = (INT16)((*src_16 >> 5) & 0x3F);
|
||||
b_val = (INT16)((*src_16 >> 11) & 0x1F);
|
||||
a_val = 0xFF;
|
||||
src += 2;
|
||||
src_16++;
|
||||
break;
|
||||
|
||||
case PIXEL_FORMAT_A4:
|
||||
@ -210,17 +228,17 @@ static BOOL nsc_encode_argb_to_aycocg(NSC_CONTEXT* context, const BYTE* data, UI
|
||||
int shift;
|
||||
BYTE idx;
|
||||
shift = (7 - (x % 8));
|
||||
idx = ((*src) >> shift) & 1;
|
||||
idx |= (((*(src + 1)) >> shift) & 1) << 1;
|
||||
idx |= (((*(src + 2)) >> shift) & 1) << 2;
|
||||
idx |= (((*(src + 3)) >> shift) & 1) << 3;
|
||||
idx = (BYTE)(((*src_32 & 0xFF) >> shift) & 1);
|
||||
idx |= (BYTE)(((((*src_32 >> 8) & 0xFF) >> shift) & 1) << 1);
|
||||
idx |= (BYTE)(((((*src_32 >> 16) & 0xFF) >> shift) & 1) << 2);
|
||||
idx |= (BYTE)(((((*src_32 >> 24) & 0xFF) >> shift) & 1) << 3);
|
||||
idx *= 3;
|
||||
r_val = (INT16)context->palette[idx];
|
||||
g_val = (INT16)context->palette[idx + 1];
|
||||
b_val = (INT16)context->palette[idx + 2];
|
||||
|
||||
if (shift == 0)
|
||||
src += 4;
|
||||
src_32++;
|
||||
}
|
||||
|
||||
a_val = 0xFF;
|
||||
|
||||
@ -61,6 +61,7 @@ struct _NSC_CONTEXT
|
||||
UINT32 BitmapDataLength;
|
||||
|
||||
BYTE* Planes;
|
||||
size_t PlanesSize;
|
||||
UINT32 PlaneByteCount[4];
|
||||
UINT32 ColorLossLevel;
|
||||
UINT32 ChromaSubsamplingLevel;
|
||||
|
||||
@ -33,7 +33,8 @@
|
||||
|
||||
#define TAG FREERDP_TAG("codec")
|
||||
|
||||
#define ALIGN(val, align) ((val) % (align) == 0) ? (val) : ((val) + (align) - (val) % (align))
|
||||
#define PLANAR_ALIGN(val, align) \
|
||||
((val) % (align) == 0) ? (val) : ((val) + (align) - (val) % (align))
|
||||
|
||||
static INLINE UINT32 planar_invert_format(BITMAP_PLANAR_CONTEXT* planar, BOOL alpha,
|
||||
UINT32 DstFormat)
|
||||
@ -612,11 +613,20 @@ BOOL planar_decompress(BITMAP_PLANAR_CONTEXT* planar, const BYTE* pSrcData, UINT
|
||||
const UINT32 h = MIN(nSrcHeight, nDstHeight);
|
||||
const primitives_t* prims = primitives_get();
|
||||
|
||||
WINPR_ASSERT(planar);
|
||||
WINPR_ASSERT(prims);
|
||||
|
||||
if (nDstStep <= 0)
|
||||
nDstStep = nDstWidth * GetBytesPerPixel(DstFormat);
|
||||
|
||||
srcp = pSrcData;
|
||||
|
||||
if (!pSrcData)
|
||||
{
|
||||
WLog_ERR(TAG, "Invalid argument pSrcData=NULL");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!pDstData)
|
||||
{
|
||||
WLog_ERR(TAG, "Invalid argument pDstData=NULL");
|
||||
@ -1484,8 +1494,8 @@ BOOL freerdp_bitmap_planar_context_reset(BITMAP_PLANAR_CONTEXT* context, UINT32
|
||||
return FALSE;
|
||||
|
||||
context->bgr = FALSE;
|
||||
context->maxWidth = ALIGN(width, 4);
|
||||
context->maxHeight = ALIGN(height, 4);
|
||||
context->maxWidth = PLANAR_ALIGN(width, 4);
|
||||
context->maxHeight = PLANAR_ALIGN(height, 4);
|
||||
context->maxPlaneSize = context->maxWidth * context->maxHeight;
|
||||
context->nTempStep = context->maxWidth * 4;
|
||||
free(context->planesBuffer);
|
||||
|
||||
@ -415,7 +415,7 @@ static INLINE BOOL progressive_tile_allocate(RFX_PROGRESSIVE_TILE* tile)
|
||||
tile->stride = 4 * tile->width;
|
||||
|
||||
{
|
||||
size_t dataLen = tile->stride * tile->height * 1ULL;
|
||||
size_t dataLen = 1ull * tile->stride * tile->height;
|
||||
tile->data = (BYTE*)_aligned_malloc(dataLen, 16);
|
||||
}
|
||||
|
||||
@ -2422,11 +2422,17 @@ INT32 progressive_decompress_ex(PROGRESSIVE_CONTEXT* progressive, const BYTE* pS
|
||||
for (j = 0; j < nbUpdateRects; j++)
|
||||
{
|
||||
const RECTANGLE_16* rect = &updateRects[j];
|
||||
const UINT32 nXSrc = rect->left - (nXDst + tile->x);
|
||||
const UINT32 nYSrc = rect->top - (nYDst + tile->y);
|
||||
if (rect->left < updateRect.left)
|
||||
goto fail;
|
||||
const UINT32 nXSrc = rect->left - updateRect.left;
|
||||
const UINT32 nYSrc = rect->top - updateRect.top;
|
||||
const UINT32 width = rect->right - rect->left;
|
||||
const UINT32 height = rect->bottom - rect->top;
|
||||
|
||||
if (rect->left + width > surface->width)
|
||||
goto fail;
|
||||
if (rect->top + height > surface->height)
|
||||
goto fail;
|
||||
if (!freerdp_image_copy(pDstData, DstFormat, nDstStep, rect->left, rect->top, width,
|
||||
height, tile->data, progressive->format, tile->stride, nXSrc,
|
||||
nYSrc, NULL, FREERDP_FLIP_NONE))
|
||||
|
||||
@ -936,6 +936,27 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa
|
||||
Stream_Read_UINT8(&sub, tile->quantIdxY); /* quantIdxY (1 byte) */
|
||||
Stream_Read_UINT8(&sub, tile->quantIdxCb); /* quantIdxCb (1 byte) */
|
||||
Stream_Read_UINT8(&sub, tile->quantIdxCr); /* quantIdxCr (1 byte) */
|
||||
if (tile->quantIdxY >= context->numQuant)
|
||||
{
|
||||
WLog_Print(context->priv->log, WLOG_ERROR, "quantIdxY %" PRIu8 " >= numQuant %" PRIu8,
|
||||
tile->quantIdxY, context->numQuant);
|
||||
rc = FALSE;
|
||||
break;
|
||||
}
|
||||
else if (tile->quantIdxCb >= context->numQuant)
|
||||
{
|
||||
WLog_Print(context->priv->log, WLOG_ERROR, "quantIdxCb %" PRIu8 " >= numQuant %" PRIu8,
|
||||
tile->quantIdxCb, context->numQuant);
|
||||
rc = FALSE;
|
||||
break;
|
||||
}
|
||||
else if (tile->quantIdxCr >= context->numQuant)
|
||||
{
|
||||
WLog_Print(context->priv->log, WLOG_ERROR, "quantIdxCr %" PRIu8 " >= numQuant %" PRIu8,
|
||||
tile->quantIdxCr, context->numQuant);
|
||||
rc = FALSE;
|
||||
break;
|
||||
}
|
||||
Stream_Read_UINT16(&sub, tile->xIdx); /* xIdx (2 bytes) */
|
||||
Stream_Read_UINT16(&sub, tile->yIdx); /* yIdx (2 bytes) */
|
||||
Stream_Read_UINT16(&sub, tile->YLen); /* YLen (2 bytes) */
|
||||
@ -1109,8 +1130,18 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data, UINT32 length,
|
||||
}
|
||||
}
|
||||
|
||||
Stream_StaticInit(&subStream, Stream_Pointer(s), blockLen - (6 + extraBlockLen));
|
||||
Stream_Seek(s, blockLen - (6 + extraBlockLen));
|
||||
const size_t blockLenNoHeader = blockLen - 6;
|
||||
if (blockLenNoHeader < extraBlockLen)
|
||||
{
|
||||
WLog_Print(context->priv->log, WLOG_ERROR,
|
||||
"blockLen too small(%" PRIu32 "), must be >= 6 + %" PRIu16, blockLen,
|
||||
extraBlockLen);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const size_t subStreamLen = blockLenNoHeader - extraBlockLen;
|
||||
Stream_StaticInit(&subStream, Stream_Pointer(s), subStreamLen);
|
||||
Stream_Seek(s, subStreamLen);
|
||||
|
||||
switch (blockType)
|
||||
{
|
||||
@ -1231,6 +1262,11 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data, UINT32 length,
|
||||
region16_uninit(&clippingRects);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
rfx_message_free(context, message);
|
||||
context->currentMessage.freeArray = TRUE;
|
||||
}
|
||||
|
||||
WLog_ERR(TAG, "%s failed", __FUNCTION__);
|
||||
return FALSE;
|
||||
|
||||
@ -49,6 +49,8 @@ static void rfx_encode_format_rgb(const BYTE* rgb_data, int width, int height, i
|
||||
int x_exceed;
|
||||
int y_exceed;
|
||||
const BYTE* src;
|
||||
const UINT32* src_32;
|
||||
const UINT16* src_16;
|
||||
INT16 r, g, b;
|
||||
INT16 *r_last, *g_last, *b_last;
|
||||
x_exceed = 64 - width;
|
||||
@ -57,6 +59,8 @@ static void rfx_encode_format_rgb(const BYTE* rgb_data, int width, int height, i
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
src = rgb_data + y * rowstride;
|
||||
src_32 = (UINT32*)src;
|
||||
src_16 = (UINT16*)src;
|
||||
|
||||
switch (pixel_format)
|
||||
{
|
||||
@ -64,10 +68,10 @@ static void rfx_encode_format_rgb(const BYTE* rgb_data, int width, int height, i
|
||||
case PIXEL_FORMAT_BGRA32:
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
*b_buf++ = (INT16)(*src++);
|
||||
*g_buf++ = (INT16)(*src++);
|
||||
*r_buf++ = (INT16)(*src++);
|
||||
src++;
|
||||
*b_buf++ = (INT16)(*src_32 & 0xFF);
|
||||
*g_buf++ = (INT16)((*src_32 >> 8) & 0xFF);
|
||||
*r_buf++ = (INT16)((*src_32 >> 16) & 0xFF);
|
||||
src_32++;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -76,10 +80,10 @@ static void rfx_encode_format_rgb(const BYTE* rgb_data, int width, int height, i
|
||||
case PIXEL_FORMAT_ABGR32:
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
src++;
|
||||
*b_buf++ = (INT16)(*src++);
|
||||
*g_buf++ = (INT16)(*src++);
|
||||
*r_buf++ = (INT16)(*src++);
|
||||
*b_buf++ = (INT16)((*src_32 >> 8) & 0xFF);
|
||||
*g_buf++ = (INT16)((*src_32 >> 16) & 0xFF);
|
||||
*r_buf++ = (INT16)((*src_32 >> 24) & 0xFF);
|
||||
src_32++;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -88,10 +92,10 @@ static void rfx_encode_format_rgb(const BYTE* rgb_data, int width, int height, i
|
||||
case PIXEL_FORMAT_RGBA32:
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
*r_buf++ = (INT16)(*src++);
|
||||
*g_buf++ = (INT16)(*src++);
|
||||
*b_buf++ = (INT16)(*src++);
|
||||
src++;
|
||||
*r_buf++ = (INT16)(*src_32 & 0xFF);
|
||||
*g_buf++ = (INT16)((*src_32 >> 8) & 0xFF);
|
||||
*b_buf++ = (INT16)((*src_32 >> 16) & 0xFF);
|
||||
src_32++;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -100,10 +104,10 @@ static void rfx_encode_format_rgb(const BYTE* rgb_data, int width, int height, i
|
||||
case PIXEL_FORMAT_ARGB32:
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
src++;
|
||||
*r_buf++ = (INT16)(*src++);
|
||||
*g_buf++ = (INT16)(*src++);
|
||||
*b_buf++ = (INT16)(*src++);
|
||||
*r_buf++ = (INT16)((*src_32 >> 8) & 0xFF);
|
||||
*g_buf++ = (INT16)((*src_32 >> 16) & 0xFF);
|
||||
*b_buf++ = (INT16)((*src_32 >> 24) & 0xFF);
|
||||
src_32++;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -111,9 +115,15 @@ static void rfx_encode_format_rgb(const BYTE* rgb_data, int width, int height, i
|
||||
case PIXEL_FORMAT_BGR24:
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
*b_buf++ = (INT16)(*src++);
|
||||
*g_buf++ = (INT16)(*src++);
|
||||
*r_buf++ = (INT16)(*src++);
|
||||
#else
|
||||
*r_buf++ = (INT16)(*src++);
|
||||
*g_buf++ = (INT16)(*src++);
|
||||
*b_buf++ = (INT16)(*src++);
|
||||
#endif
|
||||
}
|
||||
|
||||
break;
|
||||
@ -121,9 +131,15 @@ static void rfx_encode_format_rgb(const BYTE* rgb_data, int width, int height, i
|
||||
case PIXEL_FORMAT_RGB24:
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
*r_buf++ = (INT16)(*src++);
|
||||
*g_buf++ = (INT16)(*src++);
|
||||
*b_buf++ = (INT16)(*src++);
|
||||
#else
|
||||
*b_buf++ = (INT16)(*src++);
|
||||
*g_buf++ = (INT16)(*src++);
|
||||
*r_buf++ = (INT16)(*src++);
|
||||
#endif
|
||||
}
|
||||
|
||||
break;
|
||||
@ -131,10 +147,10 @@ static void rfx_encode_format_rgb(const BYTE* rgb_data, int width, int height, i
|
||||
case PIXEL_FORMAT_BGR16:
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
*b_buf++ = (INT16)(((*(src + 1)) & 0xF8) | ((*(src + 1)) >> 5));
|
||||
*g_buf++ = (INT16)((((*(src + 1)) & 0x07) << 5) | (((*src) & 0xE0) >> 3));
|
||||
*r_buf++ = (INT16)((((*src) & 0x1F) << 3) | (((*src) >> 2) & 0x07));
|
||||
src += 2;
|
||||
*b_buf++ = (INT16)((*src_16) & 0x1F);
|
||||
*g_buf++ = (INT16)((*src_16 >> 5) & 0x3F);
|
||||
*r_buf++ = (INT16)((*src_16 >> 11) & 0x1F);
|
||||
src_16++;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -142,10 +158,10 @@ static void rfx_encode_format_rgb(const BYTE* rgb_data, int width, int height, i
|
||||
case PIXEL_FORMAT_RGB16:
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
*r_buf++ = (INT16)(((*(src + 1)) & 0xF8) | ((*(src + 1)) >> 5));
|
||||
*g_buf++ = (INT16)((((*(src + 1)) & 0x07) << 5) | (((*src) & 0xE0) >> 3));
|
||||
*b_buf++ = (INT16)((((*src) & 0x1F) << 3) | (((*src) >> 2) & 0x07));
|
||||
src += 2;
|
||||
*r_buf++ = (INT16)((*src_16 & 0x1F));
|
||||
*g_buf++ = (INT16)((*src_16 >> 5) & 0x3F);
|
||||
*b_buf++ = (INT16)((*src_16 >> 11) & 0x1F);
|
||||
src_16++;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -159,17 +175,17 @@ static void rfx_encode_format_rgb(const BYTE* rgb_data, int width, int height, i
|
||||
int shift;
|
||||
BYTE idx;
|
||||
shift = (7 - (x % 8));
|
||||
idx = ((*src) >> shift) & 1;
|
||||
idx |= (((*(src + 1)) >> shift) & 1) << 1;
|
||||
idx |= (((*(src + 2)) >> shift) & 1) << 2;
|
||||
idx |= (((*(src + 3)) >> shift) & 1) << 3;
|
||||
idx = (BYTE)(((*src_32 & 0xFF) >> shift) & 1);
|
||||
idx |= (BYTE)(((((*src_32 >> 8) & 0xFF) >> shift) & 1) << 1);
|
||||
idx |= (BYTE)(((((*src_32 >> 16) & 0xFF) >> shift) & 1) << 2);
|
||||
idx |= (BYTE)(((((*src_32 >> 24) & 0xFF) >> shift) & 1) << 3);
|
||||
idx *= 3;
|
||||
*r_buf++ = (INT16)palette[idx];
|
||||
*g_buf++ = (INT16)palette[idx + 1];
|
||||
*b_buf++ = (INT16)palette[idx + 2];
|
||||
|
||||
if (shift == 0)
|
||||
src += 4;
|
||||
src_32++;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@ -674,7 +674,7 @@ static int xcrush_generate_output(XCRUSH_CONTEXT* xcrush, BYTE* OutputBuffer, UI
|
||||
if (&OutputBuffer[2] >= &OutputBuffer[OutputSize])
|
||||
return -6001; /* error */
|
||||
|
||||
*((UINT16*)OutputBuffer) = MatchCount;
|
||||
Data_Write_UINT16(OutputBuffer, MatchCount);
|
||||
MatchDetails = (RDP61_MATCH_DETAILS*)&OutputBuffer[2];
|
||||
Literals = (BYTE*)&MatchDetails[MatchCount];
|
||||
|
||||
@ -683,12 +683,12 @@ static int xcrush_generate_output(XCRUSH_CONTEXT* xcrush, BYTE* OutputBuffer, UI
|
||||
|
||||
for (MatchIndex = 0; MatchIndex < MatchCount; MatchIndex++)
|
||||
{
|
||||
MatchDetails[MatchIndex].MatchLength =
|
||||
(UINT16)(xcrush->OptimizedMatches[MatchIndex].MatchLength);
|
||||
MatchDetails[MatchIndex].MatchOutputOffset =
|
||||
(UINT16)(xcrush->OptimizedMatches[MatchIndex].MatchOffset - HistoryOffset);
|
||||
MatchDetails[MatchIndex].MatchHistoryOffset =
|
||||
xcrush->OptimizedMatches[MatchIndex].ChunkOffset;
|
||||
Data_Write_UINT16(&MatchDetails[MatchIndex].MatchLength,
|
||||
xcrush->OptimizedMatches[MatchIndex].MatchLength);
|
||||
Data_Write_UINT16(&MatchDetails[MatchIndex].MatchOutputOffset,
|
||||
xcrush->OptimizedMatches[MatchIndex].MatchOffset - HistoryOffset);
|
||||
Data_Write_UINT32(&MatchDetails[MatchIndex].MatchHistoryOffset,
|
||||
xcrush->OptimizedMatches[MatchIndex].ChunkOffset);
|
||||
}
|
||||
|
||||
CurrentOffset = HistoryOffset;
|
||||
|
||||
@ -259,7 +259,11 @@ static BOOL zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, wStream* stream, size_t
|
||||
zgfx->pbInputCurrent = pbSegment;
|
||||
zgfx->pbInputEnd = &pbSegment[cbSegment - 1];
|
||||
/* NumberOfBitsToDecode = ((NumberOfBytesToDecode - 1) * 8) - ValueOfLastByte */
|
||||
zgfx->cBitsRemaining = 8 * (cbSegment - 1) - *zgfx->pbInputEnd;
|
||||
const UINT32 bits = 8u * (cbSegment - 1u);
|
||||
if (bits < *zgfx->pbInputEnd)
|
||||
return FALSE;
|
||||
|
||||
zgfx->cBitsRemaining = bits - *zgfx->pbInputEnd;
|
||||
zgfx->cBitsCurrent = 0;
|
||||
zgfx->BitsCurrent = 0;
|
||||
|
||||
|
||||
@ -231,6 +231,9 @@ BOOL freerdp_settings_get_bool(const rdpSettings* settings, size_t id)
|
||||
case FreeRDP_GrabKeyboard:
|
||||
return settings->GrabKeyboard;
|
||||
|
||||
case FreeRDP_GrabMouse:
|
||||
return settings->GrabMouse;
|
||||
|
||||
case FreeRDP_HasExtendedMouseEvent:
|
||||
return settings->HasExtendedMouseEvent;
|
||||
|
||||
@ -809,6 +812,10 @@ BOOL freerdp_settings_set_bool(rdpSettings* settings, size_t id, BOOL val)
|
||||
settings->GrabKeyboard = val;
|
||||
break;
|
||||
|
||||
case FreeRDP_GrabMouse:
|
||||
settings->GrabMouse = val;
|
||||
break;
|
||||
|
||||
case FreeRDP_HasExtendedMouseEvent:
|
||||
settings->HasExtendedMouseEvent = val;
|
||||
break;
|
||||
|
||||
@ -87,6 +87,7 @@ static const struct settings_str_entry settings_map[] = {
|
||||
{ FreeRDP_GfxSmallCache, 0, "FreeRDP_GfxSmallCache" },
|
||||
{ FreeRDP_GfxThinClient, 0, "FreeRDP_GfxThinClient" },
|
||||
{ FreeRDP_GrabKeyboard, 0, "FreeRDP_GrabKeyboard" },
|
||||
{ FreeRDP_GrabMouse, 0, "FreeRDP_GrabMouse" },
|
||||
{ FreeRDP_HasExtendedMouseEvent, 0, "FreeRDP_HasExtendedMouseEvent" },
|
||||
{ FreeRDP_HasHorizontalWheel, 0, "FreeRDP_HasHorizontalWheel" },
|
||||
{ FreeRDP_HasMonitorAttributes, 0, "FreeRDP_HasMonitorAttributes" },
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
|
||||
#include <winpr/wtypes.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/assert.h>
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/log.h>
|
||||
@ -1373,12 +1374,13 @@ static BOOL update_read_draw_nine_grid_order(wStream* s, const ORDER_INFO* order
|
||||
static BOOL update_read_multi_dstblt_order(wStream* s, const ORDER_INFO* orderInfo,
|
||||
MULTI_DSTBLT_ORDER* multi_dstblt)
|
||||
{
|
||||
UINT32 numRectangles = multi_dstblt->numRectangles;
|
||||
if (!read_order_field_coord(orderInfo, s, 1, &multi_dstblt->nLeftRect, FALSE) ||
|
||||
!read_order_field_coord(orderInfo, s, 2, &multi_dstblt->nTopRect, FALSE) ||
|
||||
!read_order_field_coord(orderInfo, s, 3, &multi_dstblt->nWidth, FALSE) ||
|
||||
!read_order_field_coord(orderInfo, s, 4, &multi_dstblt->nHeight, FALSE) ||
|
||||
!read_order_field_byte(orderInfo, s, 5, &multi_dstblt->bRop, TRUE) ||
|
||||
!read_order_field_byte(orderInfo, s, 6, &multi_dstblt->numRectangles, TRUE))
|
||||
!read_order_field_byte(orderInfo, s, 6, &numRectangles, TRUE))
|
||||
return FALSE;
|
||||
|
||||
if ((orderInfo->fieldFlags & ORDER_FIELD_07) != 0)
|
||||
@ -1386,12 +1388,21 @@ static BOOL update_read_multi_dstblt_order(wStream* s, const ORDER_INFO* orderIn
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return FALSE;
|
||||
|
||||
multi_dstblt->numRectangles = numRectangles;
|
||||
Stream_Read_UINT16(s, multi_dstblt->cbData);
|
||||
return update_read_delta_rects(s, multi_dstblt->rectangles, &multi_dstblt->numRectangles);
|
||||
}
|
||||
|
||||
if (numRectangles > multi_dstblt->numRectangles)
|
||||
{
|
||||
const char* orderName = __func__;
|
||||
WLog_ERR(TAG, "%s numRectangles %" PRIu32 " > %" PRIu32, orderName, numRectangles,
|
||||
multi_dstblt->numRectangles);
|
||||
return FALSE;
|
||||
}
|
||||
multi_dstblt->numRectangles = numRectangles;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL update_read_multi_patblt_order(wStream* s, const ORDER_INFO* orderInfo,
|
||||
MULTI_PATBLT_ORDER* multi_patblt)
|
||||
{
|
||||
@ -1407,7 +1418,8 @@ static BOOL update_read_multi_patblt_order(wStream* s, const ORDER_INFO* orderIn
|
||||
if (!update_read_brush(s, &multi_patblt->brush, orderInfo->fieldFlags >> 7))
|
||||
return FALSE;
|
||||
|
||||
if (!read_order_field_byte(orderInfo, s, 13, &multi_patblt->numRectangles, TRUE))
|
||||
UINT32 numRectangles = multi_patblt->numRectangles;
|
||||
if (!read_order_field_byte(orderInfo, s, 13, &numRectangles, TRUE))
|
||||
return FALSE;
|
||||
|
||||
if ((orderInfo->fieldFlags & ORDER_FIELD_14) != 0)
|
||||
@ -1415,17 +1427,31 @@ static BOOL update_read_multi_patblt_order(wStream* s, const ORDER_INFO* orderIn
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return FALSE;
|
||||
|
||||
multi_patblt->numRectangles = numRectangles;
|
||||
Stream_Read_UINT16(s, multi_patblt->cbData);
|
||||
|
||||
if (!update_read_delta_rects(s, multi_patblt->rectangles, &multi_patblt->numRectangles))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (numRectangles > multi_patblt->numRectangles)
|
||||
{
|
||||
const char* orderName = __func__;
|
||||
WLog_ERR(TAG, "%s numRectangles %" PRIu32 " > %" PRIu32, orderName, numRectangles,
|
||||
multi_patblt->numRectangles);
|
||||
return FALSE;
|
||||
}
|
||||
multi_patblt->numRectangles = numRectangles;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
static BOOL update_read_multi_scrblt_order(wStream* s, const ORDER_INFO* orderInfo,
|
||||
MULTI_SCRBLT_ORDER* multi_scrblt)
|
||||
{
|
||||
WINPR_ASSERT(orderInfo);
|
||||
WINPR_ASSERT(multi_scrblt);
|
||||
|
||||
UINT32 numRectangles = multi_scrblt->numRectangles;
|
||||
if (!read_order_field_coord(orderInfo, s, 1, &multi_scrblt->nLeftRect, FALSE) ||
|
||||
!read_order_field_coord(orderInfo, s, 2, &multi_scrblt->nTopRect, FALSE) ||
|
||||
!read_order_field_coord(orderInfo, s, 3, &multi_scrblt->nWidth, FALSE) ||
|
||||
@ -1433,7 +1459,7 @@ static BOOL update_read_multi_scrblt_order(wStream* s, const ORDER_INFO* orderIn
|
||||
!read_order_field_byte(orderInfo, s, 5, &multi_scrblt->bRop, TRUE) ||
|
||||
!read_order_field_coord(orderInfo, s, 6, &multi_scrblt->nXSrc, FALSE) ||
|
||||
!read_order_field_coord(orderInfo, s, 7, &multi_scrblt->nYSrc, FALSE) ||
|
||||
!read_order_field_byte(orderInfo, s, 8, &multi_scrblt->numRectangles, TRUE))
|
||||
!read_order_field_byte(orderInfo, s, 8, &numRectangles, TRUE))
|
||||
return FALSE;
|
||||
|
||||
if ((orderInfo->fieldFlags & ORDER_FIELD_09) != 0)
|
||||
@ -1441,10 +1467,20 @@ static BOOL update_read_multi_scrblt_order(wStream* s, const ORDER_INFO* orderIn
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return FALSE;
|
||||
|
||||
multi_scrblt->numRectangles = numRectangles;
|
||||
Stream_Read_UINT16(s, multi_scrblt->cbData);
|
||||
return update_read_delta_rects(s, multi_scrblt->rectangles, &multi_scrblt->numRectangles);
|
||||
}
|
||||
|
||||
if (numRectangles > multi_scrblt->numRectangles)
|
||||
{
|
||||
const char* orderName = __func__;
|
||||
WLog_ERR(TAG, "%s numRectangles %" PRIu32 " > %" PRIu32, orderName, numRectangles,
|
||||
multi_scrblt->numRectangles);
|
||||
return FALSE;
|
||||
}
|
||||
multi_scrblt->numRectangles = numRectangles;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
static BOOL update_read_multi_opaque_rect_order(wStream* s, const ORDER_INFO* orderInfo,
|
||||
@ -1484,7 +1520,8 @@ static BOOL update_read_multi_opaque_rect_order(wStream* s, const ORDER_INFO* or
|
||||
multi_opaque_rect->color = (multi_opaque_rect->color & 0x0000FFFF) | ((UINT32)byte << 16);
|
||||
}
|
||||
|
||||
if (!read_order_field_byte(orderInfo, s, 8, &multi_opaque_rect->numRectangles, TRUE))
|
||||
UINT32 numRectangles = multi_opaque_rect->numRectangles;
|
||||
if (!read_order_field_byte(orderInfo, s, 8, &numRectangles, TRUE))
|
||||
return FALSE;
|
||||
|
||||
if ((orderInfo->fieldFlags & ORDER_FIELD_09) != 0)
|
||||
@ -1492,22 +1529,32 @@ static BOOL update_read_multi_opaque_rect_order(wStream* s, const ORDER_INFO* or
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return FALSE;
|
||||
|
||||
multi_opaque_rect->numRectangles = numRectangles;
|
||||
Stream_Read_UINT16(s, multi_opaque_rect->cbData);
|
||||
return update_read_delta_rects(s, multi_opaque_rect->rectangles,
|
||||
&multi_opaque_rect->numRectangles);
|
||||
}
|
||||
if (numRectangles > multi_opaque_rect->numRectangles)
|
||||
{
|
||||
const char* orderName = __func__;
|
||||
WLog_ERR(TAG, "%s numRectangles %" PRIu32 " > %" PRIu32, orderName, numRectangles,
|
||||
multi_opaque_rect->numRectangles);
|
||||
return FALSE;
|
||||
}
|
||||
multi_opaque_rect->numRectangles = numRectangles;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
static BOOL update_read_multi_draw_nine_grid_order(wStream* s, const ORDER_INFO* orderInfo,
|
||||
MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid)
|
||||
{
|
||||
UINT32 nDeltaEntries = multi_draw_nine_grid->nDeltaEntries;
|
||||
if (!read_order_field_coord(orderInfo, s, 1, &multi_draw_nine_grid->srcLeft, FALSE) ||
|
||||
!read_order_field_coord(orderInfo, s, 2, &multi_draw_nine_grid->srcTop, FALSE) ||
|
||||
!read_order_field_coord(orderInfo, s, 3, &multi_draw_nine_grid->srcRight, FALSE) ||
|
||||
!read_order_field_coord(orderInfo, s, 4, &multi_draw_nine_grid->srcBottom, FALSE) ||
|
||||
!read_order_field_uint16(orderInfo, s, 5, &multi_draw_nine_grid->bitmapId, TRUE) ||
|
||||
!read_order_field_byte(orderInfo, s, 6, &multi_draw_nine_grid->nDeltaEntries, TRUE))
|
||||
!read_order_field_byte(orderInfo, s, 6, &nDeltaEntries, TRUE))
|
||||
return FALSE;
|
||||
|
||||
if ((orderInfo->fieldFlags & ORDER_FIELD_07) != 0)
|
||||
@ -1515,11 +1562,21 @@ static BOOL update_read_multi_draw_nine_grid_order(wStream* s, const ORDER_INFO*
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return FALSE;
|
||||
|
||||
multi_draw_nine_grid->nDeltaEntries = nDeltaEntries;
|
||||
Stream_Read_UINT16(s, multi_draw_nine_grid->cbData);
|
||||
return update_read_delta_rects(s, multi_draw_nine_grid->rectangles,
|
||||
&multi_draw_nine_grid->nDeltaEntries);
|
||||
}
|
||||
|
||||
if (nDeltaEntries > multi_draw_nine_grid->nDeltaEntries)
|
||||
{
|
||||
const char* orderName = __func__;
|
||||
WLog_ERR(TAG, "%s nDeltaEntries %" PRIu32 " > %" PRIu32, orderName, nDeltaEntries,
|
||||
multi_draw_nine_grid->nDeltaEntries);
|
||||
return FALSE;
|
||||
}
|
||||
multi_draw_nine_grid->nDeltaEntries = nDeltaEntries;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
static BOOL update_read_line_to_order(wStream* s, const ORDER_INFO* orderInfo,
|
||||
@ -1610,6 +1667,14 @@ static BOOL update_read_polyline_order(wStream* s, const ORDER_INFO* orderInfo,
|
||||
return update_read_delta_points(s, polyline->points, polyline->numDeltaEntries,
|
||||
polyline->xStart, polyline->yStart);
|
||||
}
|
||||
if (new_num > polyline->numDeltaEntries)
|
||||
{
|
||||
const char* orderName = __func__;
|
||||
WLog_ERR(TAG, "%s numDeltaEntries %" PRIu32 " > %" PRIu32, orderName, new_num,
|
||||
polyline->numDeltaEntries);
|
||||
return FALSE;
|
||||
}
|
||||
polyline->numDeltaEntries = new_num;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -1942,6 +2007,13 @@ static BOOL update_read_polygon_sc_order(wStream* s, const ORDER_INFO* orderInfo
|
||||
return update_read_delta_points(s, polygon_sc->points, polygon_sc->numPoints,
|
||||
polygon_sc->xStart, polygon_sc->yStart);
|
||||
}
|
||||
if (num > polygon_sc->numPoints)
|
||||
{
|
||||
const char* orderName = __func__;
|
||||
WLog_ERR(TAG, "%s numPoints %" PRIu32 " > %" PRIu32, orderName, num, polygon_sc->numPoints);
|
||||
return FALSE;
|
||||
}
|
||||
polygon_sc->numPoints = num;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -1987,6 +2059,14 @@ static BOOL update_read_polygon_cb_order(wStream* s, const ORDER_INFO* orderInfo
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (num > polygon_cb->numPoints)
|
||||
{
|
||||
const char* orderName = __func__;
|
||||
WLog_ERR(TAG, "%s numPoints %" PRIu32 " > %" PRIu32, orderName, num, polygon_cb->numPoints);
|
||||
return FALSE;
|
||||
}
|
||||
polygon_cb->numPoints = num;
|
||||
|
||||
polygon_cb->backMode = (polygon_cb->bRop2 & 0x80) ? BACKMODE_TRANSPARENT : BACKMODE_OPAQUE;
|
||||
polygon_cb->bRop2 = (polygon_cb->bRop2 & 0x1F);
|
||||
return TRUE;
|
||||
|
||||
@ -493,7 +493,7 @@ BOOL WTSVirtualChannelManagerCheckFileDescriptor(HANDLE hServer)
|
||||
{
|
||||
ULONG written;
|
||||
vcm->drdynvc_channel = channel;
|
||||
dynvc_caps = 0x00010050; /* DYNVC_CAPS_VERSION1 (4 bytes) */
|
||||
Data_Write_UINT32(&dynvc_caps, 0x00010050); /* DYNVC_CAPS_VERSION1 (4 bytes) */
|
||||
|
||||
if (!WTSVirtualChannelWrite(channel, (PCHAR)&dynvc_caps, sizeof(dynvc_caps), &written))
|
||||
return FALSE;
|
||||
|
||||
@ -76,6 +76,7 @@ static const size_t bool_list_indices[] = {
|
||||
FreeRDP_GfxSmallCache,
|
||||
FreeRDP_GfxThinClient,
|
||||
FreeRDP_GrabKeyboard,
|
||||
FreeRDP_GrabMouse,
|
||||
FreeRDP_HasExtendedMouseEvent,
|
||||
FreeRDP_HasHorizontalWheel,
|
||||
FreeRDP_HasMonitorAttributes,
|
||||
|
||||
@ -359,33 +359,31 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI
|
||||
|
||||
Stream_Read_UINT16(s, windowState->numWindowRects); /* numWindowRects (2 bytes) */
|
||||
|
||||
if (windowState->numWindowRects == 0)
|
||||
if (windowState->numWindowRects > 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
size = sizeof(RECTANGLE_16) * windowState->numWindowRects;
|
||||
newRect = (RECTANGLE_16*)realloc(windowState->windowRects, size);
|
||||
|
||||
size = sizeof(RECTANGLE_16) * windowState->numWindowRects;
|
||||
newRect = (RECTANGLE_16*)realloc(windowState->windowRects, size);
|
||||
if (!newRect)
|
||||
{
|
||||
free(windowState->windowRects);
|
||||
windowState->windowRects = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!newRect)
|
||||
{
|
||||
free(windowState->windowRects);
|
||||
windowState->windowRects = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
windowState->windowRects = newRect;
|
||||
|
||||
windowState->windowRects = newRect;
|
||||
if (Stream_GetRemainingLength(s) < 8 * windowState->numWindowRects)
|
||||
return FALSE;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 8 * windowState->numWindowRects)
|
||||
return FALSE;
|
||||
|
||||
/* windowRects */
|
||||
for (i = 0; i < windowState->numWindowRects; i++)
|
||||
{
|
||||
Stream_Read_UINT16(s, windowState->windowRects[i].left); /* left (2 bytes) */
|
||||
Stream_Read_UINT16(s, windowState->windowRects[i].top); /* top (2 bytes) */
|
||||
Stream_Read_UINT16(s, windowState->windowRects[i].right); /* right (2 bytes) */
|
||||
Stream_Read_UINT16(s, windowState->windowRects[i].bottom); /* bottom (2 bytes) */
|
||||
/* windowRects */
|
||||
for (i = 0; i < windowState->numWindowRects; i++)
|
||||
{
|
||||
Stream_Read_UINT16(s, windowState->windowRects[i].left); /* left (2 bytes) */
|
||||
Stream_Read_UINT16(s, windowState->windowRects[i].top); /* top (2 bytes) */
|
||||
Stream_Read_UINT16(s, windowState->windowRects[i].right); /* right (2 bytes) */
|
||||
Stream_Read_UINT16(s, windowState->windowRects[i].bottom); /* bottom (2 bytes) */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -950,10 +950,12 @@ WINPR_MD_TYPE crypto_cert_get_signature_alg(X509* xcert)
|
||||
{
|
||||
WINPR_ASSERT(xcert);
|
||||
|
||||
const int nid = X509_get_signature_nid(xcert);
|
||||
EVP_PKEY* evp = X509_get0_pubkey(xcert);
|
||||
WINPR_ASSERT(evp);
|
||||
|
||||
int hash_nid = 0;
|
||||
if (OBJ_find_sigid_algs(nid, &hash_nid, NULL) != 1)
|
||||
const int res = EVP_PKEY_get_default_digest_nid(evp, &hash_nid);
|
||||
if (res <= 0)
|
||||
return WINPR_MD_NONE;
|
||||
|
||||
switch (hash_nid)
|
||||
@ -976,7 +978,7 @@ WINPR_MD_TYPE crypto_cert_get_signature_alg(X509* xcert)
|
||||
return WINPR_MD_SHA512;
|
||||
case NID_ripemd160:
|
||||
return WINPR_MD_RIPEMD160;
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x1010101fL) || defined(LIBRESSL_VERSION_NUMBER)
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x1010101fL) && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
case NID_sha3_224:
|
||||
return WINPR_MD_SHA3_224;
|
||||
case NID_sha3_256:
|
||||
@ -985,11 +987,11 @@ WINPR_MD_TYPE crypto_cert_get_signature_alg(X509* xcert)
|
||||
return WINPR_MD_SHA3_384;
|
||||
case NID_sha3_512:
|
||||
return WINPR_MD_SHA3_512;
|
||||
#endif
|
||||
case NID_shake128:
|
||||
return WINPR_MD_SHAKE128;
|
||||
case NID_shake256:
|
||||
return WINPR_MD_SHAKE256;
|
||||
#endif
|
||||
case NID_undef:
|
||||
default:
|
||||
return WINPR_MD_NONE;
|
||||
|
||||
@ -148,7 +148,7 @@ HGDI_BITMAP gdi_CreateCompatibleBitmap(HGDI_DC hdc, UINT32 nWidth, UINT32 nHeigh
|
||||
hBitmap->width = nWidth;
|
||||
hBitmap->height = nHeight;
|
||||
hBitmap->data =
|
||||
_aligned_malloc(nWidth * nHeight * GetBytesPerPixel(hBitmap->format) * 1ULL, 16);
|
||||
_aligned_malloc(1ull * nWidth * nHeight * GetBytesPerPixel(hBitmap->format), 16);
|
||||
hBitmap->free = _aligned_free;
|
||||
|
||||
if (!hBitmap->data)
|
||||
|
||||
@ -997,16 +997,46 @@ static BOOL gdi_surface_frame_marker(rdpContext* context,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL intersect_rect(const rdpGdi* gdi, const SURFACE_BITS_COMMAND* cmd, RECTANGLE_16* prect)
|
||||
{
|
||||
const UINT32 w = (const UINT32)gdi->width;
|
||||
const UINT32 h = (const UINT32)gdi->height;
|
||||
|
||||
if (cmd->destLeft > w)
|
||||
return FALSE;
|
||||
if (cmd->destRight > w)
|
||||
return FALSE;
|
||||
if (cmd->destLeft > cmd->destRight)
|
||||
return FALSE;
|
||||
if (cmd->destRight > UINT16_MAX)
|
||||
return FALSE;
|
||||
|
||||
if (cmd->destTop > h)
|
||||
return FALSE;
|
||||
if (cmd->destBottom > h)
|
||||
return FALSE;
|
||||
if (cmd->destTop > cmd->destBottom)
|
||||
return FALSE;
|
||||
if (cmd->destBottom > UINT16_MAX)
|
||||
return FALSE;
|
||||
|
||||
prect->left = (const UINT16)cmd->destLeft;
|
||||
prect->top = (const UINT16)cmd->destTop;
|
||||
prect->right = MIN((UINT16)cmd->destRight, prect->left + cmd->bmp.width);
|
||||
prect->bottom = MIN((UINT16)cmd->destBottom, prect->top + cmd->bmp.height);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL gdi_surface_bits(rdpContext* context, const SURFACE_BITS_COMMAND* cmd)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
DWORD format;
|
||||
rdpGdi* gdi;
|
||||
rdpGdi* gdi = NULL;
|
||||
size_t size;
|
||||
REGION16 region;
|
||||
RECTANGLE_16 cmdRect;
|
||||
UINT32 i, nbRects;
|
||||
const RECTANGLE_16* rects;
|
||||
RECTANGLE_16 cmdRect = { 0 };
|
||||
UINT32 nbRects;
|
||||
const RECTANGLE_16* rects = NULL;
|
||||
|
||||
if (!context || !cmd)
|
||||
return FALSE;
|
||||
@ -1020,16 +1050,15 @@ static BOOL gdi_surface_bits(rdpContext* context, const SURFACE_BITS_COMMAND* cm
|
||||
cmd->destLeft, cmd->destTop, cmd->destRight, cmd->destBottom, cmd->bmp.bpp, cmd->bmp.flags,
|
||||
cmd->bmp.codecID, cmd->bmp.width, cmd->bmp.height, cmd->bmp.bitmapDataLength);
|
||||
region16_init(®ion);
|
||||
cmdRect.left = cmd->destLeft;
|
||||
cmdRect.top = cmd->destTop;
|
||||
cmdRect.right = cmdRect.left + cmd->bmp.width;
|
||||
cmdRect.bottom = cmdRect.top + cmd->bmp.height;
|
||||
|
||||
if (!intersect_rect(gdi, cmd, &cmdRect))
|
||||
goto out;
|
||||
|
||||
switch (cmd->bmp.codecID)
|
||||
{
|
||||
case RDP_CODEC_ID_REMOTEFX:
|
||||
if (!rfx_process_message(context->codecs->rfx, cmd->bmp.bitmapData,
|
||||
cmd->bmp.bitmapDataLength, cmd->destLeft, cmd->destTop,
|
||||
cmd->bmp.bitmapDataLength, cmdRect.left, cmdRect.top,
|
||||
gdi->primary_buffer, gdi->dstFormat, gdi->stride, gdi->height,
|
||||
®ion))
|
||||
{
|
||||
@ -1042,11 +1071,11 @@ static BOOL gdi_surface_bits(rdpContext* context, const SURFACE_BITS_COMMAND* cm
|
||||
case RDP_CODEC_ID_NSCODEC:
|
||||
format = gdi->dstFormat;
|
||||
|
||||
if (!nsc_process_message(context->codecs->nsc, cmd->bmp.bpp, cmd->bmp.width,
|
||||
cmd->bmp.height, cmd->bmp.bitmapData,
|
||||
cmd->bmp.bitmapDataLength, gdi->primary_buffer, format,
|
||||
gdi->stride, cmd->destLeft, cmd->destTop, cmd->bmp.width,
|
||||
cmd->bmp.height, FREERDP_FLIP_VERTICAL))
|
||||
if (!nsc_process_message(
|
||||
context->codecs->nsc, cmd->bmp.bpp, cmd->bmp.width, cmd->bmp.height,
|
||||
cmd->bmp.bitmapData, cmd->bmp.bitmapDataLength, gdi->primary_buffer, format,
|
||||
gdi->stride, cmdRect.left, cmdRect.top, cmdRect.right - cmdRect.left,
|
||||
cmdRect.bottom - cmdRect.top, FREERDP_FLIP_VERTICAL))
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to process NSCodec message");
|
||||
goto out;
|
||||
@ -1057,17 +1086,18 @@ static BOOL gdi_surface_bits(rdpContext* context, const SURFACE_BITS_COMMAND* cm
|
||||
|
||||
case RDP_CODEC_ID_NONE:
|
||||
format = gdi_get_pixel_format(cmd->bmp.bpp);
|
||||
size = cmd->bmp.width * cmd->bmp.height * GetBytesPerPixel(format) * 1ULL;
|
||||
size = 1ull * cmd->bmp.width * cmd->bmp.height * GetBytesPerPixel(format);
|
||||
if (size > cmd->bmp.bitmapDataLength)
|
||||
{
|
||||
WLog_ERR(TAG, "Short nocodec message: got %" PRIu32 " bytes, require %" PRIuz,
|
||||
cmd->bmp.bitmapDataLength, size);
|
||||
goto out;
|
||||
}
|
||||
if (!freerdp_image_copy(gdi->primary_buffer, gdi->dstFormat, gdi->stride, cmd->destLeft,
|
||||
cmd->destTop, cmd->bmp.width, cmd->bmp.height,
|
||||
cmd->bmp.bitmapData, format, 0, 0, 0, &gdi->palette,
|
||||
FREERDP_FLIP_VERTICAL))
|
||||
|
||||
if (!freerdp_image_copy(gdi->primary_buffer, gdi->dstFormat, gdi->stride, cmdRect.left,
|
||||
cmdRect.top, cmdRect.right - cmdRect.left,
|
||||
cmdRect.bottom - cmdRect.top, cmd->bmp.bitmapData, format, 0, 0,
|
||||
0, &gdi->palette, FREERDP_FLIP_VERTICAL))
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to process nocodec message");
|
||||
goto out;
|
||||
@ -1084,7 +1114,7 @@ static BOOL gdi_surface_bits(rdpContext* context, const SURFACE_BITS_COMMAND* cm
|
||||
if (!(rects = region16_rects(®ion, &nbRects)))
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < nbRects; i++)
|
||||
for (UINT32 i = 0; i < nbRects; i++)
|
||||
{
|
||||
UINT32 left = rects[i].left;
|
||||
UINT32 top = rects[i].top;
|
||||
|
||||
@ -726,7 +726,7 @@ static UINT gdi_SurfaceCommand_Alpha(rdpGdi* gdi, RdpgfxClientContext* context,
|
||||
{
|
||||
UINT32 x, y;
|
||||
|
||||
if (Stream_GetRemainingLength(&s) < cmd->height * cmd->width * 1ULL)
|
||||
if (Stream_GetRemainingLength(&s) < 1ull * cmd->height * cmd->width)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
for (y = cmd->top; y < cmd->top + cmd->height; y++)
|
||||
@ -1025,7 +1025,7 @@ static UINT gdi_CreateSurface(RdpgfxClientContext* context,
|
||||
}
|
||||
|
||||
surface->scanline = gfx_align_scanline(surface->width * 4UL, 16);
|
||||
surface->data = (BYTE*)_aligned_malloc(surface->scanline * surface->height * 1ULL, 16);
|
||||
surface->data = (BYTE*)_aligned_malloc(1ull * surface->scanline * surface->height, 16);
|
||||
|
||||
if (!surface->data)
|
||||
{
|
||||
@ -1079,6 +1079,28 @@ static UINT gdi_DeleteSurface(RdpgfxClientContext* context,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static BOOL intersect_rect(const RECTANGLE_16* rect, const gdiGfxSurface* surface,
|
||||
RECTANGLE_16* prect)
|
||||
{
|
||||
WINPR_ASSERT(rect);
|
||||
WINPR_ASSERT(surface);
|
||||
WINPR_ASSERT(prect);
|
||||
|
||||
if (rect->left > rect->right)
|
||||
return FALSE;
|
||||
if (rect->left > surface->width)
|
||||
return FALSE;
|
||||
if (rect->top > rect->bottom)
|
||||
return FALSE;
|
||||
if (rect->top > surface->height)
|
||||
return FALSE;
|
||||
prect->left = rect->left;
|
||||
prect->top = rect->top;
|
||||
prect->right = MIN(rect->right, surface->width);
|
||||
prect->bottom = MIN(rect->bottom, surface->height);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
@ -1087,40 +1109,36 @@ static UINT gdi_DeleteSurface(RdpgfxClientContext* context,
|
||||
static UINT gdi_SolidFill(RdpgfxClientContext* context, const RDPGFX_SOLID_FILL_PDU* solidFill)
|
||||
{
|
||||
UINT status = ERROR_INTERNAL_ERROR;
|
||||
UINT16 index;
|
||||
UINT32 color;
|
||||
BYTE a, r, g, b;
|
||||
UINT32 nWidth, nHeight;
|
||||
RECTANGLE_16* rect;
|
||||
gdiGfxSurface* surface;
|
||||
RECTANGLE_16 invalidRect;
|
||||
BYTE a = 0;
|
||||
RECTANGLE_16 invalidRect = { 0 };
|
||||
rdpGdi* gdi = (rdpGdi*)context->custom;
|
||||
|
||||
EnterCriticalSection(&context->mux);
|
||||
surface = (gdiGfxSurface*)context->GetSurfaceData(context, solidFill->surfaceId);
|
||||
|
||||
WINPR_ASSERT(context->GetSurfaceData);
|
||||
gdiGfxSurface* surface = (gdiGfxSurface*)context->GetSurfaceData(context, solidFill->surfaceId);
|
||||
|
||||
if (!surface)
|
||||
goto fail;
|
||||
|
||||
b = solidFill->fillPixel.B;
|
||||
g = solidFill->fillPixel.G;
|
||||
r = solidFill->fillPixel.R;
|
||||
/* a = solidFill->fillPixel.XA;
|
||||
* Ignore alpha channel, this is a solid fill. */
|
||||
const BYTE b = solidFill->fillPixel.B;
|
||||
const BYTE g = solidFill->fillPixel.G;
|
||||
const BYTE r = solidFill->fillPixel.R;
|
||||
a = 0xFF;
|
||||
color = FreeRDPGetColor(surface->format, r, g, b, a);
|
||||
const UINT32 color = FreeRDPGetColor(surface->format, r, g, b, a);
|
||||
|
||||
for (index = 0; index < solidFill->fillRectCount; index++)
|
||||
for (UINT16 index = 0; index < solidFill->fillRectCount; index++)
|
||||
{
|
||||
rect = &(solidFill->fillRects[index]);
|
||||
nWidth = rect->right - rect->left;
|
||||
nHeight = rect->bottom - rect->top;
|
||||
invalidRect.left = rect->left;
|
||||
invalidRect.top = rect->top;
|
||||
invalidRect.right = rect->right;
|
||||
invalidRect.bottom = rect->bottom;
|
||||
const RECTANGLE_16* rect = &(solidFill->fillRects[index]);
|
||||
|
||||
if (!freerdp_image_fill(surface->data, surface->format, surface->scanline, rect->left,
|
||||
rect->top, nWidth, nHeight, color))
|
||||
if (!intersect_rect(rect, surface, &invalidRect))
|
||||
goto fail;
|
||||
|
||||
const UINT32 nWidth = invalidRect.right - invalidRect.left;
|
||||
const UINT32 nHeight = invalidRect.bottom - invalidRect.top;
|
||||
|
||||
if (!freerdp_image_fill(surface->data, surface->format, surface->scanline, invalidRect.left,
|
||||
invalidRect.top, nWidth, nHeight, color))
|
||||
goto fail;
|
||||
|
||||
region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect);
|
||||
|
||||
@ -52,7 +52,7 @@ HGDI_BITMAP gdi_create_bitmap(rdpGdi* gdi, UINT32 nWidth, UINT32 nHeight, UINT32
|
||||
return NULL;
|
||||
|
||||
nDstStep = nWidth * GetBytesPerPixel(gdi->dstFormat);
|
||||
pDstData = _aligned_malloc(nHeight * nDstStep * 1ULL, 16);
|
||||
pDstData = _aligned_malloc(1ull * nHeight * nDstStep, 16);
|
||||
|
||||
if (!pDstData)
|
||||
return NULL;
|
||||
|
||||
@ -158,7 +158,7 @@ BOOL gdi_FillRect(HGDI_DC hdc, const HGDI_RECT rect, HGDI_BRUSH hbr)
|
||||
for (y = 1; y < nHeight; y++)
|
||||
{
|
||||
BYTE* dstp = gdi_get_bitmap_pointer(hdc, nXDest, nYDest + y);
|
||||
memcpy(dstp, srcp, nWidth * formatSize * 1ULL);
|
||||
memcpy(dstp, srcp, 1ull * nWidth * formatSize);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@ -66,7 +66,7 @@ static VideoSurface* gdiVideoCreateSurface(VideoClientContext* video, BYTE* data
|
||||
ret->base.w = width;
|
||||
ret->base.h = height;
|
||||
ret->scanline = width * bpp;
|
||||
ret->image = _aligned_malloc(ret->scanline * height * 1ULL, 16);
|
||||
ret->image = _aligned_malloc(1ull * ret->scanline * height, 16);
|
||||
|
||||
if (!ret->image)
|
||||
{
|
||||
|
||||
@ -60,14 +60,14 @@ static BOOL memory_regions_overlap_2d(const BYTE* p1, int p1Step, int p1Size, co
|
||||
|
||||
if (p1m <= p2m)
|
||||
{
|
||||
ULONG_PTR p1mEnd = p1m + (height - 1) * p1Step * 1ULL + width * p1Size * 1ULL;
|
||||
ULONG_PTR p1mEnd = p1m + 1ull * (height - 1) * p1Step + 1ull * width * p1Size;
|
||||
|
||||
if (p1mEnd > p2m)
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ULONG_PTR p2mEnd = p2m + (height - 1) * p2Step * 1ULL + width * p2Size * 1ULL;
|
||||
ULONG_PTR p2mEnd = p2m + 1ull * (height - 1) * p2Step + 1ull * width * p2Size;
|
||||
|
||||
if (p2mEnd > p1m)
|
||||
return TRUE;
|
||||
|
||||
@ -157,7 +157,7 @@ static primitives_YUV_benchmark* primitives_YUV_benchmark_init(primitives_YUV_be
|
||||
if (!buf)
|
||||
goto fail;
|
||||
|
||||
winpr_RAND(buf, roi->width * roi->height * 1ULL);
|
||||
winpr_RAND(buf, 1ull * roi->width * roi->height);
|
||||
ret->steps[i] = roi->width;
|
||||
}
|
||||
|
||||
|
||||
@ -17,8 +17,8 @@
|
||||
|
||||
# Soname versioning
|
||||
set(UWAC_VERSION_MAJOR "0")
|
||||
set(UWAC_VERSION_MINOR "1")
|
||||
set(UWAC_VERSION_REVISION "1")
|
||||
set(UWAC_VERSION_MINOR "2")
|
||||
set(UWAC_VERSION_REVISION "0")
|
||||
set(UWAC_VERSION "${UWAC_VERSION_MAJOR}.${UWAC_VERSION_MINOR}.${UWAC_VERSION_REVISION}")
|
||||
set(UWAC_VERSION_FULL "${UWAC_VERSION}")
|
||||
set(UWAC_API_VERSION "${UWAC_VERSION_MAJOR}")
|
||||
|
||||
@ -107,7 +107,9 @@ enum
|
||||
UWAC_EVENT_CLIPBOARD_OFFER,
|
||||
UWAC_EVENT_OUTPUT_GEOMETRY,
|
||||
UWAC_EVENT_KEYBOARD_MODIFIERS,
|
||||
UWAC_EVENT_POINTER_AXIS_DISCRETE
|
||||
UWAC_EVENT_POINTER_AXIS_DISCRETE,
|
||||
UWAC_EVENT_POINTER_FRAME,
|
||||
UWAC_EVENT_POINTER_SOURCE
|
||||
};
|
||||
|
||||
/** @brief window states */
|
||||
@ -195,6 +197,23 @@ struct uwac_pointer_axis_event
|
||||
};
|
||||
typedef struct uwac_pointer_axis_event UwacPointerAxisEvent;
|
||||
|
||||
struct uwac_pointer_frame_event
|
||||
{
|
||||
int type;
|
||||
UwacWindow* window;
|
||||
UwacSeat* seat;
|
||||
};
|
||||
typedef struct uwac_pointer_frame_event UwacPointerFrameEvent;
|
||||
|
||||
struct uwac_pointer_source_event
|
||||
{
|
||||
int type;
|
||||
UwacWindow* window;
|
||||
UwacSeat* seat;
|
||||
enum wl_pointer_axis_source axis_source;
|
||||
};
|
||||
typedef struct uwac_pointer_source_event UwacPointerSourceEvent;
|
||||
|
||||
struct uwac_touch_frame_event
|
||||
{
|
||||
int type;
|
||||
@ -286,6 +305,8 @@ union uwac_event {
|
||||
UwacPointerMotionEvent mouse_motion;
|
||||
UwacPointerButtonEvent mouse_button;
|
||||
UwacPointerAxisEvent mouse_axis;
|
||||
UwacPointerFrameEvent mouse_frame;
|
||||
UwacPointerSourceEvent mouse_source;
|
||||
UwacKeyboardEnterLeaveEvent keyboard_enter_leave;
|
||||
UwacKeyboardModifiersEvent keyboard_modifiers;
|
||||
UwacClipboardEvent clipboard;
|
||||
|
||||
@ -846,12 +846,37 @@ static void pointer_handle_axis(void* data, struct wl_pointer* pointer, uint32_t
|
||||
|
||||
static void pointer_frame(void* data, struct wl_pointer* wl_pointer)
|
||||
{
|
||||
/*UwacSeat *seat = data;*/
|
||||
UwacPointerFrameEvent* event;
|
||||
UwacSeat* seat = data;
|
||||
UwacWindow* window = seat->pointer_focus;
|
||||
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
event = (UwacPointerFrameEvent*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_POINTER_FRAME);
|
||||
if (!event)
|
||||
return;
|
||||
|
||||
event->seat = seat;
|
||||
event->window = window;
|
||||
}
|
||||
|
||||
static void pointer_axis_source(void* data, struct wl_pointer* wl_pointer, uint32_t axis_source)
|
||||
{
|
||||
/*UwacSeat *seat = data;*/
|
||||
UwacPointerSourceEvent* event;
|
||||
UwacSeat* seat = data;
|
||||
UwacWindow* window = seat->pointer_focus;
|
||||
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
event = (UwacPointerSourceEvent*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_POINTER_SOURCE);
|
||||
if (!event)
|
||||
return;
|
||||
|
||||
event->seat = seat;
|
||||
event->window = window;
|
||||
event->axis_source = axis_source;
|
||||
}
|
||||
|
||||
static void pointer_axis_stop(void* data, struct wl_pointer* wl_pointer, uint32_t time,
|
||||
|
||||
@ -320,14 +320,14 @@ int UwacWindowShmAllocBuffers(UwacWindow* w, int nbuffers, int allocSize, uint32
|
||||
|
||||
w->buffers = newBuffers;
|
||||
memset(w->buffers + w->nbuffers, 0, sizeof(UwacBuffer) * nbuffers);
|
||||
fd = uwac_create_anonymous_file(allocSize * nbuffers * 1ULL);
|
||||
fd = uwac_create_anonymous_file(1ull * allocSize * nbuffers);
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
return UWAC_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
data = mmap(NULL, allocSize * nbuffers * 1ULL, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
data = mmap(NULL, 1ull * allocSize * nbuffers, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
|
||||
if (data == MAP_FAILED)
|
||||
{
|
||||
@ -339,7 +339,7 @@ int UwacWindowShmAllocBuffers(UwacWindow* w, int nbuffers, int allocSize, uint32
|
||||
|
||||
if (!pool)
|
||||
{
|
||||
munmap(data, allocSize * nbuffers * 1ULL);
|
||||
munmap(data, 1ull * allocSize * nbuffers);
|
||||
ret = UWAC_ERROR_NOMEMORY;
|
||||
goto error_mmap;
|
||||
}
|
||||
@ -764,7 +764,7 @@ UwacReturnCode UwacWindowSubmitBuffer(UwacWindow* window, bool copyContentForNex
|
||||
|
||||
if (copyContentForNextFrame)
|
||||
memcpy(nextDrawingBuffer->data, pendingBuffer->data,
|
||||
window->stride * window->height * 1ULL);
|
||||
1ull * window->stride * window->height);
|
||||
|
||||
UwacSubmitBufferPtr(window, pendingBuffer);
|
||||
return UWAC_SUCCESS;
|
||||
|
||||
@ -57,7 +57,7 @@ if (NOT WIN32)
|
||||
endif()
|
||||
|
||||
# Soname versioning
|
||||
set(RAW_VERSION_STRING "2.10.0")
|
||||
set(RAW_VERSION_STRING "2.11.2")
|
||||
if(EXISTS "${CMAKE_SOURCE_DIR}/.source_tag")
|
||||
file(READ ${CMAKE_SOURCE_DIR}/.source_tag RAW_VERSION_STRING)
|
||||
elseif(USE_VERSION_FROM_GIT_TAG)
|
||||
|
||||
@ -161,8 +161,9 @@ typedef void* PVOID, *LPVOID, *PVOID64, *LPVOID64;
|
||||
#ifndef __APPLE__
|
||||
typedef __int32 BOOL;
|
||||
#else /* __APPLE__ */
|
||||
#include <TargetConditionals.h>
|
||||
/* ensure compatibility with objc libraries */
|
||||
#if (TARGET_OS_IPHONE && __LP64__) || TARGET_OS_WATCH
|
||||
#if (defined(TARGET_OS_IPHONE) && (TARGET_OS_IPHONE != 0) && defined(__LP64__)) || (defined(TARGET_OS_WATCH) && (TARGET_OS_WATCH != 0))
|
||||
typedef bool BOOL;
|
||||
#else
|
||||
typedef signed char BOOL;
|
||||
|
||||
@ -19,8 +19,8 @@ winpr_module_add(credui.c)
|
||||
|
||||
if(WIN32)
|
||||
winpr_library_add_public(credui)
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_subdirectory(test)
|
||||
else()
|
||||
if(BUILD_TESTING)
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@ -233,6 +233,18 @@ BOOL ArrayList_Contains(wArrayList* arrayList, void* obj)
|
||||
* Adds an object to the end of the ArrayList.
|
||||
*/
|
||||
|
||||
static int insert(wArrayList* arrayList, size_t index, void* obj)
|
||||
{
|
||||
if (arrayList->object.fnObjectNew)
|
||||
{
|
||||
obj = arrayList->object.fnObjectNew(obj);
|
||||
arrayList->array[index] = obj;
|
||||
}
|
||||
else
|
||||
arrayList->array[index] = obj;
|
||||
return index + 1;
|
||||
}
|
||||
|
||||
int ArrayList_Add(wArrayList* arrayList, void* obj)
|
||||
{
|
||||
int index = -1;
|
||||
@ -253,8 +265,7 @@ int ArrayList_Add(wArrayList* arrayList, void* obj)
|
||||
arrayList->capacity = newCapacity;
|
||||
}
|
||||
|
||||
arrayList->array[arrayList->size++] = obj;
|
||||
index = arrayList->size;
|
||||
index = arrayList->size = insert(arrayList, arrayList->size, obj);
|
||||
out:
|
||||
|
||||
if (arrayList->synchronized)
|
||||
@ -282,7 +293,7 @@ BOOL ArrayList_Insert(wArrayList* arrayList, int index, void* obj)
|
||||
}
|
||||
else
|
||||
{
|
||||
arrayList->array[index] = obj;
|
||||
insert(arrayList, index, obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3815,7 +3815,7 @@ unsigned lodepng_convert(unsigned char* out, const unsigned char* in, LodePNGCol
|
||||
{
|
||||
size_t i;
|
||||
ColorTree tree;
|
||||
size_t numpixels = w * h * 1ULL;
|
||||
size_t numpixels = 1ull * w * h;
|
||||
|
||||
if (lodepng_color_mode_equal(mode_out, mode_in))
|
||||
{
|
||||
@ -3918,7 +3918,7 @@ unsigned get_color_profile(LodePNGColorProfile* profile, const unsigned char* in
|
||||
unsigned error = 0;
|
||||
size_t i;
|
||||
ColorTree tree;
|
||||
size_t numpixels = w * h * 1ULL;
|
||||
size_t numpixels = 1ull * w * h;
|
||||
|
||||
unsigned colored_done = lodepng_is_greyscale_type(mode) ? 1 : 0;
|
||||
unsigned alpha_done = lodepng_can_have_alpha(mode) ? 0 : 1;
|
||||
@ -4539,7 +4539,7 @@ static unsigned postProcessScanlines(unsigned char* out, unsigned char* in, unsi
|
||||
if (bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8)
|
||||
{
|
||||
CERROR_TRY_RETURN(unfilter(in, in, w, h, bpp));
|
||||
removePaddingBits(out, in, w * bpp * 1ULL, ((w * bpp + 7ULL) / 8ULL) * 8ULL, h);
|
||||
removePaddingBits(out, in, 1ull * w * bpp, ((w * bpp + 7ULL) / 8ULL) * 8ULL, h);
|
||||
}
|
||||
/*we can immediatly filter into the out buffer, no other steps needed*/
|
||||
else
|
||||
@ -4565,7 +4565,7 @@ static unsigned postProcessScanlines(unsigned char* out, unsigned char* in, unsi
|
||||
bits between the different reduced images: each reduced image still starts nicely at
|
||||
a byte*/
|
||||
removePaddingBits(&in[passstart[i]], &in[padded_passstart[i]],
|
||||
passw[i] * bpp * 1ULL, ((passw[i] * bpp + 7ULL) / 8ULL) * 8ULL,
|
||||
1ull * passw[i] * bpp, ((passw[i] * bpp + 7ULL) / 8ULL) * 8ULL,
|
||||
passh[i]);
|
||||
}
|
||||
}
|
||||
@ -6056,7 +6056,7 @@ static unsigned preProcessScanlines(unsigned char** out, size_t* outsize, const
|
||||
error = 83; /*alloc fail*/
|
||||
if (!error)
|
||||
{
|
||||
addPaddingBits(padded, in, ((w * bpp + 7ULL) / 8ULL) * 8ULL, w * bpp * 1ULL, h);
|
||||
addPaddingBits(padded, in, ((w * bpp + 7ULL) / 8ULL) * 8ULL, 1ull * w * bpp, h);
|
||||
error = filter(*out, padded, w, h, &info_png->color, settings);
|
||||
}
|
||||
free(padded);
|
||||
@ -6100,8 +6100,8 @@ static unsigned preProcessScanlines(unsigned char** out, size_t* outsize, const
|
||||
if (!padded)
|
||||
ERROR_BREAK(83); /*alloc fail*/
|
||||
addPaddingBits(padded, &adam7[passstart[i]],
|
||||
((passw[i] * bpp + 7ULL) / 8ULL) * 8ULL, passw[i] * bpp * 1ULL,
|
||||
passh[i] * 1ULL);
|
||||
((passw[i] * bpp + 7ULL) / 8ULL) * 8ULL, 1ull * passw[i] * bpp,
|
||||
1ull * passh[i]);
|
||||
error = filter(&(*out)[filter_passstart[i]], padded, passw[i], passh[i],
|
||||
&info_png->color, settings);
|
||||
free(padded);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user