Compare commits
36 Commits
debian/boo
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1cc8082c0a | ||
|
|
b607683919 | ||
|
|
dc059a2d39 | ||
|
|
cc9c0a66c8 | ||
|
|
4d650bf630 | ||
|
|
48be888513 | ||
|
|
6187297b6e | ||
|
|
47c0f4de25 | ||
|
|
5685a9eca1 | ||
|
|
40ac300cbc | ||
|
|
4930b843f5 | ||
|
|
66e976dd46 | ||
|
|
7a0cfc871a | ||
|
|
d8fe268285 | ||
|
|
22e2e0315b | ||
|
|
f78f13ecf5 | ||
|
|
ce01c78202 | ||
|
|
3d3a1415b7 | ||
|
|
df721c20b4 | ||
|
|
eeaac3f057 | ||
|
|
2d6a9f3b9b | ||
|
|
6fe4ba798f | ||
|
|
995fbfcdd7 | ||
|
|
a0544fd1f6 | ||
|
|
1c5b0b32c3 | ||
|
|
382aa6b66a | ||
|
|
bdad2ddbfa | ||
|
|
da7dfbb2d6 | ||
|
|
682454acf9 | ||
|
|
577316d7c0 | ||
|
|
928c8abca7 | ||
|
|
5bbfde9671 | ||
|
|
057b4985ff | ||
|
|
4bb5bc077f | ||
|
|
3d5ae03c6a | ||
|
|
d260e3c398 |
@ -104,7 +104,6 @@ ForEachMacros:
|
|||||||
...
|
...
|
||||||
Language: ObjC
|
Language: ObjC
|
||||||
PointerBindsToType: false
|
PointerBindsToType: false
|
||||||
ObjCSpaceAfterProperty: true
|
|
||||||
SortIncludes: false
|
SortIncludes: false
|
||||||
ObjCBlockIndentWidth: 4
|
ObjCBlockIndentWidth: 4
|
||||||
ObjCSpaceAfterProperty: false
|
ObjCSpaceAfterProperty: false
|
||||||
|
|||||||
@ -34,9 +34,9 @@ if(NOT DEFINED FREERDP_VENDOR)
|
|||||||
set(FREERDP_VENDOR 1)
|
set(FREERDP_VENDOR 1)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(CMAKE_COLOR_MAKEFILE ON)
|
option(CMAKE_COLOR_MAKEFILE "colorful CMake makefile" ON)
|
||||||
|
option(CMAKE_VERBOSE_MAKEFILE "verbose CMake makefile" ON)
|
||||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
option(CMAKE_POSITION_INDEPENDENT_CODE "build with position independent code (-fPIC or -fPIE)" ON)
|
||||||
|
|
||||||
# Include our extra modules
|
# Include our extra modules
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/)
|
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/)
|
||||||
@ -85,7 +85,7 @@ if ($ENV{BUILD_NUMBER})
|
|||||||
endif()
|
endif()
|
||||||
set(WITH_LIBRARY_VERSIONING "ON")
|
set(WITH_LIBRARY_VERSIONING "ON")
|
||||||
|
|
||||||
set(RAW_VERSION_STRING "2.10.0")
|
set(RAW_VERSION_STRING "2.11.7")
|
||||||
if(EXISTS "${CMAKE_SOURCE_DIR}/.source_tag")
|
if(EXISTS "${CMAKE_SOURCE_DIR}/.source_tag")
|
||||||
file(READ ${CMAKE_SOURCE_DIR}/.source_tag RAW_VERSION_STRING)
|
file(READ ${CMAKE_SOURCE_DIR}/.source_tag RAW_VERSION_STRING)
|
||||||
elseif(USE_VERSION_FROM_GIT_TAG)
|
elseif(USE_VERSION_FROM_GIT_TAG)
|
||||||
@ -225,7 +225,7 @@ endif()
|
|||||||
if(MSVC)
|
if(MSVC)
|
||||||
include(MSVCRuntime)
|
include(MSVCRuntime)
|
||||||
if(NOT DEFINED MSVC_RUNTIME)
|
if(NOT DEFINED MSVC_RUNTIME)
|
||||||
set(MSVC_RUNTIME "dynamic")
|
set(MSVC_RUNTIME "dynamic" CACHE STRING "MSVC runtime type [dynamic|static]")
|
||||||
endif()
|
endif()
|
||||||
if(MSVC_RUNTIME STREQUAL "static")
|
if(MSVC_RUNTIME STREQUAL "static")
|
||||||
if(BUILD_SHARED_LIBS)
|
if(BUILD_SHARED_LIBS)
|
||||||
|
|||||||
97
ChangeLog
97
ChangeLog
@ -1,6 +1,97 @@
|
|||||||
|
# 2024-04-22 Version 2.11.7
|
||||||
|
|
||||||
|
Noteworthy changes:
|
||||||
|
* Backported oss-fuzz fixes
|
||||||
|
|
||||||
|
For a complete and detailed change log since the last release run:
|
||||||
|
git log 2.11.7...2.11.6
|
||||||
|
|
||||||
|
# 2024-04-17 Version 2.11.6
|
||||||
|
|
||||||
|
CVE:
|
||||||
|
CVE-2024-32041 [Low[ OutOfBound Read in zgfx_decompress_segment
|
||||||
|
CVE-2024-32039 [Moderate] Integer overflow & OutOfBound Write in clear_decompress_residual_data
|
||||||
|
CVE-2024-32040 [Low] integer underflow in nsc_rle_decode
|
||||||
|
CVE-2024-32458 [Low] OutOfBound Read in planar_skip_plane_rle
|
||||||
|
CVE-2024-32459 [Low] OutOfBound Read in ncrush_decompress
|
||||||
|
CVE-2024-32460 [Low] OutOfBound Read in interleaved_decompress
|
||||||
|
|
||||||
|
Noteworthy changes:
|
||||||
|
* Backported #10077
|
||||||
|
|
||||||
|
For a complete and detailed change log since the last release run:
|
||||||
|
git log 2.11.6...2.11.5
|
||||||
|
|
||||||
|
# 2024-01-19 Version 2.11.5
|
||||||
|
|
||||||
|
Noteworthy changes:
|
||||||
|
* Fix integer overflow in progressive decoder
|
||||||
|
* Update OpenSSL API usage for compatiblility with newer versions (#9747)
|
||||||
|
* Prevent NULL dereference for single thread decoder (#9712)
|
||||||
|
|
||||||
|
For a complete and detailed change log since the last release run:
|
||||||
|
git log 2.11.5...2.11.4
|
||||||
|
|
||||||
|
# 2023-12-14 Version 2.11.4
|
||||||
|
|
||||||
|
Notworthy changes:
|
||||||
|
* fix a typo in unicode commit (#9652)
|
||||||
|
|
||||||
|
For a complete and detailed change log since the last release run:
|
||||||
|
git log 2.11.4...2.11.3
|
||||||
|
|
||||||
|
# 2023-12-14 Version 2.11.3
|
||||||
|
|
||||||
|
Notworthy changes:
|
||||||
|
* Disabled windows MEDIA FOUNDATION h264 decoder due to reported issues (#9469)
|
||||||
|
* Fix issues with drive redirection (#9530,9554, #9586, #9617)
|
||||||
|
* Use endian safe ICU string converter (#9631)
|
||||||
|
* Improve AAC support (#9577)
|
||||||
|
* Fix swiss german keyboard layout (#9560)
|
||||||
|
* Enable rfx-mode:image (#9428)
|
||||||
|
|
||||||
|
For a complete and detailed change log since the last release run:
|
||||||
|
git log 2.11.3...2.11.2
|
||||||
|
|
||||||
|
# 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
|
# 2023-02-16 Version 2.10.0
|
||||||
|
|
||||||
Notewhorth changes:
|
Noteworthy changes:
|
||||||
* Fix android build scripts, use CMake from SDK
|
* Fix android build scripts, use CMake from SDK
|
||||||
* Fix connection negotiation with mstsc/msrdc #8426
|
* Fix connection negotiation with mstsc/msrdc #8426
|
||||||
* [ntlm]: use rfc5929 binding hash algorithm #8430
|
* [ntlm]: use rfc5929 binding hash algorithm #8430
|
||||||
@ -23,7 +114,7 @@ Fixed issues:
|
|||||||
|
|
||||||
# 2022-11-16 Version 2.9.0
|
# 2022-11-16 Version 2.9.0
|
||||||
|
|
||||||
Notewhorth changes:
|
Noteworthy changes:
|
||||||
* Backported #8252: Support sending server redirection PDU
|
* Backported #8252: Support sending server redirection PDU
|
||||||
* Backported #8406: Ensure X11 client cursor is never smaller 1x1
|
* Backported #8406: Ensure X11 client cursor is never smaller 1x1
|
||||||
* Backported #8403: Fixed multiple client side input validation issues
|
* Backported #8403: Fixed multiple client side input validation issues
|
||||||
@ -49,7 +140,7 @@ git log 2.8.1..2.9.0
|
|||||||
|
|
||||||
# 2022-10-12 Version 2.8.1
|
# 2022-10-12 Version 2.8.1
|
||||||
|
|
||||||
Notewhorth changes:
|
Noteworthy changes:
|
||||||
* Fixed CVE-2022-39282
|
* Fixed CVE-2022-39282
|
||||||
* Fixed CVE-2022-39283
|
* Fixed CVE-2022-39283
|
||||||
* Added missing commit for backported #8041: Remove ALAW/ULAW codecs from linux backends (unreliable)
|
* 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)
|
if (!unlockClipboardData)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
s = cliprdr_packet_new(CB_LOCK_CLIPDATA, 0, 4);
|
s = cliprdr_packet_new(CB_UNLOCK_CLIPDATA, 0, 4);
|
||||||
|
|
||||||
if (!s)
|
if (!s)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@ -41,6 +41,8 @@
|
|||||||
|
|
||||||
#include "devman.h"
|
#include "devman.h"
|
||||||
|
|
||||||
|
#define TAG CHANNELS_TAG("rdpdr.client")
|
||||||
|
|
||||||
static void devman_device_free(void* obj)
|
static void devman_device_free(void* obj)
|
||||||
{
|
{
|
||||||
DEVICE* device = (DEVICE*)obj;
|
DEVICE* device = (DEVICE*)obj;
|
||||||
@ -62,7 +64,7 @@ DEVMAN* devman_new(rdpdrPlugin* rdpdr)
|
|||||||
|
|
||||||
if (!devman)
|
if (!devman)
|
||||||
{
|
{
|
||||||
WLog_INFO(TAG, "calloc failed!");
|
WLog_Print(rdpdr->log, WLOG_INFO, "calloc failed!");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +74,7 @@ DEVMAN* devman_new(rdpdrPlugin* rdpdr)
|
|||||||
|
|
||||||
if (!devman->devices)
|
if (!devman->devices)
|
||||||
{
|
{
|
||||||
WLog_INFO(TAG, "ListDictionary_New failed!");
|
WLog_Print(rdpdr->log, WLOG_INFO, "ListDictionary_New failed!");
|
||||||
free(devman);
|
free(devman);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -76,13 +76,13 @@ static UINT irp_complete(IRP* irp)
|
|||||||
return irp_free(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;
|
IRP* irp;
|
||||||
DEVICE* device;
|
DEVICE* device;
|
||||||
UINT32 DeviceId;
|
UINT32 DeviceId;
|
||||||
|
|
||||||
if (Stream_GetRemainingLength(s) < 20)
|
if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 20))
|
||||||
{
|
{
|
||||||
if (error)
|
if (error)
|
||||||
*error = ERROR_INVALID_DATA;
|
*error = ERROR_INVALID_DATA;
|
||||||
@ -94,7 +94,7 @@ IRP* irp_new(DEVMAN* devman, wStream* s, UINT* error)
|
|||||||
|
|
||||||
if (!device)
|
if (!device)
|
||||||
{
|
{
|
||||||
WLog_WARN(TAG, "devman_get_device_by_id failed!");
|
WLog_Print(log, WLOG_WARN, "devman_get_device_by_id failed!");
|
||||||
if (error)
|
if (error)
|
||||||
*error = CHANNEL_RC_OK;
|
*error = CHANNEL_RC_OK;
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ IRP* irp_new(DEVMAN* devman, wStream* s, UINT* error)
|
|||||||
|
|
||||||
if (!irp)
|
if (!irp)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "_aligned_malloc failed!");
|
WLog_Print(log, WLOG_ERROR, "_aligned_malloc failed!");
|
||||||
if (error)
|
if (error)
|
||||||
*error = CHANNEL_RC_NO_MEMORY;
|
*error = CHANNEL_RC_NO_MEMORY;
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -125,7 +125,7 @@ IRP* irp_new(DEVMAN* devman, wStream* s, UINT* error)
|
|||||||
irp->output = Stream_New(NULL, 256);
|
irp->output = Stream_New(NULL, 256);
|
||||||
if (!irp->output)
|
if (!irp->output)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Stream_New failed!");
|
WLog_Print(log, WLOG_ERROR, "Stream_New failed!");
|
||||||
_aligned_free(irp);
|
_aligned_free(irp);
|
||||||
if (error)
|
if (error)
|
||||||
*error = CHANNEL_RC_NO_MEMORY;
|
*error = CHANNEL_RC_NO_MEMORY;
|
||||||
|
|||||||
@ -21,8 +21,9 @@
|
|||||||
#ifndef FREERDP_CHANNEL_RDPDR_CLIENT_IRP_H
|
#ifndef FREERDP_CHANNEL_RDPDR_CLIENT_IRP_H
|
||||||
#define FREERDP_CHANNEL_RDPDR_CLIENT_IRP_H
|
#define FREERDP_CHANNEL_RDPDR_CLIENT_IRP_H
|
||||||
|
|
||||||
|
#include <winpr/wlog.h>
|
||||||
#include "rdpdr_main.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 */
|
#endif /* FREERDP_CHANNEL_RDPDR_CLIENT_IRP_H */
|
||||||
|
|||||||
@ -35,6 +35,8 @@
|
|||||||
#include "rdpdr_main.h"
|
#include "rdpdr_main.h"
|
||||||
#include "rdpdr_capabilities.h"
|
#include "rdpdr_capabilities.h"
|
||||||
|
|
||||||
|
#define RDPDR_CAPABILITY_HEADER_LENGTH 8
|
||||||
|
|
||||||
/* Output device redirection capability set header */
|
/* Output device redirection capability set header */
|
||||||
static void rdpdr_write_capset_header(wStream* s, UINT16 capabilityType, UINT16 capabilityLength,
|
static void rdpdr_write_capset_header(wStream* s, UINT16 capabilityType, UINT16 capabilityLength,
|
||||||
UINT32 version)
|
UINT32 version)
|
||||||
@ -48,39 +50,59 @@ static void rdpdr_write_capset_header(wStream* s, UINT16 capabilityType, UINT16
|
|||||||
static void rdpdr_write_general_capset(rdpdrPlugin* rdpdr, wStream* s)
|
static void rdpdr_write_general_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||||
{
|
{
|
||||||
WINPR_UNUSED(rdpdr);
|
WINPR_UNUSED(rdpdr);
|
||||||
rdpdr_write_capset_header(s, CAP_GENERAL_TYPE, 44, GENERAL_CAPABILITY_VERSION_02);
|
|
||||||
Stream_Write_UINT32(s, 0); /* osType, ignored on receipt */
|
const UINT32 ioCode1 = rdpdr->clientIOCode1 & rdpdr->serverIOCode1;
|
||||||
Stream_Write_UINT32(s, 0); /* osVersion, unused and must be set to zero */
|
const UINT32 ioCode2 = rdpdr->clientIOCode2 & rdpdr->serverIOCode2;
|
||||||
Stream_Write_UINT16(s, 1); /* protocolMajorVersion, must be set to 1 */
|
|
||||||
Stream_Write_UINT16(s, RDPDR_MINOR_RDP_VERSION_5_2); /* protocolMinorVersion */
|
rdpdr_write_capset_header(s, CAP_GENERAL_TYPE, RDPDR_CAPABILITY_HEADER_LENGTH + 36,
|
||||||
Stream_Write_UINT32(s, 0x0000FFFF); /* ioCode1 */
|
GENERAL_CAPABILITY_VERSION_02);
|
||||||
Stream_Write_UINT32(s, 0); /* ioCode2, must be set to zero, reserved for future use */
|
Stream_Write_UINT32(s, rdpdr->clientOsType); /* osType, ignored on receipt */
|
||||||
Stream_Write_UINT32(s, RDPDR_DEVICE_REMOVE_PDUS | RDPDR_CLIENT_DISPLAY_NAME_PDU |
|
Stream_Write_UINT32(s, rdpdr->clientOsVersion); /* osVersion, unused and must be set to zero */
|
||||||
RDPDR_USER_LOGGEDON_PDU); /* extendedPDU */
|
Stream_Write_UINT16(s, rdpdr->clientVersionMajor); /* protocolMajorVersion, must be set to 1 */
|
||||||
Stream_Write_UINT32(s, ENABLE_ASYNCIO); /* extraFlags1 */
|
Stream_Write_UINT16(s, rdpdr->clientVersionMinor); /* protocolMinorVersion */
|
||||||
Stream_Write_UINT32(s, 0); /* extraFlags2, must be set to zero, reserved for future use */
|
Stream_Write_UINT32(s, ioCode1); /* ioCode1 */
|
||||||
|
Stream_Write_UINT32(s, ioCode2); /* ioCode2, must be set to zero, reserved for future use */
|
||||||
|
Stream_Write_UINT32(s, rdpdr->clientExtendedPDU); /* extendedPDU */
|
||||||
|
Stream_Write_UINT32(s, rdpdr->clientExtraFlags1); /* extraFlags1 */
|
||||||
Stream_Write_UINT32(
|
Stream_Write_UINT32(
|
||||||
s, 0); /* SpecialTypeDeviceCap, number of special devices to be redirected before logon */
|
s,
|
||||||
|
rdpdr->clientExtraFlags2); /* extraFlags2, must be set to zero, reserved for future use */
|
||||||
|
Stream_Write_UINT32(
|
||||||
|
s, rdpdr->clientSpecialTypeDeviceCap); /* SpecialTypeDeviceCap, number of special devices to
|
||||||
|
be redirected before logon */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process device direction general capability set */
|
/* Process device direction general capability set */
|
||||||
static UINT rdpdr_process_general_capset(rdpdrPlugin* rdpdr, wStream* s)
|
static UINT rdpdr_process_general_capset(rdpdrPlugin* rdpdr, wStream* s, UINT16 capabilityLength)
|
||||||
{
|
{
|
||||||
UINT16 capabilityLength;
|
|
||||||
WINPR_UNUSED(rdpdr);
|
WINPR_UNUSED(rdpdr);
|
||||||
|
|
||||||
if (Stream_GetRemainingLength(s) < 2)
|
if (capabilityLength != 36)
|
||||||
|
{
|
||||||
|
WLog_Print(rdpdr->log, WLOG_ERROR,
|
||||||
|
"CAP_GENERAL_TYPE::CapabilityLength expected 36, got %" PRIu32,
|
||||||
|
capabilityLength);
|
||||||
|
return ERROR_INVALID_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, capabilityLength))
|
||||||
return ERROR_INVALID_DATA;
|
return ERROR_INVALID_DATA;
|
||||||
|
|
||||||
Stream_Read_UINT16(s, capabilityLength);
|
Stream_Read_UINT32(s, rdpdr->serverOsType); /* osType, ignored on receipt */
|
||||||
|
Stream_Read_UINT32(s, rdpdr->serverOsVersion); /* osVersion, unused and must be set to zero */
|
||||||
if (capabilityLength < 4)
|
Stream_Read_UINT16(s, rdpdr->serverVersionMajor); /* protocolMajorVersion, must be set to 1 */
|
||||||
return ERROR_INVALID_DATA;
|
Stream_Read_UINT16(s, rdpdr->serverVersionMinor); /* protocolMinorVersion */
|
||||||
|
Stream_Read_UINT32(s, rdpdr->serverIOCode1); /* ioCode1 */
|
||||||
if (Stream_GetRemainingLength(s) < capabilityLength - 4U)
|
Stream_Read_UINT32(
|
||||||
return ERROR_INVALID_DATA;
|
s, rdpdr->serverIOCode2); /* ioCode2, must be set to zero, reserved for future use */
|
||||||
|
Stream_Read_UINT32(s, rdpdr->serverExtendedPDU); /* extendedPDU */
|
||||||
Stream_Seek(s, capabilityLength - 4U);
|
Stream_Read_UINT32(s, rdpdr->serverExtraFlags1); /* extraFlags1 */
|
||||||
|
Stream_Read_UINT32(
|
||||||
|
s,
|
||||||
|
rdpdr->serverExtraFlags2); /* extraFlags2, must be set to zero, reserved for future use */
|
||||||
|
Stream_Read_UINT32(
|
||||||
|
s, rdpdr->serverSpecialTypeDeviceCap); /* SpecialTypeDeviceCap, number of special devices to
|
||||||
|
be redirected before logon */
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,23 +114,14 @@ static void rdpdr_write_printer_capset(rdpdrPlugin* rdpdr, wStream* s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Process printer direction capability set */
|
/* Process printer direction capability set */
|
||||||
static UINT rdpdr_process_printer_capset(rdpdrPlugin* rdpdr, wStream* s)
|
static UINT rdpdr_process_printer_capset(rdpdrPlugin* rdpdr, wStream* s, UINT16 capabilityLength)
|
||||||
{
|
{
|
||||||
UINT16 capabilityLength;
|
|
||||||
WINPR_UNUSED(rdpdr);
|
WINPR_UNUSED(rdpdr);
|
||||||
|
|
||||||
if (Stream_GetRemainingLength(s) < 2)
|
if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, capabilityLength))
|
||||||
return ERROR_INVALID_DATA;
|
return ERROR_INVALID_DATA;
|
||||||
|
|
||||||
Stream_Read_UINT16(s, capabilityLength);
|
Stream_Seek(s, capabilityLength);
|
||||||
|
|
||||||
if (capabilityLength < 4)
|
|
||||||
return ERROR_INVALID_DATA;
|
|
||||||
|
|
||||||
if (Stream_GetRemainingLength(s) < capabilityLength - 4U)
|
|
||||||
return ERROR_INVALID_DATA;
|
|
||||||
|
|
||||||
Stream_Seek(s, capabilityLength - 4U);
|
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,23 +133,14 @@ static void rdpdr_write_port_capset(rdpdrPlugin* rdpdr, wStream* s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Process port redirection capability set */
|
/* Process port redirection capability set */
|
||||||
static UINT rdpdr_process_port_capset(rdpdrPlugin* rdpdr, wStream* s)
|
static UINT rdpdr_process_port_capset(rdpdrPlugin* rdpdr, wStream* s, UINT16 capabilityLength)
|
||||||
{
|
{
|
||||||
UINT16 capabilityLength;
|
|
||||||
WINPR_UNUSED(rdpdr);
|
WINPR_UNUSED(rdpdr);
|
||||||
|
|
||||||
if (Stream_GetRemainingLength(s) < 2)
|
if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, capabilityLength))
|
||||||
return ERROR_INVALID_DATA;
|
return ERROR_INVALID_DATA;
|
||||||
|
|
||||||
Stream_Read_UINT16(s, capabilityLength);
|
Stream_Seek(s, capabilityLength);
|
||||||
|
|
||||||
if (capabilityLength < 4U)
|
|
||||||
return ERROR_INVALID_DATA;
|
|
||||||
|
|
||||||
if (Stream_GetRemainingLength(s) < capabilityLength - 4U)
|
|
||||||
return ERROR_INVALID_DATA;
|
|
||||||
|
|
||||||
Stream_Seek(s, capabilityLength - 4U);
|
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,23 +152,14 @@ static void rdpdr_write_drive_capset(rdpdrPlugin* rdpdr, wStream* s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Process drive redirection capability set */
|
/* Process drive redirection capability set */
|
||||||
static UINT rdpdr_process_drive_capset(rdpdrPlugin* rdpdr, wStream* s)
|
static UINT rdpdr_process_drive_capset(rdpdrPlugin* rdpdr, wStream* s, UINT16 capabilityLength)
|
||||||
{
|
{
|
||||||
UINT16 capabilityLength;
|
|
||||||
WINPR_UNUSED(rdpdr);
|
WINPR_UNUSED(rdpdr);
|
||||||
|
|
||||||
if (Stream_GetRemainingLength(s) < 2)
|
if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, capabilityLength))
|
||||||
return ERROR_INVALID_DATA;
|
return ERROR_INVALID_DATA;
|
||||||
|
|
||||||
Stream_Read_UINT16(s, capabilityLength);
|
Stream_Seek(s, capabilityLength);
|
||||||
|
|
||||||
if (capabilityLength < 4)
|
|
||||||
return ERROR_INVALID_DATA;
|
|
||||||
|
|
||||||
if (Stream_GetRemainingLength(s) < capabilityLength - 4U)
|
|
||||||
return ERROR_INVALID_DATA;
|
|
||||||
|
|
||||||
Stream_Seek(s, capabilityLength - 4U);
|
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,23 +171,14 @@ static void rdpdr_write_smartcard_capset(rdpdrPlugin* rdpdr, wStream* s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Process smartcard redirection capability set */
|
/* Process smartcard redirection capability set */
|
||||||
static UINT rdpdr_process_smartcard_capset(rdpdrPlugin* rdpdr, wStream* s)
|
static UINT rdpdr_process_smartcard_capset(rdpdrPlugin* rdpdr, wStream* s, UINT16 capabilityLength)
|
||||||
{
|
{
|
||||||
UINT16 capabilityLength;
|
|
||||||
WINPR_UNUSED(rdpdr);
|
WINPR_UNUSED(rdpdr);
|
||||||
|
|
||||||
if (Stream_GetRemainingLength(s) < 2)
|
if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, capabilityLength))
|
||||||
return ERROR_INVALID_DATA;
|
return ERROR_INVALID_DATA;
|
||||||
|
|
||||||
Stream_Read_UINT16(s, capabilityLength);
|
Stream_Seek(s, capabilityLength);
|
||||||
|
|
||||||
if (capabilityLength < 4)
|
|
||||||
return ERROR_INVALID_DATA;
|
|
||||||
|
|
||||||
if (Stream_GetRemainingLength(s) < capabilityLength - 4U)
|
|
||||||
return ERROR_INVALID_DATA;
|
|
||||||
|
|
||||||
Stream_Seek(s, capabilityLength - 4U);
|
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,12 +187,14 @@ UINT rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s)
|
|||||||
UINT status = CHANNEL_RC_OK;
|
UINT status = CHANNEL_RC_OK;
|
||||||
UINT16 i;
|
UINT16 i;
|
||||||
UINT16 numCapabilities;
|
UINT16 numCapabilities;
|
||||||
UINT16 capabilityType;
|
|
||||||
|
|
||||||
if (!rdpdr || !s)
|
if (!rdpdr || !s)
|
||||||
return CHANNEL_RC_NULL_DATA;
|
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;
|
return ERROR_INVALID_DATA;
|
||||||
|
|
||||||
Stream_Read_UINT16(s, numCapabilities);
|
Stream_Read_UINT16(s, numCapabilities);
|
||||||
@ -214,31 +202,44 @@ UINT rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s)
|
|||||||
|
|
||||||
for (i = 0; i < numCapabilities; i++)
|
for (i = 0; i < numCapabilities; i++)
|
||||||
{
|
{
|
||||||
if (Stream_GetRemainingLength(s) < sizeof(UINT16))
|
UINT16 capabilityType;
|
||||||
|
UINT16 capabilityLength;
|
||||||
|
UINT32 version = 0;
|
||||||
|
|
||||||
|
if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s,
|
||||||
|
2 * sizeof(UINT16) + sizeof(UINT32)))
|
||||||
return ERROR_INVALID_DATA;
|
return ERROR_INVALID_DATA;
|
||||||
|
|
||||||
Stream_Read_UINT16(s, capabilityType);
|
Stream_Read_UINT16(s, capabilityType);
|
||||||
|
Stream_Read_UINT16(s, capabilityLength);
|
||||||
|
Stream_Read_UINT32(s, version);
|
||||||
|
|
||||||
|
if (capabilityLength < 8)
|
||||||
|
{
|
||||||
|
return ERROR_INVALID_DATA;
|
||||||
|
}
|
||||||
|
capabilityLength -= 8;
|
||||||
|
|
||||||
switch (capabilityType)
|
switch (capabilityType)
|
||||||
{
|
{
|
||||||
case CAP_GENERAL_TYPE:
|
case CAP_GENERAL_TYPE:
|
||||||
status = rdpdr_process_general_capset(rdpdr, s);
|
status = rdpdr_process_general_capset(rdpdr, s, capabilityLength);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAP_PRINTER_TYPE:
|
case CAP_PRINTER_TYPE:
|
||||||
status = rdpdr_process_printer_capset(rdpdr, s);
|
status = rdpdr_process_printer_capset(rdpdr, s, capabilityLength);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAP_PORT_TYPE:
|
case CAP_PORT_TYPE:
|
||||||
status = rdpdr_process_port_capset(rdpdr, s);
|
status = rdpdr_process_port_capset(rdpdr, s, capabilityLength);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAP_DRIVE_TYPE:
|
case CAP_DRIVE_TYPE:
|
||||||
status = rdpdr_process_drive_capset(rdpdr, s);
|
status = rdpdr_process_drive_capset(rdpdr, s, capabilityLength);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAP_SMARTCARD_TYPE:
|
case CAP_SMARTCARD_TYPE:
|
||||||
status = rdpdr_process_smartcard_capset(rdpdr, s);
|
status = rdpdr_process_smartcard_capset(rdpdr, s, capabilityLength);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -264,7 +265,7 @@ UINT rdpdr_send_capability_response(rdpdrPlugin* rdpdr)
|
|||||||
|
|
||||||
if (!s)
|
if (!s)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Stream_New failed!");
|
WLog_Print(rdpdr->log, WLOG_ERROR, "Stream_New failed!");
|
||||||
return CHANNEL_RC_NO_MEMORY;
|
return CHANNEL_RC_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -42,15 +42,33 @@
|
|||||||
#include <CoreServices/CoreServices.h>
|
#include <CoreServices/CoreServices.h>
|
||||||
#endif
|
#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;
|
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
|
struct rdpdr_plugin
|
||||||
{
|
{
|
||||||
CHANNEL_DEF channelDef;
|
CHANNEL_DEF channelDef;
|
||||||
CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints;
|
CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints;
|
||||||
|
|
||||||
|
enum RDPDR_CHANNEL_STATE state;
|
||||||
HANDLE thread;
|
HANDLE thread;
|
||||||
wStream* data_in;
|
wStream* data_in;
|
||||||
void* InitHandle;
|
void* InitHandle;
|
||||||
@ -59,12 +77,33 @@ struct rdpdr_plugin
|
|||||||
|
|
||||||
DEVMAN* devman;
|
DEVMAN* devman;
|
||||||
|
|
||||||
UINT16 versionMajor;
|
UINT32 serverOsType;
|
||||||
UINT16 versionMinor;
|
UINT32 serverOsVersion;
|
||||||
UINT16 clientID;
|
UINT16 serverVersionMajor;
|
||||||
|
UINT16 serverVersionMinor;
|
||||||
|
UINT32 serverExtendedPDU;
|
||||||
|
UINT32 serverIOCode1;
|
||||||
|
UINT32 serverIOCode2;
|
||||||
|
UINT32 serverExtraFlags1;
|
||||||
|
UINT32 serverExtraFlags2;
|
||||||
|
UINT32 serverSpecialTypeDeviceCap;
|
||||||
|
|
||||||
|
UINT32 clientOsType;
|
||||||
|
UINT32 clientOsVersion;
|
||||||
|
UINT16 clientVersionMajor;
|
||||||
|
UINT16 clientVersionMinor;
|
||||||
|
UINT32 clientExtendedPDU;
|
||||||
|
UINT32 clientIOCode1;
|
||||||
|
UINT32 clientIOCode2;
|
||||||
|
UINT32 clientExtraFlags1;
|
||||||
|
UINT32 clientExtraFlags2;
|
||||||
|
UINT32 clientSpecialTypeDeviceCap;
|
||||||
|
|
||||||
|
UINT32 clientID;
|
||||||
char computerName[256];
|
char computerName[256];
|
||||||
|
|
||||||
UINT32 sequenceId;
|
UINT32 sequenceId;
|
||||||
|
BOOL userLoggedOn;
|
||||||
|
|
||||||
/* hotplug support */
|
/* hotplug support */
|
||||||
HANDLE hotplugThread;
|
HANDLE hotplugThread;
|
||||||
@ -78,8 +117,10 @@ struct rdpdr_plugin
|
|||||||
HANDLE stopEvent;
|
HANDLE stopEvent;
|
||||||
#endif
|
#endif
|
||||||
rdpContext* rdpcontext;
|
rdpContext* rdpcontext;
|
||||||
|
wLog* log;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BOOL rdpdr_state_advance(rdpdrPlugin* rdpdr, enum RDPDR_CHANNEL_STATE next);
|
||||||
UINT rdpdr_send(rdpdrPlugin* rdpdr, wStream* s);
|
UINT rdpdr_send(rdpdrPlugin* rdpdr, wStream* s);
|
||||||
|
|
||||||
#endif /* FREERDP_CHANNEL_RDPDR_CLIENT_MAIN_H */
|
#endif /* FREERDP_CHANNEL_RDPDR_CLIENT_MAIN_H */
|
||||||
|
|||||||
@ -57,13 +57,6 @@ struct _RDPDR_HEADER
|
|||||||
};
|
};
|
||||||
typedef struct _RDPDR_HEADER RDPDR_HEADER;
|
typedef struct _RDPDR_HEADER RDPDR_HEADER;
|
||||||
|
|
||||||
#define RDPDR_VERSION_MAJOR 0x0001
|
|
||||||
|
|
||||||
#define RDPDR_VERSION_MINOR_RDP50 0x0002
|
|
||||||
#define RDPDR_VERSION_MINOR_RDP51 0x0005
|
|
||||||
#define RDPDR_VERSION_MINOR_RDP52 0x000A
|
|
||||||
#define RDPDR_VERSION_MINOR_RDP6X 0x000C
|
|
||||||
|
|
||||||
#define RDPDR_CAPABILITY_HEADER_LENGTH 8
|
#define RDPDR_CAPABILITY_HEADER_LENGTH 8
|
||||||
|
|
||||||
struct _RDPDR_CAPABILITY_HEADER
|
struct _RDPDR_CAPABILITY_HEADER
|
||||||
|
|||||||
@ -686,8 +686,6 @@ static wStream* device_server_packet_new(size_t size, BYTE version, BYTE message
|
|||||||
{
|
{
|
||||||
wStream* s;
|
wStream* s;
|
||||||
|
|
||||||
WINPR_ASSERT(size > 0);
|
|
||||||
|
|
||||||
/* Allocate what we need plus header bytes */
|
/* Allocate what we need plus header bytes */
|
||||||
s = Stream_New(NULL, size + CAM_HEADER_SIZE);
|
s = Stream_New(NULL, size + CAM_HEADER_SIZE);
|
||||||
if (!s)
|
if (!s)
|
||||||
|
|||||||
@ -23,11 +23,15 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#include <winpr/crt.h>
|
#include <winpr/crt.h>
|
||||||
|
#include <winpr/assert.h>
|
||||||
#include <winpr/stream.h>
|
#include <winpr/stream.h>
|
||||||
#include <winpr/cmdline.h>
|
#include <winpr/cmdline.h>
|
||||||
|
|
||||||
@ -51,8 +55,39 @@ struct rdpsnd_pulse_plugin
|
|||||||
pa_stream* stream;
|
pa_stream* stream;
|
||||||
UINT32 latency;
|
UINT32 latency;
|
||||||
UINT32 volume;
|
UINT32 volume;
|
||||||
|
time_t reconnect_delay_seconds;
|
||||||
|
time_t reconnect_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static BOOL rdpsnd_check_pulse(rdpsndPulsePlugin* pulse, BOOL haveStream)
|
||||||
|
{
|
||||||
|
BOOL rc = TRUE;
|
||||||
|
WINPR_ASSERT(pulse);
|
||||||
|
|
||||||
|
if (!pulse->context)
|
||||||
|
{
|
||||||
|
WLog_WARN(TAG, "pulse->context=%p", pulse->context);
|
||||||
|
rc = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (haveStream)
|
||||||
|
{
|
||||||
|
if (!pulse->stream)
|
||||||
|
{
|
||||||
|
WLog_WARN(TAG, "pulse->stream=%p", pulse->stream);
|
||||||
|
rc = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pulse->mainloop)
|
||||||
|
{
|
||||||
|
WLog_WARN(TAG, "pulse->mainloop=%p", pulse->mainloop);
|
||||||
|
rc = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL rdpsnd_pulse_format_supported(rdpsndDevicePlugin* device, const AUDIO_FORMAT* format);
|
static BOOL rdpsnd_pulse_format_supported(rdpsndDevicePlugin* device, const AUDIO_FORMAT* format);
|
||||||
|
|
||||||
static void rdpsnd_pulse_get_sink_info(pa_context* c, const pa_sink_info* i, int eol,
|
static void rdpsnd_pulse_get_sink_info(pa_context* c, const pa_sink_info* i, int eol,
|
||||||
@ -65,7 +100,8 @@ static void rdpsnd_pulse_get_sink_info(pa_context* c, const pa_sink_info* i, int
|
|||||||
;
|
;
|
||||||
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)userdata;
|
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)userdata;
|
||||||
|
|
||||||
if (!pulse || !c || !i)
|
WINPR_ASSERT(c);
|
||||||
|
if (!rdpsnd_check_pulse(pulse, FALSE) || !i)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (x = 0; x < i->volume.channels; x++)
|
for (x = 0; x < i->volume.channels; x++)
|
||||||
@ -97,6 +133,10 @@ static void rdpsnd_pulse_context_state_callback(pa_context* context, void* userd
|
|||||||
{
|
{
|
||||||
pa_context_state_t state;
|
pa_context_state_t state;
|
||||||
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)userdata;
|
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)userdata;
|
||||||
|
|
||||||
|
WINPR_ASSERT(context);
|
||||||
|
WINPR_ASSERT(pulse);
|
||||||
|
|
||||||
state = pa_context_get_state(context);
|
state = pa_context_get_state(context);
|
||||||
|
|
||||||
switch (state)
|
switch (state)
|
||||||
@ -106,6 +146,14 @@ static void rdpsnd_pulse_context_state_callback(pa_context* context, void* userd
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PA_CONTEXT_FAILED:
|
case PA_CONTEXT_FAILED:
|
||||||
|
// Destroy context now, create new one for next connection attempt
|
||||||
|
pa_context_unref(pulse->context);
|
||||||
|
pulse->context = NULL;
|
||||||
|
if (pulse->reconnect_delay_seconds >= 0)
|
||||||
|
pulse->reconnect_time = time(NULL) + pulse->reconnect_delay_seconds;
|
||||||
|
pa_threaded_mainloop_signal(pulse->mainloop, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
case PA_CONTEXT_TERMINATED:
|
case PA_CONTEXT_TERMINATED:
|
||||||
pa_threaded_mainloop_signal(pulse->mainloop, 0);
|
pa_threaded_mainloop_signal(pulse->mainloop, 0);
|
||||||
break;
|
break;
|
||||||
@ -117,21 +165,17 @@ static void rdpsnd_pulse_context_state_callback(pa_context* context, void* userd
|
|||||||
|
|
||||||
static BOOL rdpsnd_pulse_connect(rdpsndDevicePlugin* device)
|
static BOOL rdpsnd_pulse_connect(rdpsndDevicePlugin* device)
|
||||||
{
|
{
|
||||||
|
BOOL rc;
|
||||||
pa_operation* o;
|
pa_operation* o;
|
||||||
pa_context_state_t state;
|
pa_context_state_t state;
|
||||||
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
|
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
|
||||||
|
|
||||||
if (!pulse->context)
|
if (!rdpsnd_check_pulse(pulse, FALSE))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (pa_context_connect(pulse->context, NULL, 0, NULL))
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
pa_threaded_mainloop_lock(pulse->mainloop);
|
pa_threaded_mainloop_lock(pulse->mainloop);
|
||||||
|
|
||||||
if (pa_threaded_mainloop_start(pulse->mainloop) < 0)
|
if (pa_context_connect(pulse->context, NULL, 0, NULL) < 0)
|
||||||
{
|
{
|
||||||
pa_threaded_mainloop_unlock(pulse->mainloop);
|
pa_threaded_mainloop_unlock(pulse->mainloop);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -157,27 +201,35 @@ static BOOL rdpsnd_pulse_connect(rdpsndDevicePlugin* device)
|
|||||||
if (o)
|
if (o)
|
||||||
pa_operation_unref(o);
|
pa_operation_unref(o);
|
||||||
|
|
||||||
pa_threaded_mainloop_unlock(pulse->mainloop);
|
|
||||||
|
|
||||||
if (state == PA_CONTEXT_READY)
|
if (state == PA_CONTEXT_READY)
|
||||||
{
|
{
|
||||||
return TRUE;
|
rc = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pa_context_disconnect(pulse->context);
|
pa_context_disconnect(pulse->context);
|
||||||
return FALSE;
|
rc = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pa_threaded_mainloop_unlock(pulse->mainloop);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rdpsnd_pulse_stream_success_callback(pa_stream* stream, int success, void* userdata)
|
static void rdpsnd_pulse_stream_success_callback(pa_stream* stream, int success, void* userdata)
|
||||||
{
|
{
|
||||||
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)userdata;
|
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)userdata;
|
||||||
|
|
||||||
|
if (!rdpsnd_check_pulse(pulse, TRUE))
|
||||||
|
return;
|
||||||
|
|
||||||
pa_threaded_mainloop_signal(pulse->mainloop, 0);
|
pa_threaded_mainloop_signal(pulse->mainloop, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rdpsnd_pulse_wait_for_operation(rdpsndPulsePlugin* pulse, pa_operation* operation)
|
static void rdpsnd_pulse_wait_for_operation(rdpsndPulsePlugin* pulse, pa_operation* operation)
|
||||||
{
|
{
|
||||||
|
if (!rdpsnd_check_pulse(pulse, TRUE))
|
||||||
|
return;
|
||||||
|
|
||||||
if (!operation)
|
if (!operation)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -193,6 +245,11 @@ static void rdpsnd_pulse_stream_state_callback(pa_stream* stream, void* userdata
|
|||||||
{
|
{
|
||||||
pa_stream_state_t state;
|
pa_stream_state_t state;
|
||||||
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)userdata;
|
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)userdata;
|
||||||
|
|
||||||
|
WINPR_ASSERT(stream);
|
||||||
|
if (!rdpsnd_check_pulse(pulse, TRUE))
|
||||||
|
return;
|
||||||
|
|
||||||
state = pa_stream_get_state(stream);
|
state = pa_stream_get_state(stream);
|
||||||
|
|
||||||
switch (state)
|
switch (state)
|
||||||
@ -203,6 +260,8 @@ static void rdpsnd_pulse_stream_state_callback(pa_stream* stream, void* userdata
|
|||||||
|
|
||||||
case PA_STREAM_FAILED:
|
case PA_STREAM_FAILED:
|
||||||
case PA_STREAM_TERMINATED:
|
case PA_STREAM_TERMINATED:
|
||||||
|
// Stream object is about to be destroyed, clean up our pointer
|
||||||
|
pulse->stream = NULL;
|
||||||
pa_threaded_mainloop_signal(pulse->mainloop, 0);
|
pa_threaded_mainloop_signal(pulse->mainloop, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -214,6 +273,11 @@ static void rdpsnd_pulse_stream_state_callback(pa_stream* stream, void* userdata
|
|||||||
static void rdpsnd_pulse_stream_request_callback(pa_stream* stream, size_t length, void* userdata)
|
static void rdpsnd_pulse_stream_request_callback(pa_stream* stream, size_t length, void* userdata)
|
||||||
{
|
{
|
||||||
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)userdata;
|
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)userdata;
|
||||||
|
|
||||||
|
WINPR_ASSERT(stream);
|
||||||
|
if (!rdpsnd_check_pulse(pulse, TRUE))
|
||||||
|
return;
|
||||||
|
|
||||||
pa_threaded_mainloop_signal(pulse->mainloop, 0);
|
pa_threaded_mainloop_signal(pulse->mainloop, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,15 +285,20 @@ static void rdpsnd_pulse_close(rdpsndDevicePlugin* device)
|
|||||||
{
|
{
|
||||||
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
|
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
|
||||||
|
|
||||||
if (!pulse->context || !pulse->stream)
|
WINPR_ASSERT(pulse);
|
||||||
|
|
||||||
|
if (!rdpsnd_check_pulse(pulse, FALSE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pa_threaded_mainloop_lock(pulse->mainloop);
|
pa_threaded_mainloop_lock(pulse->mainloop);
|
||||||
rdpsnd_pulse_wait_for_operation(
|
if (pulse->stream)
|
||||||
pulse, pa_stream_drain(pulse->stream, rdpsnd_pulse_stream_success_callback, pulse));
|
{
|
||||||
pa_stream_disconnect(pulse->stream);
|
rdpsnd_pulse_wait_for_operation(
|
||||||
pa_stream_unref(pulse->stream);
|
pulse, pa_stream_drain(pulse->stream, rdpsnd_pulse_stream_success_callback, pulse));
|
||||||
pulse->stream = NULL;
|
pa_stream_disconnect(pulse->stream);
|
||||||
|
pa_stream_unref(pulse->stream);
|
||||||
|
pulse->stream = NULL;
|
||||||
|
}
|
||||||
pa_threaded_mainloop_unlock(pulse->mainloop);
|
pa_threaded_mainloop_unlock(pulse->mainloop);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,7 +306,9 @@ static BOOL rdpsnd_pulse_set_format_spec(rdpsndPulsePlugin* pulse, const AUDIO_F
|
|||||||
{
|
{
|
||||||
pa_sample_spec sample_spec = { 0 };
|
pa_sample_spec sample_spec = { 0 };
|
||||||
|
|
||||||
if (!pulse->context)
|
WINPR_ASSERT(format);
|
||||||
|
|
||||||
|
if (!rdpsnd_check_pulse(pulse, FALSE))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!rdpsnd_pulse_format_supported(&pulse->device, format))
|
if (!rdpsnd_pulse_format_supported(&pulse->device, format))
|
||||||
@ -281,30 +352,52 @@ static BOOL rdpsnd_pulse_set_format_spec(rdpsndPulsePlugin* pulse, const AUDIO_F
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL rdpsnd_pulse_open(rdpsndDevicePlugin* device, const AUDIO_FORMAT* format,
|
static BOOL rdpsnd_pulse_context_connect(rdpsndDevicePlugin* device)
|
||||||
UINT32 latency)
|
{
|
||||||
|
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
|
||||||
|
|
||||||
|
pulse->context = pa_context_new(pa_threaded_mainloop_get_api(pulse->mainloop), "freerdp");
|
||||||
|
|
||||||
|
if (!pulse->context)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
pa_context_set_state_callback(pulse->context, rdpsnd_pulse_context_state_callback, pulse);
|
||||||
|
|
||||||
|
if (!rdpsnd_pulse_connect((rdpsndDevicePlugin*)pulse))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL rdpsnd_pulse_open_stream(rdpsndDevicePlugin* device)
|
||||||
{
|
{
|
||||||
pa_stream_state_t state;
|
pa_stream_state_t state;
|
||||||
pa_stream_flags_t flags;
|
pa_stream_flags_t flags;
|
||||||
pa_buffer_attr buffer_attr = { 0 };
|
pa_buffer_attr buffer_attr = { 0 };
|
||||||
char ss[PA_SAMPLE_SPEC_SNPRINT_MAX];
|
char ss[PA_SAMPLE_SPEC_SNPRINT_MAX] = { 0 };
|
||||||
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
|
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
|
||||||
|
|
||||||
if (!pulse->context || pulse->stream)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
if (!rdpsnd_pulse_set_format_spec(pulse, format))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
pulse->latency = latency;
|
|
||||||
|
|
||||||
if (pa_sample_spec_valid(&pulse->sample_spec) == 0)
|
if (pa_sample_spec_valid(&pulse->sample_spec) == 0)
|
||||||
{
|
{
|
||||||
pa_sample_spec_snprint(ss, sizeof(ss), &pulse->sample_spec);
|
pa_sample_spec_snprint(ss, sizeof(ss), &pulse->sample_spec);
|
||||||
return TRUE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_threaded_mainloop_lock(pulse->mainloop);
|
pa_threaded_mainloop_lock(pulse->mainloop);
|
||||||
|
if (!pulse->context)
|
||||||
|
{
|
||||||
|
pa_threaded_mainloop_unlock(pulse->mainloop);
|
||||||
|
if (pulse->reconnect_delay_seconds >= 0 && time(NULL) - pulse->reconnect_time >= 0)
|
||||||
|
rdpsnd_pulse_context_connect(device);
|
||||||
|
pa_threaded_mainloop_lock(pulse->mainloop);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rdpsnd_check_pulse(pulse, FALSE))
|
||||||
|
{
|
||||||
|
pa_threaded_mainloop_unlock(pulse->mainloop);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
pulse->stream = pa_stream_new(pulse->context, "freerdp", &pulse->sample_spec, NULL);
|
pulse->stream = pa_stream_new(pulse->context, "freerdp", &pulse->sample_spec, NULL);
|
||||||
|
|
||||||
if (!pulse->stream)
|
if (!pulse->stream)
|
||||||
@ -320,19 +413,22 @@ static BOOL rdpsnd_pulse_open(rdpsndDevicePlugin* device, const AUDIO_FORMAT* fo
|
|||||||
|
|
||||||
if (pulse->latency > 0)
|
if (pulse->latency > 0)
|
||||||
{
|
{
|
||||||
buffer_attr.maxlength = pa_usec_to_bytes(pulse->latency * 2 * 1000, &pulse->sample_spec);
|
buffer_attr.maxlength = UINT32_MAX;
|
||||||
buffer_attr.tlength = pa_usec_to_bytes(pulse->latency * 1000, &pulse->sample_spec);
|
buffer_attr.tlength = pa_usec_to_bytes(pulse->latency * 1000, &pulse->sample_spec);
|
||||||
buffer_attr.prebuf = (UINT32)-1;
|
buffer_attr.prebuf = UINT32_MAX;
|
||||||
buffer_attr.minreq = (UINT32)-1;
|
buffer_attr.minreq = UINT32_MAX;
|
||||||
buffer_attr.fragsize = (UINT32)-1;
|
buffer_attr.fragsize = UINT32_MAX;
|
||||||
flags |= PA_STREAM_ADJUST_LATENCY;
|
flags |= PA_STREAM_ADJUST_LATENCY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pa_stream_connect_playback(pulse->stream, pulse->device_name,
|
if (pa_stream_connect_playback(pulse->stream, pulse->device_name,
|
||||||
pulse->latency > 0 ? &buffer_attr : NULL, flags, NULL, NULL) < 0)
|
pulse->latency > 0 ? &buffer_attr : NULL, flags, NULL, NULL) < 0)
|
||||||
{
|
{
|
||||||
|
WLog_ERR(TAG, "error connecting playback stream");
|
||||||
|
pa_stream_unref(pulse->stream);
|
||||||
|
pulse->stream = NULL;
|
||||||
pa_threaded_mainloop_unlock(pulse->mainloop);
|
pa_threaded_mainloop_unlock(pulse->mainloop);
|
||||||
return TRUE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
@ -359,6 +455,24 @@ static BOOL rdpsnd_pulse_open(rdpsndDevicePlugin* device, const AUDIO_FORMAT* fo
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL rdpsnd_pulse_open(rdpsndDevicePlugin* device, const AUDIO_FORMAT* format,
|
||||||
|
UINT32 latency)
|
||||||
|
{
|
||||||
|
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
|
||||||
|
|
||||||
|
WINPR_ASSERT(format);
|
||||||
|
|
||||||
|
if (!rdpsnd_check_pulse(pulse, FALSE))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (!rdpsnd_pulse_set_format_spec(pulse, format))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
pulse->latency = latency;
|
||||||
|
|
||||||
|
return rdpsnd_pulse_open_stream(device);
|
||||||
|
}
|
||||||
|
|
||||||
static void rdpsnd_pulse_free(rdpsndDevicePlugin* device)
|
static void rdpsnd_pulse_free(rdpsndDevicePlugin* device)
|
||||||
{
|
{
|
||||||
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
|
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
|
||||||
@ -369,9 +483,7 @@ static void rdpsnd_pulse_free(rdpsndDevicePlugin* device)
|
|||||||
rdpsnd_pulse_close(device);
|
rdpsnd_pulse_close(device);
|
||||||
|
|
||||||
if (pulse->mainloop)
|
if (pulse->mainloop)
|
||||||
{
|
|
||||||
pa_threaded_mainloop_stop(pulse->mainloop);
|
pa_threaded_mainloop_stop(pulse->mainloop);
|
||||||
}
|
|
||||||
|
|
||||||
if (pulse->context)
|
if (pulse->context)
|
||||||
{
|
{
|
||||||
@ -394,6 +506,7 @@ static BOOL rdpsnd_pulse_default_format(rdpsndDevicePlugin* device, const AUDIO_
|
|||||||
AUDIO_FORMAT* defaultFormat)
|
AUDIO_FORMAT* defaultFormat)
|
||||||
{
|
{
|
||||||
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
|
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
|
||||||
|
|
||||||
if (!pulse || !defaultFormat)
|
if (!pulse || !defaultFormat)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@ -415,6 +528,9 @@ static BOOL rdpsnd_pulse_default_format(rdpsndDevicePlugin* device, const AUDIO_
|
|||||||
|
|
||||||
BOOL rdpsnd_pulse_format_supported(rdpsndDevicePlugin* device, const AUDIO_FORMAT* format)
|
BOOL rdpsnd_pulse_format_supported(rdpsndDevicePlugin* device, const AUDIO_FORMAT* format)
|
||||||
{
|
{
|
||||||
|
WINPR_ASSERT(device);
|
||||||
|
WINPR_ASSERT(format);
|
||||||
|
|
||||||
switch (format->wFormatTag)
|
switch (format->wFormatTag)
|
||||||
{
|
{
|
||||||
case WAVE_FORMAT_PCM:
|
case WAVE_FORMAT_PCM:
|
||||||
@ -439,39 +555,51 @@ static UINT32 rdpsnd_pulse_get_volume(rdpsndDevicePlugin* device)
|
|||||||
pa_operation* o;
|
pa_operation* o;
|
||||||
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
|
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
|
||||||
|
|
||||||
if (!pulse)
|
if (!rdpsnd_check_pulse(pulse, FALSE))
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!pulse->context || !pulse->mainloop)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
pa_threaded_mainloop_lock(pulse->mainloop);
|
pa_threaded_mainloop_lock(pulse->mainloop);
|
||||||
o = pa_context_get_sink_info_by_index(pulse->context, 0, rdpsnd_pulse_get_sink_info, pulse);
|
o = pa_context_get_sink_info_by_index(pulse->context, 0, rdpsnd_pulse_get_sink_info, pulse);
|
||||||
pa_operation_unref(o);
|
if (o)
|
||||||
|
pa_operation_unref(o);
|
||||||
pa_threaded_mainloop_unlock(pulse->mainloop);
|
pa_threaded_mainloop_unlock(pulse->mainloop);
|
||||||
return pulse->volume;
|
return pulse->volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rdpsnd_set_volume_success_cb(pa_context* c, int success, void* userdata)
|
||||||
|
{
|
||||||
|
rdpsndPulsePlugin* pulse = userdata;
|
||||||
|
|
||||||
|
if (!rdpsnd_check_pulse(pulse, TRUE))
|
||||||
|
return;
|
||||||
|
WINPR_ASSERT(c);
|
||||||
|
|
||||||
|
WLog_INFO(TAG, "%s: %d", __FUNCTION__, success);
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL rdpsnd_pulse_set_volume(rdpsndDevicePlugin* device, UINT32 value)
|
static BOOL rdpsnd_pulse_set_volume(rdpsndDevicePlugin* device, UINT32 value)
|
||||||
{
|
{
|
||||||
pa_cvolume cv;
|
pa_cvolume cv = { 0 };
|
||||||
pa_volume_t left;
|
pa_volume_t left;
|
||||||
pa_volume_t right;
|
pa_volume_t right;
|
||||||
pa_operation* operation;
|
pa_operation* operation;
|
||||||
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
|
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
|
||||||
|
|
||||||
if (!pulse->context || !pulse->stream)
|
if (!rdpsnd_check_pulse(pulse, TRUE))
|
||||||
|
{
|
||||||
|
WLog_WARN(TAG, "%s called before pulse backend was initialized");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
left = (pa_volume_t)(value & 0xFFFF);
|
left = (pa_volume_t)(value & 0xFFFF);
|
||||||
right = (pa_volume_t)((value >> 16) & 0xFFFF);
|
right = (pa_volume_t)((value >> 16) & 0xFFFF);
|
||||||
pa_cvolume_init(&cv);
|
pa_cvolume_init(&cv);
|
||||||
cv.channels = 2;
|
cv.channels = 2;
|
||||||
cv.values[0] = PA_VOLUME_MUTED + (left * (PA_VOLUME_NORM - PA_VOLUME_MUTED)) / 0xFFFF;
|
cv.values[0] = PA_VOLUME_MUTED + (left * (PA_VOLUME_NORM - PA_VOLUME_MUTED)) / PA_VOLUME_NORM;
|
||||||
cv.values[1] = PA_VOLUME_MUTED + (right * (PA_VOLUME_NORM - PA_VOLUME_MUTED)) / 0xFFFF;
|
cv.values[1] = PA_VOLUME_MUTED + (right * (PA_VOLUME_NORM - PA_VOLUME_MUTED)) / PA_VOLUME_NORM;
|
||||||
pa_threaded_mainloop_lock(pulse->mainloop);
|
pa_threaded_mainloop_lock(pulse->mainloop);
|
||||||
operation = pa_context_set_sink_input_volume(pulse->context, pa_stream_get_index(pulse->stream),
|
operation = pa_context_set_sink_input_volume(pulse->context, pa_stream_get_index(pulse->stream),
|
||||||
&cv, NULL, NULL);
|
&cv, rdpsnd_set_volume_success_cb, pulse);
|
||||||
|
|
||||||
if (operation)
|
if (operation)
|
||||||
pa_operation_unref(operation);
|
pa_operation_unref(operation);
|
||||||
@ -483,28 +611,38 @@ static BOOL rdpsnd_pulse_set_volume(rdpsndDevicePlugin* device, UINT32 value)
|
|||||||
static UINT rdpsnd_pulse_play(rdpsndDevicePlugin* device, const BYTE* data, size_t size)
|
static UINT rdpsnd_pulse_play(rdpsndDevicePlugin* device, const BYTE* data, size_t size)
|
||||||
{
|
{
|
||||||
size_t length;
|
size_t length;
|
||||||
|
void* pa_data;
|
||||||
int status;
|
int status;
|
||||||
pa_usec_t latency;
|
pa_usec_t latency;
|
||||||
int negative;
|
int negative;
|
||||||
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
|
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
|
||||||
|
|
||||||
if (!pulse->stream || !data)
|
if (!data)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
pa_threaded_mainloop_lock(pulse->mainloop);
|
pa_threaded_mainloop_lock(pulse->mainloop);
|
||||||
|
|
||||||
|
if (!rdpsnd_check_pulse(pulse, TRUE))
|
||||||
|
{
|
||||||
|
pa_threaded_mainloop_unlock(pulse->mainloop);
|
||||||
|
// Discard this playback request and just attempt to reconnect the stream
|
||||||
|
WLog_DBG(TAG, "reconnecting playback stream");
|
||||||
|
rdpsnd_pulse_open_stream(device);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
while (size > 0)
|
while (size > 0)
|
||||||
{
|
{
|
||||||
while ((length = pa_stream_writable_size(pulse->stream)) == 0)
|
length = size;
|
||||||
pa_threaded_mainloop_wait(pulse->mainloop);
|
|
||||||
|
|
||||||
if (length == (size_t)-1)
|
status = pa_stream_begin_write(pulse->stream, &pa_data, &length);
|
||||||
|
|
||||||
|
if (status < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (length > size)
|
memcpy(pa_data, data, length);
|
||||||
length = size;
|
|
||||||
|
|
||||||
status = pa_stream_write(pulse->stream, data, length, NULL, 0LL, PA_SEEK_RELATIVE);
|
status = pa_stream_write(pulse->stream, pa_data, length, NULL, 0LL, PA_SEEK_RELATIVE);
|
||||||
|
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
{
|
{
|
||||||
@ -522,22 +660,24 @@ static UINT rdpsnd_pulse_play(rdpsndDevicePlugin* device, const BYTE* data, size
|
|||||||
return latency / 1000;
|
return latency / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Function description
|
|
||||||
*
|
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
|
||||||
*/
|
|
||||||
static UINT rdpsnd_pulse_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV* args)
|
static UINT rdpsnd_pulse_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV* args)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
DWORD flags;
|
DWORD flags;
|
||||||
COMMAND_LINE_ARGUMENT_A* arg;
|
COMMAND_LINE_ARGUMENT_A* arg;
|
||||||
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
|
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
|
||||||
COMMAND_LINE_ARGUMENT_A rdpsnd_pulse_args[] = { { "dev", COMMAND_LINE_VALUE_REQUIRED,
|
COMMAND_LINE_ARGUMENT_A rdpsnd_pulse_args[] = {
|
||||||
"<device>", NULL, NULL, -1, NULL, "device" },
|
{ "dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "device" },
|
||||||
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } };
|
{ "reconnect_delay_seconds", COMMAND_LINE_VALUE_REQUIRED, "<reconnect_delay_seconds>", NULL,
|
||||||
|
NULL, -1, NULL, "reconnect_delay_seconds" },
|
||||||
|
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
|
||||||
|
};
|
||||||
flags =
|
flags =
|
||||||
COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_IGN_UNKNOWN_KEYWORD;
|
COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_IGN_UNKNOWN_KEYWORD;
|
||||||
|
|
||||||
|
WINPR_ASSERT(pulse);
|
||||||
|
WINPR_ASSERT(args);
|
||||||
|
|
||||||
status = CommandLineParseArgumentsA(args->argc, args->argv, rdpsnd_pulse_args, flags, pulse,
|
status = CommandLineParseArgumentsA(args->argc, args->argv, rdpsnd_pulse_args, flags, pulse,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
|
||||||
@ -558,6 +698,15 @@ static UINT rdpsnd_pulse_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV
|
|||||||
if (!pulse->device_name)
|
if (!pulse->device_name)
|
||||||
return ERROR_OUTOFMEMORY;
|
return ERROR_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
CommandLineSwitchCase(arg, "reconnect_delay_seconds")
|
||||||
|
{
|
||||||
|
unsigned long val = strtoul(arg->Value, NULL, 0);
|
||||||
|
|
||||||
|
if ((errno != 0) || (val > INT32_MAX))
|
||||||
|
return ERROR_INVALID_DATA;
|
||||||
|
|
||||||
|
pulse->reconnect_delay_seconds = val;
|
||||||
|
}
|
||||||
CommandLineSwitchEnd(arg)
|
CommandLineSwitchEnd(arg)
|
||||||
} while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
|
} while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
|
||||||
|
|
||||||
@ -570,16 +719,14 @@ static UINT rdpsnd_pulse_parse_addin_args(rdpsndDevicePlugin* device, ADDIN_ARGV
|
|||||||
#define freerdp_rdpsnd_client_subsystem_entry FREERDP_API freerdp_rdpsnd_client_subsystem_entry
|
#define freerdp_rdpsnd_client_subsystem_entry FREERDP_API freerdp_rdpsnd_client_subsystem_entry
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* Function description
|
|
||||||
*
|
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
|
||||||
*/
|
|
||||||
UINT freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints)
|
UINT freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints)
|
||||||
{
|
{
|
||||||
ADDIN_ARGV* args;
|
ADDIN_ARGV* args;
|
||||||
rdpsndPulsePlugin* pulse;
|
rdpsndPulsePlugin* pulse;
|
||||||
UINT ret;
|
UINT ret;
|
||||||
|
|
||||||
|
WINPR_ASSERT(pEntryPoints);
|
||||||
|
|
||||||
pulse = (rdpsndPulsePlugin*)calloc(1, sizeof(rdpsndPulsePlugin));
|
pulse = (rdpsndPulsePlugin*)calloc(1, sizeof(rdpsndPulsePlugin));
|
||||||
|
|
||||||
if (!pulse)
|
if (!pulse)
|
||||||
@ -605,6 +752,8 @@ UINT freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS p
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pulse->reconnect_delay_seconds = 5;
|
||||||
|
pulse->reconnect_time = time(NULL);
|
||||||
|
|
||||||
ret = CHANNEL_RC_NO_MEMORY;
|
ret = CHANNEL_RC_NO_MEMORY;
|
||||||
pulse->mainloop = pa_threaded_mainloop_new();
|
pulse->mainloop = pa_threaded_mainloop_new();
|
||||||
@ -612,15 +761,17 @@ UINT freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS p
|
|||||||
if (!pulse->mainloop)
|
if (!pulse->mainloop)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
pulse->context = pa_context_new(pa_threaded_mainloop_get_api(pulse->mainloop), "freerdp");
|
pa_threaded_mainloop_lock(pulse->mainloop);
|
||||||
|
|
||||||
if (!pulse->context)
|
if (pa_threaded_mainloop_start(pulse->mainloop) < 0)
|
||||||
goto error;
|
{
|
||||||
|
pa_threaded_mainloop_unlock(pulse->mainloop);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
pa_context_set_state_callback(pulse->context, rdpsnd_pulse_context_state_callback, pulse);
|
pa_threaded_mainloop_unlock(pulse->mainloop);
|
||||||
ret = ERROR_INVALID_OPERATION;
|
|
||||||
|
|
||||||
if (!rdpsnd_pulse_connect((rdpsndDevicePlugin*)pulse))
|
if (!rdpsnd_pulse_context_connect((rdpsndDevicePlugin*)pulse))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
pEntryPoints->pRegisterRdpsndDevice(pEntryPoints->rdpsnd, (rdpsndDevicePlugin*)pulse);
|
pEntryPoints->pRegisterRdpsndDevice(pEntryPoints->rdpsnd, (rdpsndDevicePlugin*)pulse);
|
||||||
|
|||||||
@ -126,6 +126,10 @@ struct rdpsnd_plugin
|
|||||||
HANDLE thread;
|
HANDLE thread;
|
||||||
wMessageQueue* queue;
|
wMessageQueue* queue;
|
||||||
BOOL initialized;
|
BOOL initialized;
|
||||||
|
|
||||||
|
UINT16 wVersion;
|
||||||
|
UINT32 volume;
|
||||||
|
BOOL applyVolume;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* rdpsnd_is_dyn_str(BOOL dynamic)
|
static const char* rdpsnd_is_dyn_str(BOOL dynamic)
|
||||||
@ -268,9 +272,9 @@ static UINT rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd)
|
|||||||
static UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* s)
|
static UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* s)
|
||||||
{
|
{
|
||||||
UINT16 index;
|
UINT16 index;
|
||||||
UINT16 wVersion;
|
|
||||||
UINT16 wNumberOfFormats;
|
UINT16 wNumberOfFormats;
|
||||||
UINT ret = ERROR_BAD_LENGTH;
|
UINT ret = ERROR_BAD_LENGTH;
|
||||||
|
|
||||||
audio_formats_free(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats);
|
audio_formats_free(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats);
|
||||||
rdpsnd->NumberOfServerFormats = 0;
|
rdpsnd->NumberOfServerFormats = 0;
|
||||||
rdpsnd->ServerFormats = NULL;
|
rdpsnd->ServerFormats = NULL;
|
||||||
@ -285,7 +289,7 @@ static UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream*
|
|||||||
Stream_Seek_UINT16(s); /* wDGramPort */
|
Stream_Seek_UINT16(s); /* wDGramPort */
|
||||||
Stream_Read_UINT16(s, wNumberOfFormats);
|
Stream_Read_UINT16(s, wNumberOfFormats);
|
||||||
Stream_Read_UINT8(s, rdpsnd->cBlockNo); /* cLastBlockConfirmed */
|
Stream_Read_UINT8(s, rdpsnd->cBlockNo); /* cLastBlockConfirmed */
|
||||||
Stream_Read_UINT16(s, wVersion); /* wVersion */
|
Stream_Read_UINT16(s, rdpsnd->wVersion); /* wVersion */
|
||||||
Stream_Seek_UINT8(s); /* bPad */
|
Stream_Seek_UINT8(s); /* bPad */
|
||||||
rdpsnd->NumberOfServerFormats = wNumberOfFormats;
|
rdpsnd->NumberOfServerFormats = wNumberOfFormats;
|
||||||
|
|
||||||
@ -312,7 +316,7 @@ static UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream*
|
|||||||
|
|
||||||
if (ret == CHANNEL_RC_OK)
|
if (ret == CHANNEL_RC_OK)
|
||||||
{
|
{
|
||||||
if (wVersion >= CHANNEL_VERSION_WIN_7)
|
if (rdpsnd->wVersion >= CHANNEL_VERSION_WIN_7)
|
||||||
ret = rdpsnd_send_quality_mode_pdu(rdpsnd);
|
ret = rdpsnd_send_quality_mode_pdu(rdpsnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,6 +377,20 @@ static UINT rdpsnd_recv_training_pdu(rdpsndPlugin* rdpsnd, wStream* s)
|
|||||||
return rdpsnd_send_training_confirm_pdu(rdpsnd, wTimeStamp, wPackSize);
|
return rdpsnd_send_training_confirm_pdu(rdpsnd, wTimeStamp, wPackSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL rdpsnd_apply_volume(rdpsndPlugin* rdpsnd)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(rdpsnd);
|
||||||
|
|
||||||
|
if (rdpsnd->isOpen && rdpsnd->applyVolume && rdpsnd->device)
|
||||||
|
{
|
||||||
|
BOOL rc = IFCALLRESULT(TRUE, rdpsnd->device->SetVolume, rdpsnd->device, rdpsnd->volume);
|
||||||
|
if (!rc)
|
||||||
|
return FALSE;
|
||||||
|
rdpsnd->applyVolume = FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL rdpsnd_ensure_device_is_open(rdpsndPlugin* rdpsnd, UINT32 wFormatNo,
|
static BOOL rdpsnd_ensure_device_is_open(rdpsndPlugin* rdpsnd, UINT32 wFormatNo,
|
||||||
const AUDIO_FORMAT* format)
|
const AUDIO_FORMAT* format)
|
||||||
{
|
{
|
||||||
@ -421,7 +439,7 @@ static BOOL rdpsnd_ensure_device_is_open(rdpsndPlugin* rdpsnd, UINT32 wFormatNo,
|
|||||||
rdpsnd->totalPlaySize = 0;
|
rdpsnd->totalPlaySize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return rdpsnd_apply_volume(rdpsnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -710,7 +728,7 @@ static void rdpsnd_recv_close_pdu(rdpsndPlugin* rdpsnd)
|
|||||||
*/
|
*/
|
||||||
static UINT rdpsnd_recv_volume_pdu(rdpsndPlugin* rdpsnd, wStream* s)
|
static UINT rdpsnd_recv_volume_pdu(rdpsndPlugin* rdpsnd, wStream* s)
|
||||||
{
|
{
|
||||||
BOOL rc = FALSE;
|
BOOL rc = TRUE;
|
||||||
UINT32 dwVolume;
|
UINT32 dwVolume;
|
||||||
|
|
||||||
if (Stream_GetRemainingLength(s) < 4)
|
if (Stream_GetRemainingLength(s) < 4)
|
||||||
@ -719,8 +737,10 @@ static UINT rdpsnd_recv_volume_pdu(rdpsndPlugin* rdpsnd, wStream* s)
|
|||||||
Stream_Read_UINT32(s, dwVolume);
|
Stream_Read_UINT32(s, dwVolume);
|
||||||
WLog_Print(rdpsnd->log, WLOG_DEBUG, "%s Volume: 0x%08" PRIX32 "",
|
WLog_Print(rdpsnd->log, WLOG_DEBUG, "%s Volume: 0x%08" PRIX32 "",
|
||||||
rdpsnd_is_dyn_str(rdpsnd->dynamic), dwVolume);
|
rdpsnd_is_dyn_str(rdpsnd->dynamic), dwVolume);
|
||||||
if (rdpsnd->device)
|
|
||||||
rc = IFCALLRESULT(FALSE, rdpsnd->device->SetVolume, rdpsnd->device, dwVolume);
|
rdpsnd->volume = dwVolume;
|
||||||
|
rdpsnd->applyVolume = TRUE;
|
||||||
|
rc = rdpsnd_apply_volume(rdpsnd);
|
||||||
|
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -523,7 +523,7 @@ static UINT rdpsnd_server_send_wave_pdu(RdpsndServerContext* context, UINT16 wTi
|
|||||||
Stream_Seek(s, 3); /* bPad */
|
Stream_Seek(s, 3); /* bPad */
|
||||||
start = Stream_GetPosition(s);
|
start = Stream_GetPosition(s);
|
||||||
src = context->priv->out_buffer;
|
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))
|
if (!freerdp_dsp_encode(context->priv->dsp_context, context->src_format, src, length, s))
|
||||||
return ERROR_INTERNAL_ERROR;
|
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)
|
if (mdecoder->codec->capabilities & AV_CODEC_CAP_TRUNCATED)
|
||||||
mdecoder->codec_context->flags |= AV_CODEC_FLAG_TRUNCATED;
|
mdecoder->codec_context->flags |= AV_CODEC_FLAG_TRUNCATED;
|
||||||
|
#endif
|
||||||
|
|
||||||
return TRUE;
|
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)
|
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;
|
rdpInput* input;
|
||||||
UINT16 flags = 0;
|
UINT16 flags = 0;
|
||||||
int32_t direction;
|
int32_t direction;
|
||||||
uint32_t x, y;
|
uint32_t avalue = abs(value);
|
||||||
uint32_t i;
|
|
||||||
|
|
||||||
if (!instance || !ev || !instance->input)
|
input = instance->input;
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
x = ev->x;
|
|
||||||
y = ev->y;
|
|
||||||
|
|
||||||
if (!wlf_scale_coordinates(instance->context, &x, &y, TRUE))
|
if (!wlf_scale_coordinates(instance->context, &x, &y, TRUE))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
input = instance->input;
|
input = instance->input;
|
||||||
|
|
||||||
direction = ev->value;
|
direction = value;
|
||||||
switch (ev->axis)
|
switch (axis)
|
||||||
{
|
{
|
||||||
case WL_POINTER_AXIS_VERTICAL_SCROLL:
|
case WL_POINTER_AXIS_VERTICAL_SCROLL:
|
||||||
flags |= PTR_FLAGS_WHEEL;
|
flags |= PTR_FLAGS_WHEEL;
|
||||||
@ -176,16 +194,102 @@ BOOL wlf_handle_pointer_axis(freerdp* instance, const UwacPointerAxisEvent* ev)
|
|||||||
* positive: 0 ... 0xFF -> slow ... fast
|
* positive: 0 ... 0xFF -> slow ... fast
|
||||||
* negative: 0 ... 0xFF -> fast ... slow
|
* 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 */
|
/* Convert negative values to 9bit twos complement */
|
||||||
if (flags & PTR_FLAGS_WHEEL_NEGATIVE)
|
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))
|
if (!freerdp_input_send_mouse_event(input, cflags, (UINT16)x, (UINT16)y))
|
||||||
return FALSE;
|
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;
|
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_motion(freerdp* instance, const UwacPointerMotionEvent* ev);
|
||||||
BOOL wlf_handle_pointer_buttons(freerdp* instance, const UwacPointerButtonEvent* 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(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_up(freerdp* instance, const UwacTouchUp* ev);
|
||||||
BOOL wlf_handle_touch_down(freerdp* instance, const UwacTouchDown* ev);
|
BOOL wlf_handle_touch_down(freerdp* instance, const UwacTouchDown* ev);
|
||||||
BOOL wlf_handle_touch_motion(freerdp* instance, const UwacTouchMotion* 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;
|
break;
|
||||||
|
|
||||||
case UWAC_EVENT_POINTER_AXIS:
|
case UWAC_EVENT_POINTER_AXIS:
|
||||||
|
if (!wlf_handle_pointer_axis(instance, &event.mouse_axis))
|
||||||
|
return FALSE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UWAC_EVENT_POINTER_AXIS_DISCRETE:
|
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;
|
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;
|
break;
|
||||||
|
|
||||||
case UWAC_EVENT_KEY:
|
case UWAC_EVENT_KEY:
|
||||||
@ -561,8 +571,37 @@ static int wlf_logon_error_info(freerdp* instance, UINT32 data, UINT32 type)
|
|||||||
return 1;
|
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)
|
static BOOL wlf_client_new(freerdp* instance, rdpContext* context)
|
||||||
{
|
{
|
||||||
|
wObject* obj;
|
||||||
UwacReturnCode status;
|
UwacReturnCode status;
|
||||||
wlfContext* wfl = (wlfContext*)context;
|
wlfContext* wfl = (wlfContext*)context;
|
||||||
|
|
||||||
@ -590,26 +629,19 @@ static BOOL wlf_client_new(freerdp* instance, rdpContext* context)
|
|||||||
if (!wfl->displayHandle)
|
if (!wfl->displayHandle)
|
||||||
return FALSE;
|
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);
|
InitializeCriticalSection(&wfl->critical);
|
||||||
|
|
||||||
return TRUE;
|
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)
|
static int wfl_client_start(rdpContext* context)
|
||||||
{
|
{
|
||||||
WINPR_UNUSED(context);
|
WINPR_UNUSED(context);
|
||||||
|
|||||||
@ -53,6 +53,7 @@ struct wlf_context
|
|||||||
wlfDispContext* disp;
|
wlfDispContext* disp;
|
||||||
wLog* log;
|
wLog* log;
|
||||||
CRITICAL_SECTION critical;
|
CRITICAL_SECTION critical;
|
||||||
|
wArrayList* events;
|
||||||
};
|
};
|
||||||
|
|
||||||
BOOL wlf_scale_coordinates(rdpContext* context, UINT32* px, UINT32* py, BOOL fromLocalToRDP);
|
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:
|
case RDP_CODEC_ID_NONE:
|
||||||
pSrcData = cmd->bmp.bitmapData;
|
pSrcData = cmd->bmp.bitmapData;
|
||||||
format = gdi_get_pixel_format(cmd->bmp.bpp);
|
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)
|
if (size > cmd->bmp.bitmapDataLength)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Short nocodec message: got %" PRIu32 " bytes, require %" PRIuz,
|
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 = surface->gdi.width * GetBytesPerPixel(surface->gdi.format);
|
||||||
surface->gdi.scanline = x11_pad_scanline(surface->gdi.scanline, xfc->scanline_pad);
|
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);
|
surface->gdi.data = (BYTE*)_aligned_malloc(size, 16);
|
||||||
|
|
||||||
if (!surface->gdi.data)
|
if (!surface->gdi.data)
|
||||||
@ -312,7 +312,7 @@ static UINT xf_CreateSurface(RdpgfxClientContext* context,
|
|||||||
UINT32 bytes = GetBytesPerPixel(gdi->dstFormat);
|
UINT32 bytes = GetBytesPerPixel(gdi->dstFormat);
|
||||||
surface->stageScanline = width * bytes;
|
surface->stageScanline = width * bytes;
|
||||||
surface->stageScanline = x11_pad_scanline(surface->stageScanline, xfc->scanline_pad);
|
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);
|
surface->stage = (BYTE*)_aligned_malloc(size, 16);
|
||||||
|
|
||||||
if (!surface->stage)
|
if (!surface->stage)
|
||||||
|
|||||||
@ -311,7 +311,7 @@ static BOOL xf_Pointer_GetCursorForCurrentScale(rdpContext* context, const rdpPo
|
|||||||
ci.height = yTargetSize;
|
ci.height = yTargetSize;
|
||||||
ci.xhot = pointer->xPos * xscale;
|
ci.xhot = pointer->xPos * xscale;
|
||||||
ci.yhot = pointer->yPos * yscale;
|
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)))
|
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->nCursors = 0;
|
||||||
xpointer->mCursors = 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)))
|
if (!(xpointer->cursorPixels = (XcursorPixel*)_aligned_malloc(size, 16)))
|
||||||
goto fail;
|
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);
|
WLog_DBG(TAG, "%s: %" PRIu32 "x%" PRIu32, __func__, x, y);
|
||||||
if (xfc->remote_app && !xfc->focused)
|
if (!xfc->focused)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
xf_adjust_coordinates_to_screen(xfc, &x, &y);
|
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;
|
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)
|
if (rc == 0)
|
||||||
WLog_WARN(TAG, "%s: XWarpPointer==%d", __func__, rc);
|
WLog_WARN(TAG, "%s: XWarpPointer==%d", __func__, rc);
|
||||||
tmp.event_mask = current.your_event_mask;
|
tmp.event_mask = current.your_event_mask;
|
||||||
|
|||||||
@ -544,7 +544,7 @@ static xfRailIconCache* RailIconCache_New(rdpSettings* settings)
|
|||||||
|
|
||||||
cache->numCaches = settings->RemoteAppNumIconCaches;
|
cache->numCaches = settings->RemoteAppNumIconCaches;
|
||||||
cache->numCacheEntries = settings->RemoteAppNumIconCacheEntries;
|
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)
|
if (!cache->entries)
|
||||||
{
|
{
|
||||||
@ -614,7 +614,7 @@ static BOOL convert_rail_icon(const ICON_INFO* iconInfo, xfRailIcon* railIcon)
|
|||||||
long* pixels;
|
long* pixels;
|
||||||
int i;
|
int i;
|
||||||
int nelements;
|
int nelements;
|
||||||
argbPixels = calloc(iconInfo->width * iconInfo->height * 1ULL, 4);
|
argbPixels = calloc(1ull * iconInfo->width * iconInfo->height, 4);
|
||||||
|
|
||||||
if (!argbPixels)
|
if (!argbPixels)
|
||||||
goto error;
|
goto error;
|
||||||
|
|||||||
@ -2728,7 +2728,10 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
|
|||||||
if (strcmp(arg->Value, "video") == 0)
|
if (strcmp(arg->Value, "video") == 0)
|
||||||
settings->RemoteFxCodecMode = 0x00;
|
settings->RemoteFxCodecMode = 0x00;
|
||||||
else if (strcmp(arg->Value, "image") == 0)
|
else if (strcmp(arg->Value, "image") == 0)
|
||||||
|
{
|
||||||
|
settings->RemoteFxImageCodec = TRUE;
|
||||||
settings->RemoteFxCodecMode = 0x02;
|
settings->RemoteFxCodecMode = 0x02;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CommandLineSwitchCase(arg, "frame-ack")
|
CommandLineSwitchCase(arg, "frame-ack")
|
||||||
{
|
{
|
||||||
@ -2996,6 +2999,10 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
|
|||||||
{
|
{
|
||||||
settings->GrabKeyboard = enable;
|
settings->GrabKeyboard = enable;
|
||||||
}
|
}
|
||||||
|
CommandLineSwitchCase(arg, "grab-mouse")
|
||||||
|
{
|
||||||
|
settings->GrabMouse = enable;
|
||||||
|
}
|
||||||
CommandLineSwitchCase(arg, "unmap-buttons")
|
CommandLineSwitchCase(arg, "unmap-buttons")
|
||||||
{
|
{
|
||||||
settings->UnmapButtons = enable;
|
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" },
|
{ "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", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
|
||||||
"Grab keyboard" },
|
"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,
|
{ "gt", COMMAND_LINE_VALUE_REQUIRED, "[rpc|http[,no-websockets]|auto[,no-websockets]]", NULL,
|
||||||
NULL, -1, NULL, "Gateway transport type" },
|
NULL, -1, NULL, "Gateway transport type" },
|
||||||
{ "gu", COMMAND_LINE_VALUE_REQUIRED, "[[<domain>\\]<user>|<user>[@<domain>]]", NULL, NULL, -1,
|
{ "gu", COMMAND_LINE_VALUE_REQUIRED, "[[<domain>\\]<user>|<user>[@<domain>]]", NULL, NULL, -1,
|
||||||
|
|||||||
48
cmake/ClangDetectTool.cmake
Normal file
48
cmake/ClangDetectTool.cmake
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
function (clang_detect_tool VAR NAME OPTS)
|
||||||
|
set(NAMES "")
|
||||||
|
foreach(CNT RANGE 12 22)
|
||||||
|
list(APPEND NAMES "${NAME}-${CNT}")
|
||||||
|
endforeach()
|
||||||
|
list(REVERSE NAMES)
|
||||||
|
list(APPEND NAMES ${NAME})
|
||||||
|
|
||||||
|
find_program(${VAR}
|
||||||
|
NAMES ${NAMES}
|
||||||
|
${OPTS}
|
||||||
|
)
|
||||||
|
if (NOT ${VAR})
|
||||||
|
message(WARNING "clang tool ${NAME} (${VAR}) not detected, skipping")
|
||||||
|
unset(${VAR})
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${${VAR}} "--version"
|
||||||
|
OUTPUT_VARIABLE _CLANG_TOOL_VERSION
|
||||||
|
RESULT_VARIABLE _CLANG_TOOL_VERSION_FAILED
|
||||||
|
)
|
||||||
|
|
||||||
|
if (_CLANG_TOOL_VERSION_FAILED)
|
||||||
|
message(WARNING "A problem was encounterd with ${${VAR}}")
|
||||||
|
message(WARNING "${_CLANG_TOOL_VERSION_FAILED}")
|
||||||
|
unset(${VAR})
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
string(REGEX MATCH "([7-9]|[1-9][0-9])\\.[0-9]\\.[0-9]" CLANG_TOOL_VERSION
|
||||||
|
"${_CLANG_TOOL_VERSION}")
|
||||||
|
|
||||||
|
if (NOT CLANG_TOOL_VERSION)
|
||||||
|
message(WARNING "problem parsing ${NAME} version for ${${VAR}}")
|
||||||
|
unset(${VAR})
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(_CLANG_TOOL_MINIMUM_VERSION "12.0.0")
|
||||||
|
if (${CLANG_TOOL_VERSION} VERSION_LESS ${_CLANG_TOOL_MINIMUM_VERSION})
|
||||||
|
message(WARNING "clang-format version ${CLANG_TOOL_VERSION} not supported")
|
||||||
|
message(WARNING "Minimum version required: ${_CLANG_TOOL_MINIMUM_VERSION}")
|
||||||
|
unset(${VAR})
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
@ -1,43 +1,12 @@
|
|||||||
# get all project files
|
# get all project files
|
||||||
file(GLOB_RECURSE ALL_SOURCE_FILES *.cpp *.c *.h *.m *.java)
|
file(GLOB_RECURSE ALL_SOURCE_FILES *.cpp *.c *.h *.m *.java)
|
||||||
# minimum version required
|
|
||||||
set(_CLANG_FORMAT_MINIMUM_VERSION 7.0.0)
|
|
||||||
|
|
||||||
find_program(CLANG_FORMAT
|
include(ClangDetectTool)
|
||||||
NAMES
|
clang_detect_tool(CLANG_FORMAT clang-format "")
|
||||||
clang-format-8
|
|
||||||
clang-format-7
|
|
||||||
clang-format
|
|
||||||
)
|
|
||||||
|
|
||||||
if (NOT CLANG_FORMAT)
|
if (NOT CLANG_FORMAT)
|
||||||
message(WARNING "clang-format not found in path! code format target not available.")
|
message(WARNING "clang-format not found in path! code format target not available.")
|
||||||
else()
|
else()
|
||||||
execute_process(
|
|
||||||
COMMAND ${CLANG_FORMAT} "--version"
|
|
||||||
OUTPUT_VARIABLE _CLANG_FORMAT_VERSION
|
|
||||||
RESULT_VARIABLE _CLANG_FORMAT_VERSION_FAILED
|
|
||||||
)
|
|
||||||
|
|
||||||
if (_CLANG_FORMAT_VERSION_FAILED)
|
|
||||||
message(WARNING "A problem was encounterd with ${CLANG_FORMAT}")
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
string(REGEX MATCH "([7-9]|[1-9][0-9])\\.[0-9]\\.[0-9]" CLANG_FORMAT_VERSION
|
|
||||||
"${_CLANG_FORMAT_VERSION}")
|
|
||||||
|
|
||||||
if (NOT CLANG_FORMAT_VERSION)
|
|
||||||
message(WARNING "problem parsing clang-fromat version for ${CLANG_FORMAT}")
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (${CLANG_FORMAT_VERSION} VERSION_LESS ${_CLANG_FORMAT_MINIMUM_VERSION})
|
|
||||||
message(WARNING "clang-format version ${CLANG_FORMAT_VERSION} not supported")
|
|
||||||
message(WARNING "Minimum version required: ${_CLANG_FORMAT_MINIMUM_VERSION}")
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_custom_target(
|
add_custom_target(
|
||||||
clangformat
|
clangformat
|
||||||
COMMAND ${CLANG_FORMAT}
|
COMMAND ${CLANG_FORMAT}
|
||||||
|
|||||||
@ -47,12 +47,12 @@ if(NOT WIN32)
|
|||||||
CMAKE_DEPENDENT_OPTION(WITH_SANITIZE_ADDRESS "Compile with gcc/clang address sanitizer." OFF
|
CMAKE_DEPENDENT_OPTION(WITH_SANITIZE_ADDRESS "Compile with gcc/clang address sanitizer." OFF
|
||||||
"NOT WITH_VALGRIND_MEMCHECK; NOT WITH_SANITIZE_MEMORY; NOT WITH_SANITIZE_THREAD" OFF)
|
"NOT WITH_VALGRIND_MEMCHECK; NOT WITH_SANITIZE_MEMORY; NOT WITH_SANITIZE_THREAD" OFF)
|
||||||
CMAKE_DEPENDENT_OPTION(WITH_SANITIZE_MEMORY "Compile with gcc/clang memory sanitizer." OFF
|
CMAKE_DEPENDENT_OPTION(WITH_SANITIZE_MEMORY "Compile with gcc/clang memory sanitizer." OFF
|
||||||
"NOT WITH_VALGRIND_MEMCHECK; NOT WITH_SANITIZE_ADDRESS; NOT WITH_SANITIZE_THREAD" OFF)
|
"NOT WITH_VALGRIND_MEMCHECK; NOT WITH_SANITIZE_ADDRESS; NOT WITH_SANITIZE_THREAD" OFF)
|
||||||
CMAKE_DEPENDENT_OPTION(WITH_SANITIZE_THREAD "Compile with gcc/clang thread sanitizer." OFF
|
CMAKE_DEPENDENT_OPTION(WITH_SANITIZE_THREAD "Compile with gcc/clang thread sanitizer." OFF
|
||||||
"NOT WITH_VALGRIND_MEMCHECK; NOT WITH_SANITIZE_ADDRESS; NOT WITH_SANITIZE_MEMORY" OFF)
|
"NOT WITH_VALGRIND_MEMCHECK; NOT WITH_SANITIZE_ADDRESS; NOT WITH_SANITIZE_MEMORY" OFF)
|
||||||
else()
|
else()
|
||||||
if(NOT UWP)
|
if(NOT UWP)
|
||||||
option(WITH_MEDIA_FOUNDATION "Enable H264 media foundation decoder." ON)
|
option(WITH_MEDIA_FOUNDATION "Enable H264 media foundation decoder." OFF)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ option(WITH_SERVER_INTERFACE "Build servers as a library with an interface" ON)
|
|||||||
option(WITH_DEBUG_ALL "Print all debug messages." OFF)
|
option(WITH_DEBUG_ALL "Print all debug messages." OFF)
|
||||||
|
|
||||||
if(WITH_DEBUG_ALL)
|
if(WITH_DEBUG_ALL)
|
||||||
message(WARNING "WITH_DEBUG_ALL=ON, the build will be slow and might leak sensitive information, do not use with release builds!")
|
message(WARNING "WITH_DEBUG_ALL=ON, the build will be slow and might leak sensitive information, do not use with release builds!")
|
||||||
set(DEFAULT_DEBUG_OPTION "ON")
|
set(DEFAULT_DEBUG_OPTION "ON")
|
||||||
else()
|
else()
|
||||||
set(DEFAULT_DEBUG_OPTION "OFF")
|
set(DEFAULT_DEBUG_OPTION "OFF")
|
||||||
@ -106,7 +106,7 @@ endif()
|
|||||||
|
|
||||||
option(WITH_DEBUG_CERTIFICATE "Print certificate related debug messages." ${DEFAULT_DEBUG_OPTION})
|
option(WITH_DEBUG_CERTIFICATE "Print certificate related debug messages." ${DEFAULT_DEBUG_OPTION})
|
||||||
if(WITH_DEBUG_CERTIFICATE)
|
if(WITH_DEBUG_CERTIFICATE)
|
||||||
message(WARNING "WITH_DEBUG_CERTIFICATE=ON, the build might leak sensitive information, do not use with release builds!")
|
message(WARNING "WITH_DEBUG_CERTIFICATE=ON, the build might leak sensitive information, do not use with release builds!")
|
||||||
endif()
|
endif()
|
||||||
option(WITH_DEBUG_CAPABILITIES "Print capability negotiation debug messages." ${DEFAULT_DEBUG_OPTION})
|
option(WITH_DEBUG_CAPABILITIES "Print capability negotiation debug messages." ${DEFAULT_DEBUG_OPTION})
|
||||||
option(WITH_DEBUG_CHANNELS "Print channel manager debug messages." ${DEFAULT_DEBUG_OPTION})
|
option(WITH_DEBUG_CHANNELS "Print channel manager debug messages." ${DEFAULT_DEBUG_OPTION})
|
||||||
@ -116,23 +116,23 @@ option(WITH_DEBUG_DVC "Print dynamic virtual channel debug messages." ${DEFAULT_
|
|||||||
CMAKE_DEPENDENT_OPTION(WITH_DEBUG_TSMF "Print TSMF virtual channel debug messages." ${DEFAULT_DEBUG_OPTION} "CHANNEL_TSMF" OFF)
|
CMAKE_DEPENDENT_OPTION(WITH_DEBUG_TSMF "Print TSMF virtual channel debug messages." ${DEFAULT_DEBUG_OPTION} "CHANNEL_TSMF" OFF)
|
||||||
option(WITH_DEBUG_KBD "Print keyboard related debug messages." OFF)
|
option(WITH_DEBUG_KBD "Print keyboard related debug messages." OFF)
|
||||||
if(WITH_DEBUG_KBD)
|
if(WITH_DEBUG_KBD)
|
||||||
message(WARNING "WITH_DEBUG_KBD=ON, the build might leak sensitive information, do not use with release builds!")
|
message(WARNING "WITH_DEBUG_KBD=ON, the build might leak sensitive information, do not use with release builds!")
|
||||||
endif()
|
endif()
|
||||||
option(WITH_DEBUG_LICENSE "Print license debug messages." OFF)
|
option(WITH_DEBUG_LICENSE "Print license debug messages." OFF)
|
||||||
if(WITH_DEBUG_LICENSE)
|
if(WITH_DEBUG_LICENSE)
|
||||||
message(WARNING "WITH_DEBUG_LICENSE=ON, the build might leak sensitive information, do not use with release builds!")
|
message(WARNING "WITH_DEBUG_LICENSE=ON, the build might leak sensitive information, do not use with release builds!")
|
||||||
endif()
|
endif()
|
||||||
option(WITH_DEBUG_NEGO "Print negotiation related debug messages." OFF)
|
option(WITH_DEBUG_NEGO "Print negotiation related debug messages." OFF)
|
||||||
if(WITH_DEBUG_NEGO)
|
if(WITH_DEBUG_NEGO)
|
||||||
message(WARNING "WITH_DEBUG_NEGO=ON, the build might leak sensitive information, do not use with release builds!")
|
message(WARNING "WITH_DEBUG_NEGO=ON, the build might leak sensitive information, do not use with release builds!")
|
||||||
endif()
|
endif()
|
||||||
option(WITH_DEBUG_NLA "Print authentication related debug messages." OFF)
|
option(WITH_DEBUG_NLA "Print authentication related debug messages." OFF)
|
||||||
if(WITH_DEBUG_NLA)
|
if(WITH_DEBUG_NLA)
|
||||||
message(WARNING "WITH_DEBUG_NLA=ON, the build might leak sensitive information, do not use with release builds!")
|
message(WARNING "WITH_DEBUG_NLA=ON, the build might leak sensitive information, do not use with release builds!")
|
||||||
endif()
|
endif()
|
||||||
option(WITH_DEBUG_NTLM "Print NTLM debug messages" OFF)
|
option(WITH_DEBUG_NTLM "Print NTLM debug messages" OFF)
|
||||||
if(WITH_DEBUG_NTLM)
|
if(WITH_DEBUG_NTLM)
|
||||||
message(WARNING "WITH_DEBUG_NTLM=ON, the build might leak sensitive information, do not use with release builds!")
|
message(WARNING "WITH_DEBUG_NTLM=ON, the build might leak sensitive information, do not use with release builds!")
|
||||||
endif()
|
endif()
|
||||||
option(WITH_DEBUG_TSG "Print Terminal Server Gateway debug messages" ${DEFAULT_DEBUG_OPTION})
|
option(WITH_DEBUG_TSG "Print Terminal Server Gateway debug messages" ${DEFAULT_DEBUG_OPTION})
|
||||||
option(WITH_DEBUG_RAIL "Print RemoteApp debug messages" ${DEFAULT_DEBUG_OPTION})
|
option(WITH_DEBUG_RAIL "Print RemoteApp debug messages" ${DEFAULT_DEBUG_OPTION})
|
||||||
@ -163,13 +163,13 @@ option(WITH_GSSAPI "Compile support for kerberos authentication. (EXPERIMENTAL)"
|
|||||||
|
|
||||||
option(WITH_DSP_EXPERIMENTAL "Enable experimental sound encoder/decoder formats" OFF)
|
option(WITH_DSP_EXPERIMENTAL "Enable experimental sound encoder/decoder formats" OFF)
|
||||||
if (WITH_FFMPEG)
|
if (WITH_FFMPEG)
|
||||||
option(WITH_DSP_FFMPEG "Use FFMPEG for audio encoding/decoding" OFF)
|
option(WITH_DSP_FFMPEG "Use FFMPEG for audio encoding/decoding" OFF)
|
||||||
option(WITH_VAAPI "Use FFMPEG VAAPI (EXPERIMENTAL)" OFF)
|
option(WITH_VAAPI "Use FFMPEG VAAPI (EXPERIMENTAL)" OFF)
|
||||||
endif(WITH_FFMPEG)
|
endif(WITH_FFMPEG)
|
||||||
|
|
||||||
option(USE_VERSION_FROM_GIT_TAG "Extract FreeRDP version from git tag." OFF)
|
option(USE_VERSION_FROM_GIT_TAG "Extract FreeRDP version from git tag." OFF)
|
||||||
|
|
||||||
option(WITH_CAIRO "Use CAIRO image library for screen resizing" OFF)
|
option(WITH_CAIRO "Use CAIRO image library for screen resizing" OFF)
|
||||||
option(WITH_SWSCALE "Use SWScale image library for screen resizing" OFF)
|
option(WITH_SWSCALE "Use SWScale image library for screen resizing" OFF)
|
||||||
|
|
||||||
option(DEFINE_NO_DEPRECATED "Compile without legacy functions and symbols" OFF)
|
option(DEFINE_NO_DEPRECATED "Compile without legacy functions and symbols" OFF)
|
||||||
|
|||||||
@ -55,7 +55,7 @@ FIND_PATH(OPENSSL_INCLUDE_DIR
|
|||||||
NAMES
|
NAMES
|
||||||
openssl/ssl.h
|
openssl/ssl.h
|
||||||
PATH_SUFFIXES
|
PATH_SUFFIXES
|
||||||
"include"
|
"include"
|
||||||
HINTS
|
HINTS
|
||||||
${_OPENSSL_INCLUDEDIR}
|
${_OPENSSL_INCLUDEDIR}
|
||||||
${_OPENSSL_ROOT_HINTS_AND_PATHS}
|
${_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_DEBUG_LIBRARIES ${SSL_EAY_DEBUG} ${LIB_EAY_DEBUG} )
|
||||||
set( OPENSSL_RELEASE_LIBRARIES ${SSL_EAY_RELEASE} ${LIB_EAY_RELEASE} )
|
set( OPENSSL_RELEASE_LIBRARIES ${SSL_EAY_RELEASE} ${LIB_EAY_RELEASE} )
|
||||||
set( OPENSSL_LIBRARIES ${OPENSSL_RELEASE_LIBRARIES} )
|
set( OPENSSL_LIBRARIES ${OPENSSL_RELEASE_LIBRARIES} )
|
||||||
|
|
||||||
MARK_AS_ADVANCED(SSL_EAY_DEBUG SSL_EAY_RELEASE)
|
MARK_AS_ADVANCED(SSL_EAY_DEBUG SSL_EAY_RELEASE)
|
||||||
MARK_AS_ADVANCED(LIB_EAY_DEBUG LIB_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]).*$"
|
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}")
|
"\\1;\\2;\\3;\\4;\\5" OPENSSL_VERSION_LIST "${openssl_version_str}")
|
||||||
list(GET OPENSSL_VERSION_LIST 0 OPENSSL_VERSION_MAJOR)
|
if (OPENSSL_VERSION_LIST)
|
||||||
list(GET OPENSSL_VERSION_LIST 1 OPENSSL_VERSION_MINOR)
|
list(GET OPENSSL_VERSION_LIST 0 OPENSSL_VERSION_MAJOR)
|
||||||
from_hex("${OPENSSL_VERSION_MINOR}" OPENSSL_VERSION_MINOR)
|
list(GET OPENSSL_VERSION_LIST 1 OPENSSL_VERSION_MINOR)
|
||||||
list(GET OPENSSL_VERSION_LIST 2 OPENSSL_VERSION_FIX)
|
from_hex("${OPENSSL_VERSION_MINOR}" OPENSSL_VERSION_MINOR)
|
||||||
from_hex("${OPENSSL_VERSION_FIX}" OPENSSL_VERSION_FIX)
|
list(GET OPENSSL_VERSION_LIST 2 OPENSSL_VERSION_FIX)
|
||||||
list(GET OPENSSL_VERSION_LIST 3 OPENSSL_VERSION_PATCH)
|
from_hex("${OPENSSL_VERSION_FIX}" OPENSSL_VERSION_FIX)
|
||||||
|
list(GET OPENSSL_VERSION_LIST 3 OPENSSL_VERSION_PATCH)
|
||||||
|
|
||||||
if (NOT OPENSSL_VERSION_PATCH STREQUAL "00")
|
if (NOT OPENSSL_VERSION_PATCH STREQUAL "00")
|
||||||
from_hex("${OPENSSL_VERSION_PATCH}" _tmp)
|
from_hex("${OPENSSL_VERSION_PATCH}" _tmp)
|
||||||
# 96 is the ASCII code of 'a' minus 1
|
# 96 is the ASCII code of 'a' minus 1
|
||||||
math(EXPR OPENSSL_VERSION_PATCH_ASCII "${_tmp} + 96")
|
math(EXPR OPENSSL_VERSION_PATCH_ASCII "${_tmp} + 96")
|
||||||
unset(_tmp)
|
unset(_tmp)
|
||||||
# Once anyone knows how OpenSSL would call the patch versions beyond 'z'
|
# 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
|
# this should be updated to handle that, too. This has not happened yet
|
||||||
# so it is simply ignored here for now.
|
# so it is simply ignored here for now.
|
||||||
string(ASCII "${OPENSSL_VERSION_PATCH_ASCII}" OPENSSL_VERSION_PATCH_STRING)
|
string(ASCII "${OPENSSL_VERSION_PATCH_ASCII}" OPENSSL_VERSION_PATCH_STRING)
|
||||||
endif (NOT OPENSSL_VERSION_PATCH STREQUAL "00")
|
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_VERSION)
|
||||||
endif (OPENSSL_INCLUDE_DIR)
|
endif (OPENSSL_INCLUDE_DIR)
|
||||||
|
|
||||||
|
|||||||
33
debian/.gitignore
vendored
33
debian/.gitignore
vendored
@ -1,33 +0,0 @@
|
|||||||
*.log
|
|
||||||
freerdp2-x11/
|
|
||||||
freerdp2-x11-dbg/
|
|
||||||
libfreerdp-client2/
|
|
||||||
libfreerdp-server2/
|
|
||||||
libfreerdp2-dev/
|
|
||||||
libfreerdp2/
|
|
||||||
libwinpr2-dev/
|
|
||||||
libwinpr2/
|
|
||||||
tmp/
|
|
||||||
*.substvars
|
|
||||||
.debhelper/
|
|
||||||
files
|
|
||||||
freerdp2-shadow-x11-dbg/
|
|
||||||
freerdp2-shadow-x11/
|
|
||||||
freerdp2-dev/
|
|
||||||
libfreerdp-client2-dbg/
|
|
||||||
libfreerdp-server2-dbg/
|
|
||||||
libfreerdp2-dbg/
|
|
||||||
libwinpr2-dbg/
|
|
||||||
winpr-utils-dbg/
|
|
||||||
winpr-utils/
|
|
||||||
freerdp2-wayland-dbg/
|
|
||||||
freerdp2-wayland/
|
|
||||||
libfreerdp-shadow2-dbg/
|
|
||||||
libfreerdp-shadow2/
|
|
||||||
libuwac0-dbg/
|
|
||||||
libuwac0-dev/
|
|
||||||
libuwac0/
|
|
||||||
debhelper-build-stamp
|
|
||||||
libxfreerdp-client2
|
|
||||||
libxfreerdp-client2-dbg
|
|
||||||
libwinpr-tools2
|
|
||||||
137
debian/changelog
vendored
137
debian/changelog
vendored
@ -1,3 +1,140 @@
|
|||||||
|
freerdp2 (2.11.7+dfsg1-6) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Team upload
|
||||||
|
* d/tests/connect: use /cert-tofu to avoid errors with proxies
|
||||||
|
|
||||||
|
-- Adrien Nader <adrien.nader@canonical.com> Wed, 18 Dec 2024 13:02:02 +0100
|
||||||
|
|
||||||
|
freerdp2 (2.11.7+dfsg1-5) unstable; urgency=medium
|
||||||
|
|
||||||
|
* autopkgtest: add Depends: ca-certificates
|
||||||
|
|
||||||
|
-- Jeremy Bícha <jbicha@ubuntu.com> Mon, 16 Dec 2024 22:57:23 -0500
|
||||||
|
|
||||||
|
freerdp2 (2.11.7+dfsg1-4) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Replace autopkgtests with the tests used by freerdp3 (Closes: #1079025)
|
||||||
|
|
||||||
|
-- Jeremy Bícha <jbicha@ubuntu.com> Fri, 04 Oct 2024 16:21:36 -0400
|
||||||
|
|
||||||
|
freerdp2 (2.11.7+dfsg1-3) unstable; urgency=high
|
||||||
|
|
||||||
|
* Team upload
|
||||||
|
|
||||||
|
[ Jeremy Bícha ]
|
||||||
|
* SECURITY UPDATE: NULL access and crash (Closes: #1072112
|
||||||
|
- debian/patches/CVE-2024-32661.patch: fix missing check in
|
||||||
|
rdp_write_logon_info_v1 in libfreerdp/core/info.c.
|
||||||
|
- CVE-2024-32661
|
||||||
|
* Cherry-pick several patches to fix build with gcc-14
|
||||||
|
(Closes: #1074969) (LP: #2075965)
|
||||||
|
* Remove obsolete 32-bit time transition lintian overrides
|
||||||
|
|
||||||
|
[ Sébastien Noel ]
|
||||||
|
* Add patch to fix build with ffmpeg 7 (Closes: #1072413)
|
||||||
|
|
||||||
|
[ Bernhard Übelacker ]
|
||||||
|
* Apply multiple fixes to autopkgtests (Closes: #1079025)
|
||||||
|
|
||||||
|
-- Jeremy Bícha <jbicha@ubuntu.com> Thu, 03 Oct 2024 11:10:42 -0400
|
||||||
|
|
||||||
|
freerdp2 (2.11.7+dfsg1-2) unstable; urgency=medium
|
||||||
|
|
||||||
|
* debian/tests/control:
|
||||||
|
+ Add xauth. Fix tests on Debian, where xvfb does not pull-in xauth as
|
||||||
|
dependency (other than in Ubuntu).
|
||||||
|
|
||||||
|
-- Mike Gabriel <sunweaver@debian.org> Sat, 20 Jul 2024 15:37:09 +0200
|
||||||
|
|
||||||
|
freerdp2 (2.11.7+dfsg1-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
[ Mike Gabriel ]
|
||||||
|
* New upstream release. (Closes: #1069728).
|
||||||
|
+ CVE-2024-32041 [Low[ OutOfBound Read in zgfx_decompress_segment.
|
||||||
|
+ CVE-2024-32039 [Moderate] Integer overflow & OutOfBound Write in
|
||||||
|
clear_decompress_residual_data.
|
||||||
|
+ CVE-2024-32040 [Low] integer underflow in nsc_rle_decode.
|
||||||
|
+ CVE-2024-32458 [Low] OutOfBound Read in planar_skip_plane_rle.
|
||||||
|
+ CVE-2024-32459 [Low] OutOfBound Read in ncrush_decompress.
|
||||||
|
+ CVE-2024-32460 [Low] OutOfBound Read in interleaved_decompress.
|
||||||
|
|
||||||
|
[ Nathan Pratta Teodosio ]
|
||||||
|
* Add autopkgtest to test whether a client can connect
|
||||||
|
to an XRDP server via freerdp2 and that the login screen shows up
|
||||||
|
(Closes: #1073156) (LP: #2060976)
|
||||||
|
|
||||||
|
-- Mike Gabriel <sunweaver@debian.org> Mon, 15 Jul 2024 16:46:25 +0200
|
||||||
|
|
||||||
|
freerdp2 (2.11.5+dfsg1-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* New upstream release.
|
||||||
|
- CVE-2024-22211: Fix integer overflow in progressive decoder. (Closes:
|
||||||
|
#1061173).
|
||||||
|
* Upload time_t64 changes to unstable. (Closes: #1061952).
|
||||||
|
* debian/watch:
|
||||||
|
+ Adjust so we only see 2.x release.
|
||||||
|
* debian/control:
|
||||||
|
+ Switch from pkg-config to pkgconf. Thanks, lintian.
|
||||||
|
|
||||||
|
-- Mike Gabriel <sunweaver@debian.org> Mon, 25 Mar 2024 16:09:04 +0100
|
||||||
|
|
||||||
|
freerdp2 (2.11.2+dfsg1-1.1~exp2) experimental; urgency=medium
|
||||||
|
|
||||||
|
* Non-maintainer upload.
|
||||||
|
* Rename libraries for 64-bit time_t transition.
|
||||||
|
* Account for additional t64 Breaks/Replaces (Closes #1061982).
|
||||||
|
|
||||||
|
-- Lukas Märdian <slyon@debian.org> Tue, 30 Jan 2024 13:19:02 +0000
|
||||||
|
|
||||||
|
freerdp2 (2.11.2+dfsg1-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* New upstream release. (Closes: #1051638).
|
||||||
|
* Fixed security issues since v2.11.0:
|
||||||
|
- CVE-2023-40589: [codec,ncrush] fix index checks properly verify all
|
||||||
|
offsets while decoding data.
|
||||||
|
- CVE-2023-40567: Fix out-of-bounds write in the
|
||||||
|
`clear_decompress_bands_data` function.
|
||||||
|
- CVE-2023-40188: Fix out-of-bounds read in the `general_LumaToYUV444`
|
||||||
|
function.
|
||||||
|
- CVE-2023-40186: Fix out-of-bounds write in the `gdi_CreateSurface`
|
||||||
|
function.
|
||||||
|
- CVE-2023-40181: Fix out-of-bounds read in the `zgfx_decompress_segment`
|
||||||
|
function.
|
||||||
|
- CVE-2023-39356: Fix out-of-bounds read in the `gdi_multi_opaque_rect`
|
||||||
|
function.
|
||||||
|
- CVE-2023-39355: Fix use-after-free in processing
|
||||||
|
`RDPGFX_CMDID_RESETGRAPHICS` packets.
|
||||||
|
- CVE-2023-39354: Fix out-of-bounds read in the `nsc_rle_decompress_data`
|
||||||
|
function.
|
||||||
|
- CVE-2023-39353: Fix missing offset validation leading to out-of-bounds
|
||||||
|
read in the `libfreerdp/codec/rfx.c` file.
|
||||||
|
- CVE-2023-39352: Fix invalid offset validation leading to out-of-bounds
|
||||||
|
write.
|
||||||
|
- CVE-2023-39351: Fix null-pointer-dereference leading a crash in the
|
||||||
|
RemoteFX (rfx) handling.
|
||||||
|
- CVE-2023-39350: Fix integer underflow leading to DOS (e.g. abort due to
|
||||||
|
`WINPR_ASSERT` with default compilation flags).
|
||||||
|
* debian/patches:
|
||||||
|
+ Drop 0001_fix_ftbfs_1041377.patch. Applied upstream.
|
||||||
|
* debian/control:
|
||||||
|
+ Add B-D: libkrb5-dev.
|
||||||
|
* debian/rules:
|
||||||
|
+ Add -DWITH_KERBEROS=ON configure option. (Closes: #1036095).
|
||||||
|
* debian/watch:
|
||||||
|
+ Rework file. Find all released versions of freerdp2. (Closes: #1053317).
|
||||||
|
Thanks to Tobias Frost for sending a patch.
|
||||||
|
|
||||||
|
-- Mike Gabriel <sunweaver@debian.org> Sun, 01 Oct 2023 23:21:15 +0200
|
||||||
|
|
||||||
|
freerdp2 (2.10.0+dfsg1-1.1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Non-maintainer upload.
|
||||||
|
* debian/patches/0001_fix_ftbfs_1041377.patch:
|
||||||
|
- include upstream fix for FTBFS with FFmpeg 6.0
|
||||||
|
(Closes: #1041377)
|
||||||
|
|
||||||
|
-- Héctor Orón Martínez <zumbi@debian.org> Fri, 04 Aug 2023 04:08:40 -0400
|
||||||
|
|
||||||
freerdp2 (2.10.0+dfsg1-1) unstable; urgency=medium
|
freerdp2 (2.10.0+dfsg1-1) unstable; urgency=medium
|
||||||
|
|
||||||
* New upstream release.
|
* New upstream release.
|
||||||
|
|||||||
85
debian/control
vendored
85
debian/control
vendored
@ -17,6 +17,7 @@ Build-Depends:
|
|||||||
libgsm1-dev,
|
libgsm1-dev,
|
||||||
libicu-dev,
|
libicu-dev,
|
||||||
libjpeg-dev,
|
libjpeg-dev,
|
||||||
|
libkrb5-dev,
|
||||||
libpam0g-dev,
|
libpam0g-dev,
|
||||||
libpcsclite-dev,
|
libpcsclite-dev,
|
||||||
libpulse-dev,
|
libpulse-dev,
|
||||||
@ -39,7 +40,7 @@ Build-Depends:
|
|||||||
libxrender-dev,
|
libxrender-dev,
|
||||||
libxtst-dev,
|
libxtst-dev,
|
||||||
libxv-dev,
|
libxv-dev,
|
||||||
pkg-config,
|
pkgconf,
|
||||||
uuid-dev,
|
uuid-dev,
|
||||||
xmlto,
|
xmlto,
|
||||||
xsltproc,
|
xsltproc,
|
||||||
@ -54,7 +55,7 @@ Architecture: any
|
|||||||
Depends:
|
Depends:
|
||||||
${misc:Depends},
|
${misc:Depends},
|
||||||
${shlibs:Depends},
|
${shlibs:Depends},
|
||||||
libfreerdp-client2-2 (= ${binary:Version}),
|
libfreerdp-client2-2t64 (= ${binary:Version}),
|
||||||
Provides:
|
Provides:
|
||||||
freerdp,
|
freerdp,
|
||||||
Replaces:
|
Replaces:
|
||||||
@ -80,7 +81,8 @@ Description: RDP client for Windows Terminal Services (X11 client)
|
|||||||
.
|
.
|
||||||
This package contains the X11 based client.
|
This package contains the X11 based client.
|
||||||
|
|
||||||
Package: libfreerdp2-2
|
Package: libfreerdp2-2t64
|
||||||
|
Provides: ${t64:Provides}
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Section: libs
|
Section: libs
|
||||||
Pre-Depends:
|
Pre-Depends:
|
||||||
@ -88,10 +90,12 @@ Pre-Depends:
|
|||||||
Depends:
|
Depends:
|
||||||
${misc:Depends},
|
${misc:Depends},
|
||||||
${shlibs:Depends},
|
${shlibs:Depends},
|
||||||
libwinpr2-2 (= ${binary:Version}),
|
libwinpr2-2t64 (= ${binary:Version}),
|
||||||
Breaks:
|
Breaks:
|
||||||
|
libfreerdp2-2 (<< ${source:Version}),
|
||||||
libfreerdp2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
libfreerdp2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
||||||
Replaces:
|
Replaces:
|
||||||
|
libfreerdp2-2,
|
||||||
libfreerdp2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
libfreerdp2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
||||||
Multi-Arch: same
|
Multi-Arch: same
|
||||||
Suggests:
|
Suggests:
|
||||||
@ -102,7 +106,8 @@ Description: Free Remote Desktop Protocol library (core library)
|
|||||||
.
|
.
|
||||||
This package contains the shared library with all core functionality.
|
This package contains the shared library with all core functionality.
|
||||||
|
|
||||||
Package: libfreerdp-client2-2
|
Package: libfreerdp-client2-2t64
|
||||||
|
Provides: ${t64:Provides}
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Section: libs
|
Section: libs
|
||||||
Pre-Depends:
|
Pre-Depends:
|
||||||
@ -110,10 +115,12 @@ Pre-Depends:
|
|||||||
Depends:
|
Depends:
|
||||||
${misc:Depends},
|
${misc:Depends},
|
||||||
${shlibs:Depends},
|
${shlibs:Depends},
|
||||||
libfreerdp2-2 (= ${binary:Version}),
|
libfreerdp2-2t64 (= ${binary:Version}),
|
||||||
Breaks:
|
Breaks:
|
||||||
|
libfreerdp-client2-2 (<< ${source:Version}),
|
||||||
libfreerdp-client2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
libfreerdp-client2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
||||||
Replaces:
|
Replaces:
|
||||||
|
libfreerdp-client2-2,
|
||||||
libfreerdp-client2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
libfreerdp-client2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
||||||
Multi-Arch: same
|
Multi-Arch: same
|
||||||
Description: Free Remote Desktop Protocol library (client library)
|
Description: Free Remote Desktop Protocol library (client library)
|
||||||
@ -122,7 +129,8 @@ Description: Free Remote Desktop Protocol library (client library)
|
|||||||
.
|
.
|
||||||
This package contains the shared library for common client functionality.
|
This package contains the shared library for common client functionality.
|
||||||
|
|
||||||
Package: libfreerdp-server2-2
|
Package: libfreerdp-server2-2t64
|
||||||
|
Provides: ${t64:Provides}
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Section: libs
|
Section: libs
|
||||||
Pre-Depends:
|
Pre-Depends:
|
||||||
@ -130,10 +138,12 @@ Pre-Depends:
|
|||||||
Depends:
|
Depends:
|
||||||
${misc:Depends},
|
${misc:Depends},
|
||||||
${shlibs:Depends},
|
${shlibs:Depends},
|
||||||
libfreerdp2-2 (= ${binary:Version}),
|
libfreerdp2-2t64 (= ${binary:Version}),
|
||||||
Breaks:
|
Breaks:
|
||||||
|
libfreerdp-server2-2 (<< ${source:Version}),
|
||||||
libfreerdp-server2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
libfreerdp-server2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
||||||
Replaces:
|
Replaces:
|
||||||
|
libfreerdp-server2-2,
|
||||||
libfreerdp-server2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
libfreerdp-server2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
||||||
Multi-Arch: same
|
Multi-Arch: same
|
||||||
Description: Free Remote Desktop Protocol library (server library)
|
Description: Free Remote Desktop Protocol library (server library)
|
||||||
@ -142,7 +152,8 @@ Description: Free Remote Desktop Protocol library (server library)
|
|||||||
.
|
.
|
||||||
This package contains the shared library with common server functionality.
|
This package contains the shared library with common server functionality.
|
||||||
|
|
||||||
Package: libwinpr2-2
|
Package: libwinpr2-2t64
|
||||||
|
Provides: ${t64:Provides}
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Section: libs
|
Section: libs
|
||||||
Pre-Depends:
|
Pre-Depends:
|
||||||
@ -151,8 +162,10 @@ Depends:
|
|||||||
${misc:Depends},
|
${misc:Depends},
|
||||||
${shlibs:Depends},
|
${shlibs:Depends},
|
||||||
Breaks:
|
Breaks:
|
||||||
|
libwinpr2-2 (<< ${source:Version}),
|
||||||
libwinpr2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
libwinpr2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
||||||
Replaces:
|
Replaces:
|
||||||
|
libwinpr2-2,
|
||||||
libwinpr2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
libwinpr2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
||||||
Multi-Arch: same
|
Multi-Arch: same
|
||||||
Suggests:
|
Suggests:
|
||||||
@ -169,7 +182,8 @@ Description: Windows Portable Runtime library
|
|||||||
.
|
.
|
||||||
This package contains the WinPR shared library.
|
This package contains the WinPR shared library.
|
||||||
|
|
||||||
Package: libwinpr-tools2-2
|
Package: libwinpr-tools2-2t64
|
||||||
|
Provides: ${t64:Provides}
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Section: libs
|
Section: libs
|
||||||
Pre-Depends:
|
Pre-Depends:
|
||||||
@ -177,10 +191,12 @@ Pre-Depends:
|
|||||||
Depends:
|
Depends:
|
||||||
${misc:Depends},
|
${misc:Depends},
|
||||||
${shlibs:Depends},
|
${shlibs:Depends},
|
||||||
libwinpr2-2 (= ${binary:Version}),
|
libwinpr2-2t64 (= ${binary:Version}),
|
||||||
Breaks:
|
Breaks:
|
||||||
|
libwinpr-tools2-2 (<< ${source:Version}),
|
||||||
libwinpr-tools2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
libwinpr-tools2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
||||||
Replaces:
|
Replaces:
|
||||||
|
libwinpr-tools2-2,
|
||||||
libwinpr-tools2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
libwinpr-tools2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
||||||
Multi-Arch: same
|
Multi-Arch: same
|
||||||
Description: Windows Portable Runtime Tools library
|
Description: Windows Portable Runtime Tools library
|
||||||
@ -196,8 +212,8 @@ Architecture: any
|
|||||||
Multi-Arch: same
|
Multi-Arch: same
|
||||||
Depends:
|
Depends:
|
||||||
libssl-dev,
|
libssl-dev,
|
||||||
libwinpr-tools2-2 (= ${binary:Version}),
|
libwinpr-tools2-2t64 (= ${binary:Version}),
|
||||||
libwinpr2-2 (= ${binary:Version}),
|
libwinpr2-2t64 (= ${binary:Version}),
|
||||||
${misc:Depends},
|
${misc:Depends},
|
||||||
Description: Windows Portable Runtime library (development files)
|
Description: Windows Portable Runtime library (development files)
|
||||||
WinPR is a spin-off project of FreeRDP which aims at providing a portable
|
WinPR is a spin-off project of FreeRDP which aims at providing a portable
|
||||||
@ -215,11 +231,11 @@ Package: freerdp2-dev
|
|||||||
Section: devel
|
Section: devel
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Depends:
|
Depends:
|
||||||
libfreerdp-client2-2 (= ${binary:Version}),
|
libfreerdp-client2-2t64 (= ${binary:Version}),
|
||||||
libfreerdp-server2-2 (= ${binary:Version}),
|
libfreerdp-server2-2t64 (= ${binary:Version}),
|
||||||
libfreerdp-shadow-subsystem2-2 (= ${binary:Version}),
|
libfreerdp-shadow-subsystem2-2t64 (= ${binary:Version}),
|
||||||
libfreerdp-shadow2-2 (= ${binary:Version}),
|
libfreerdp-shadow2-2t64 (= ${binary:Version}),
|
||||||
libfreerdp2-2 (= ${binary:Version}),
|
libfreerdp2-2t64 (= ${binary:Version}),
|
||||||
libwinpr2-dev (= ${binary:Version}),
|
libwinpr2-dev (= ${binary:Version}),
|
||||||
winpr-utils (= ${binary:Version}),
|
winpr-utils (= ${binary:Version}),
|
||||||
${misc:Depends},
|
${misc:Depends},
|
||||||
@ -236,7 +252,7 @@ Architecture: any
|
|||||||
Depends:
|
Depends:
|
||||||
${misc:Depends},
|
${misc:Depends},
|
||||||
${shlibs:Depends},
|
${shlibs:Depends},
|
||||||
libwinpr-tools2-2 (= ${binary:Version}),
|
libwinpr-tools2-2t64 (= ${binary:Version}),
|
||||||
Description: Windows Portable Runtime library command line utilities
|
Description: Windows Portable Runtime library command line utilities
|
||||||
WinPR is a spin-off project of FreeRDP which aims at providing a portable
|
WinPR is a spin-off project of FreeRDP which aims at providing a portable
|
||||||
implementation of important portions of the Windows API. Just like FreeRDP,
|
implementation of important portions of the Windows API. Just like FreeRDP,
|
||||||
@ -249,7 +265,8 @@ Description: Windows Portable Runtime library command line utilities
|
|||||||
.
|
.
|
||||||
This package contains WinPR command line utils (winpr-hash, winpr-makecert).
|
This package contains WinPR command line utils (winpr-hash, winpr-makecert).
|
||||||
|
|
||||||
Package: libfreerdp-shadow2-2
|
Package: libfreerdp-shadow2-2t64
|
||||||
|
Provides: ${t64:Provides}
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Section: libs
|
Section: libs
|
||||||
Pre-Depends:
|
Pre-Depends:
|
||||||
@ -257,11 +274,13 @@ Pre-Depends:
|
|||||||
Depends:
|
Depends:
|
||||||
${misc:Depends},
|
${misc:Depends},
|
||||||
${shlibs:Depends},
|
${shlibs:Depends},
|
||||||
libfreerdp-server2-2 (= ${binary:Version}),
|
libfreerdp-server2-2t64 (= ${binary:Version}),
|
||||||
libwinpr-tools2-2 (= ${binary:Version}),
|
libwinpr-tools2-2t64 (= ${binary:Version}),
|
||||||
Breaks:
|
Breaks:
|
||||||
|
libfreerdp-shadow2-2 (<< ${source:Version}),
|
||||||
libfreerdp-shadow2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
libfreerdp-shadow2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
||||||
Replaces:
|
Replaces:
|
||||||
|
libfreerdp-shadow2-2,
|
||||||
libfreerdp-shadow2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
libfreerdp-shadow2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
||||||
Multi-Arch: same
|
Multi-Arch: same
|
||||||
Description: FreeRDP Remote Desktop Protocol shadow libraries
|
Description: FreeRDP Remote Desktop Protocol shadow libraries
|
||||||
@ -270,7 +289,8 @@ Description: FreeRDP Remote Desktop Protocol shadow libraries
|
|||||||
.
|
.
|
||||||
This package contains the shadow libraries.
|
This package contains the shadow libraries.
|
||||||
|
|
||||||
Package: libfreerdp-shadow-subsystem2-2
|
Package: libfreerdp-shadow-subsystem2-2t64
|
||||||
|
Provides: ${t64:Provides}
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Section: libs
|
Section: libs
|
||||||
Pre-Depends:
|
Pre-Depends:
|
||||||
@ -278,10 +298,12 @@ Pre-Depends:
|
|||||||
Depends:
|
Depends:
|
||||||
${misc:Depends},
|
${misc:Depends},
|
||||||
${shlibs:Depends},
|
${shlibs:Depends},
|
||||||
libfreerdp-shadow2-2 (= ${binary:Version}),
|
libfreerdp-shadow2-2t64 (= ${binary:Version}),
|
||||||
Breaks:
|
Breaks:
|
||||||
|
libfreerdp-shadow-subsystem2-2 (<< ${source:Version}),
|
||||||
libfreerdp-shadow2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
libfreerdp-shadow2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
||||||
Replaces:
|
Replaces:
|
||||||
|
libfreerdp-shadow-subsystem2-2,
|
||||||
libfreerdp-shadow2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
libfreerdp-shadow2 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
||||||
Multi-Arch: same
|
Multi-Arch: same
|
||||||
Description: FreeRDP Remote Desktop Protocol shadow subsystem libraries
|
Description: FreeRDP Remote Desktop Protocol shadow subsystem libraries
|
||||||
@ -295,7 +317,7 @@ Architecture: any
|
|||||||
Depends:
|
Depends:
|
||||||
${misc:Depends},
|
${misc:Depends},
|
||||||
${shlibs:Depends},
|
${shlibs:Depends},
|
||||||
libfreerdp-shadow-subsystem2-2 (= ${binary:Version}),
|
libfreerdp-shadow-subsystem2-2t64 (= ${binary:Version}),
|
||||||
Provides:
|
Provides:
|
||||||
freerdp,
|
freerdp,
|
||||||
Description: FreeRDP x11 shadowing server
|
Description: FreeRDP x11 shadowing server
|
||||||
@ -305,7 +327,8 @@ Description: FreeRDP x11 shadowing server
|
|||||||
This package contains a "shadowing" server that can be used to
|
This package contains a "shadowing" server that can be used to
|
||||||
share an already started X11 DISPLAY.
|
share an already started X11 DISPLAY.
|
||||||
|
|
||||||
Package: libuwac0-0
|
Package: libuwac0-0t64
|
||||||
|
Provides: ${t64:Provides}
|
||||||
Architecture: linux-any
|
Architecture: linux-any
|
||||||
Section: libs
|
Section: libs
|
||||||
Pre-Depends:
|
Pre-Depends:
|
||||||
@ -313,10 +336,12 @@ Pre-Depends:
|
|||||||
Depends:
|
Depends:
|
||||||
${misc:Depends},
|
${misc:Depends},
|
||||||
${shlibs:Depends},
|
${shlibs:Depends},
|
||||||
libfreerdp2-2 (= ${binary:Version}),
|
libfreerdp2-2t64 (= ${binary:Version}),
|
||||||
Breaks:
|
Breaks:
|
||||||
|
libuwac0-0 (<< ${source:Version}),
|
||||||
libuwac0 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
libuwac0 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
||||||
Replaces:
|
Replaces:
|
||||||
|
libuwac0-0,
|
||||||
libuwac0 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
libuwac0 (<< 2.0.0~git20170725.1.1648deb+dfsg1-1~),
|
||||||
Multi-Arch: same
|
Multi-Arch: same
|
||||||
Description: Using wayland as a client library
|
Description: Using wayland as a client library
|
||||||
@ -330,7 +355,7 @@ Section: libdevel
|
|||||||
Architecture: linux-any
|
Architecture: linux-any
|
||||||
Multi-Arch: same
|
Multi-Arch: same
|
||||||
Depends:
|
Depends:
|
||||||
libuwac0-0 (= ${binary:Version}),
|
libuwac0-0t64 (= ${binary:Version}),
|
||||||
${misc:Depends},
|
${misc:Depends},
|
||||||
Description: Using wayland as a client (development files)
|
Description: Using wayland as a client (development files)
|
||||||
Using wayland as a client (uwac) is a library to provide common
|
Using wayland as a client (uwac) is a library to provide common
|
||||||
@ -343,8 +368,8 @@ Architecture: linux-any
|
|||||||
Depends:
|
Depends:
|
||||||
${misc:Depends},
|
${misc:Depends},
|
||||||
${shlibs:Depends},
|
${shlibs:Depends},
|
||||||
libfreerdp-client2-2 (= ${binary:Version}),
|
libfreerdp-client2-2t64 (= ${binary:Version}),
|
||||||
libuwac0-0 (= ${binary:Version}),
|
libuwac0-0t64 (= ${binary:Version}),
|
||||||
Description: RDP client for Windows Terminal Services (wayland client)
|
Description: RDP client for Windows Terminal Services (wayland client)
|
||||||
FreeRDP is a libre client/server implementation of the Remote
|
FreeRDP is a libre client/server implementation of the Remote
|
||||||
Desktop Protocol (RDP).
|
Desktop Protocol (RDP).
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
libfreerdp-client2.so.2 libfreerdp-client2-2 #MINVER#
|
libfreerdp-client2.so.2 libfreerdp-client2-2t64 #MINVER#
|
||||||
* Build-Depends-Package: freerdp2-dev
|
* Build-Depends-Package: freerdp2-dev
|
||||||
add_device@Base 2.1.0+dfsg1
|
add_device@Base 2.1.0+dfsg1
|
||||||
client_auto_reconnect@Base 2.0.0~git20181120.1.e21b72c95+dfsg1
|
client_auto_reconnect@Base 2.0.0~git20181120.1.e21b72c95+dfsg1
|
||||||
@ -1,4 +1,4 @@
|
|||||||
libfreerdp-server2.so.2 libfreerdp-server2-2 #MINVER#
|
libfreerdp-server2.so.2 libfreerdp-server2-2t64 #MINVER#
|
||||||
* Build-Depends-Package: freerdp2-dev
|
* Build-Depends-Package: freerdp2-dev
|
||||||
ainput_server_context_free@Base 2.6.0+dfsg1
|
ainput_server_context_free@Base 2.6.0+dfsg1
|
||||||
ainput_server_context_new@Base 2.6.0+dfsg1
|
ainput_server_context_new@Base 2.6.0+dfsg1
|
||||||
@ -1,4 +1,4 @@
|
|||||||
libfreerdp-shadow-subsystem2.so.2 libfreerdp-shadow-subsystem2-2 #MINVER#
|
libfreerdp-shadow-subsystem2.so.2 libfreerdp-shadow-subsystem2-2t64 #MINVER#
|
||||||
* Build-Depends-Package: freerdp2-dev
|
* Build-Depends-Package: freerdp2-dev
|
||||||
X11_ShadowSubsystemEntry@Base 2.0.0~git20160317.1.75ae3f5+dfsg1
|
X11_ShadowSubsystemEntry@Base 2.0.0~git20160317.1.75ae3f5+dfsg1
|
||||||
shadow_subsystem_set_entry_builtin@Base 2.0.0~git20160317.1.75ae3f5+dfsg1
|
shadow_subsystem_set_entry_builtin@Base 2.0.0~git20160317.1.75ae3f5+dfsg1
|
||||||
@ -1,4 +1,4 @@
|
|||||||
libfreerdp-shadow2.so.2 libfreerdp-shadow2-2 #MINVER#
|
libfreerdp-shadow2.so.2 libfreerdp-shadow2-2t64 #MINVER#
|
||||||
* Build-Depends-Package: freerdp2-dev
|
* Build-Depends-Package: freerdp2-dev
|
||||||
shadow_capture_align_clip_rect@Base 2.0.0~git20160317.1.75ae3f5+dfsg1
|
shadow_capture_align_clip_rect@Base 2.0.0~git20160317.1.75ae3f5+dfsg1
|
||||||
shadow_capture_compare@Base 2.0.0~git20160317.1.75ae3f5+dfsg1
|
shadow_capture_compare@Base 2.0.0~git20160317.1.75ae3f5+dfsg1
|
||||||
@ -1,4 +1,4 @@
|
|||||||
libfreerdp2.so.2 libfreerdp2-2 #MINVER#
|
libfreerdp2.so.2 libfreerdp2-2t64 #MINVER#
|
||||||
* Build-Depends-Package: freerdp2-dev
|
* Build-Depends-Package: freerdp2-dev
|
||||||
Bitmap_Alloc@Base 2.0.0~git20160317.1.75ae3f5+dfsg1
|
Bitmap_Alloc@Base 2.0.0~git20160317.1.75ae3f5+dfsg1
|
||||||
Bitmap_SetDimensions@Base 2.0.0~git20160317.1.75ae3f5+dfsg1
|
Bitmap_SetDimensions@Base 2.0.0~git20160317.1.75ae3f5+dfsg1
|
||||||
@ -1,4 +1,4 @@
|
|||||||
libuwac0.so.0 libuwac0-0 #MINVER#
|
libuwac0.so.0 libuwac0-0t64 #MINVER#
|
||||||
* Build-Depends-Package: libuwac0-dev
|
* Build-Depends-Package: libuwac0-dev
|
||||||
UwacClipboardDataGet@Base 2.0.0~git20190204.1.2693389a+dfsg1
|
UwacClipboardDataGet@Base 2.0.0~git20190204.1.2693389a+dfsg1
|
||||||
UwacClipboardOfferAnnounce@Base 2.0.0~git20190204.1.2693389a+dfsg1
|
UwacClipboardOfferAnnounce@Base 2.0.0~git20190204.1.2693389a+dfsg1
|
||||||
@ -1,4 +1,4 @@
|
|||||||
libwinpr-tools2.so.2 libwinpr-tools2-2 #MINVER#
|
libwinpr-tools2.so.2 libwinpr-tools2-2t64 #MINVER#
|
||||||
* Build-Depends-Package: libwinpr2-dev
|
* Build-Depends-Package: libwinpr2-dev
|
||||||
makecert_context_free@Base 2.0.0~git20160503.1.f828595+dfsg1
|
makecert_context_free@Base 2.0.0~git20160503.1.f828595+dfsg1
|
||||||
makecert_context_new@Base 2.0.0~git20160503.1.f828595+dfsg1
|
makecert_context_new@Base 2.0.0~git20160503.1.f828595+dfsg1
|
||||||
@ -1,4 +1,4 @@
|
|||||||
libwinpr2.so.2 libwinpr2-2 #MINVER#
|
libwinpr2.so.2 libwinpr2-2t64 #MINVER#
|
||||||
* Build-Depends-Package: libwinpr2-dev
|
* Build-Depends-Package: libwinpr2-dev
|
||||||
ASN1DecSetError@Base 2.0.0~git20160317.1.75ae3f5+dfsg1
|
ASN1DecSetError@Base 2.0.0~git20160317.1.75ae3f5+dfsg1
|
||||||
ASN1EncSetError@Base 2.0.0~git20160317.1.75ae3f5+dfsg1
|
ASN1EncSetError@Base 2.0.0~git20160317.1.75ae3f5+dfsg1
|
||||||
32
debian/patches/0001-info-Fix-incompatible-pointer-type.patch
vendored
Normal file
32
debian/patches/0001-info-Fix-incompatible-pointer-type.patch
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
From: Alessandro Bono <alessandro.bono369@gmail.com>
|
||||||
|
Date: Wed, 8 May 2024 16:06:17 +0200
|
||||||
|
Subject: info: Fix incompatible pointer type
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset="utf-8"
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
This fixes the following:
|
||||||
|
```
|
||||||
|
libfreerdp/core/info.c: In function ‘rdp_read_info_null_string’:
|
||||||
|
libfreerdp/core/info.c:88:39: error: initialization of ‘const WCHAR *’ {aka ‘const short unsigned int *’} from incompatible pointer type ‘BYTE *’ {aka ‘unsigned char *’} [-Wincompatible-pointer-types]
|
||||||
|
88 | const WCHAR* domain = Stream_Pointer(s);
|
||||||
|
```
|
||||||
|
|
||||||
|
(cherry picked from commit 4f411197dc9d2076f00748b1178a60b2423030bf)
|
||||||
|
---
|
||||||
|
libfreerdp/core/info.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c
|
||||||
|
index 9aaa6cf..c9b2fc6 100644
|
||||||
|
--- a/libfreerdp/core/info.c
|
||||||
|
+++ b/libfreerdp/core/info.c
|
||||||
|
@@ -85,7 +85,7 @@ static BOOL rdp_read_info_null_string(const char* what, UINT32 flags, wStream* s
|
||||||
|
|
||||||
|
if (cbLen > 0)
|
||||||
|
{
|
||||||
|
- const WCHAR* domain = Stream_Pointer(s);
|
||||||
|
+ const WCHAR* domain = (WCHAR*)Stream_Pointer(s);
|
||||||
|
|
||||||
|
if (isNullTerminated && (max > 0))
|
||||||
|
max -= nullSize;
|
||||||
38
debian/patches/0002-redirection-Fix-incompatible-pointer-type.patch
vendored
Normal file
38
debian/patches/0002-redirection-Fix-incompatible-pointer-type.patch
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
From: Alessandro Bono <alessandro.bono369@gmail.com>
|
||||||
|
Date: Wed, 8 May 2024 16:06:26 +0200
|
||||||
|
Subject: redirection: Fix incompatible pointer type
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset="utf-8"
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
This fixes the following:
|
||||||
|
```
|
||||||
|
libfreerdp/core/redirection.c: In function ‘redirection_copy_data’:
|
||||||
|
libfreerdp/core/redirection.c:91:31: error: passing argument 1 of ‘redirection_free_data’ from incompatible pointer type [-Wincompatible-pointer-types]
|
||||||
|
91 | redirection_free_data(dst, plen);
|
||||||
|
| ^~~
|
||||||
|
| |
|
||||||
|
| char **
|
||||||
|
libfreerdp/core/redirection.c:80:42: note: expected ‘BYTE **’ {aka ‘unsigned char **’} but argument is of type ‘char **’
|
||||||
|
80 | static void redirection_free_data(BYTE** str, UINT32* length)
|
||||||
|
| ~~~~~~~^~~
|
||||||
|
```
|
||||||
|
|
||||||
|
(cherry picked from commit f3ed1f1ac367eb21f93c9fba5047447fdccdb5cc)
|
||||||
|
---
|
||||||
|
libfreerdp/core/redirection.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/libfreerdp/core/redirection.c b/libfreerdp/core/redirection.c
|
||||||
|
index 59c6dbc..63bc8cc 100644
|
||||||
|
--- a/libfreerdp/core/redirection.c
|
||||||
|
+++ b/libfreerdp/core/redirection.c
|
||||||
|
@@ -86,7 +86,7 @@ static void redirection_free_data(BYTE** str, UINT32* length)
|
||||||
|
*str = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static BOOL redirection_copy_data(char** dst, UINT32* plen, const char* str, UINT32 len)
|
||||||
|
+static BOOL redirection_copy_data(BYTE** dst, UINT32* plen, const BYTE* str, UINT32 len)
|
||||||
|
{
|
||||||
|
redirection_free_data(dst, plen);
|
||||||
|
|
||||||
33
debian/patches/0003-redirection-Fix-incompatible-pointer-type.patch
vendored
Normal file
33
debian/patches/0003-redirection-Fix-incompatible-pointer-type.patch
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
From: Alessandro Bono <alessandro.bono369@gmail.com>
|
||||||
|
Date: Wed, 8 May 2024 16:06:30 +0200
|
||||||
|
Subject: redirection: Fix incompatible pointer type
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset="utf-8"
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
This fixes the following:
|
||||||
|
```
|
||||||
|
libfreerdp/core/redirection.c: In function ‘freerdp_settings_set_pointer_len’:
|
||||||
|
libfreerdp/core/redirection.c:112:31: error: assignment to ‘BYTE **’ {aka ‘unsigned char **’} from incompatible pointer type ‘char **’ [-Wincompatible-pointer-types]
|
||||||
|
112 | pdata = &settings->TargetNetAddress;
|
||||||
|
| ^
|
||||||
|
```
|
||||||
|
|
||||||
|
(cherry picked from commit 7894a7dfc5f811cb5dacc57a09236c11744b1ec8)
|
||||||
|
---
|
||||||
|
libfreerdp/core/redirection.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/libfreerdp/core/redirection.c b/libfreerdp/core/redirection.c
|
||||||
|
index 63bc8cc..4872d4b 100644
|
||||||
|
--- a/libfreerdp/core/redirection.c
|
||||||
|
+++ b/libfreerdp/core/redirection.c
|
||||||
|
@@ -109,7 +109,7 @@ static BOOL freerdp_settings_set_pointer_len(rdpSettings* settings, size_t id, c
|
||||||
|
switch (id)
|
||||||
|
{
|
||||||
|
case FreeRDP_TargetNetAddress:
|
||||||
|
- pdata = &settings->TargetNetAddress;
|
||||||
|
+ pdata = (BYTE**)&settings->TargetNetAddress;
|
||||||
|
plen = &settings->TargetNetAddressCount;
|
||||||
|
break;
|
||||||
|
case FreeRDP_LoadBalanceInfo:
|
||||||
24
debian/patches/0004-X11-fix-pointer-integer-type-mismatch.patch
vendored
Normal file
24
debian/patches/0004-X11-fix-pointer-integer-type-mismatch.patch
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
From: Mike Gilbert <floppym@gentoo.org>
|
||||||
|
Date: Wed, 22 May 2024 17:04:43 -0400
|
||||||
|
Subject: X11: fix pointer/integer type mismatch
|
||||||
|
|
||||||
|
Fixed on master in 2da280b8a1748052b70b3f5a1ef0d8e932c33adc.
|
||||||
|
|
||||||
|
(cherry picked from commit d2b6771c748e54e659d5f1243a92e499c3beaa36)
|
||||||
|
---
|
||||||
|
client/X11/xf_graphics.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c
|
||||||
|
index 5aa1fd4..fe81e0e 100644
|
||||||
|
--- a/client/X11/xf_graphics.c
|
||||||
|
+++ b/client/X11/xf_graphics.c
|
||||||
|
@@ -438,7 +438,7 @@ static BOOL xf_Pointer_New(rdpContext* context, rdpPointer* pointer)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
fail:
|
||||||
|
- WLog_DBG(TAG, "%s: %ld", __func__, rc ? pointer : -1);
|
||||||
|
+ WLog_DBG(TAG, "%s: %p", __func__, rc ? pointer : NULL);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
22
debian/patches/0005-client-wayland-fix-const-correctness.patch
vendored
Normal file
22
debian/patches/0005-client-wayland-fix-const-correctness.patch
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
From: akallabeth <akallabeth@posteo.net>
|
||||||
|
Date: Thu, 23 May 2024 09:30:33 +0200
|
||||||
|
Subject: [client,wayland] fix const correctness
|
||||||
|
|
||||||
|
(cherry picked from commit 67818bddb31900cdf3acb26cb0b673cc90b71cc9)
|
||||||
|
---
|
||||||
|
client/Wayland/wlfreerdp.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/client/Wayland/wlfreerdp.c b/client/Wayland/wlfreerdp.c
|
||||||
|
index 65e29bc..5988aed 100644
|
||||||
|
--- a/client/Wayland/wlfreerdp.c
|
||||||
|
+++ b/client/Wayland/wlfreerdp.c
|
||||||
|
@@ -587,7 +587,7 @@ static void wlf_client_free(freerdp* instance, rdpContext* context)
|
||||||
|
DeleteCriticalSection(&wlf->critical);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void* uwac_event_clone(const void* val)
|
||||||
|
+static void* uwac_event_clone(void* val)
|
||||||
|
{
|
||||||
|
UwacEvent* copy;
|
||||||
|
UwacEvent* ev = (UwacEvent*)val;
|
||||||
89
debian/patches/0006-warnings-fix-Wincompatible-pointer-types.patch
vendored
Normal file
89
debian/patches/0006-warnings-fix-Wincompatible-pointer-types.patch
vendored
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
From: Armin Novak <armin.novak@thincast.com>
|
||||||
|
Date: Thu, 8 Aug 2024 11:03:24 +0200
|
||||||
|
Subject: [warnings] fix -Wincompatible-pointer-types
|
||||||
|
|
||||||
|
(cherry picked from commit 5b2b53b15c9af46b85c4ef0007e7fb59d7608289)
|
||||||
|
---
|
||||||
|
channels/ainput/server/ainput_main.c | 8 ++++----
|
||||||
|
libfreerdp/codec/dsp_ffmpeg.c | 2 +-
|
||||||
|
winpr/libwinpr/crt/unicode.c | 8 ++++----
|
||||||
|
3 files changed, 9 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/channels/ainput/server/ainput_main.c b/channels/ainput/server/ainput_main.c
|
||||||
|
index 943d0fa..fc61f9b 100644
|
||||||
|
--- a/channels/ainput/server/ainput_main.c
|
||||||
|
+++ b/channels/ainput/server/ainput_main.c
|
||||||
|
@@ -222,7 +222,7 @@ static HANDLE ainput_server_get_channel_handle(ainput_server* ainput)
|
||||||
|
|
||||||
|
WINPR_ASSERT(ainput);
|
||||||
|
|
||||||
|
- if (WTSVirtualChannelQuery(ainput->ainput_channel, WTSVirtualEventHandle, &buffer,
|
||||||
|
+ if (WTSVirtualChannelQuery(ainput->ainput_channel, WTSVirtualEventHandle, (void**)&buffer,
|
||||||
|
&BytesReturned) == TRUE)
|
||||||
|
{
|
||||||
|
if (BytesReturned == sizeof(HANDLE))
|
||||||
|
@@ -416,7 +416,7 @@ ainput_server_context* ainput_server_context_new(HANDLE vcm)
|
||||||
|
goto fail;
|
||||||
|
return &ainput->context;
|
||||||
|
fail:
|
||||||
|
- ainput_server_context_free(ainput);
|
||||||
|
+ ainput_server_context_free(&ainput->context);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -539,8 +539,8 @@ UINT ainput_server_context_poll_int(ainput_server_context* context)
|
||||||
|
BYTE* buffer = NULL;
|
||||||
|
DWORD BytesReturned = 0;
|
||||||
|
|
||||||
|
- if (WTSVirtualChannelQuery(ainput->ainput_channel, WTSVirtualChannelReady, &buffer,
|
||||||
|
- &BytesReturned) != TRUE)
|
||||||
|
+ if (WTSVirtualChannelQuery(ainput->ainput_channel, WTSVirtualChannelReady,
|
||||||
|
+ (void**)&buffer, &BytesReturned) != TRUE)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "WTSVirtualChannelReady failed,");
|
||||||
|
}
|
||||||
|
diff --git a/libfreerdp/codec/dsp_ffmpeg.c b/libfreerdp/codec/dsp_ffmpeg.c
|
||||||
|
index ef67914..80df188 100644
|
||||||
|
--- a/libfreerdp/codec/dsp_ffmpeg.c
|
||||||
|
+++ b/libfreerdp/codec/dsp_ffmpeg.c
|
||||||
|
@@ -423,7 +423,7 @@ static BOOL ffmpeg_encode_frame(AVCodecContext* context, AVFrame* in, AVPacket*
|
||||||
|
uint8_t** pp = in->extended_data;
|
||||||
|
for (int y = 0; y < in->channels; y++)
|
||||||
|
{
|
||||||
|
- float* data = pp[y];
|
||||||
|
+ float* data = (float*)pp[y];
|
||||||
|
for (int x = 0; x < in->nb_samples; x++)
|
||||||
|
{
|
||||||
|
const float val1 = data[x];
|
||||||
|
diff --git a/winpr/libwinpr/crt/unicode.c b/winpr/libwinpr/crt/unicode.c
|
||||||
|
index dc3533a..acbec01 100644
|
||||||
|
--- a/winpr/libwinpr/crt/unicode.c
|
||||||
|
+++ b/winpr/libwinpr/crt/unicode.c
|
||||||
|
@@ -215,8 +215,8 @@ int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int
|
||||||
|
else
|
||||||
|
{
|
||||||
|
targetLength =
|
||||||
|
- ucnv_convert("UTF-16LE", "UTF-8", targetStart, targetCapacity * sizeof(WCHAR),
|
||||||
|
- lpMultiByteStr, cbMultiByte, &error);
|
||||||
|
+ ucnv_convert("UTF-16LE", "UTF-8", (char*)targetStart,
|
||||||
|
+ targetCapacity * sizeof(WCHAR), lpMultiByteStr, cbMultiByte, &error);
|
||||||
|
if (targetLength > 0)
|
||||||
|
targetLength /= sizeof(WCHAR);
|
||||||
|
cchWideChar = U_SUCCESS(error) ? targetLength : 0;
|
||||||
|
@@ -353,14 +353,14 @@ int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int
|
||||||
|
#if defined(UCNV_CONVERT)
|
||||||
|
if (cbMultiByte == 0)
|
||||||
|
{
|
||||||
|
- targetLength = ucnv_convert("UTF-8", "UTF-16LE", NULL, 0, lpWideCharStr,
|
||||||
|
+ targetLength = ucnv_convert("UTF-8", "UTF-16LE", NULL, 0, (char*)lpWideCharStr,
|
||||||
|
cchWideChar * sizeof(WCHAR), &error);
|
||||||
|
cbMultiByte = targetLength;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
targetLength = ucnv_convert("UTF-8", "UTF-16LE", targetStart, targetCapacity,
|
||||||
|
- lpWideCharStr, cchWideChar * sizeof(WCHAR), &error);
|
||||||
|
+ (char*)lpWideCharStr, cchWideChar * sizeof(WCHAR), &error);
|
||||||
|
cbMultiByte = U_SUCCESS(error) ? targetLength : 0;
|
||||||
|
}
|
||||||
|
|
||||||
48
debian/patches/0007-server-proxy-deactivate-capture-module.patch
vendored
Normal file
48
debian/patches/0007-server-proxy-deactivate-capture-module.patch
vendored
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
From: Armin Novak <armin.novak@thincast.com>
|
||||||
|
Date: Thu, 8 Aug 2024 11:06:54 +0200
|
||||||
|
Subject: [server,proxy] deactivate capture module
|
||||||
|
|
||||||
|
the module does not work (and did not for a long time)
|
||||||
|
|
||||||
|
(cherry picked from commit be23ed4ba990bd39391a651444fbb9130722c93b)
|
||||||
|
---
|
||||||
|
server/proxy/modules/capture/CMakeLists.txt | 28 +++++++++++++++-------------
|
||||||
|
1 file changed, 15 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/server/proxy/modules/capture/CMakeLists.txt b/server/proxy/modules/capture/CMakeLists.txt
|
||||||
|
index 80ba3b7..4004aaa 100644
|
||||||
|
--- a/server/proxy/modules/capture/CMakeLists.txt
|
||||||
|
+++ b/server/proxy/modules/capture/CMakeLists.txt
|
||||||
|
@@ -17,17 +17,19 @@
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
-set(PLUGIN_NAME "proxy-capture-plugin")
|
||||||
|
+# deactivated: does not work
|
||||||
|
|
||||||
|
-add_library(${PLUGIN_NAME} MODULE
|
||||||
|
- cap_main.c
|
||||||
|
- cap_config.c
|
||||||
|
- cap_config.h
|
||||||
|
- cap_protocol.c
|
||||||
|
- cap_protocol.h
|
||||||
|
-)
|
||||||
|
-
|
||||||
|
-set_target_properties(${PLUGIN_NAME} PROPERTIES PREFIX "")
|
||||||
|
-set_target_properties(${PLUGIN_NAME} PROPERTIES NO_SONAME 1)
|
||||||
|
-set_target_properties(${PLUGIN_NAME} PROPERTIES
|
||||||
|
-LIBRARY_OUTPUT_DIRECTORY "${FREERDP_PROXY_PLUGINDIR}")
|
||||||
|
+#set(PLUGIN_NAME "proxy-capture-plugin")
|
||||||
|
+#
|
||||||
|
+#add_library(${PLUGIN_NAME} MODULE
|
||||||
|
+# cap_main.c
|
||||||
|
+# cap_config.c
|
||||||
|
+# cap_config.h
|
||||||
|
+# cap_protocol.c
|
||||||
|
+# cap_protocol.h
|
||||||
|
+#)
|
||||||
|
+#
|
||||||
|
+#set_target_properties(${PLUGIN_NAME} PROPERTIES PREFIX "")
|
||||||
|
+#set_target_properties(${PLUGIN_NAME} PROPERTIES NO_SONAME 1)
|
||||||
|
+#set_target_properties(${PLUGIN_NAME} PROPERTIES
|
||||||
|
+#LIBRARY_OUTPUT_DIRECTORY "${FREERDP_PROXY_PLUGINDIR}")
|
||||||
114
debian/patches/1000-ffmpeg7.patch
vendored
Normal file
114
debian/patches/1000-ffmpeg7.patch
vendored
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
From: =?utf-8?q?S=C3=A9bastien_Noel?= <sebastien@twolife.be>
|
||||||
|
Date: Tue, 30 Jul 2024 11:29:58 +0200
|
||||||
|
Subject: Fix build with ffmpeg 7
|
||||||
|
|
||||||
|
cherry picked from d0c5b1ae4289c7f3cde3fbc031cb4a3160df05ff
|
||||||
|
from freerdp3
|
||||||
|
---
|
||||||
|
libfreerdp/codec/dsp_ffmpeg.c | 28 ++++++++++------------------
|
||||||
|
1 file changed, 10 insertions(+), 18 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libfreerdp/codec/dsp_ffmpeg.c b/libfreerdp/codec/dsp_ffmpeg.c
|
||||||
|
index 80df188..68dfe5f 100644
|
||||||
|
--- a/libfreerdp/codec/dsp_ffmpeg.c
|
||||||
|
+++ b/libfreerdp/codec/dsp_ffmpeg.c
|
||||||
|
@@ -225,18 +225,15 @@ static void ffmpeg_close_context(FREERDP_DSP_CONTEXT* context)
|
||||||
|
static BOOL ffmpeg_open_context(FREERDP_DSP_CONTEXT* context)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
- int layout;
|
||||||
|
- const AUDIO_FORMAT* format;
|
||||||
|
|
||||||
|
if (!context || context->isOpen)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
- format = &context->format;
|
||||||
|
+ const AUDIO_FORMAT* format = &context->format;
|
||||||
|
|
||||||
|
if (!format)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
- layout = av_get_default_channel_layout(format->nChannels);
|
||||||
|
context->id = ffmpeg_get_avcodec(format);
|
||||||
|
|
||||||
|
if (ffmpeg_codec_is_filtered(context->id, context->encoder))
|
||||||
|
@@ -270,8 +267,7 @@ static BOOL ffmpeg_open_context(FREERDP_DSP_CONTEXT* context)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- context->context->channels = format->nChannels;
|
||||||
|
- context->context->channel_layout = layout;
|
||||||
|
+ av_channel_layout_default(&context->context->ch_layout, format->nChannels);
|
||||||
|
context->context->sample_rate = format->nSamplesPerSec;
|
||||||
|
context->context->block_align = format->nBlockAlign;
|
||||||
|
context->context->bit_rate = format->nAvgBytesPerSec * 8;
|
||||||
|
@@ -314,8 +310,7 @@ static BOOL ffmpeg_open_context(FREERDP_DSP_CONTEXT* context)
|
||||||
|
if (!context->rcontext)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
- context->frame->channel_layout = layout;
|
||||||
|
- context->frame->channels = format->nChannels;
|
||||||
|
+ av_channel_layout_default(&context->frame->ch_layout, format->nChannels);
|
||||||
|
context->frame->sample_rate = format->nSamplesPerSec;
|
||||||
|
context->frame->format = AV_SAMPLE_FMT_S16;
|
||||||
|
|
||||||
|
@@ -330,13 +325,11 @@ static BOOL ffmpeg_open_context(FREERDP_DSP_CONTEXT* context)
|
||||||
|
context->resampled->sample_rate = format->nSamplesPerSec;
|
||||||
|
}
|
||||||
|
|
||||||
|
- context->resampled->channel_layout = layout;
|
||||||
|
- context->resampled->channels = format->nChannels;
|
||||||
|
+ av_channel_layout_default(&context->resampled->ch_layout, format->nChannels);
|
||||||
|
|
||||||
|
if (context->context->frame_size > 0)
|
||||||
|
{
|
||||||
|
- context->buffered->channel_layout = context->resampled->channel_layout;
|
||||||
|
- context->buffered->channels = context->resampled->channels;
|
||||||
|
+ av_channel_layout_copy(&context->buffered->ch_layout, &context->resampled->ch_layout);
|
||||||
|
context->buffered->format = context->resampled->format;
|
||||||
|
context->buffered->nb_samples = context->context->frame_size;
|
||||||
|
|
||||||
|
@@ -421,7 +414,7 @@ static BOOL ffmpeg_encode_frame(AVCodecContext* context, AVFrame* in, AVPacket*
|
||||||
|
if (in->format == AV_SAMPLE_FMT_FLTP)
|
||||||
|
{
|
||||||
|
uint8_t** pp = in->extended_data;
|
||||||
|
- for (int y = 0; y < in->channels; y++)
|
||||||
|
+ for (int y = 0; y < in->ch_layout.nb_channels; y++)
|
||||||
|
{
|
||||||
|
float* data = (float*)pp[y];
|
||||||
|
for (int x = 0; x < in->nb_samples; x++)
|
||||||
|
@@ -477,14 +470,13 @@ static BOOL ffmpeg_fill_frame(AVFrame* frame, const AUDIO_FORMAT* inputFormat, c
|
||||||
|
size_t size)
|
||||||
|
{
|
||||||
|
int ret, bpp;
|
||||||
|
- frame->channels = inputFormat->nChannels;
|
||||||
|
+ av_channel_layout_default(&frame->ch_layout, inputFormat->nChannels);
|
||||||
|
frame->sample_rate = inputFormat->nSamplesPerSec;
|
||||||
|
frame->format = ffmpeg_sample_format(inputFormat);
|
||||||
|
- frame->channel_layout = av_get_default_channel_layout(frame->channels);
|
||||||
|
bpp = av_get_bytes_per_sample(frame->format);
|
||||||
|
frame->nb_samples = size / inputFormat->nChannels / bpp;
|
||||||
|
|
||||||
|
- if ((ret = avcodec_fill_audio_frame(frame, frame->channels, frame->format, data, size, 1)) < 0)
|
||||||
|
+ if ((ret = avcodec_fill_audio_frame(frame, inputFormat->nChannels, frame->format, data, size, 1)) < 0)
|
||||||
|
{
|
||||||
|
const char* err = av_err2str(ret);
|
||||||
|
WLog_ERR(TAG, "Error during audio frame fill %s [%d]", err, ret);
|
||||||
|
@@ -566,7 +558,7 @@ static BOOL ffmpeg_decode(AVCodecContext* dec_ctx, AVPacket* pkt, AVFrame* frame
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
- const size_t data_size = resampled->channels * resampled->nb_samples * 2;
|
||||||
|
+ const size_t data_size = resampled->ch_layout.nb_channels * resampled->nb_samples * 2;
|
||||||
|
Stream_EnsureRemainingCapacity(out, data_size);
|
||||||
|
Stream_Write(out, resampled->data[0], data_size);
|
||||||
|
}
|
||||||
|
@@ -664,7 +656,7 @@ BOOL freerdp_dsp_ffmpeg_encode(FREERDP_DSP_CONTEXT* context, const AUDIO_FORMAT*
|
||||||
|
rc =
|
||||||
|
av_samples_copy(context->buffered->extended_data, context->resampled->extended_data,
|
||||||
|
(int)context->bufferedSamples, copied, inSamples,
|
||||||
|
- context->context->channels, context->context->sample_fmt);
|
||||||
|
+ context->context->ch_layout.nb_channels, context->context->sample_fmt);
|
||||||
|
rest -= inSamples;
|
||||||
|
copied += inSamples;
|
||||||
|
context->bufferedSamples += (UINT32)inSamples;
|
||||||
24
debian/patches/CVE-2024-32661.patch
vendored
Normal file
24
debian/patches/CVE-2024-32661.patch
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
From: akallabeth <akallabeth@posteo.net>
|
||||||
|
Date: Sun, 21 Apr 2024 13:56:13 +0200
|
||||||
|
Subject: fix missing check in rdp_write_logon_info_v1
|
||||||
|
|
||||||
|
(cherrypicked from commit 71e463e31b4d69f4022d36bfc814592f56600793)
|
||||||
|
---
|
||||||
|
libfreerdp/core/info.c | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c
|
||||||
|
index c9b2fc6..dc72b61 100644
|
||||||
|
--- a/libfreerdp/core/info.c
|
||||||
|
+++ b/libfreerdp/core/info.c
|
||||||
|
@@ -1322,6 +1322,10 @@ static BOOL rdp_write_logon_info_v1(wStream* s, logon_info* info)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* domain */
|
||||||
|
+ WINPR_ASSERT(info);
|
||||||
|
+ if (!info->domain || !info->username)
|
||||||
|
+ return FALSE;
|
||||||
|
+
|
||||||
|
ilen = ConvertToUnicode(CP_UTF8, 0, info->domain, -1, &wString, 0);
|
||||||
|
|
||||||
|
if (ilen < 0)
|
||||||
9
debian/patches/series
vendored
Normal file
9
debian/patches/series
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
0001-info-Fix-incompatible-pointer-type.patch
|
||||||
|
0002-redirection-Fix-incompatible-pointer-type.patch
|
||||||
|
0003-redirection-Fix-incompatible-pointer-type.patch
|
||||||
|
0004-X11-fix-pointer-integer-type-mismatch.patch
|
||||||
|
0005-client-wayland-fix-const-correctness.patch
|
||||||
|
0006-warnings-fix-Wincompatible-pointer-types.patch
|
||||||
|
0007-server-proxy-deactivate-capture-module.patch
|
||||||
|
1000-ffmpeg7.patch
|
||||||
|
CVE-2024-32661.patch
|
||||||
1
debian/rules
vendored
1
debian/rules
vendored
@ -31,6 +31,7 @@ DEB_CMAKE_EXTRA_FLAGS = \
|
|||||||
-DWITH_CUPS=ON \
|
-DWITH_CUPS=ON \
|
||||||
-DWITH_PCSC=ON \
|
-DWITH_PCSC=ON \
|
||||||
-DWITH_JPEG=ON \
|
-DWITH_JPEG=ON \
|
||||||
|
-DWITH_KERBEROS=ON \
|
||||||
$(empty)
|
$(empty)
|
||||||
|
|
||||||
ifneq (,$(filter armel,$(DEB_HOST_ARCH)))
|
ifneq (,$(filter armel,$(DEB_HOST_ARCH)))
|
||||||
|
|||||||
22
debian/tests/connect
vendored
Normal file
22
debian/tests/connect
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/sh -x
|
||||||
|
isNaturalNumber(){
|
||||||
|
case "$1" in
|
||||||
|
''|*[!0-9]*) return 0;;
|
||||||
|
*) return 1;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
sudo systemctl start xrdp
|
||||||
|
# XXX: Is there a better way to get the port number other than by parsing the
|
||||||
|
# configuration file?
|
||||||
|
port=$(sed -n '/^port=[0123456789]/{s/port=//p;q;}' /etc/xrdp/xrdp.ini)
|
||||||
|
if test ! isNaturalNumber "$port"; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
timeout 2s xvfb-run -l xfreerdp /v:localhost:"$port" /p: /u: /d: /cert-tofu
|
||||||
|
if test $? != 124; then
|
||||||
|
2>&1 printf "%s\n" "Xfreerdp exited before the timeout, it has likely " \
|
||||||
|
"failed to connect. The test has therefore failed."
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
3
debian/tests/control
vendored
Normal file
3
debian/tests/control
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Tests: connect
|
||||||
|
Depends: @, ca-certificates, xauth, xrdp, xvfb
|
||||||
|
Restrictions: allow-stderr, needs-sudo
|
||||||
2
debian/watch
vendored
2
debian/watch
vendored
@ -3,5 +3,5 @@ opts=\
|
|||||||
filenamemangle=s/.*\/v?([\d\.-]+)\.tar\.gz/freerdp-$1.tar.gz/,\
|
filenamemangle=s/.*\/v?([\d\.-]+)\.tar\.gz/freerdp-$1.tar.gz/,\
|
||||||
dversionmangle=s/\+dfsg1//,\
|
dversionmangle=s/\+dfsg1//,\
|
||||||
repacksuffix=+dfsg1 \
|
repacksuffix=+dfsg1 \
|
||||||
https://github.com/FreeRDP/FreeRDP/tags .*/archive/refs/tags/v?([\d\.]+).tar.gz \
|
https://github.com/FreeRDP/FreeRDP/tags .*/archive/refs/tags/v?(2\.[\d\.]+).tar.gz \
|
||||||
debian
|
debian
|
||||||
|
|||||||
@ -41,6 +41,14 @@
|
|||||||
#define RDPDR_DEVICE_IO_CONTROL_REQ_HDR_LENGTH 32
|
#define RDPDR_DEVICE_IO_CONTROL_REQ_HDR_LENGTH 32
|
||||||
#define RDPDR_DEVICE_IO_CONTROL_RSP_HDR_LENGTH 4
|
#define RDPDR_DEVICE_IO_CONTROL_RSP_HDR_LENGTH 4
|
||||||
|
|
||||||
|
#define RDPDR_VERSION_MAJOR 0x0001
|
||||||
|
|
||||||
|
#define RDPDR_VERSION_MINOR_RDP50 0x0002
|
||||||
|
#define RDPDR_VERSION_MINOR_RDP51 0x0005
|
||||||
|
#define RDPDR_VERSION_MINOR_RDP52 0x000A
|
||||||
|
#define RDPDR_VERSION_MINOR_RDP6X 0x000C
|
||||||
|
#define RDPDR_VERSION_MINOR_RDP10X 0x000D
|
||||||
|
|
||||||
/* RDPDR_HEADER.Component */
|
/* RDPDR_HEADER.Component */
|
||||||
enum RDPDR_CTYP
|
enum RDPDR_CTYP
|
||||||
{
|
{
|
||||||
|
|||||||
@ -730,6 +730,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
|
|||||||
#define FreeRDP_PercentScreenUseWidth (1556)
|
#define FreeRDP_PercentScreenUseWidth (1556)
|
||||||
#define FreeRDP_PercentScreenUseHeight (1557)
|
#define FreeRDP_PercentScreenUseHeight (1557)
|
||||||
#define FreeRDP_DynamicResolutionUpdate (1558)
|
#define FreeRDP_DynamicResolutionUpdate (1558)
|
||||||
|
#define FreeRDP_GrabMouse (1559)
|
||||||
#define FreeRDP_SoftwareGdi (1601)
|
#define FreeRDP_SoftwareGdi (1601)
|
||||||
#define FreeRDP_LocalConnection (1602)
|
#define FreeRDP_LocalConnection (1602)
|
||||||
#define FreeRDP_AuthenticationOnly (1603)
|
#define FreeRDP_AuthenticationOnly (1603)
|
||||||
@ -1216,7 +1217,8 @@ struct rdp_settings
|
|||||||
ALIGN64 BOOL PercentScreenUseWidth; /* 1556 */
|
ALIGN64 BOOL PercentScreenUseWidth; /* 1556 */
|
||||||
ALIGN64 BOOL PercentScreenUseHeight; /* 1557 */
|
ALIGN64 BOOL PercentScreenUseHeight; /* 1557 */
|
||||||
ALIGN64 BOOL DynamicResolutionUpdate; /* 1558 */
|
ALIGN64 BOOL DynamicResolutionUpdate; /* 1558 */
|
||||||
UINT64 padding1601[1601 - 1559]; /* 1559 */
|
ALIGN64 BOOL GrabMouse; /* 1559 */
|
||||||
|
UINT64 padding1601[1601 - 1560]; /* 1560 */
|
||||||
|
|
||||||
/* Miscellaneous */
|
/* Miscellaneous */
|
||||||
ALIGN64 BOOL SoftwareGdi; /* 1601 */
|
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)
|
!pointer_position)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
if (!context->settings->GrabMouse)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
pointer = context->graphics->Pointer_Prototype;
|
pointer = context->graphics->Pointer_Prototype;
|
||||||
return IFCALLRESULT(TRUE, pointer->SetPosition, context, pointer_position->xPos,
|
return IFCALLRESULT(TRUE, pointer->SetPosition, context, pointer_position->xPos,
|
||||||
pointer_position->yPos);
|
pointer_position->yPos);
|
||||||
|
|||||||
@ -410,7 +410,7 @@ static BOOL clear_decompress_residual_data(CLEAR_CONTEXT* clear, wStream* s,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pixelIndex + runLengthFactor) > pixelCount)
|
if ((pixelIndex >= pixelCount) || (runLengthFactor > (pixelCount - pixelIndex)))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG,
|
WLog_ERR(TAG,
|
||||||
"pixelIndex %" PRIu32 " + runLengthFactor %" PRIu32 " > pixelCount %" PRIu32
|
"pixelIndex %" PRIu32 " + runLengthFactor %" PRIu32 " > pixelCount %" PRIu32
|
||||||
@ -512,12 +512,12 @@ static BOOL clear_decompress_subcodecs_data(CLEAR_CONTEXT* clear, wStream* s,
|
|||||||
{
|
{
|
||||||
case 0: /* Uncompressed */
|
case 0: /* Uncompressed */
|
||||||
{
|
{
|
||||||
UINT32 nSrcStep = width * GetBytesPerPixel(PIXEL_FORMAT_BGR24);
|
const UINT32 nSrcStep = width * GetBytesPerPixel(PIXEL_FORMAT_BGR24);
|
||||||
UINT32 nSrcSize = nSrcStep * height;
|
const size_t nSrcSize = 1ull * nSrcStep * height;
|
||||||
|
|
||||||
if (bitmapDataByteCount != nSrcSize)
|
if (bitmapDataByteCount != nSrcSize)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "bitmapDataByteCount %" PRIu32 " != nSrcSize %" PRIu32 "",
|
WLog_ERR(TAG, "bitmapDataByteCount %" PRIu32 " != nSrcSize %" PRIuz "",
|
||||||
bitmapDataByteCount, nSrcSize);
|
bitmapDataByteCount, nSrcSize);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -566,7 +566,7 @@ static BOOL resize_vbar_entry(CLEAR_CONTEXT* clear, CLEAR_VBAR_ENTRY* vBarEntry)
|
|||||||
const UINT32 diffSize = (vBarEntry->count - vBarEntry->size) * bpp;
|
const UINT32 diffSize = (vBarEntry->count - vBarEntry->size) * bpp;
|
||||||
BYTE* tmp;
|
BYTE* tmp;
|
||||||
vBarEntry->size = vBarEntry->count;
|
vBarEntry->size = vBarEntry->count;
|
||||||
tmp = (BYTE*)realloc(vBarEntry->pixels, vBarEntry->count * bpp * 1ULL);
|
tmp = (BYTE*)realloc(vBarEntry->pixels, 1ull * vBarEntry->count * bpp);
|
||||||
|
|
||||||
if (!tmp)
|
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,
|
static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32 bandsByteCount,
|
||||||
UINT32 nWidth, UINT32 nHeight, BYTE* pDstData,
|
UINT32 nWidth, UINT32 nHeight, BYTE* pDstData,
|
||||||
UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst,
|
UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst,
|
||||||
UINT32 nYDst)
|
UINT32 nYDst, UINT32 nDstWidth, UINT32 nDstHeight)
|
||||||
{
|
{
|
||||||
UINT32 i, y;
|
UINT32 suboffset = 0;
|
||||||
UINT32 count;
|
|
||||||
UINT32 suboffset;
|
|
||||||
UINT32 nXDstRel;
|
|
||||||
UINT32 nYDstRel;
|
|
||||||
|
|
||||||
if (Stream_GetRemainingLength(s) < bandsByteCount)
|
if (Stream_GetRemainingLength(s) < bandsByteCount)
|
||||||
{
|
{
|
||||||
@ -605,22 +601,20 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
suboffset = 0;
|
|
||||||
|
|
||||||
while (suboffset < bandsByteCount)
|
while (suboffset < bandsByteCount)
|
||||||
{
|
{
|
||||||
BYTE r, g, b;
|
BYTE cr, cg, cb;
|
||||||
UINT16 xStart;
|
UINT16 xStart;
|
||||||
UINT16 xEnd;
|
UINT16 xEnd;
|
||||||
UINT16 yStart;
|
UINT16 yStart;
|
||||||
UINT16 yEnd;
|
UINT16 yEnd;
|
||||||
UINT32 colorBkg;
|
UINT32 colorBkg;
|
||||||
UINT16 vBarHeader;
|
UINT16 vBarHeader;
|
||||||
UINT16 vBarYOn;
|
UINT16 vBarYOn = 0;
|
||||||
UINT16 vBarYOff;
|
UINT16 vBarYOff;
|
||||||
UINT32 vBarCount;
|
UINT32 vBarCount;
|
||||||
UINT32 vBarPixelCount;
|
UINT32 vBarPixelCount;
|
||||||
UINT32 vBarShortPixelCount;
|
UINT32 vBarShortPixelCount = 0;
|
||||||
|
|
||||||
if (Stream_GetRemainingLength(s) < 11)
|
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, xEnd);
|
||||||
Stream_Read_UINT16(s, yStart);
|
Stream_Read_UINT16(s, yStart);
|
||||||
Stream_Read_UINT16(s, yEnd);
|
Stream_Read_UINT16(s, yEnd);
|
||||||
Stream_Read_UINT8(s, b);
|
Stream_Read_UINT8(s, cb);
|
||||||
Stream_Read_UINT8(s, g);
|
Stream_Read_UINT8(s, cg);
|
||||||
Stream_Read_UINT8(s, r);
|
Stream_Read_UINT8(s, cr);
|
||||||
suboffset += 11;
|
suboffset += 11;
|
||||||
colorBkg = FreeRDPGetColor(clear->format, r, g, b, 0xFF);
|
colorBkg = FreeRDPGetColor(clear->format, cr, cg, cb, 0xFF);
|
||||||
|
|
||||||
if (xEnd < xStart)
|
if (xEnd < xStart)
|
||||||
{
|
{
|
||||||
@ -652,13 +646,13 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32
|
|||||||
|
|
||||||
vBarCount = (xEnd - xStart) + 1;
|
vBarCount = (xEnd - xStart) + 1;
|
||||||
|
|
||||||
for (i = 0; i < vBarCount; i++)
|
for (UINT32 i = 0; i < vBarCount; i++)
|
||||||
{
|
{
|
||||||
UINT32 vBarHeight;
|
UINT32 vBarHeight;
|
||||||
CLEAR_VBAR_ENTRY* vBarEntry = NULL;
|
CLEAR_VBAR_ENTRY* vBarEntry = NULL;
|
||||||
CLEAR_VBAR_ENTRY* vBarShortEntry;
|
CLEAR_VBAR_ENTRY* vBarShortEntry = NULL;
|
||||||
BOOL vBarUpdate = FALSE;
|
BOOL vBarUpdate = FALSE;
|
||||||
const BYTE* pSrcPixel;
|
const BYTE* cpSrcPixel;
|
||||||
|
|
||||||
if (Stream_GetRemainingLength(s) < 2)
|
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))
|
if (!resize_vbar_entry(clear, vBarShortEntry))
|
||||||
return FALSE;
|
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)];
|
BYTE* dstBuffer = &vBarShortEntry->pixels[y * GetBytesPerPixel(clear->format)];
|
||||||
UINT32 color;
|
UINT32 color = 0;
|
||||||
Stream_Read_UINT8(s, b);
|
Stream_Read_UINT8(s, b);
|
||||||
Stream_Read_UINT8(s, g);
|
Stream_Read_UINT8(s, g);
|
||||||
Stream_Read_UINT8(s, r);
|
Stream_Read_UINT8(s, r);
|
||||||
@ -804,8 +798,8 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32
|
|||||||
|
|
||||||
dstBuffer = vBarEntry->pixels;
|
dstBuffer = vBarEntry->pixels;
|
||||||
/* if (y < vBarYOn), use colorBkg */
|
/* if (y < vBarYOn), use colorBkg */
|
||||||
y = 0;
|
UINT32 y = 0;
|
||||||
count = vBarYOn;
|
UINT32 count = vBarYOn;
|
||||||
|
|
||||||
if ((y + count) > vBarPixelCount)
|
if ((y + count) > vBarPixelCount)
|
||||||
count = (vBarPixelCount > y) ? (vBarPixelCount - y) : 0;
|
count = (vBarPixelCount > y) ? (vBarPixelCount - y) : 0;
|
||||||
@ -827,8 +821,15 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32
|
|||||||
count = (vBarPixelCount > y) ? (vBarPixelCount - y) : 0;
|
count = (vBarPixelCount > y) ? (vBarPixelCount - y) : 0;
|
||||||
|
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
pSrcPixel =
|
{
|
||||||
&vBarShortEntry->pixels[(y - vBarYOn) * GetBytesPerPixel(clear->format)];
|
const size_t offset = (1ull * y - vBarYOn) * GetBytesPerPixel(clear->format);
|
||||||
|
pSrcPixel = &vBarShortEntry->pixels[offset];
|
||||||
|
if (offset + count > vBarShortEntry->count)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "offset + count > vBarShortEntry->count");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (x = 0; x < count; x++)
|
for (x = 0; x < count; x++)
|
||||||
{
|
{
|
||||||
@ -868,28 +869,31 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* clear, wStream* s, UINT32
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nXDstRel = nXDst + xStart;
|
const UINT32 nXDstRel = nXDst + xStart;
|
||||||
nYDstRel = nYDst + yStart;
|
const UINT32 nYDstRel = nYDst + yStart;
|
||||||
pSrcPixel = vBarEntry->pixels;
|
cpSrcPixel = vBarEntry->pixels;
|
||||||
|
|
||||||
if (i < nWidth)
|
if (i < nWidth)
|
||||||
{
|
{
|
||||||
count = vBarEntry->count;
|
UINT32 count = vBarEntry->count;
|
||||||
|
|
||||||
if (count > nHeight)
|
if (count > nHeight)
|
||||||
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) +
|
BYTE* pDstPixel8 = &pDstData[((nYDstRel + y) * nDstStep) +
|
||||||
((nXDstRel + i) * GetBytesPerPixel(DstFormat))];
|
((nXDstRel + i) * GetBytesPerPixel(DstFormat))];
|
||||||
UINT32 color = ReadColor(pSrcPixel, clear->format);
|
UINT32 color = ReadColor(cpSrcPixel, clear->format);
|
||||||
color = FreeRDPConvertColor(color, clear->format, DstFormat, NULL);
|
color = FreeRDPConvertColor(color, clear->format, DstFormat, NULL);
|
||||||
|
|
||||||
if (!WriteColor(pDstPixel8, DstFormat, color))
|
if (!WriteColor(pDstPixel8, DstFormat, color))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
pSrcPixel += GetBytesPerPixel(clear->format);
|
cpSrcPixel += GetBytesPerPixel(clear->format);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -980,7 +984,7 @@ static BOOL clear_decompress_glyph_data(CLEAR_CONTEXT* clear, wStream* s, UINT32
|
|||||||
if (glyphEntry->count > glyphEntry->size)
|
if (glyphEntry->count > glyphEntry->size)
|
||||||
{
|
{
|
||||||
BYTE* tmp;
|
BYTE* tmp;
|
||||||
tmp = realloc(glyphEntry->pixels, glyphEntry->count * bpp * 1ULL);
|
tmp = realloc(glyphEntry->pixels, 1ull * glyphEntry->count * bpp);
|
||||||
|
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
{
|
{
|
||||||
@ -1117,7 +1121,7 @@ INT32 clear_decompress(CLEAR_CONTEXT* clear, const BYTE* pSrcData, UINT32 SrcSiz
|
|||||||
if (bandsByteCount > 0)
|
if (bandsByteCount > 0)
|
||||||
{
|
{
|
||||||
if (!clear_decompress_bands_data(clear, s, bandsByteCount, nWidth, nHeight, pDstData,
|
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!");
|
WLog_ERR(TAG, "clear_decompress_bands_data failed!");
|
||||||
goto fail;
|
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
|
* means of accessing individual pixels in blitting operations
|
||||||
*/
|
*/
|
||||||
scanline = (width + 7) / 8;
|
scanline = (width + 7) / 8;
|
||||||
dstData = (BYTE*)_aligned_malloc(width * height * 1ULL, 16);
|
dstData = (BYTE*)_aligned_malloc(1ull * width * height, 16);
|
||||||
|
|
||||||
if (!dstData)
|
if (!dstData)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -545,7 +545,7 @@ BOOL freerdp_image_copy_from_pointer_data(BYTE* pDstData, UINT32 DstFormat, UINT
|
|||||||
for (y = nYDst; y < nHeight; y++)
|
for (y = nYDst; y < nHeight; y++)
|
||||||
{
|
{
|
||||||
BYTE* pDstLine = &pDstData[y * nDstStep + nXDst * dstBytesPerPixel];
|
BYTE* pDstLine = &pDstData[y * nDstStep + nXDst * dstBytesPerPixel];
|
||||||
memset(pDstLine, 0, dstBytesPerPixel * (nWidth - nXDst) * 1ULL);
|
memset(pDstLine, 0, 1ull * dstBytesPerPixel * (nWidth - nXDst));
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (xorBpp)
|
switch (xorBpp)
|
||||||
@ -613,6 +613,9 @@ BOOL freerdp_image_copy(BYTE* pDstData, DWORD DstFormat, UINT32 nDstStep, UINT32
|
|||||||
if (!pDstData || !pSrcData)
|
if (!pDstData || !pSrcData)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
if ((nWidth == 0) || (nHeight == 0))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
if (nDstStep == 0)
|
if (nDstStep == 0)
|
||||||
nDstStep = nWidth * GetBytesPerPixel(DstFormat);
|
nDstStep = nWidth * GetBytesPerPixel(DstFormat);
|
||||||
|
|
||||||
@ -728,21 +731,22 @@ BOOL freerdp_image_copy(BYTE* pDstData, DWORD DstFormat, UINT32 nDstStep, UINT32
|
|||||||
BOOL freerdp_image_fill(BYTE* pDstData, DWORD DstFormat, UINT32 nDstStep, UINT32 nXDst,
|
BOOL freerdp_image_fill(BYTE* pDstData, DWORD DstFormat, UINT32 nDstStep, UINT32 nXDst,
|
||||||
UINT32 nYDst, UINT32 nWidth, UINT32 nHeight, UINT32 color)
|
UINT32 nYDst, UINT32 nWidth, UINT32 nHeight, UINT32 color)
|
||||||
{
|
{
|
||||||
UINT32 x, y;
|
if ((nWidth == 0) || (nHeight == 0))
|
||||||
|
return TRUE;
|
||||||
const UINT32 bpp = GetBytesPerPixel(DstFormat);
|
const UINT32 bpp = GetBytesPerPixel(DstFormat);
|
||||||
BYTE* pFirstDstLine = &pDstData[nYDst * nDstStep];
|
BYTE* pFirstDstLine = &pDstData[nYDst * nDstStep];
|
||||||
BYTE* pFirstDstLineXOffset = &pFirstDstLine[nXDst * bpp];
|
BYTE* pFirstDstLineXOffset = &pFirstDstLine[nXDst * bpp];
|
||||||
|
|
||||||
for (x = 0; x < nWidth; x++)
|
for (UINT32 x = 0; x < nWidth; x++)
|
||||||
{
|
{
|
||||||
BYTE* pDst = &pFirstDstLine[(x + nXDst) * bpp];
|
BYTE* pDst = &pFirstDstLine[(x + nXDst) * bpp];
|
||||||
WriteColor(pDst, DstFormat, color);
|
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];
|
BYTE* pDstLine = &pDstData[(y + nYDst) * nDstStep + nXDst * bpp];
|
||||||
memcpy(pDstLine, pFirstDstLineXOffset, nWidth * bpp * 1ULL);
|
memcpy(pDstLine, pFirstDstLineXOffset, 1ull * nWidth * bpp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|||||||
@ -418,9 +418,29 @@ static BOOL ffmpeg_resample_frame(AVAudioResampleContext* context, AVFrame* in,
|
|||||||
static BOOL ffmpeg_encode_frame(AVCodecContext* context, AVFrame* in, AVPacket* packet,
|
static BOOL ffmpeg_encode_frame(AVCodecContext* context, AVFrame* in, AVPacket* packet,
|
||||||
wStream* out)
|
wStream* out)
|
||||||
{
|
{
|
||||||
int ret;
|
if (in->format == AV_SAMPLE_FMT_FLTP)
|
||||||
|
{
|
||||||
|
uint8_t** pp = in->extended_data;
|
||||||
|
for (int y = 0; y < in->channels; y++)
|
||||||
|
{
|
||||||
|
float* data = pp[y];
|
||||||
|
for (int x = 0; x < in->nb_samples; x++)
|
||||||
|
{
|
||||||
|
const float val1 = data[x];
|
||||||
|
if (isnan(val1))
|
||||||
|
data[x] = 0.0f;
|
||||||
|
else if (isinf(val1))
|
||||||
|
{
|
||||||
|
if (val1 < 0.0f)
|
||||||
|
data[x] = -1.0f;
|
||||||
|
else
|
||||||
|
data[x] = 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
/* send the packet with the compressed data to the encoder */
|
/* send the packet with the compressed data to the encoder */
|
||||||
ret = avcodec_send_frame(context, in);
|
int ret = avcodec_send_frame(context, in);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -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[0]);
|
||||||
_aligned_free(h264->pYUVData[1]);
|
_aligned_free(h264->pYUVData[1]);
|
||||||
_aligned_free(h264->pYUVData[2]);
|
_aligned_free(h264->pYUVData[2]);
|
||||||
h264->pYUVData[0] = _aligned_malloc(h264->iStride[0] * height * 1ULL, 16);
|
h264->pYUVData[0] = _aligned_malloc(1ull * h264->iStride[0] * height, 16);
|
||||||
h264->pYUVData[1] = _aligned_malloc(h264->iStride[1] * height * 1ULL, 16);
|
h264->pYUVData[1] = _aligned_malloc(1ull * h264->iStride[1] * height, 16);
|
||||||
h264->pYUVData[2] = _aligned_malloc(h264->iStride[2] * height * 1ULL, 16);
|
h264->pYUVData[2] = _aligned_malloc(1ull * h264->iStride[2] * height, 16);
|
||||||
|
|
||||||
if (!h264->pYUVData[0] || !h264->pYUVData[1] || !h264->pYUVData[2])
|
if (!h264->pYUVData[0] || !h264->pYUVData[1] || !h264->pYUVData[2])
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|||||||
@ -529,10 +529,12 @@ static BOOL libavcodec_init(H264_CONTEXT* h264)
|
|||||||
goto EXCEPTION;
|
goto EXCEPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 18, 100)
|
||||||
if (sys->codecDecoder->capabilities & AV_CODEC_CAP_TRUNCATED)
|
if (sys->codecDecoder->capabilities & AV_CODEC_CAP_TRUNCATED)
|
||||||
{
|
{
|
||||||
sys->codecDecoderContext->flags |= AV_CODEC_FLAG_TRUNCATED;
|
sys->codecDecoderContext->flags |= AV_CODEC_FLAG_TRUNCATED;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_VAAPI
|
#ifdef WITH_VAAPI
|
||||||
|
|
||||||
|
|||||||
@ -31,7 +31,10 @@ static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, const BYTE* pbDestEnd, UINT32 r
|
|||||||
BYTE mask = 0x01;
|
BYTE mask = 0x01;
|
||||||
|
|
||||||
if (cBits > 8)
|
if (cBits > 8)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "cBits %d > 8", cBits);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
|
if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -46,7 +49,6 @@ static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, const BYTE* pbDestEnd, UINT32 r
|
|||||||
data = xorPixel;
|
data = xorPixel;
|
||||||
|
|
||||||
DESTWRITEPIXEL(pbDest, data);
|
DESTWRITEPIXEL(pbDest, data);
|
||||||
DESTNEXTPIXEL(pbDest);
|
|
||||||
mask = mask << 1;
|
mask = mask << 1;
|
||||||
});
|
});
|
||||||
return pbDest;
|
return pbDest;
|
||||||
@ -62,7 +64,10 @@ static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, const BYTE* pbDestEnd,
|
|||||||
BYTE mask = 0x01;
|
BYTE mask = 0x01;
|
||||||
|
|
||||||
if (cBits > 8)
|
if (cBits > 8)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "cBits %d > 8", cBits);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
|
if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -76,7 +81,6 @@ static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, const BYTE* pbDestEnd,
|
|||||||
data = BLACK_PIXEL;
|
data = BLACK_PIXEL;
|
||||||
|
|
||||||
DESTWRITEPIXEL(pbDest, data);
|
DESTWRITEPIXEL(pbDest, data);
|
||||||
DESTNEXTPIXEL(pbDest);
|
|
||||||
mask = mask << 1;
|
mask = mask << 1;
|
||||||
});
|
});
|
||||||
return pbDest;
|
return pbDest;
|
||||||
@ -88,6 +92,9 @@ static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, const BYTE* pbDestEnd,
|
|||||||
static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, BYTE* pbDestBuffer,
|
static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, BYTE* pbDestBuffer,
|
||||||
UINT32 rowDelta, UINT32 width, UINT32 height)
|
UINT32 rowDelta, UINT32 width, UINT32 height)
|
||||||
{
|
{
|
||||||
|
#if defined(WITH_DEBUG_CODECS)
|
||||||
|
char sbuffer[128] = { 0 };
|
||||||
|
#endif
|
||||||
const BYTE* pbSrc = pbSrcBuffer;
|
const BYTE* pbSrc = pbSrcBuffer;
|
||||||
const BYTE* pbEnd;
|
const BYTE* pbEnd;
|
||||||
const BYTE* pbDestEnd;
|
const BYTE* pbDestEnd;
|
||||||
@ -100,14 +107,22 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, BY
|
|||||||
PIXEL pixelA, pixelB;
|
PIXEL pixelA, pixelB;
|
||||||
UINT32 runLength;
|
UINT32 runLength;
|
||||||
UINT32 code;
|
UINT32 code;
|
||||||
UINT32 advance;
|
UINT32 advance = 0;
|
||||||
RLEEXTRA
|
RLEEXTRA
|
||||||
|
|
||||||
if ((rowDelta == 0) || (rowDelta < width))
|
if ((rowDelta == 0) || (rowDelta < width))
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "Invalid arguments: rowDelta=%" PRIu32 " == 0 || < width=%" PRIu32, rowDelta,
|
||||||
|
width);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (!pbSrcBuffer || !pbDestBuffer)
|
if (!pbSrcBuffer || !pbDestBuffer)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "Invalid arguments: pbSrcBuffer=%p, pbDestBuffer=%p", pbSrcBuffer,
|
||||||
|
pbDestBuffer);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
pbEnd = pbSrcBuffer + cbSrcBuffer;
|
pbEnd = pbSrcBuffer + cbSrcBuffer;
|
||||||
pbDestEnd = pbDestBuffer + rowDelta * height;
|
pbDestEnd = pbDestBuffer + rowDelta * height;
|
||||||
@ -130,10 +145,17 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, BY
|
|||||||
*/
|
*/
|
||||||
code = ExtractCodeId(*pbSrc);
|
code = ExtractCodeId(*pbSrc);
|
||||||
|
|
||||||
|
#if defined(WITH_DEBUG_CODECS)
|
||||||
|
WLog_VRB(TAG, "pbSrc=%p code=%s, rem=%" PRIuz, pbSrc,
|
||||||
|
rle_code_str_buffer(code, sbuffer, sizeof(sbuffer)), pbEnd - pbSrc);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Handle Background Run Orders. */
|
/* Handle Background Run Orders. */
|
||||||
if (code == REGULAR_BG_RUN || code == MEGA_MEGA_BG_RUN)
|
if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
|
||||||
{
|
{
|
||||||
runLength = ExtractRunLength(code, pbSrc, &advance);
|
runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
|
||||||
|
if (advance == 0)
|
||||||
|
return FALSE;
|
||||||
pbSrc = pbSrc + advance;
|
pbSrc = pbSrc + advance;
|
||||||
|
|
||||||
if (fFirstLine)
|
if (fFirstLine)
|
||||||
@ -144,17 +166,13 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, BY
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
DESTWRITEPIXEL(pbDest, fgPel);
|
DESTWRITEPIXEL(pbDest, fgPel);
|
||||||
DESTNEXTPIXEL(pbDest);
|
|
||||||
runLength = runLength - 1;
|
runLength = runLength - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
|
if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
UNROLL(runLength, {
|
UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
|
||||||
DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
|
|
||||||
DESTNEXTPIXEL(pbDest);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -166,7 +184,6 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, BY
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
DESTWRITEPIXEL(pbDest, temp ^ fgPel);
|
DESTWRITEPIXEL(pbDest, temp ^ fgPel);
|
||||||
DESTNEXTPIXEL(pbDest);
|
|
||||||
runLength--;
|
runLength--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,7 +193,6 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, BY
|
|||||||
UNROLL(runLength, {
|
UNROLL(runLength, {
|
||||||
DESTREADPIXEL(temp, pbDest - rowDelta);
|
DESTREADPIXEL(temp, pbDest - rowDelta);
|
||||||
DESTWRITEPIXEL(pbDest, temp);
|
DESTWRITEPIXEL(pbDest, temp);
|
||||||
DESTNEXTPIXEL(pbDest);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,15 +212,16 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, BY
|
|||||||
case MEGA_MEGA_FG_RUN:
|
case MEGA_MEGA_FG_RUN:
|
||||||
case LITE_SET_FG_FG_RUN:
|
case LITE_SET_FG_FG_RUN:
|
||||||
case MEGA_MEGA_SET_FG_RUN:
|
case MEGA_MEGA_SET_FG_RUN:
|
||||||
runLength = ExtractRunLength(code, pbSrc, &advance);
|
runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
|
||||||
|
if (advance == 0)
|
||||||
|
return FALSE;
|
||||||
pbSrc = pbSrc + advance;
|
pbSrc = pbSrc + advance;
|
||||||
|
|
||||||
if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
|
if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
|
||||||
{
|
{
|
||||||
if (pbSrc >= pbEnd)
|
if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
SRCREADPIXEL(fgPel, pbSrc);
|
SRCREADPIXEL(fgPel, pbSrc);
|
||||||
SRCNEXTPIXEL(pbSrc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
|
if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
|
||||||
@ -212,17 +229,13 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, BY
|
|||||||
|
|
||||||
if (fFirstLine)
|
if (fFirstLine)
|
||||||
{
|
{
|
||||||
UNROLL(runLength, {
|
UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
|
||||||
DESTWRITEPIXEL(pbDest, fgPel);
|
|
||||||
DESTNEXTPIXEL(pbDest);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UNROLL(runLength, {
|
UNROLL(runLength, {
|
||||||
DESTREADPIXEL(temp, pbDest - rowDelta);
|
DESTREADPIXEL(temp, pbDest - rowDelta);
|
||||||
DESTWRITEPIXEL(pbDest, temp ^ fgPel);
|
DESTWRITEPIXEL(pbDest, temp ^ fgPel);
|
||||||
DESTNEXTPIXEL(pbDest);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,45 +244,41 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, BY
|
|||||||
/* Handle Dithered Run Orders. */
|
/* Handle Dithered Run Orders. */
|
||||||
case LITE_DITHERED_RUN:
|
case LITE_DITHERED_RUN:
|
||||||
case MEGA_MEGA_DITHERED_RUN:
|
case MEGA_MEGA_DITHERED_RUN:
|
||||||
runLength = ExtractRunLength(code, pbSrc, &advance);
|
runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
|
||||||
|
if (advance == 0)
|
||||||
|
return FALSE;
|
||||||
pbSrc = pbSrc + advance;
|
pbSrc = pbSrc + advance;
|
||||||
if (pbSrc >= pbEnd)
|
if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
SRCREADPIXEL(pixelA, pbSrc);
|
SRCREADPIXEL(pixelA, pbSrc);
|
||||||
SRCNEXTPIXEL(pbSrc);
|
if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
|
||||||
if (pbSrc >= pbEnd)
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
SRCREADPIXEL(pixelB, pbSrc);
|
SRCREADPIXEL(pixelB, pbSrc);
|
||||||
SRCNEXTPIXEL(pbSrc);
|
|
||||||
|
|
||||||
if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
|
if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
UNROLL(runLength, {
|
UNROLL(runLength, {
|
||||||
DESTWRITEPIXEL(pbDest, pixelA);
|
DESTWRITEPIXEL(pbDest, pixelA);
|
||||||
DESTNEXTPIXEL(pbDest);
|
|
||||||
DESTWRITEPIXEL(pbDest, pixelB);
|
DESTWRITEPIXEL(pbDest, pixelB);
|
||||||
DESTNEXTPIXEL(pbDest);
|
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Handle Color Run Orders. */
|
/* Handle Color Run Orders. */
|
||||||
case REGULAR_COLOR_RUN:
|
case REGULAR_COLOR_RUN:
|
||||||
case MEGA_MEGA_COLOR_RUN:
|
case MEGA_MEGA_COLOR_RUN:
|
||||||
runLength = ExtractRunLength(code, pbSrc, &advance);
|
runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
|
||||||
|
if (advance == 0)
|
||||||
|
return FALSE;
|
||||||
pbSrc = pbSrc + advance;
|
pbSrc = pbSrc + advance;
|
||||||
if (pbSrc >= pbEnd)
|
if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
SRCREADPIXEL(pixelA, pbSrc);
|
SRCREADPIXEL(pixelA, pbSrc);
|
||||||
SRCNEXTPIXEL(pbSrc);
|
|
||||||
|
|
||||||
if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
|
if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
UNROLL(runLength, {
|
UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
|
||||||
DESTWRITEPIXEL(pbDest, pixelA);
|
|
||||||
DESTNEXTPIXEL(pbDest);
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Handle Foreground/Background Image Orders. */
|
/* Handle Foreground/Background Image Orders. */
|
||||||
@ -277,17 +286,20 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, BY
|
|||||||
case MEGA_MEGA_FGBG_IMAGE:
|
case MEGA_MEGA_FGBG_IMAGE:
|
||||||
case LITE_SET_FG_FGBG_IMAGE:
|
case LITE_SET_FG_FGBG_IMAGE:
|
||||||
case MEGA_MEGA_SET_FGBG_IMAGE:
|
case MEGA_MEGA_SET_FGBG_IMAGE:
|
||||||
runLength = ExtractRunLength(code, pbSrc, &advance);
|
runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
|
||||||
|
if (advance == 0)
|
||||||
|
return FALSE;
|
||||||
pbSrc = pbSrc + advance;
|
pbSrc = pbSrc + advance;
|
||||||
|
|
||||||
if (pbSrc >= pbEnd)
|
|
||||||
return FALSE;
|
|
||||||
if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
|
if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
|
||||||
{
|
{
|
||||||
|
if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
|
||||||
|
return FALSE;
|
||||||
SRCREADPIXEL(fgPel, pbSrc);
|
SRCREADPIXEL(fgPel, pbSrc);
|
||||||
SRCNEXTPIXEL(pbSrc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
|
||||||
|
return FALSE;
|
||||||
if (fFirstLine)
|
if (fFirstLine)
|
||||||
{
|
{
|
||||||
while (runLength > 8)
|
while (runLength > 8)
|
||||||
@ -306,8 +318,8 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, BY
|
|||||||
{
|
{
|
||||||
while (runLength > 8)
|
while (runLength > 8)
|
||||||
{
|
{
|
||||||
bitmask = *pbSrc;
|
bitmask = *pbSrc++;
|
||||||
pbSrc = pbSrc + 1;
|
|
||||||
pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
|
pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
|
||||||
|
|
||||||
if (!pbDest)
|
if (!pbDest)
|
||||||
@ -319,8 +331,9 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, BY
|
|||||||
|
|
||||||
if (runLength > 0)
|
if (runLength > 0)
|
||||||
{
|
{
|
||||||
bitmask = *pbSrc;
|
if (!buffer_within_range(pbSrc, 1, pbEnd))
|
||||||
pbSrc = pbSrc + 1;
|
return FALSE;
|
||||||
|
bitmask = *pbSrc++;
|
||||||
|
|
||||||
if (fFirstLine)
|
if (fFirstLine)
|
||||||
{
|
{
|
||||||
@ -342,23 +355,25 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, BY
|
|||||||
/* Handle Color Image Orders. */
|
/* Handle Color Image Orders. */
|
||||||
case REGULAR_COLOR_IMAGE:
|
case REGULAR_COLOR_IMAGE:
|
||||||
case MEGA_MEGA_COLOR_IMAGE:
|
case MEGA_MEGA_COLOR_IMAGE:
|
||||||
runLength = ExtractRunLength(code, pbSrc, &advance);
|
runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
|
||||||
|
if (advance == 0)
|
||||||
|
return FALSE;
|
||||||
pbSrc = pbSrc + advance;
|
pbSrc = pbSrc + advance;
|
||||||
if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
|
if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
UNROLL(runLength, {
|
UNROLL(runLength, {
|
||||||
if (pbSrc >= pbEnd)
|
|
||||||
return FALSE;
|
|
||||||
SRCREADPIXEL(temp, pbSrc);
|
SRCREADPIXEL(temp, pbSrc);
|
||||||
SRCNEXTPIXEL(pbSrc);
|
|
||||||
DESTWRITEPIXEL(pbDest, temp);
|
DESTWRITEPIXEL(pbDest, temp);
|
||||||
DESTNEXTPIXEL(pbDest);
|
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Handle Special Order 1. */
|
/* Handle Special Order 1. */
|
||||||
case SPECIAL_FGBG_1:
|
case SPECIAL_FGBG_1:
|
||||||
|
if (!buffer_within_range(pbSrc, 1, pbEnd))
|
||||||
|
return FALSE;
|
||||||
pbSrc = pbSrc + 1;
|
pbSrc = pbSrc + 1;
|
||||||
|
|
||||||
if (fFirstLine)
|
if (fFirstLine)
|
||||||
@ -379,6 +394,8 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, BY
|
|||||||
|
|
||||||
/* Handle Special Order 2. */
|
/* Handle Special Order 2. */
|
||||||
case SPECIAL_FGBG_2:
|
case SPECIAL_FGBG_2:
|
||||||
|
if (!buffer_within_range(pbSrc, 1, pbEnd))
|
||||||
|
return FALSE;
|
||||||
pbSrc = pbSrc + 1;
|
pbSrc = pbSrc + 1;
|
||||||
|
|
||||||
if (fFirstLine)
|
if (fFirstLine)
|
||||||
@ -399,27 +416,31 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, BY
|
|||||||
|
|
||||||
/* Handle White Order. */
|
/* Handle White Order. */
|
||||||
case SPECIAL_WHITE:
|
case SPECIAL_WHITE:
|
||||||
|
if (!buffer_within_range(pbSrc, 1, pbEnd))
|
||||||
|
return FALSE;
|
||||||
pbSrc = pbSrc + 1;
|
pbSrc = pbSrc + 1;
|
||||||
|
|
||||||
if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
|
if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
|
DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
|
||||||
DESTNEXTPIXEL(pbDest);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Handle Black Order. */
|
/* Handle Black Order. */
|
||||||
case SPECIAL_BLACK:
|
case SPECIAL_BLACK:
|
||||||
|
if (!buffer_within_range(pbSrc, 1, pbEnd))
|
||||||
|
return FALSE;
|
||||||
pbSrc = pbSrc + 1;
|
pbSrc = pbSrc + 1;
|
||||||
|
|
||||||
if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
|
if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
|
DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
|
||||||
DESTNEXTPIXEL(pbDest);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
|
||||||
|
code, pbSrcBuffer, pbSrc, pbEnd);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <winpr/assert.h>
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
@ -30,15 +31,16 @@
|
|||||||
|
|
||||||
#define TAG FREERDP_TAG("codec")
|
#define TAG FREERDP_TAG("codec")
|
||||||
|
|
||||||
#define UNROLL_BODY(_exp, _count) \
|
#define UNROLL_BODY(_exp, _count) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
size_t x; \
|
for (size_t x = 0; x < (_count); x++) \
|
||||||
for (x = 0; x < (_count); x++) \
|
{ \
|
||||||
{ \
|
do \
|
||||||
do \
|
{ \
|
||||||
_exp while (FALSE); \
|
_exp \
|
||||||
} \
|
} while (FALSE); \
|
||||||
|
} \
|
||||||
} while (FALSE)
|
} while (FALSE)
|
||||||
|
|
||||||
#define UNROLL_MULTIPLE(_condition, _exp, _count) \
|
#define UNROLL_MULTIPLE(_condition, _exp, _count) \
|
||||||
@ -97,6 +99,80 @@ static const BYTE g_MaskSpecialFgBg2 = 0x05;
|
|||||||
static const BYTE g_MaskRegularRunLength = 0x1F;
|
static const BYTE g_MaskRegularRunLength = 0x1F;
|
||||||
static const BYTE g_MaskLiteRunLength = 0x0F;
|
static const BYTE g_MaskLiteRunLength = 0x0F;
|
||||||
|
|
||||||
|
static const char* rle_code_str(UINT32 code)
|
||||||
|
{
|
||||||
|
switch (code)
|
||||||
|
{
|
||||||
|
case REGULAR_BG_RUN:
|
||||||
|
return "REGULAR_BG_RUN";
|
||||||
|
case MEGA_MEGA_BG_RUN:
|
||||||
|
return "MEGA_MEGA_BG_RUN";
|
||||||
|
case REGULAR_FG_RUN:
|
||||||
|
return "REGULAR_FG_RUN";
|
||||||
|
case MEGA_MEGA_FG_RUN:
|
||||||
|
return "MEGA_MEGA_FG_RUN";
|
||||||
|
case LITE_SET_FG_FG_RUN:
|
||||||
|
return "LITE_SET_FG_FG_RUN";
|
||||||
|
case MEGA_MEGA_SET_FG_RUN:
|
||||||
|
return "MEGA_MEGA_SET_FG_RUN";
|
||||||
|
case LITE_DITHERED_RUN:
|
||||||
|
return "LITE_DITHERED_RUN";
|
||||||
|
case MEGA_MEGA_DITHERED_RUN:
|
||||||
|
return "MEGA_MEGA_DITHERED_RUN";
|
||||||
|
case REGULAR_COLOR_RUN:
|
||||||
|
return "REGULAR_COLOR_RUN";
|
||||||
|
case MEGA_MEGA_COLOR_RUN:
|
||||||
|
return "MEGA_MEGA_COLOR_RUN";
|
||||||
|
case REGULAR_FGBG_IMAGE:
|
||||||
|
return "REGULAR_FGBG_IMAGE";
|
||||||
|
case MEGA_MEGA_FGBG_IMAGE:
|
||||||
|
return "MEGA_MEGA_FGBG_IMAGE";
|
||||||
|
case LITE_SET_FG_FGBG_IMAGE:
|
||||||
|
return "LITE_SET_FG_FGBG_IMAGE";
|
||||||
|
case MEGA_MEGA_SET_FGBG_IMAGE:
|
||||||
|
return "MEGA_MEGA_SET_FGBG_IMAGE";
|
||||||
|
case REGULAR_COLOR_IMAGE:
|
||||||
|
return "REGULAR_COLOR_IMAGE";
|
||||||
|
case MEGA_MEGA_COLOR_IMAGE:
|
||||||
|
return "MEGA_MEGA_COLOR_IMAGE";
|
||||||
|
case SPECIAL_FGBG_1:
|
||||||
|
return "SPECIAL_FGBG_1";
|
||||||
|
case SPECIAL_FGBG_2:
|
||||||
|
return "SPECIAL_FGBG_2";
|
||||||
|
case SPECIAL_WHITE:
|
||||||
|
return "SPECIAL_WHITE";
|
||||||
|
case SPECIAL_BLACK:
|
||||||
|
return "SPECIAL_BLACK";
|
||||||
|
default:
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* rle_code_str_buffer(UINT32 code, char* buffer, size_t size)
|
||||||
|
{
|
||||||
|
const char* str = rle_code_str(code);
|
||||||
|
_snprintf(buffer, size, "%s [0x%08" PRIx32 "]", str, code);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define buffer_within_range(pbSrc, size, pbEnd) \
|
||||||
|
buffer_within_range_((pbSrc), (size), (pbEnd), __func__, __FILE__, __LINE__)
|
||||||
|
static INLINE BOOL buffer_within_range_(const void* pbSrc, size_t size, const void* pbEnd,
|
||||||
|
const char* fkt, const char* file, size_t line)
|
||||||
|
{
|
||||||
|
WINPR_UNUSED(file);
|
||||||
|
WINPR_ASSERT(pbSrc);
|
||||||
|
WINPR_ASSERT(pbEnd);
|
||||||
|
|
||||||
|
if ((const char*)pbSrc + size > (const char*)pbEnd)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "[%s:%" PRIuz "] pbSrc=%p + %" PRIuz " > pbEnd=%p", fkt, line, pbSrc, size,
|
||||||
|
pbEnd);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the supplied order header and extracts the compression
|
* Reads the supplied order header and extracts the compression
|
||||||
* order code ID.
|
* order code ID.
|
||||||
@ -127,71 +203,155 @@ static INLINE UINT32 ExtractCodeId(BYTE bOrderHdr)
|
|||||||
/**
|
/**
|
||||||
* Extract the run length of a compression order.
|
* Extract the run length of a compression order.
|
||||||
*/
|
*/
|
||||||
static INLINE UINT32 ExtractRunLength(UINT32 code, const BYTE* pbOrderHdr, UINT32* advance)
|
static UINT ExtractRunLengthRegularFgBg(const BYTE* pbOrderHdr, const BYTE* pbEnd, UINT32* advance)
|
||||||
{
|
{
|
||||||
UINT32 runLength;
|
UINT runLength = 0;
|
||||||
UINT32 ladvance;
|
|
||||||
ladvance = 1;
|
WINPR_ASSERT(pbOrderHdr);
|
||||||
runLength = 0;
|
WINPR_ASSERT(pbEnd);
|
||||||
|
WINPR_ASSERT(advance);
|
||||||
|
|
||||||
|
runLength = (*pbOrderHdr) & g_MaskRegularRunLength;
|
||||||
|
if (runLength == 0)
|
||||||
|
{
|
||||||
|
if (!buffer_within_range(pbOrderHdr, 2, pbEnd))
|
||||||
|
{
|
||||||
|
*advance = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
runLength = *(pbOrderHdr + 1) + 1;
|
||||||
|
(*advance)++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
runLength = runLength * 8;
|
||||||
|
|
||||||
|
return runLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT ExtractRunLengthLiteFgBg(const BYTE* pbOrderHdr, const BYTE* pbEnd, UINT32* advance)
|
||||||
|
{
|
||||||
|
UINT runLength = 0;
|
||||||
|
|
||||||
|
WINPR_ASSERT(pbOrderHdr);
|
||||||
|
WINPR_ASSERT(pbEnd);
|
||||||
|
WINPR_ASSERT(advance);
|
||||||
|
|
||||||
|
runLength = *pbOrderHdr & g_MaskLiteRunLength;
|
||||||
|
if (runLength == 0)
|
||||||
|
{
|
||||||
|
if (!buffer_within_range(pbOrderHdr, 2, pbEnd))
|
||||||
|
{
|
||||||
|
*advance = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
runLength = *(pbOrderHdr + 1) + 1;
|
||||||
|
(*advance)++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
runLength = runLength * 8;
|
||||||
|
|
||||||
|
return runLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT ExtractRunLengthRegular(const BYTE* pbOrderHdr, const BYTE* pbEnd, UINT32* advance)
|
||||||
|
{
|
||||||
|
UINT runLength = 0;
|
||||||
|
|
||||||
|
WINPR_ASSERT(pbOrderHdr);
|
||||||
|
WINPR_ASSERT(pbEnd);
|
||||||
|
WINPR_ASSERT(advance);
|
||||||
|
|
||||||
|
runLength = *pbOrderHdr & g_MaskRegularRunLength;
|
||||||
|
if (runLength == 0)
|
||||||
|
{
|
||||||
|
if (!buffer_within_range(pbOrderHdr, 2, pbEnd))
|
||||||
|
{
|
||||||
|
*advance = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
runLength = *(pbOrderHdr + 1) + 32;
|
||||||
|
(*advance)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return runLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT ExtractRunLengthMegaMega(const BYTE* pbOrderHdr, const BYTE* pbEnd, UINT32* advance)
|
||||||
|
{
|
||||||
|
UINT runLength = 0;
|
||||||
|
|
||||||
|
WINPR_ASSERT(pbOrderHdr);
|
||||||
|
WINPR_ASSERT(pbEnd);
|
||||||
|
WINPR_ASSERT(advance);
|
||||||
|
|
||||||
|
if (!buffer_within_range(pbOrderHdr, 3, pbEnd))
|
||||||
|
{
|
||||||
|
*advance = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
runLength = ((UINT16)pbOrderHdr[1]) | (((UINT16)pbOrderHdr[2]) << 8);
|
||||||
|
(*advance) += 2;
|
||||||
|
|
||||||
|
return runLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT ExtractRunLengthLite(const BYTE* pbOrderHdr, const BYTE* pbEnd, UINT32* advance)
|
||||||
|
{
|
||||||
|
UINT runLength = 0;
|
||||||
|
|
||||||
|
WINPR_ASSERT(pbOrderHdr);
|
||||||
|
WINPR_ASSERT(pbEnd);
|
||||||
|
WINPR_ASSERT(advance);
|
||||||
|
|
||||||
|
runLength = *pbOrderHdr & g_MaskLiteRunLength;
|
||||||
|
if (runLength == 0)
|
||||||
|
{
|
||||||
|
if (!buffer_within_range(pbOrderHdr, 2, pbEnd))
|
||||||
|
{
|
||||||
|
*advance = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
runLength = *(pbOrderHdr + 1) + 16;
|
||||||
|
(*advance)++;
|
||||||
|
}
|
||||||
|
return runLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE UINT32 ExtractRunLength(UINT32 code, const BYTE* pbOrderHdr, const BYTE* pbEnd,
|
||||||
|
UINT32* advance)
|
||||||
|
{
|
||||||
|
UINT32 runLength = 0;
|
||||||
|
UINT32 ladvance = 1;
|
||||||
|
|
||||||
|
WINPR_ASSERT(pbOrderHdr);
|
||||||
|
WINPR_ASSERT(pbEnd);
|
||||||
|
WINPR_ASSERT(advance);
|
||||||
|
|
||||||
|
*advance = 0;
|
||||||
|
if (!buffer_within_range(pbOrderHdr, 0, pbEnd))
|
||||||
|
return 0;
|
||||||
|
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
case REGULAR_FGBG_IMAGE:
|
case REGULAR_FGBG_IMAGE:
|
||||||
runLength = (*pbOrderHdr) & g_MaskRegularRunLength;
|
runLength = ExtractRunLengthRegularFgBg(pbOrderHdr, pbEnd, &ladvance);
|
||||||
|
|
||||||
if (runLength == 0)
|
|
||||||
{
|
|
||||||
runLength = (*(pbOrderHdr + 1)) + 1;
|
|
||||||
ladvance += 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
runLength = runLength * 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LITE_SET_FG_FGBG_IMAGE:
|
case LITE_SET_FG_FGBG_IMAGE:
|
||||||
runLength = (*pbOrderHdr) & g_MaskLiteRunLength;
|
runLength = ExtractRunLengthLiteFgBg(pbOrderHdr, pbEnd, &ladvance);
|
||||||
|
|
||||||
if (runLength == 0)
|
|
||||||
{
|
|
||||||
runLength = (*(pbOrderHdr + 1)) + 1;
|
|
||||||
ladvance += 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
runLength = runLength * 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REGULAR_BG_RUN:
|
case REGULAR_BG_RUN:
|
||||||
case REGULAR_FG_RUN:
|
case REGULAR_FG_RUN:
|
||||||
case REGULAR_COLOR_RUN:
|
case REGULAR_COLOR_RUN:
|
||||||
case REGULAR_COLOR_IMAGE:
|
case REGULAR_COLOR_IMAGE:
|
||||||
runLength = (*pbOrderHdr) & g_MaskRegularRunLength;
|
runLength = ExtractRunLengthRegular(pbOrderHdr, pbEnd, &ladvance);
|
||||||
|
|
||||||
if (runLength == 0)
|
|
||||||
{
|
|
||||||
/* An extended (MEGA) run. */
|
|
||||||
runLength = (*(pbOrderHdr + 1)) + 32;
|
|
||||||
ladvance += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LITE_SET_FG_FG_RUN:
|
case LITE_SET_FG_FG_RUN:
|
||||||
case LITE_DITHERED_RUN:
|
case LITE_DITHERED_RUN:
|
||||||
runLength = (*pbOrderHdr) & g_MaskLiteRunLength;
|
runLength = ExtractRunLengthLite(pbOrderHdr, pbEnd, &ladvance);
|
||||||
|
|
||||||
if (runLength == 0)
|
|
||||||
{
|
|
||||||
/* An extended (MEGA) run. */
|
|
||||||
runLength = (*(pbOrderHdr + 1)) + 16;
|
|
||||||
ladvance += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MEGA_MEGA_BG_RUN:
|
case MEGA_MEGA_BG_RUN:
|
||||||
@ -202,8 +362,12 @@ static INLINE UINT32 ExtractRunLength(UINT32 code, const BYTE* pbOrderHdr, UINT3
|
|||||||
case MEGA_MEGA_FGBG_IMAGE:
|
case MEGA_MEGA_FGBG_IMAGE:
|
||||||
case MEGA_MEGA_SET_FGBG_IMAGE:
|
case MEGA_MEGA_SET_FGBG_IMAGE:
|
||||||
case MEGA_MEGA_COLOR_IMAGE:
|
case MEGA_MEGA_COLOR_IMAGE:
|
||||||
runLength = ((UINT16)pbOrderHdr[1]) | ((UINT16)(pbOrderHdr[2] << 8));
|
runLength = ExtractRunLengthMegaMega(pbOrderHdr, pbEnd, &ladvance);
|
||||||
ladvance += 2;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
runLength = 0;
|
||||||
|
ladvance = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,20 +375,32 @@ static INLINE UINT32 ExtractRunLength(UINT32 code, const BYTE* pbOrderHdr, UINT3
|
|||||||
return runLength;
|
return runLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE BOOL ensure_capacity(const BYTE* start, const BYTE* end, size_t size, size_t base)
|
#define ensure_capacity(start, end, size, base) \
|
||||||
|
ensure_capacity_((start), (end), (size), (base), __func__, __FILE__, __LINE__)
|
||||||
|
static INLINE BOOL ensure_capacity_(const BYTE* start, const BYTE* end, size_t size, size_t base,
|
||||||
|
const char* fkt, const char* file, size_t line)
|
||||||
{
|
{
|
||||||
const size_t available = (uintptr_t)end - (uintptr_t)start;
|
const size_t available = (uintptr_t)end - (uintptr_t)start;
|
||||||
const BOOL rc = available >= size * base;
|
const BOOL rc = available >= size * base;
|
||||||
return rc && (start <= end);
|
const BOOL res = rc && (start <= end);
|
||||||
|
|
||||||
|
if (!res)
|
||||||
|
WLog_ERR(TAG,
|
||||||
|
"[%s:%" PRIuz "] failed: start=%p <= end=%p, available=%" PRIuz " >= size=%" PRIuz
|
||||||
|
" * base=%" PRIuz,
|
||||||
|
fkt, line, start, end, available, size, base);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE void write_pixel_8(BYTE* _buf, BYTE _pix)
|
static INLINE void write_pixel_8(BYTE* _buf, BYTE _pix)
|
||||||
{
|
{
|
||||||
|
WINPR_ASSERT(_buf);
|
||||||
*_buf = _pix;
|
*_buf = _pix;
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE void write_pixel_24(BYTE* _buf, UINT32 _pix)
|
static INLINE void write_pixel_24(BYTE* _buf, UINT32 _pix)
|
||||||
{
|
{
|
||||||
|
WINPR_ASSERT(_buf);
|
||||||
(_buf)[0] = (BYTE)(_pix);
|
(_buf)[0] = (BYTE)(_pix);
|
||||||
(_buf)[1] = (BYTE)((_pix) >> 8);
|
(_buf)[1] = (BYTE)((_pix) >> 8);
|
||||||
(_buf)[2] = (BYTE)((_pix) >> 16);
|
(_buf)[2] = (BYTE)((_pix) >> 16);
|
||||||
@ -232,6 +408,7 @@ static INLINE void write_pixel_24(BYTE* _buf, UINT32 _pix)
|
|||||||
|
|
||||||
static INLINE void write_pixel_16(BYTE* _buf, UINT16 _pix)
|
static INLINE void write_pixel_16(BYTE* _buf, UINT16 _pix)
|
||||||
{
|
{
|
||||||
|
WINPR_ASSERT(_buf);
|
||||||
_buf[0] = _pix & 0xFF;
|
_buf[0] = _pix & 0xFF;
|
||||||
_buf[1] = (_pix >> 8) & 0xFF;
|
_buf[1] = (_pix >> 8) & 0xFF;
|
||||||
}
|
}
|
||||||
@ -239,19 +416,30 @@ static INLINE void write_pixel_16(BYTE* _buf, UINT16 _pix)
|
|||||||
#undef DESTWRITEPIXEL
|
#undef DESTWRITEPIXEL
|
||||||
#undef DESTREADPIXEL
|
#undef DESTREADPIXEL
|
||||||
#undef SRCREADPIXEL
|
#undef SRCREADPIXEL
|
||||||
#undef DESTNEXTPIXEL
|
|
||||||
#undef SRCNEXTPIXEL
|
|
||||||
#undef WRITEFGBGIMAGE
|
#undef WRITEFGBGIMAGE
|
||||||
#undef WRITEFIRSTLINEFGBGIMAGE
|
#undef WRITEFIRSTLINEFGBGIMAGE
|
||||||
#undef RLEDECOMPRESS
|
#undef RLEDECOMPRESS
|
||||||
#undef RLEEXTRA
|
#undef RLEEXTRA
|
||||||
#undef WHITE_PIXEL
|
#undef WHITE_PIXEL
|
||||||
|
#undef PIXEL_SIZE
|
||||||
|
#undef PIXEL
|
||||||
|
#define PIXEL_SIZE 1
|
||||||
|
#define PIXEL BYTE
|
||||||
#define WHITE_PIXEL 0xFF
|
#define WHITE_PIXEL 0xFF
|
||||||
#define DESTWRITEPIXEL(_buf, _pix) write_pixel_8(_buf, _pix)
|
#define DESTWRITEPIXEL(_buf, _pix) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
write_pixel_8(_buf, _pix); \
|
||||||
|
_buf += 1; \
|
||||||
|
} while (0)
|
||||||
#define DESTREADPIXEL(_pix, _buf) _pix = (_buf)[0]
|
#define DESTREADPIXEL(_pix, _buf) _pix = (_buf)[0]
|
||||||
#define SRCREADPIXEL(_pix, _buf) _pix = (_buf)[0]
|
#define SRCREADPIXEL(_pix, _buf) \
|
||||||
#define DESTNEXTPIXEL(_buf) _buf += 1
|
do \
|
||||||
#define SRCNEXTPIXEL(_buf) _buf += 1
|
{ \
|
||||||
|
_pix = (_buf)[0]; \
|
||||||
|
_buf += 1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define WRITEFGBGIMAGE WriteFgBgImage8to8
|
#define WRITEFGBGIMAGE WriteFgBgImage8to8
|
||||||
#define WRITEFIRSTLINEFGBGIMAGE WriteFirstLineFgBgImage8to8
|
#define WRITEFIRSTLINEFGBGIMAGE WriteFirstLineFgBgImage8to8
|
||||||
#define RLEDECOMPRESS RleDecompress8to8
|
#define RLEDECOMPRESS RleDecompress8to8
|
||||||
@ -263,19 +451,29 @@ static INLINE void write_pixel_16(BYTE* _buf, UINT16 _pix)
|
|||||||
#undef DESTWRITEPIXEL
|
#undef DESTWRITEPIXEL
|
||||||
#undef DESTREADPIXEL
|
#undef DESTREADPIXEL
|
||||||
#undef SRCREADPIXEL
|
#undef SRCREADPIXEL
|
||||||
#undef DESTNEXTPIXEL
|
|
||||||
#undef SRCNEXTPIXEL
|
|
||||||
#undef WRITEFGBGIMAGE
|
#undef WRITEFGBGIMAGE
|
||||||
#undef WRITEFIRSTLINEFGBGIMAGE
|
#undef WRITEFIRSTLINEFGBGIMAGE
|
||||||
#undef RLEDECOMPRESS
|
#undef RLEDECOMPRESS
|
||||||
#undef RLEEXTRA
|
#undef RLEEXTRA
|
||||||
#undef WHITE_PIXEL
|
#undef WHITE_PIXEL
|
||||||
|
#undef PIXEL_SIZE
|
||||||
|
#undef PIXEL
|
||||||
|
#define PIXEL_SIZE 2
|
||||||
|
#define PIXEL UINT16
|
||||||
#define WHITE_PIXEL 0xFFFF
|
#define WHITE_PIXEL 0xFFFF
|
||||||
#define DESTWRITEPIXEL(_buf, _pix) write_pixel_16(_buf, _pix)
|
#define DESTWRITEPIXEL(_buf, _pix) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
write_pixel_16(_buf, _pix); \
|
||||||
|
_buf += 2; \
|
||||||
|
} while (0)
|
||||||
#define DESTREADPIXEL(_pix, _buf) _pix = ((UINT16*)(_buf))[0]
|
#define DESTREADPIXEL(_pix, _buf) _pix = ((UINT16*)(_buf))[0]
|
||||||
#define SRCREADPIXEL(_pix, _buf) _pix = (_buf)[0] | ((_buf)[1] << 8)
|
#define SRCREADPIXEL(_pix, _buf) \
|
||||||
#define DESTNEXTPIXEL(_buf) _buf += 2
|
do \
|
||||||
#define SRCNEXTPIXEL(_buf) _buf += 2
|
{ \
|
||||||
|
_pix = (_buf)[0] | ((_buf)[1] << 8); \
|
||||||
|
_buf += 2; \
|
||||||
|
} while (0)
|
||||||
#define WRITEFGBGIMAGE WriteFgBgImage16to16
|
#define WRITEFGBGIMAGE WriteFgBgImage16to16
|
||||||
#define WRITEFIRSTLINEFGBGIMAGE WriteFirstLineFgBgImage16to16
|
#define WRITEFIRSTLINEFGBGIMAGE WriteFirstLineFgBgImage16to16
|
||||||
#define RLEDECOMPRESS RleDecompress16to16
|
#define RLEDECOMPRESS RleDecompress16to16
|
||||||
@ -287,19 +485,30 @@ static INLINE void write_pixel_16(BYTE* _buf, UINT16 _pix)
|
|||||||
#undef DESTWRITEPIXEL
|
#undef DESTWRITEPIXEL
|
||||||
#undef DESTREADPIXEL
|
#undef DESTREADPIXEL
|
||||||
#undef SRCREADPIXEL
|
#undef SRCREADPIXEL
|
||||||
#undef DESTNEXTPIXEL
|
|
||||||
#undef SRCNEXTPIXEL
|
|
||||||
#undef WRITEFGBGIMAGE
|
#undef WRITEFGBGIMAGE
|
||||||
#undef WRITEFIRSTLINEFGBGIMAGE
|
#undef WRITEFIRSTLINEFGBGIMAGE
|
||||||
#undef RLEDECOMPRESS
|
#undef RLEDECOMPRESS
|
||||||
#undef RLEEXTRA
|
#undef RLEEXTRA
|
||||||
#undef WHITE_PIXEL
|
#undef WHITE_PIXEL
|
||||||
#define WHITE_PIXEL 0xFFFFFF
|
#undef PIXEL_SIZE
|
||||||
#define DESTWRITEPIXEL(_buf, _pix) write_pixel_24(_buf, _pix)
|
#undef PIXEL
|
||||||
|
#define PIXEL_SIZE 3
|
||||||
|
#define PIXEL UINT32
|
||||||
|
#define WHITE_PIXEL 0xffffff
|
||||||
|
#define DESTWRITEPIXEL(_buf, _pix) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
write_pixel_24(_buf, _pix); \
|
||||||
|
_buf += 3; \
|
||||||
|
} while (0)
|
||||||
#define DESTREADPIXEL(_pix, _buf) _pix = (_buf)[0] | ((_buf)[1] << 8) | ((_buf)[2] << 16)
|
#define DESTREADPIXEL(_pix, _buf) _pix = (_buf)[0] | ((_buf)[1] << 8) | ((_buf)[2] << 16)
|
||||||
#define SRCREADPIXEL(_pix, _buf) _pix = (_buf)[0] | ((_buf)[1] << 8) | ((_buf)[2] << 16)
|
#define SRCREADPIXEL(_pix, _buf) \
|
||||||
#define DESTNEXTPIXEL(_buf) _buf += 3
|
do \
|
||||||
#define SRCNEXTPIXEL(_buf) _buf += 3
|
{ \
|
||||||
|
_pix = (_buf)[0] | ((_buf)[1] << 8) | ((_buf)[2] << 16); \
|
||||||
|
_buf += 3; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define WRITEFGBGIMAGE WriteFgBgImage24to24
|
#define WRITEFGBGIMAGE WriteFgBgImage24to24
|
||||||
#define WRITEFIRSTLINEFGBGIMAGE WriteFirstLineFgBgImage24to24
|
#define WRITEFIRSTLINEFGBGIMAGE WriteFirstLineFgBgImage24to24
|
||||||
#define RLEDECOMPRESS RleDecompress24to24
|
#define RLEDECOMPRESS RleDecompress24to24
|
||||||
@ -308,18 +517,32 @@ static INLINE void write_pixel_16(BYTE* _buf, UINT16 _pix)
|
|||||||
#define ENSURE_CAPACITY(_start, _end, _size) ensure_capacity(_start, _end, _size, 3)
|
#define ENSURE_CAPACITY(_start, _end, _size) ensure_capacity(_start, _end, _size, 3)
|
||||||
#include "include/bitmap.c"
|
#include "include/bitmap.c"
|
||||||
|
|
||||||
|
struct S_BITMAP_INTERLEAVED_CONTEXT
|
||||||
|
{
|
||||||
|
BOOL Compressor;
|
||||||
|
|
||||||
|
UINT32 TempSize;
|
||||||
|
BYTE* TempBuffer;
|
||||||
|
|
||||||
|
wStream* bts;
|
||||||
|
};
|
||||||
|
|
||||||
BOOL interleaved_decompress(BITMAP_INTERLEAVED_CONTEXT* interleaved, const BYTE* pSrcData,
|
BOOL interleaved_decompress(BITMAP_INTERLEAVED_CONTEXT* interleaved, const BYTE* pSrcData,
|
||||||
UINT32 SrcSize, UINT32 nSrcWidth, UINT32 nSrcHeight, UINT32 bpp,
|
UINT32 SrcSize, UINT32 nSrcWidth, UINT32 nSrcHeight, UINT32 bpp,
|
||||||
BYTE* pDstData, UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst,
|
BYTE* pDstData, UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst,
|
||||||
UINT32 nYDst, UINT32 nDstWidth, UINT32 nDstHeight,
|
UINT32 nYDst, UINT32 nDstWidth, UINT32 nDstHeight,
|
||||||
const gdiPalette* palette)
|
const gdiPalette* palette)
|
||||||
{
|
{
|
||||||
UINT32 scanline;
|
UINT32 scanline = 0;
|
||||||
UINT32 SrcFormat;
|
UINT32 SrcFormat = 0;
|
||||||
UINT32 BufferSize;
|
UINT32 BufferSize = 0;
|
||||||
|
|
||||||
if (!interleaved || !pSrcData || !pDstData)
|
if (!interleaved || !pSrcData || !pDstData)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "invalid arguments: interleaved=%p, pSrcData=%p, pDstData=%p", interleaved,
|
||||||
|
pSrcData, pDstData);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
switch (bpp)
|
switch (bpp)
|
||||||
{
|
{
|
||||||
@ -352,19 +575,26 @@ BOOL interleaved_decompress(BITMAP_INTERLEAVED_CONTEXT* interleaved, const BYTE*
|
|||||||
|
|
||||||
if (BufferSize > interleaved->TempSize)
|
if (BufferSize > interleaved->TempSize)
|
||||||
{
|
{
|
||||||
interleaved->TempBuffer = _aligned_realloc(interleaved->TempBuffer, BufferSize, 16);
|
interleaved->TempBuffer =
|
||||||
|
_aligned_recalloc(interleaved->TempBuffer, BufferSize, sizeof(BYTE), 16);
|
||||||
interleaved->TempSize = BufferSize;
|
interleaved->TempSize = BufferSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!interleaved->TempBuffer)
|
if (!interleaved->TempBuffer)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "interleaved->TempBuffer=%p", interleaved->TempBuffer);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
switch (bpp)
|
switch (bpp)
|
||||||
{
|
{
|
||||||
case 24:
|
case 24:
|
||||||
if (!RleDecompress24to24(pSrcData, SrcSize, interleaved->TempBuffer, scanline,
|
if (!RleDecompress24to24(pSrcData, SrcSize, interleaved->TempBuffer, scanline,
|
||||||
nSrcWidth, nSrcHeight))
|
nSrcWidth, nSrcHeight))
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "RleDecompress24to24 failed");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -372,24 +602,36 @@ BOOL interleaved_decompress(BITMAP_INTERLEAVED_CONTEXT* interleaved, const BYTE*
|
|||||||
case 15:
|
case 15:
|
||||||
if (!RleDecompress16to16(pSrcData, SrcSize, interleaved->TempBuffer, scanline,
|
if (!RleDecompress16to16(pSrcData, SrcSize, interleaved->TempBuffer, scanline,
|
||||||
nSrcWidth, nSrcHeight))
|
nSrcWidth, nSrcHeight))
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "RleDecompress16to16 failed");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 8:
|
case 8:
|
||||||
if (!RleDecompress8to8(pSrcData, SrcSize, interleaved->TempBuffer, scanline, nSrcWidth,
|
if (!RleDecompress8to8(pSrcData, SrcSize, interleaved->TempBuffer, scanline, nSrcWidth,
|
||||||
nSrcHeight))
|
nSrcHeight))
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "RleDecompress8to8 failed");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
WLog_ERR(TAG, "Invalid color depth %" PRIu32 "", bpp);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return freerdp_image_copy(pDstData, DstFormat, nDstStep, nXDst, nYDst, nDstWidth, nDstHeight,
|
if (!freerdp_image_copy(pDstData, DstFormat, nDstStep, nXDst, nYDst, nDstWidth, nDstHeight,
|
||||||
interleaved->TempBuffer, SrcFormat, scanline, 0, 0, palette,
|
interleaved->TempBuffer, SrcFormat, scanline, 0, 0, palette,
|
||||||
FREERDP_FLIP_VERTICAL);
|
FREERDP_FLIP_VERTICAL))
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "freerdp_image_copy failed");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL interleaved_compress(BITMAP_INTERLEAVED_CONTEXT* interleaved, BYTE* pDstData, UINT32* pDstSize,
|
BOOL interleaved_compress(BITMAP_INTERLEAVED_CONTEXT* interleaved, BYTE* pDstData, UINT32* pDstSize,
|
||||||
@ -397,10 +639,10 @@ BOOL interleaved_compress(BITMAP_INTERLEAVED_CONTEXT* interleaved, BYTE* pDstDat
|
|||||||
UINT32 nSrcStep, UINT32 nXSrc, UINT32 nYSrc, const gdiPalette* palette,
|
UINT32 nSrcStep, UINT32 nXSrc, UINT32 nYSrc, const gdiPalette* palette,
|
||||||
UINT32 bpp)
|
UINT32 bpp)
|
||||||
{
|
{
|
||||||
BOOL status;
|
BOOL status = 0;
|
||||||
wStream* s;
|
wStream* s = NULL;
|
||||||
UINT32 DstFormat = 0;
|
UINT32 DstFormat = 0;
|
||||||
const size_t maxSize = 64 * 64 * 4;
|
const UINT32 maxSize = 64 * 64 * 4;
|
||||||
|
|
||||||
if (!interleaved || !pDstData || !pSrcData)
|
if (!interleaved || !pDstData || !pSrcData)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -442,7 +684,7 @@ BOOL interleaved_compress(BITMAP_INTERLEAVED_CONTEXT* interleaved, BYTE* pDstDat
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!freerdp_image_copy(interleaved->TempBuffer, DstFormat, 0, 0, 0, nWidth, nHeight, pSrcData,
|
if (!freerdp_image_copy(interleaved->TempBuffer, DstFormat, 0, 0, 0, nWidth, nHeight, pSrcData,
|
||||||
SrcFormat, nSrcStep, nXSrc, nYSrc, palette, FREERDP_FLIP_NONE))
|
SrcFormat, nSrcStep, nXSrc, nYSrc, palette, 0))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
s = Stream_New(pDstData, *pDstSize);
|
s = Stream_New(pDstData, *pDstSize);
|
||||||
@ -474,33 +716,29 @@ BOOL bitmap_interleaved_context_reset(BITMAP_INTERLEAVED_CONTEXT* interleaved)
|
|||||||
|
|
||||||
BITMAP_INTERLEAVED_CONTEXT* bitmap_interleaved_context_new(BOOL Compressor)
|
BITMAP_INTERLEAVED_CONTEXT* bitmap_interleaved_context_new(BOOL Compressor)
|
||||||
{
|
{
|
||||||
BITMAP_INTERLEAVED_CONTEXT* interleaved;
|
BITMAP_INTERLEAVED_CONTEXT* interleaved = NULL;
|
||||||
interleaved = (BITMAP_INTERLEAVED_CONTEXT*)calloc(1, sizeof(BITMAP_INTERLEAVED_CONTEXT));
|
interleaved = (BITMAP_INTERLEAVED_CONTEXT*)_aligned_recalloc(
|
||||||
|
NULL, 1, sizeof(BITMAP_INTERLEAVED_CONTEXT), 32);
|
||||||
|
|
||||||
if (interleaved)
|
if (interleaved)
|
||||||
{
|
{
|
||||||
interleaved->TempSize = 64 * 64 * 4;
|
interleaved->TempSize = 64 * 64 * 4;
|
||||||
interleaved->TempBuffer = _aligned_malloc(interleaved->TempSize, 16);
|
interleaved->TempBuffer = _aligned_malloc(interleaved->TempSize * sizeof(BYTE), 16);
|
||||||
|
|
||||||
if (!interleaved->TempBuffer)
|
if (!interleaved->TempBuffer)
|
||||||
{
|
goto fail;
|
||||||
free(interleaved);
|
|
||||||
WLog_ERR(TAG, "_aligned_malloc failed!");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
interleaved->bts = Stream_New(NULL, interleaved->TempSize);
|
interleaved->bts = Stream_New(NULL, interleaved->TempSize);
|
||||||
|
|
||||||
if (!interleaved->bts)
|
if (!interleaved->bts)
|
||||||
{
|
goto fail;
|
||||||
_aligned_free(interleaved->TempBuffer);
|
|
||||||
free(interleaved);
|
|
||||||
WLog_ERR(TAG, "Stream_New failed!");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return interleaved;
|
return interleaved;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
bitmap_interleaved_context_free(interleaved);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bitmap_interleaved_context_free(BITMAP_INTERLEAVED_CONTEXT* interleaved)
|
void bitmap_interleaved_context_free(BITMAP_INTERLEAVED_CONTEXT* interleaved)
|
||||||
@ -510,5 +748,5 @@ void bitmap_interleaved_context_free(BITMAP_INTERLEAVED_CONTEXT* interleaved)
|
|||||||
|
|
||||||
_aligned_free(interleaved->TempBuffer);
|
_aligned_free(interleaved->TempBuffer);
|
||||||
Stream_Free(interleaved->bts, TRUE);
|
Stream_Free(interleaved->bts, TRUE);
|
||||||
free(interleaved);
|
_aligned_free(interleaved);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1994,15 +1994,9 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
|||||||
UINT32* pDstSize, UINT32 flags)
|
UINT32* pDstSize, UINT32 flags)
|
||||||
{
|
{
|
||||||
UINT32 index;
|
UINT32 index;
|
||||||
UINT32 bits;
|
|
||||||
INT32 nbits;
|
|
||||||
const BYTE* SrcPtr;
|
|
||||||
const BYTE* SrcEnd;
|
|
||||||
UINT16 Mask;
|
|
||||||
BYTE Literal;
|
BYTE Literal;
|
||||||
UINT32 IndexLEC;
|
UINT32 IndexLEC;
|
||||||
UINT32 BitLength;
|
UINT32 BitLength;
|
||||||
UINT32 MaskedBits;
|
|
||||||
UINT32 CopyOffset;
|
UINT32 CopyOffset;
|
||||||
UINT32 CopyLength;
|
UINT32 CopyLength;
|
||||||
UINT32 OldCopyOffset;
|
UINT32 OldCopyOffset;
|
||||||
@ -2010,9 +2004,6 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
|||||||
UINT32 LengthOfMatch;
|
UINT32 LengthOfMatch;
|
||||||
UINT32 CopyOffsetIndex;
|
UINT32 CopyOffsetIndex;
|
||||||
UINT32 OffsetCacheIndex;
|
UINT32 OffsetCacheIndex;
|
||||||
BYTE* HistoryPtr;
|
|
||||||
BYTE* HistoryBuffer;
|
|
||||||
BYTE* HistoryBufferEnd;
|
|
||||||
UINT32 CopyOffsetBits;
|
UINT32 CopyOffsetBits;
|
||||||
UINT32 CopyOffsetBase;
|
UINT32 CopyOffsetBase;
|
||||||
UINT32 LengthOfMatchBits;
|
UINT32 LengthOfMatchBits;
|
||||||
@ -2021,8 +2012,8 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
|||||||
if (ncrush->HistoryEndOffset != 65535)
|
if (ncrush->HistoryEndOffset != 65535)
|
||||||
return -1001;
|
return -1001;
|
||||||
|
|
||||||
HistoryBuffer = ncrush->HistoryBuffer;
|
BYTE* HistoryBuffer = ncrush->HistoryBuffer;
|
||||||
HistoryBufferEnd = &HistoryBuffer[ncrush->HistoryEndOffset];
|
const BYTE* HistoryBufferEnd = &HistoryBuffer[ncrush->HistoryEndOffset];
|
||||||
|
|
||||||
if (flags & PACKET_AT_FRONT)
|
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));
|
ZeroMemory(&(ncrush->OffsetCache), sizeof(ncrush->OffsetCache));
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryPtr = ncrush->HistoryPtr;
|
BYTE* HistoryPtr = ncrush->HistoryPtr;
|
||||||
|
|
||||||
if (!(flags & PACKET_COMPRESSED))
|
if (!(flags & PACKET_COMPRESSED))
|
||||||
{
|
{
|
||||||
@ -2050,17 +2041,25 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrcEnd = &pSrcData[SrcSize];
|
if (SrcSize < 4)
|
||||||
nbits = 32;
|
{
|
||||||
bits = get_dword(pSrcData);
|
WLog_ERR(TAG, "Input size short: SrcSize %" PRIu32 " < 4", SrcSize);
|
||||||
SrcPtr = pSrcData + 4;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const BYTE* SrcEnd = &pSrcData[SrcSize];
|
||||||
|
const BYTE* SrcPtr = pSrcData + 4;
|
||||||
|
|
||||||
|
INT32 nbits = 32;
|
||||||
|
UINT32 bits = get_dword(pSrcData);
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
Mask = get_word(&HuffTableMask[29]);
|
const UINT16 Mask = get_word(&HuffTableMask[29]);
|
||||||
MaskedBits = bits & Mask;
|
const UINT32 MaskedBits = bits & Mask;
|
||||||
|
if (MaskedBits >= ARRAYSIZE(HuffTableLEC))
|
||||||
|
return -1;
|
||||||
IndexLEC = HuffTableLEC[MaskedBits] & 0xFFF;
|
IndexLEC = HuffTableLEC[MaskedBits] & 0xFFF;
|
||||||
BitLength = HuffTableLEC[MaskedBits] >> 12;
|
BitLength = HuffTableLEC[MaskedBits] >> 12;
|
||||||
bits >>= BitLength;
|
bits >>= BitLength;
|
||||||
@ -2096,8 +2095,10 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
|||||||
return -1004;
|
return -1004;
|
||||||
|
|
||||||
CopyOffset = ncrush->OffsetCache[OffsetCacheIndex];
|
CopyOffset = ncrush->OffsetCache[OffsetCacheIndex];
|
||||||
Mask = get_word(&HuffTableMask[21]);
|
const UINT16 Mask = get_word(&HuffTableMask[21]);
|
||||||
MaskedBits = bits & Mask;
|
const UINT32 MaskedBits = bits & Mask;
|
||||||
|
if (MaskedBits > ARRAYSIZE(HuffTableLOM))
|
||||||
|
return -1;
|
||||||
LengthOfMatch = HuffTableLOM[MaskedBits] & 0xFFF;
|
LengthOfMatch = HuffTableLOM[MaskedBits] & 0xFFF;
|
||||||
BitLength = HuffTableLOM[MaskedBits] >> 12;
|
BitLength = HuffTableLOM[MaskedBits] >> 12;
|
||||||
bits >>= BitLength;
|
bits >>= BitLength;
|
||||||
@ -2106,13 +2107,23 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
|||||||
if (!NCrushFetchBits(&SrcPtr, &SrcEnd, &nbits, &bits))
|
if (!NCrushFetchBits(&SrcPtr, &SrcEnd, &nbits, &bits))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (LengthOfMatch >= ARRAYSIZE(LOMBitsLUT))
|
||||||
|
return -1;
|
||||||
|
|
||||||
LengthOfMatchBits = LOMBitsLUT[LengthOfMatch];
|
LengthOfMatchBits = LOMBitsLUT[LengthOfMatch];
|
||||||
|
|
||||||
|
if (LengthOfMatch >= ARRAYSIZE(LOMBaseLUT))
|
||||||
|
return -1;
|
||||||
LengthOfMatchBase = LOMBaseLUT[LengthOfMatch];
|
LengthOfMatchBase = LOMBaseLUT[LengthOfMatch];
|
||||||
|
|
||||||
if (LengthOfMatchBits)
|
if (LengthOfMatchBits)
|
||||||
{
|
{
|
||||||
Mask = get_word(&HuffTableMask[(2 * LengthOfMatchBits) + 3]);
|
const size_t idx = (2ull * LengthOfMatchBits) + 3ull;
|
||||||
MaskedBits = bits & Mask;
|
if (idx >= ARRAYSIZE(HuffTableMask))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
const UINT16 Mask = get_word(&HuffTableMask[idx]);
|
||||||
|
const UINT32 MaskedBits = bits & Mask;
|
||||||
bits >>= LengthOfMatchBits;
|
bits >>= LengthOfMatchBits;
|
||||||
nbits -= LengthOfMatchBits;
|
nbits -= LengthOfMatchBits;
|
||||||
LengthOfMatchBase += MaskedBits;
|
LengthOfMatchBase += MaskedBits;
|
||||||
@ -2127,15 +2138,28 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (CopyOffsetIndex >= ARRAYSIZE(CopyOffsetBitsLUT))
|
||||||
|
return -1;
|
||||||
|
|
||||||
CopyOffsetBits = CopyOffsetBitsLUT[CopyOffsetIndex];
|
CopyOffsetBits = CopyOffsetBitsLUT[CopyOffsetIndex];
|
||||||
|
|
||||||
|
if (CopyOffsetIndex >= ARRAYSIZE(CopyOffsetBaseLUT))
|
||||||
|
return -1;
|
||||||
CopyOffsetBase = CopyOffsetBaseLUT[CopyOffsetIndex];
|
CopyOffsetBase = CopyOffsetBaseLUT[CopyOffsetIndex];
|
||||||
CopyOffset = CopyOffsetBase - 1;
|
CopyOffset = CopyOffsetBase - 1;
|
||||||
|
|
||||||
if (CopyOffsetBits)
|
if (CopyOffsetBits)
|
||||||
{
|
{
|
||||||
Mask = get_word(&HuffTableMask[(2 * CopyOffsetBits) + 3]);
|
const size_t idx = (2ull * CopyOffsetBits) + 3ull;
|
||||||
MaskedBits = bits & Mask;
|
if (idx >= ARRAYSIZE(HuffTableMask))
|
||||||
CopyOffset = CopyOffsetBase + MaskedBits - 1;
|
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;
|
bits >>= CopyOffsetBits;
|
||||||
nbits -= CopyOffsetBits;
|
nbits -= CopyOffsetBits;
|
||||||
|
|
||||||
@ -2143,8 +2167,11 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mask = get_word(&HuffTableMask[21]);
|
const UINT16 Mask = get_word(&HuffTableMask[21]);
|
||||||
MaskedBits = bits & Mask;
|
const UINT32 MaskedBits = bits & Mask;
|
||||||
|
if (MaskedBits >= ARRAYSIZE(HuffTableLOM))
|
||||||
|
return -1;
|
||||||
|
|
||||||
LengthOfMatch = HuffTableLOM[MaskedBits] & 0xFFF;
|
LengthOfMatch = HuffTableLOM[MaskedBits] & 0xFFF;
|
||||||
BitLength = HuffTableLOM[MaskedBits] >> 12;
|
BitLength = HuffTableLOM[MaskedBits] >> 12;
|
||||||
bits >>= BitLength;
|
bits >>= BitLength;
|
||||||
@ -2153,13 +2180,23 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
|||||||
if (!NCrushFetchBits(&SrcPtr, &SrcEnd, &nbits, &bits))
|
if (!NCrushFetchBits(&SrcPtr, &SrcEnd, &nbits, &bits))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (LengthOfMatch >= ARRAYSIZE(LOMBitsLUT))
|
||||||
|
return -1;
|
||||||
|
|
||||||
LengthOfMatchBits = LOMBitsLUT[LengthOfMatch];
|
LengthOfMatchBits = LOMBitsLUT[LengthOfMatch];
|
||||||
|
|
||||||
|
if (LengthOfMatch >= ARRAYSIZE(LOMBaseLUT))
|
||||||
|
return -1;
|
||||||
LengthOfMatchBase = LOMBaseLUT[LengthOfMatch];
|
LengthOfMatchBase = LOMBaseLUT[LengthOfMatch];
|
||||||
|
|
||||||
if (LengthOfMatchBits)
|
if (LengthOfMatchBits)
|
||||||
{
|
{
|
||||||
Mask = get_word(&HuffTableMask[(2 * LengthOfMatchBits) + 3]);
|
const size_t idx = (2ull * LengthOfMatchBits) + 3ull;
|
||||||
MaskedBits = bits & Mask;
|
if (idx >= ARRAYSIZE(HuffTableMask))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
const UINT16 Mask = get_word(&HuffTableMask[idx]);
|
||||||
|
const UINT32 MaskedBits = bits & Mask;
|
||||||
bits >>= LengthOfMatchBits;
|
bits >>= LengthOfMatchBits;
|
||||||
nbits -= LengthOfMatchBits;
|
nbits -= LengthOfMatchBits;
|
||||||
LengthOfMatchBase += MaskedBits;
|
LengthOfMatchBase += MaskedBits;
|
||||||
@ -2583,7 +2620,12 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE
|
|||||||
}
|
}
|
||||||
|
|
||||||
IndexLEC = Literal;
|
IndexLEC = Literal;
|
||||||
|
if (IndexLEC >= ARRAYSIZE(HuffLengthLEC))
|
||||||
|
return -1;
|
||||||
BitLength = HuffLengthLEC[IndexLEC];
|
BitLength = HuffLengthLEC[IndexLEC];
|
||||||
|
|
||||||
|
if (IndexLEC * 2ull >= ARRAYSIZE(HuffCodeLEC))
|
||||||
|
return -1;
|
||||||
CodeLEC = get_word(&HuffCodeLEC[IndexLEC * 2]);
|
CodeLEC = get_word(&HuffCodeLEC[IndexLEC * 2]);
|
||||||
|
|
||||||
if (BitLength > 15)
|
if (BitLength > 15)
|
||||||
@ -2666,9 +2708,18 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE
|
|||||||
bits = CopyOffset;
|
bits = CopyOffset;
|
||||||
|
|
||||||
CopyOffsetIndex = ncrush->HuffTableCopyOffset[bits + 2];
|
CopyOffsetIndex = ncrush->HuffTableCopyOffset[bits + 2];
|
||||||
|
|
||||||
|
if (CopyOffsetIndex >= ARRAYSIZE(CopyOffsetBitsLUT))
|
||||||
|
return -1;
|
||||||
|
|
||||||
CopyOffsetBits = CopyOffsetBitsLUT[CopyOffsetIndex];
|
CopyOffsetBits = CopyOffsetBitsLUT[CopyOffsetIndex];
|
||||||
IndexLEC = 257 + CopyOffsetIndex;
|
IndexLEC = 257 + CopyOffsetIndex;
|
||||||
|
if (IndexLEC >= ARRAYSIZE(HuffLengthLEC))
|
||||||
|
return -1;
|
||||||
BitLength = HuffLengthLEC[IndexLEC];
|
BitLength = HuffLengthLEC[IndexLEC];
|
||||||
|
|
||||||
|
if (IndexLEC * 2ull >= ARRAYSIZE(HuffCodeLEC))
|
||||||
|
return -1;
|
||||||
CodeLEC = get_word(&HuffCodeLEC[IndexLEC * 2]);
|
CodeLEC = get_word(&HuffCodeLEC[IndexLEC * 2]);
|
||||||
|
|
||||||
if (BitLength > 15)
|
if (BitLength > 15)
|
||||||
@ -2687,13 +2738,23 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE
|
|||||||
else
|
else
|
||||||
IndexCO = ncrush->HuffTableLOM[MatchLength];
|
IndexCO = ncrush->HuffTableLOM[MatchLength];
|
||||||
|
|
||||||
|
if (IndexCO >= ARRAYSIZE(HuffLengthLOM))
|
||||||
|
return -1;
|
||||||
BitLength = HuffLengthLOM[IndexCO];
|
BitLength = HuffLengthLOM[IndexCO];
|
||||||
|
|
||||||
|
if (IndexCO >= ARRAYSIZE(LOMBitsLUT))
|
||||||
|
return -1;
|
||||||
IndexLOM = LOMBitsLUT[IndexCO];
|
IndexLOM = LOMBitsLUT[IndexCO];
|
||||||
|
|
||||||
|
if (IndexCO >= ARRAYSIZE(HuffCodeLOM))
|
||||||
|
return -1;
|
||||||
NCrushWriteBits(&DstPtr, &accumulator, &offset, HuffCodeLOM[IndexCO], BitLength);
|
NCrushWriteBits(&DstPtr, &accumulator, &offset, HuffCodeLOM[IndexCO], BitLength);
|
||||||
Mask = ((1 << IndexLOM) - 1);
|
Mask = ((1 << IndexLOM) - 1);
|
||||||
MaskedBits = (MatchLength - 2) & Mask;
|
MaskedBits = (MatchLength - 2) & Mask;
|
||||||
NCrushWriteBits(&DstPtr, &accumulator, &offset, MaskedBits, IndexLOM);
|
NCrushWriteBits(&DstPtr, &accumulator, &offset, MaskedBits, IndexLOM);
|
||||||
|
|
||||||
|
if (IndexCO >= ARRAYSIZE(LOMBaseLUT))
|
||||||
|
return -1;
|
||||||
if ((MaskedBits + LOMBaseLUT[IndexCO]) != MatchLength)
|
if ((MaskedBits + LOMBaseLUT[IndexCO]) != MatchLength)
|
||||||
return -1010;
|
return -1010;
|
||||||
}
|
}
|
||||||
@ -2701,7 +2762,11 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE
|
|||||||
{
|
{
|
||||||
/* CopyOffset in OffsetCache */
|
/* CopyOffset in OffsetCache */
|
||||||
IndexLEC = 289 + OffsetCacheIndex;
|
IndexLEC = 289 + OffsetCacheIndex;
|
||||||
|
if (IndexLEC >= ARRAYSIZE(HuffLengthLEC))
|
||||||
|
return -1;
|
||||||
BitLength = HuffLengthLEC[IndexLEC];
|
BitLength = HuffLengthLEC[IndexLEC];
|
||||||
|
if (IndexLEC * 2ull >= ARRAYSIZE(HuffCodeLEC))
|
||||||
|
return -1;
|
||||||
CodeLEC = get_word(&HuffCodeLEC[IndexLEC * 2]);
|
CodeLEC = get_word(&HuffCodeLEC[IndexLEC * 2]);
|
||||||
|
|
||||||
if (BitLength >= 15)
|
if (BitLength >= 15)
|
||||||
@ -2714,13 +2779,24 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE
|
|||||||
else
|
else
|
||||||
IndexCO = ncrush->HuffTableLOM[MatchLength];
|
IndexCO = ncrush->HuffTableLOM[MatchLength];
|
||||||
|
|
||||||
|
if (IndexCO >= ARRAYSIZE(HuffLengthLOM))
|
||||||
|
return -1;
|
||||||
|
|
||||||
BitLength = HuffLengthLOM[IndexCO];
|
BitLength = HuffLengthLOM[IndexCO];
|
||||||
|
|
||||||
|
if (IndexCO >= ARRAYSIZE(LOMBitsLUT))
|
||||||
|
return -1;
|
||||||
IndexLOM = LOMBitsLUT[IndexCO];
|
IndexLOM = LOMBitsLUT[IndexCO];
|
||||||
|
|
||||||
|
if (IndexCO >= ARRAYSIZE(HuffCodeLOM))
|
||||||
|
return -1;
|
||||||
NCrushWriteBits(&DstPtr, &accumulator, &offset, HuffCodeLOM[IndexCO], BitLength);
|
NCrushWriteBits(&DstPtr, &accumulator, &offset, HuffCodeLOM[IndexCO], BitLength);
|
||||||
Mask = ((1 << IndexLOM) - 1);
|
Mask = ((1 << IndexLOM) - 1);
|
||||||
MaskedBits = (MatchLength - 2) & Mask;
|
MaskedBits = (MatchLength - 2) & Mask;
|
||||||
NCrushWriteBits(&DstPtr, &accumulator, &offset, MaskedBits, IndexLOM);
|
NCrushWriteBits(&DstPtr, &accumulator, &offset, MaskedBits, IndexLOM);
|
||||||
|
|
||||||
|
if (IndexCO >= ARRAYSIZE(LOMBaseLUT))
|
||||||
|
return -1;
|
||||||
if ((MaskedBits + LOMBaseLUT[IndexCO]) != MatchLength)
|
if ((MaskedBits + LOMBaseLUT[IndexCO]) != MatchLength)
|
||||||
return -1012;
|
return -1012;
|
||||||
}
|
}
|
||||||
@ -2745,6 +2821,10 @@ int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE
|
|||||||
Literal = *SrcPtr++;
|
Literal = *SrcPtr++;
|
||||||
HistoryPtr++;
|
HistoryPtr++;
|
||||||
IndexLEC = Literal;
|
IndexLEC = Literal;
|
||||||
|
if (IndexLEC >= ARRAYSIZE(HuffLengthLEC))
|
||||||
|
return -1;
|
||||||
|
if (IndexLEC * 2ull >= ARRAYSIZE(HuffCodeLEC))
|
||||||
|
return -1;
|
||||||
BitLength = HuffLengthLEC[IndexLEC];
|
BitLength = HuffLengthLEC[IndexLEC];
|
||||||
CodeLEC = get_word(&HuffCodeLEC[IndexLEC * 2]);
|
CodeLEC = get_word(&HuffCodeLEC[IndexLEC * 2]);
|
||||||
|
|
||||||
@ -2817,6 +2897,11 @@ static int ncrush_generate_tables(NCRUSH_CONTEXT* context)
|
|||||||
else
|
else
|
||||||
i = context->HuffTableLOM[k];
|
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)
|
if (((((1 << LOMBitsLUT[i]) - 1) & (k - 2)) + LOMBaseLUT[i]) != k)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,6 +29,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <winpr/crt.h>
|
#include <winpr/crt.h>
|
||||||
|
#include <winpr/assert.h>
|
||||||
|
#include <winpr/stream.h>
|
||||||
|
|
||||||
#include <freerdp/codec/nsc.h>
|
#include <freerdp/codec/nsc.h>
|
||||||
#include <freerdp/codec/color.h>
|
#include <freerdp/codec/color.h>
|
||||||
@ -38,6 +40,12 @@
|
|||||||
|
|
||||||
#include "nsc_sse2.h"
|
#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
|
#ifndef NSC_INIT_SIMD
|
||||||
#define NSC_INIT_SIMD(_nsc_context) \
|
#define NSC_INIT_SIMD(_nsc_context) \
|
||||||
do \
|
do \
|
||||||
@ -87,8 +95,8 @@ static BOOL nsc_decode(NSC_CONTEXT* context)
|
|||||||
for (x = 0; x < context->width; x++)
|
for (x = 0; x < context->width; x++)
|
||||||
{
|
{
|
||||||
INT16 y_val = (INT16)*yplane;
|
INT16 y_val = (INT16)*yplane;
|
||||||
INT16 co_val = (INT16)(INT8)(*coplane << shift);
|
INT16 co_val = (INT16)(INT8)(((INT16)*coplane) << shift);
|
||||||
INT16 cg_val = (INT16)(INT8)(*cgplane << shift);
|
INT16 cg_val = (INT16)(INT8)(((INT16)*cgplane) << shift);
|
||||||
INT16 r_val = y_val + co_val - cg_val;
|
INT16 r_val = y_val + co_val - cg_val;
|
||||||
INT16 g_val = y_val + cg_val;
|
INT16 g_val = y_val + cg_val;
|
||||||
INT16 b_val = y_val - co_val - cg_val;
|
INT16 b_val = y_val - co_val - cg_val;
|
||||||
@ -111,12 +119,17 @@ static BOOL nsc_decode(NSC_CONTEXT* context)
|
|||||||
return TRUE;
|
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;
|
UINT32 left = originalSize;
|
||||||
|
|
||||||
while (left > 4)
|
while (left > 4)
|
||||||
{
|
{
|
||||||
|
if (inSize < 1)
|
||||||
|
return FALSE;
|
||||||
|
inSize--;
|
||||||
|
|
||||||
const BYTE value = *in++;
|
const BYTE value = *in++;
|
||||||
UINT32 len = 0;
|
UINT32 len = 0;
|
||||||
|
|
||||||
@ -129,17 +142,26 @@ static BOOL nsc_rle_decode(BYTE* in, BYTE* out, UINT32 outSize, UINT32 originalS
|
|||||||
*out++ = value;
|
*out++ = value;
|
||||||
left--;
|
left--;
|
||||||
}
|
}
|
||||||
|
else if (inSize < 1)
|
||||||
|
return FALSE;
|
||||||
else if (value == *in)
|
else if (value == *in)
|
||||||
{
|
{
|
||||||
|
inSize--;
|
||||||
in++;
|
in++;
|
||||||
|
|
||||||
if (*in < 0xFF)
|
if (inSize < 1)
|
||||||
|
return FALSE;
|
||||||
|
else if (*in < 0xFF)
|
||||||
{
|
{
|
||||||
|
inSize--;
|
||||||
len = (UINT32)*in++;
|
len = (UINT32)*in++;
|
||||||
len += 2;
|
len += 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (inSize < 5)
|
||||||
|
return FALSE;
|
||||||
|
inSize -= 5;
|
||||||
in++;
|
in++;
|
||||||
len = ((UINT32)(*in++));
|
len = ((UINT32)(*in++));
|
||||||
len |= ((UINT32)(*in++)) << 8U;
|
len |= ((UINT32)(*in++)) << 8U;
|
||||||
@ -147,7 +169,7 @@ static BOOL nsc_rle_decode(BYTE* in, BYTE* out, UINT32 outSize, UINT32 originalS
|
|||||||
len |= ((UINT32)(*in++)) << 24U;
|
len |= ((UINT32)(*in++)) << 24U;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outSize < len)
|
if ((outSize < len) || (left < len))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
outSize -= len;
|
outSize -= len;
|
||||||
@ -169,26 +191,28 @@ static BOOL nsc_rle_decode(BYTE* in, BYTE* out, UINT32 outSize, UINT32 originalS
|
|||||||
if ((outSize < 4) || (left < 4))
|
if ((outSize < 4) || (left < 4))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
if (inSize < 4)
|
||||||
|
return FALSE;
|
||||||
memcpy(out, in, 4);
|
memcpy(out, in, 4);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL nsc_rle_decompress_data(NSC_CONTEXT* context)
|
static BOOL nsc_rle_decompress_data(NSC_CONTEXT* context)
|
||||||
{
|
{
|
||||||
UINT16 i;
|
|
||||||
BYTE* rle;
|
|
||||||
UINT32 planeSize;
|
|
||||||
UINT32 originalSize;
|
|
||||||
|
|
||||||
if (!context)
|
if (!context)
|
||||||
return FALSE;
|
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];
|
const UINT32 originalSize = context->OrgByteCount[i];
|
||||||
planeSize = context->PlaneByteCount[i];
|
const UINT32 planeSize = context->PlaneByteCount[i];
|
||||||
|
|
||||||
|
if (rleSize < planeSize)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (planeSize == 0)
|
if (planeSize == 0)
|
||||||
{
|
{
|
||||||
@ -199,7 +223,7 @@ static BOOL nsc_rle_decompress_data(NSC_CONTEXT* context)
|
|||||||
}
|
}
|
||||||
else if (planeSize < originalSize)
|
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))
|
context->priv->PlaneBuffersLength, originalSize))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -208,6 +232,9 @@ static BOOL nsc_rle_decompress_data(NSC_CONTEXT* context)
|
|||||||
if (context->priv->PlaneBuffersLength < originalSize)
|
if (context->priv->PlaneBuffersLength < originalSize)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
if (rleSize < originalSize)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
CopyMemory(context->priv->PlaneBuffers[i], rle, originalSize);
|
CopyMemory(context->priv->PlaneBuffers[i], rle, originalSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,64 +246,71 @@ static BOOL nsc_rle_decompress_data(NSC_CONTEXT* context)
|
|||||||
|
|
||||||
static BOOL nsc_stream_initialize(NSC_CONTEXT* context, wStream* s)
|
static BOOL nsc_stream_initialize(NSC_CONTEXT* context, wStream* s)
|
||||||
{
|
{
|
||||||
int i;
|
WINPR_ASSERT(context);
|
||||||
|
WINPR_ASSERT(context->priv);
|
||||||
if (Stream_GetRemainingLength(s) < 20)
|
if (!Stream_CheckAndLogRequiredLengthWLog(context->priv->log, s, 20))
|
||||||
return FALSE;
|
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]);
|
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->ColorLossLevel); /* ColorLossLevel (1 byte) */
|
||||||
|
if ((context->ColorLossLevel < 1) || (context->ColorLossLevel > 7))
|
||||||
|
{
|
||||||
|
WLog_Print(context->priv->log, WLOG_ERROR,
|
||||||
|
"ColorLossLevel=%" PRIu8 " out of range, must be [1,7] inclusive",
|
||||||
|
context->ColorLossLevel);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
Stream_Read_UINT8(s, context->ChromaSubsamplingLevel); /* ChromaSubsamplingLevel (1 byte) */
|
Stream_Read_UINT8(s, context->ChromaSubsamplingLevel); /* ChromaSubsamplingLevel (1 byte) */
|
||||||
Stream_Seek(s, 2); /* Reserved (2 bytes) */
|
Stream_Seek(s, 2); /* Reserved (2 bytes) */
|
||||||
context->Planes = Stream_Pointer(s);
|
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)
|
static BOOL nsc_context_initialize(NSC_CONTEXT* context, wStream* s)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
UINT32 length;
|
|
||||||
UINT32 tempWidth;
|
|
||||||
UINT32 tempHeight;
|
|
||||||
|
|
||||||
if (!nsc_stream_initialize(context, s))
|
if (!nsc_stream_initialize(context, s))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
length = context->width * context->height * 4;
|
const size_t blength = context->width * context->height * 4ull;
|
||||||
|
|
||||||
if (!context->BitmapData)
|
if (!context->BitmapData)
|
||||||
{
|
{
|
||||||
context->BitmapData = calloc(1, length + 16);
|
context->BitmapData = calloc(1, blength + 16);
|
||||||
|
|
||||||
if (!context->BitmapData)
|
if (!context->BitmapData)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
context->BitmapDataLength = length;
|
context->BitmapDataLength = blength;
|
||||||
}
|
}
|
||||||
else if (length > context->BitmapDataLength)
|
else if (blength > context->BitmapDataLength)
|
||||||
{
|
{
|
||||||
void* tmp;
|
void* tmp;
|
||||||
tmp = realloc(context->BitmapData, length + 16);
|
tmp = realloc(context->BitmapData, blength + 16);
|
||||||
|
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
context->BitmapData = tmp;
|
context->BitmapData = tmp;
|
||||||
context->BitmapDataLength = length;
|
context->BitmapDataLength = blength;
|
||||||
}
|
}
|
||||||
|
|
||||||
tempWidth = ROUND_UP_TO(context->width, 8);
|
const UINT32 tempWidth = ROUND_UP_TO(context->width, 8);
|
||||||
tempHeight = ROUND_UP_TO(context->height, 2);
|
const UINT32 tempHeight = ROUND_UP_TO(context->height, 2);
|
||||||
/* The maximum length a decoded plane can reach in all cases */
|
/* 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)
|
if (!tmp)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -284,13 +318,11 @@ static BOOL nsc_context_initialize(NSC_CONTEXT* context, wStream* s)
|
|||||||
context->priv->PlaneBuffers[i] = tmp;
|
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;
|
context->OrgByteCount[i] = context->width * context->height;
|
||||||
}
|
|
||||||
|
|
||||||
if (context->ChromaSubsamplingLevel)
|
if (context->ChromaSubsamplingLevel)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -119,6 +119,8 @@ static BOOL nsc_encode_argb_to_aycocg(NSC_CONTEXT* context, const BYTE* data, UI
|
|||||||
UINT16 rw;
|
UINT16 rw;
|
||||||
BYTE ccl;
|
BYTE ccl;
|
||||||
const BYTE* src;
|
const BYTE* src;
|
||||||
|
const UINT32* src_32;
|
||||||
|
const UINT16* src_16;
|
||||||
BYTE* yplane = NULL;
|
BYTE* yplane = NULL;
|
||||||
BYTE* coplane = NULL;
|
BYTE* coplane = NULL;
|
||||||
BYTE* cgplane = 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;
|
coplane = context->priv->PlaneBuffers[1] + y * rw;
|
||||||
cgplane = context->priv->PlaneBuffers[2] + y * rw;
|
cgplane = context->priv->PlaneBuffers[2] + y * rw;
|
||||||
aplane = context->priv->PlaneBuffers[3] + y * context->width;
|
aplane = context->priv->PlaneBuffers[3] + y * context->width;
|
||||||
|
src_32 = (UINT32*)src;
|
||||||
|
src_16 = (UINT16*)src;
|
||||||
|
|
||||||
for (x = 0; x < context->width; x++)
|
for (x = 0; x < context->width; x++)
|
||||||
{
|
{
|
||||||
switch (context->format)
|
switch (context->format)
|
||||||
{
|
{
|
||||||
case PIXEL_FORMAT_BGRX32:
|
case PIXEL_FORMAT_BGRX32:
|
||||||
b_val = *src++;
|
b_val = (INT16)(*src_32 & 0xFF);
|
||||||
g_val = *src++;
|
g_val = (INT16)((*src_32 >> 8) & 0xFF);
|
||||||
r_val = *src++;
|
r_val = (INT16)((*src_32 >> 16) & 0xFF);
|
||||||
src++;
|
|
||||||
a_val = 0xFF;
|
a_val = 0xFF;
|
||||||
|
src_32++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PIXEL_FORMAT_BGRA32:
|
case PIXEL_FORMAT_BGRA32:
|
||||||
b_val = *src++;
|
b_val = (INT16)(*src_32 & 0xFF);
|
||||||
g_val = *src++;
|
g_val = (INT16)((*src_32 >> 8) & 0xFF);
|
||||||
r_val = *src++;
|
r_val = (INT16)((*src_32 >> 16) & 0xFF);
|
||||||
a_val = *src++;
|
a_val = (INT16)((*src_32 >> 24) & 0xFF);
|
||||||
|
src_32++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PIXEL_FORMAT_RGBX32:
|
case PIXEL_FORMAT_RGBX32:
|
||||||
r_val = *src++;
|
r_val = (INT16)(*src_32 & 0xFF);
|
||||||
g_val = *src++;
|
g_val = (INT16)((*src_32 >> 8) & 0xFF);
|
||||||
b_val = *src++;
|
b_val = (INT16)((*src_32 >> 16) & 0xFF);
|
||||||
src++;
|
|
||||||
a_val = 0xFF;
|
a_val = 0xFF;
|
||||||
|
src_32++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PIXEL_FORMAT_RGBA32:
|
case PIXEL_FORMAT_RGBA32:
|
||||||
r_val = *src++;
|
r_val = (INT16)(*src_32 & 0xFF);
|
||||||
g_val = *src++;
|
g_val = (INT16)((*src_32 >> 8) & 0xFF);
|
||||||
b_val = *src++;
|
b_val = (INT16)((*src_32 >> 16) & 0xFF);
|
||||||
a_val = *src++;
|
a_val = (INT16)((*src_32 >> 24) & 0xFF);
|
||||||
|
src_32++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PIXEL_FORMAT_BGR24:
|
case PIXEL_FORMAT_BGR24:
|
||||||
|
#ifdef __LITTLE_ENDIAN__
|
||||||
b_val = *src++;
|
b_val = *src++;
|
||||||
g_val = *src++;
|
g_val = *src++;
|
||||||
r_val = *src++;
|
r_val = *src++;
|
||||||
|
#else
|
||||||
|
r_val = *src++;
|
||||||
|
g_val = *src++;
|
||||||
|
b_val = *src++;
|
||||||
|
#endif
|
||||||
a_val = 0xFF;
|
a_val = 0xFF;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PIXEL_FORMAT_RGB24:
|
case PIXEL_FORMAT_RGB24:
|
||||||
|
#ifdef __LITTLE_ENDIAN__
|
||||||
r_val = *src++;
|
r_val = *src++;
|
||||||
g_val = *src++;
|
g_val = *src++;
|
||||||
b_val = *src++;
|
b_val = *src++;
|
||||||
|
#else
|
||||||
|
b_val = *src++;
|
||||||
|
g_val = *src++;
|
||||||
|
r_val = *src++;
|
||||||
|
#endif
|
||||||
a_val = 0xFF;
|
a_val = 0xFF;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PIXEL_FORMAT_BGR16:
|
case PIXEL_FORMAT_BGR16:
|
||||||
b_val = (INT16)(((*(src + 1)) & 0xF8) | ((*(src + 1)) >> 5));
|
b_val = (INT16)((*src_16) & 0x1F);
|
||||||
g_val = (INT16)((((*(src + 1)) & 0x07) << 5) | (((*src) & 0xE0) >> 3));
|
g_val = (INT16)((*src_16 >> 5) & 0x3F);
|
||||||
r_val = (INT16)((((*src) & 0x1F) << 3) | (((*src) >> 2) & 0x07));
|
r_val = (INT16)((*src_16 >> 11) & 0x1F);
|
||||||
a_val = 0xFF;
|
a_val = 0xFF;
|
||||||
src += 2;
|
src_16++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PIXEL_FORMAT_RGB16:
|
case PIXEL_FORMAT_RGB16:
|
||||||
r_val = (INT16)(((*(src + 1)) & 0xF8) | ((*(src + 1)) >> 5));
|
r_val = (INT16)((*src_16) & 0x1F);
|
||||||
g_val = (INT16)((((*(src + 1)) & 0x07) << 5) | (((*src) & 0xE0) >> 3));
|
g_val = (INT16)((*src_16 >> 5) & 0x3F);
|
||||||
b_val = (INT16)((((*src) & 0x1F) << 3) | (((*src) >> 2) & 0x07));
|
b_val = (INT16)((*src_16 >> 11) & 0x1F);
|
||||||
a_val = 0xFF;
|
a_val = 0xFF;
|
||||||
src += 2;
|
src_16++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PIXEL_FORMAT_A4:
|
case PIXEL_FORMAT_A4:
|
||||||
@ -210,17 +228,17 @@ static BOOL nsc_encode_argb_to_aycocg(NSC_CONTEXT* context, const BYTE* data, UI
|
|||||||
int shift;
|
int shift;
|
||||||
BYTE idx;
|
BYTE idx;
|
||||||
shift = (7 - (x % 8));
|
shift = (7 - (x % 8));
|
||||||
idx = ((*src) >> shift) & 1;
|
idx = (BYTE)(((*src_32 & 0xFF) >> shift) & 1);
|
||||||
idx |= (((*(src + 1)) >> shift) & 1) << 1;
|
idx |= (BYTE)(((((*src_32 >> 8) & 0xFF) >> shift) & 1) << 1);
|
||||||
idx |= (((*(src + 2)) >> shift) & 1) << 2;
|
idx |= (BYTE)(((((*src_32 >> 16) & 0xFF) >> shift) & 1) << 2);
|
||||||
idx |= (((*(src + 3)) >> shift) & 1) << 3;
|
idx |= (BYTE)(((((*src_32 >> 24) & 0xFF) >> shift) & 1) << 3);
|
||||||
idx *= 3;
|
idx *= 3;
|
||||||
r_val = (INT16)context->palette[idx];
|
r_val = (INT16)context->palette[idx];
|
||||||
g_val = (INT16)context->palette[idx + 1];
|
g_val = (INT16)context->palette[idx + 1];
|
||||||
b_val = (INT16)context->palette[idx + 2];
|
b_val = (INT16)context->palette[idx + 2];
|
||||||
|
|
||||||
if (shift == 0)
|
if (shift == 0)
|
||||||
src += 4;
|
src_32++;
|
||||||
}
|
}
|
||||||
|
|
||||||
a_val = 0xFF;
|
a_val = 0xFF;
|
||||||
|
|||||||
@ -61,6 +61,7 @@ struct _NSC_CONTEXT
|
|||||||
UINT32 BitmapDataLength;
|
UINT32 BitmapDataLength;
|
||||||
|
|
||||||
BYTE* Planes;
|
BYTE* Planes;
|
||||||
|
size_t PlanesSize;
|
||||||
UINT32 PlaneByteCount[4];
|
UINT32 PlaneByteCount[4];
|
||||||
UINT32 ColorLossLevel;
|
UINT32 ColorLossLevel;
|
||||||
UINT32 ChromaSubsamplingLevel;
|
UINT32 ChromaSubsamplingLevel;
|
||||||
|
|||||||
@ -33,7 +33,8 @@
|
|||||||
|
|
||||||
#define TAG FREERDP_TAG("codec")
|
#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,
|
static INLINE UINT32 planar_invert_format(BITMAP_PLANAR_CONTEXT* planar, BOOL alpha,
|
||||||
UINT32 DstFormat)
|
UINT32 DstFormat)
|
||||||
@ -612,11 +613,20 @@ BOOL planar_decompress(BITMAP_PLANAR_CONTEXT* planar, const BYTE* pSrcData, UINT
|
|||||||
const UINT32 h = MIN(nSrcHeight, nDstHeight);
|
const UINT32 h = MIN(nSrcHeight, nDstHeight);
|
||||||
const primitives_t* prims = primitives_get();
|
const primitives_t* prims = primitives_get();
|
||||||
|
|
||||||
|
WINPR_ASSERT(planar);
|
||||||
|
WINPR_ASSERT(prims);
|
||||||
|
|
||||||
if (nDstStep <= 0)
|
if (nDstStep <= 0)
|
||||||
nDstStep = nDstWidth * GetBytesPerPixel(DstFormat);
|
nDstStep = nDstWidth * GetBytesPerPixel(DstFormat);
|
||||||
|
|
||||||
srcp = pSrcData;
|
srcp = pSrcData;
|
||||||
|
|
||||||
|
if (!pSrcData)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "Invalid argument pSrcData=NULL");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (!pDstData)
|
if (!pDstData)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Invalid argument pDstData=NULL");
|
WLog_ERR(TAG, "Invalid argument pDstData=NULL");
|
||||||
@ -679,6 +689,13 @@ BOOL planar_decompress(BITMAP_PLANAR_CONTEXT* planar, const BYTE* pSrcData, UINT
|
|||||||
rawHeights[3] = nSrcHeight;
|
rawHeights[3] = nSrcHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const size_t diff = srcp - pSrcData;
|
||||||
|
if (SrcSize < diff)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "Size mismatch %" PRIu32 " < %" PRIuz, SrcSize, diff);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (!rle) /* RAW */
|
if (!rle) /* RAW */
|
||||||
{
|
{
|
||||||
UINT32 base = planeSize * 3;
|
UINT32 base = planeSize * 3;
|
||||||
@ -687,8 +704,12 @@ BOOL planar_decompress(BITMAP_PLANAR_CONTEXT* planar, const BYTE* pSrcData, UINT
|
|||||||
|
|
||||||
if (alpha)
|
if (alpha)
|
||||||
{
|
{
|
||||||
if ((SrcSize - (srcp - pSrcData)) < (planeSize + base))
|
if ((SrcSize - diff) < (planeSize + base))
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "Alpha plane size mismatch %" PRIuz " < %" PRIu32, SrcSize - diff,
|
||||||
|
(planeSize + base));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
planes[3] = srcp; /* AlphaPlane */
|
planes[3] = srcp; /* AlphaPlane */
|
||||||
planes[0] = planes[3] + rawSizes[3]; /* LumaOrRedPlane */
|
planes[0] = planes[3] + rawSizes[3]; /* LumaOrRedPlane */
|
||||||
@ -700,8 +721,11 @@ BOOL planar_decompress(BITMAP_PLANAR_CONTEXT* planar, const BYTE* pSrcData, UINT
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((SrcSize - (srcp - pSrcData)) < base)
|
if ((SrcSize - diff) < base)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "plane size mismatch %" PRIu32 " < %" PRIu32, SrcSize - diff, base);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
planes[0] = srcp; /* LumaOrRedPlane */
|
planes[0] = srcp; /* LumaOrRedPlane */
|
||||||
planes[1] = planes[0] + rawSizes[0]; /* OrangeChromaOrGreenPlane */
|
planes[1] = planes[0] + rawSizes[0]; /* OrangeChromaOrGreenPlane */
|
||||||
@ -716,8 +740,8 @@ BOOL planar_decompress(BITMAP_PLANAR_CONTEXT* planar, const BYTE* pSrcData, UINT
|
|||||||
if (alpha)
|
if (alpha)
|
||||||
{
|
{
|
||||||
planes[3] = srcp;
|
planes[3] = srcp;
|
||||||
rleSizes[3] = planar_skip_plane_rle(planes[3], SrcSize - (planes[3] - pSrcData),
|
rleSizes[3] = planar_skip_plane_rle(planes[3], SrcSize - diff, rawWidths[3],
|
||||||
rawWidths[3], rawHeights[3]); /* AlphaPlane */
|
rawHeights[3]); /* AlphaPlane */
|
||||||
|
|
||||||
if (rleSizes[3] < 0)
|
if (rleSizes[3] < 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -727,22 +751,41 @@ BOOL planar_decompress(BITMAP_PLANAR_CONTEXT* planar, const BYTE* pSrcData, UINT
|
|||||||
else
|
else
|
||||||
planes[0] = srcp;
|
planes[0] = srcp;
|
||||||
|
|
||||||
rleSizes[0] = planar_skip_plane_rle(planes[0], SrcSize - (planes[0] - pSrcData),
|
const size_t diff0 = (planes[0] - pSrcData);
|
||||||
rawWidths[0], rawHeights[0]); /* RedPlane */
|
if (SrcSize < diff0)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "Size mismatch %" PRIu32 " < %" PRIuz, SrcSize, diff0);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
rleSizes[0] = planar_skip_plane_rle(planes[0], SrcSize - diff0, rawWidths[0],
|
||||||
|
rawHeights[0]); /* RedPlane */
|
||||||
|
|
||||||
if (rleSizes[0] < 0)
|
if (rleSizes[0] < 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
planes[1] = planes[0] + rleSizes[0];
|
planes[1] = planes[0] + rleSizes[0];
|
||||||
rleSizes[1] = planar_skip_plane_rle(planes[1], SrcSize - (planes[1] - pSrcData),
|
|
||||||
rawWidths[1], rawHeights[1]); /* GreenPlane */
|
const size_t diff1 = (planes[1] - pSrcData);
|
||||||
|
if (SrcSize < diff1)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "Size mismatch %" PRIu32 " < %" PRIuz, SrcSize, diff1);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
rleSizes[1] = planar_skip_plane_rle(planes[1], SrcSize - diff1, rawWidths[1],
|
||||||
|
rawHeights[1]); /* GreenPlane */
|
||||||
|
|
||||||
if (rleSizes[1] < 1)
|
if (rleSizes[1] < 1)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
planes[2] = planes[1] + rleSizes[1];
|
planes[2] = planes[1] + rleSizes[1];
|
||||||
rleSizes[2] = planar_skip_plane_rle(planes[2], SrcSize - (planes[2] - pSrcData),
|
const size_t diff2 = (planes[2] - pSrcData);
|
||||||
rawWidths[2], rawHeights[2]); /* BluePlane */
|
if (SrcSize < diff2)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "Size mismatch %" PRIu32 " < %" PRIuz, SrcSize, diff);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
rleSizes[2] = planar_skip_plane_rle(planes[2], SrcSize - diff2, rawWidths[2],
|
||||||
|
rawHeights[2]); /* BluePlane */
|
||||||
|
|
||||||
if (rleSizes[2] < 1)
|
if (rleSizes[2] < 1)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -1484,9 +1527,15 @@ BOOL freerdp_bitmap_planar_context_reset(BITMAP_PLANAR_CONTEXT* context, UINT32
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
context->bgr = FALSE;
|
context->bgr = FALSE;
|
||||||
context->maxWidth = ALIGN(width, 4);
|
context->maxWidth = PLANAR_ALIGN(width, 4);
|
||||||
context->maxHeight = ALIGN(height, 4);
|
context->maxHeight = PLANAR_ALIGN(height, 4);
|
||||||
context->maxPlaneSize = context->maxWidth * context->maxHeight;
|
const UINT64 tmp = (UINT64)context->maxWidth * context->maxHeight;
|
||||||
|
if (tmp > UINT32_MAX)
|
||||||
|
return FALSE;
|
||||||
|
context->maxPlaneSize = tmp;
|
||||||
|
|
||||||
|
if (context->maxWidth > UINT32_MAX / 4)
|
||||||
|
return FALSE;
|
||||||
context->nTempStep = context->maxWidth * 4;
|
context->nTempStep = context->maxWidth * 4;
|
||||||
free(context->planesBuffer);
|
free(context->planesBuffer);
|
||||||
free(context->pTempData);
|
free(context->pTempData);
|
||||||
|
|||||||
@ -415,7 +415,7 @@ static INLINE BOOL progressive_tile_allocate(RFX_PROGRESSIVE_TILE* tile)
|
|||||||
tile->stride = 4 * tile->width;
|
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);
|
tile->data = (BYTE*)_aligned_malloc(dataLen, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1796,13 +1796,13 @@ static INLINE int progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive, wS
|
|||||||
for (index = 0; index < region->numTiles; index++)
|
for (index = 0; index < region->numTiles; index++)
|
||||||
{
|
{
|
||||||
RFX_PROGRESSIVE_TILE* tile = region->tiles[index];
|
RFX_PROGRESSIVE_TILE* tile = region->tiles[index];
|
||||||
params[index].progressive = progressive;
|
|
||||||
params[index].region = region;
|
|
||||||
params[index].context = context;
|
|
||||||
params[index].tile = tile;
|
|
||||||
|
|
||||||
if (progressive->rfx_context->priv->UseThreads)
|
if (progressive->rfx_context->priv->UseThreads)
|
||||||
{
|
{
|
||||||
|
params[index].progressive = progressive;
|
||||||
|
params[index].region = region;
|
||||||
|
params[index].context = context;
|
||||||
|
params[index].tile = tile;
|
||||||
if (!(work_objects[index] = CreateThreadpoolWork(
|
if (!(work_objects[index] = CreateThreadpoolWork(
|
||||||
progressive_process_tiles_tile_work_callback, (void*)¶ms[index],
|
progressive_process_tiles_tile_work_callback, (void*)¶ms[index],
|
||||||
&progressive->rfx_context->priv->ThreadPoolEnv)))
|
&progressive->rfx_context->priv->ThreadPoolEnv)))
|
||||||
@ -1817,7 +1817,10 @@ static INLINE int progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive, wS
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
progressive_process_tiles_tile_work_callback(0, ¶ms[index], 0);
|
PROGRESSIVE_TILE_PROCESS_WORK_PARAM param = {
|
||||||
|
.progressive = progressive, .region = region, .context = context, .tile = tile
|
||||||
|
};
|
||||||
|
progressive_process_tiles_tile_work_callback(0, ¶m, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
@ -2422,11 +2425,17 @@ INT32 progressive_decompress_ex(PROGRESSIVE_CONTEXT* progressive, const BYTE* pS
|
|||||||
for (j = 0; j < nbUpdateRects; j++)
|
for (j = 0; j < nbUpdateRects; j++)
|
||||||
{
|
{
|
||||||
const RECTANGLE_16* rect = &updateRects[j];
|
const RECTANGLE_16* rect = &updateRects[j];
|
||||||
const UINT32 nXSrc = rect->left - (nXDst + tile->x);
|
if (rect->left < updateRect.left)
|
||||||
const UINT32 nYSrc = rect->top - (nYDst + tile->y);
|
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 width = rect->right - rect->left;
|
||||||
const UINT32 height = rect->bottom - rect->top;
|
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,
|
if (!freerdp_image_copy(pDstData, DstFormat, nDstStep, rect->left, rect->top, width,
|
||||||
height, tile->data, progressive->format, tile->stride, nXSrc,
|
height, tile->data, progressive->format, tile->stride, nXSrc,
|
||||||
nYSrc, NULL, FREERDP_FLIP_NONE))
|
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->quantIdxY); /* quantIdxY (1 byte) */
|
||||||
Stream_Read_UINT8(&sub, tile->quantIdxCb); /* quantIdxCb (1 byte) */
|
Stream_Read_UINT8(&sub, tile->quantIdxCb); /* quantIdxCb (1 byte) */
|
||||||
Stream_Read_UINT8(&sub, tile->quantIdxCr); /* quantIdxCr (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->xIdx); /* xIdx (2 bytes) */
|
||||||
Stream_Read_UINT16(&sub, tile->yIdx); /* yIdx (2 bytes) */
|
Stream_Read_UINT16(&sub, tile->yIdx); /* yIdx (2 bytes) */
|
||||||
Stream_Read_UINT16(&sub, tile->YLen); /* YLen (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));
|
const size_t blockLenNoHeader = blockLen - 6;
|
||||||
Stream_Seek(s, blockLen - (6 + extraBlockLen));
|
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)
|
switch (blockType)
|
||||||
{
|
{
|
||||||
@ -1231,6 +1262,11 @@ BOOL rfx_process_message(RFX_CONTEXT* context, const BYTE* data, UINT32 length,
|
|||||||
region16_uninit(&clippingRects);
|
region16_uninit(&clippingRects);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rfx_message_free(context, message);
|
||||||
|
context->currentMessage.freeArray = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
WLog_ERR(TAG, "%s failed", __FUNCTION__);
|
WLog_ERR(TAG, "%s failed", __FUNCTION__);
|
||||||
return FALSE;
|
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 x_exceed;
|
||||||
int y_exceed;
|
int y_exceed;
|
||||||
const BYTE* src;
|
const BYTE* src;
|
||||||
|
const UINT32* src_32;
|
||||||
|
const UINT16* src_16;
|
||||||
INT16 r, g, b;
|
INT16 r, g, b;
|
||||||
INT16 *r_last, *g_last, *b_last;
|
INT16 *r_last, *g_last, *b_last;
|
||||||
x_exceed = 64 - width;
|
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++)
|
for (y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
src = rgb_data + y * rowstride;
|
src = rgb_data + y * rowstride;
|
||||||
|
src_32 = (UINT32*)src;
|
||||||
|
src_16 = (UINT16*)src;
|
||||||
|
|
||||||
switch (pixel_format)
|
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:
|
case PIXEL_FORMAT_BGRA32:
|
||||||
for (x = 0; x < width; x++)
|
for (x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
*b_buf++ = (INT16)(*src++);
|
*b_buf++ = (INT16)(*src_32 & 0xFF);
|
||||||
*g_buf++ = (INT16)(*src++);
|
*g_buf++ = (INT16)((*src_32 >> 8) & 0xFF);
|
||||||
*r_buf++ = (INT16)(*src++);
|
*r_buf++ = (INT16)((*src_32 >> 16) & 0xFF);
|
||||||
src++;
|
src_32++;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -76,10 +80,10 @@ static void rfx_encode_format_rgb(const BYTE* rgb_data, int width, int height, i
|
|||||||
case PIXEL_FORMAT_ABGR32:
|
case PIXEL_FORMAT_ABGR32:
|
||||||
for (x = 0; x < width; x++)
|
for (x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
src++;
|
*b_buf++ = (INT16)((*src_32 >> 8) & 0xFF);
|
||||||
*b_buf++ = (INT16)(*src++);
|
*g_buf++ = (INT16)((*src_32 >> 16) & 0xFF);
|
||||||
*g_buf++ = (INT16)(*src++);
|
*r_buf++ = (INT16)((*src_32 >> 24) & 0xFF);
|
||||||
*r_buf++ = (INT16)(*src++);
|
src_32++;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -88,10 +92,10 @@ static void rfx_encode_format_rgb(const BYTE* rgb_data, int width, int height, i
|
|||||||
case PIXEL_FORMAT_RGBA32:
|
case PIXEL_FORMAT_RGBA32:
|
||||||
for (x = 0; x < width; x++)
|
for (x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
*r_buf++ = (INT16)(*src++);
|
*r_buf++ = (INT16)(*src_32 & 0xFF);
|
||||||
*g_buf++ = (INT16)(*src++);
|
*g_buf++ = (INT16)((*src_32 >> 8) & 0xFF);
|
||||||
*b_buf++ = (INT16)(*src++);
|
*b_buf++ = (INT16)((*src_32 >> 16) & 0xFF);
|
||||||
src++;
|
src_32++;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -100,10 +104,10 @@ static void rfx_encode_format_rgb(const BYTE* rgb_data, int width, int height, i
|
|||||||
case PIXEL_FORMAT_ARGB32:
|
case PIXEL_FORMAT_ARGB32:
|
||||||
for (x = 0; x < width; x++)
|
for (x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
src++;
|
*r_buf++ = (INT16)((*src_32 >> 8) & 0xFF);
|
||||||
*r_buf++ = (INT16)(*src++);
|
*g_buf++ = (INT16)((*src_32 >> 16) & 0xFF);
|
||||||
*g_buf++ = (INT16)(*src++);
|
*b_buf++ = (INT16)((*src_32 >> 24) & 0xFF);
|
||||||
*b_buf++ = (INT16)(*src++);
|
src_32++;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -111,9 +115,15 @@ static void rfx_encode_format_rgb(const BYTE* rgb_data, int width, int height, i
|
|||||||
case PIXEL_FORMAT_BGR24:
|
case PIXEL_FORMAT_BGR24:
|
||||||
for (x = 0; x < width; x++)
|
for (x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
|
#ifdef __LITTLE_ENDIAN__
|
||||||
*b_buf++ = (INT16)(*src++);
|
*b_buf++ = (INT16)(*src++);
|
||||||
*g_buf++ = (INT16)(*src++);
|
*g_buf++ = (INT16)(*src++);
|
||||||
*r_buf++ = (INT16)(*src++);
|
*r_buf++ = (INT16)(*src++);
|
||||||
|
#else
|
||||||
|
*r_buf++ = (INT16)(*src++);
|
||||||
|
*g_buf++ = (INT16)(*src++);
|
||||||
|
*b_buf++ = (INT16)(*src++);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -121,9 +131,15 @@ static void rfx_encode_format_rgb(const BYTE* rgb_data, int width, int height, i
|
|||||||
case PIXEL_FORMAT_RGB24:
|
case PIXEL_FORMAT_RGB24:
|
||||||
for (x = 0; x < width; x++)
|
for (x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
|
#ifdef __LITTLE_ENDIAN__
|
||||||
*r_buf++ = (INT16)(*src++);
|
*r_buf++ = (INT16)(*src++);
|
||||||
*g_buf++ = (INT16)(*src++);
|
*g_buf++ = (INT16)(*src++);
|
||||||
*b_buf++ = (INT16)(*src++);
|
*b_buf++ = (INT16)(*src++);
|
||||||
|
#else
|
||||||
|
*b_buf++ = (INT16)(*src++);
|
||||||
|
*g_buf++ = (INT16)(*src++);
|
||||||
|
*r_buf++ = (INT16)(*src++);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -131,10 +147,10 @@ static void rfx_encode_format_rgb(const BYTE* rgb_data, int width, int height, i
|
|||||||
case PIXEL_FORMAT_BGR16:
|
case PIXEL_FORMAT_BGR16:
|
||||||
for (x = 0; x < width; x++)
|
for (x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
*b_buf++ = (INT16)(((*(src + 1)) & 0xF8) | ((*(src + 1)) >> 5));
|
*b_buf++ = (INT16)((*src_16) & 0x1F);
|
||||||
*g_buf++ = (INT16)((((*(src + 1)) & 0x07) << 5) | (((*src) & 0xE0) >> 3));
|
*g_buf++ = (INT16)((*src_16 >> 5) & 0x3F);
|
||||||
*r_buf++ = (INT16)((((*src) & 0x1F) << 3) | (((*src) >> 2) & 0x07));
|
*r_buf++ = (INT16)((*src_16 >> 11) & 0x1F);
|
||||||
src += 2;
|
src_16++;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -142,10 +158,10 @@ static void rfx_encode_format_rgb(const BYTE* rgb_data, int width, int height, i
|
|||||||
case PIXEL_FORMAT_RGB16:
|
case PIXEL_FORMAT_RGB16:
|
||||||
for (x = 0; x < width; x++)
|
for (x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
*r_buf++ = (INT16)(((*(src + 1)) & 0xF8) | ((*(src + 1)) >> 5));
|
*r_buf++ = (INT16)((*src_16 & 0x1F));
|
||||||
*g_buf++ = (INT16)((((*(src + 1)) & 0x07) << 5) | (((*src) & 0xE0) >> 3));
|
*g_buf++ = (INT16)((*src_16 >> 5) & 0x3F);
|
||||||
*b_buf++ = (INT16)((((*src) & 0x1F) << 3) | (((*src) >> 2) & 0x07));
|
*b_buf++ = (INT16)((*src_16 >> 11) & 0x1F);
|
||||||
src += 2;
|
src_16++;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -159,17 +175,17 @@ static void rfx_encode_format_rgb(const BYTE* rgb_data, int width, int height, i
|
|||||||
int shift;
|
int shift;
|
||||||
BYTE idx;
|
BYTE idx;
|
||||||
shift = (7 - (x % 8));
|
shift = (7 - (x % 8));
|
||||||
idx = ((*src) >> shift) & 1;
|
idx = (BYTE)(((*src_32 & 0xFF) >> shift) & 1);
|
||||||
idx |= (((*(src + 1)) >> shift) & 1) << 1;
|
idx |= (BYTE)(((((*src_32 >> 8) & 0xFF) >> shift) & 1) << 1);
|
||||||
idx |= (((*(src + 2)) >> shift) & 1) << 2;
|
idx |= (BYTE)(((((*src_32 >> 16) & 0xFF) >> shift) & 1) << 2);
|
||||||
idx |= (((*(src + 3)) >> shift) & 1) << 3;
|
idx |= (BYTE)(((((*src_32 >> 24) & 0xFF) >> shift) & 1) << 3);
|
||||||
idx *= 3;
|
idx *= 3;
|
||||||
*r_buf++ = (INT16)palette[idx];
|
*r_buf++ = (INT16)palette[idx];
|
||||||
*g_buf++ = (INT16)palette[idx + 1];
|
*g_buf++ = (INT16)palette[idx + 1];
|
||||||
*b_buf++ = (INT16)palette[idx + 2];
|
*b_buf++ = (INT16)palette[idx + 2];
|
||||||
|
|
||||||
if (shift == 0)
|
if (shift == 0)
|
||||||
src += 4;
|
src_32++;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -674,7 +674,7 @@ static int xcrush_generate_output(XCRUSH_CONTEXT* xcrush, BYTE* OutputBuffer, UI
|
|||||||
if (&OutputBuffer[2] >= &OutputBuffer[OutputSize])
|
if (&OutputBuffer[2] >= &OutputBuffer[OutputSize])
|
||||||
return -6001; /* error */
|
return -6001; /* error */
|
||||||
|
|
||||||
*((UINT16*)OutputBuffer) = MatchCount;
|
Data_Write_UINT16(OutputBuffer, MatchCount);
|
||||||
MatchDetails = (RDP61_MATCH_DETAILS*)&OutputBuffer[2];
|
MatchDetails = (RDP61_MATCH_DETAILS*)&OutputBuffer[2];
|
||||||
Literals = (BYTE*)&MatchDetails[MatchCount];
|
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++)
|
for (MatchIndex = 0; MatchIndex < MatchCount; MatchIndex++)
|
||||||
{
|
{
|
||||||
MatchDetails[MatchIndex].MatchLength =
|
Data_Write_UINT16(&MatchDetails[MatchIndex].MatchLength,
|
||||||
(UINT16)(xcrush->OptimizedMatches[MatchIndex].MatchLength);
|
xcrush->OptimizedMatches[MatchIndex].MatchLength);
|
||||||
MatchDetails[MatchIndex].MatchOutputOffset =
|
Data_Write_UINT16(&MatchDetails[MatchIndex].MatchOutputOffset,
|
||||||
(UINT16)(xcrush->OptimizedMatches[MatchIndex].MatchOffset - HistoryOffset);
|
xcrush->OptimizedMatches[MatchIndex].MatchOffset - HistoryOffset);
|
||||||
MatchDetails[MatchIndex].MatchHistoryOffset =
|
Data_Write_UINT32(&MatchDetails[MatchIndex].MatchHistoryOffset,
|
||||||
xcrush->OptimizedMatches[MatchIndex].ChunkOffset;
|
xcrush->OptimizedMatches[MatchIndex].ChunkOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentOffset = HistoryOffset;
|
CurrentOffset = HistoryOffset;
|
||||||
|
|||||||
@ -230,7 +230,10 @@ static BOOL zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, wStream* stream, size_t
|
|||||||
BYTE* pbSegment;
|
BYTE* pbSegment;
|
||||||
size_t cbSegment;
|
size_t cbSegment;
|
||||||
|
|
||||||
if (!zgfx || !stream || (segmentSize < 2))
|
WINPR_ASSERT(zgfx);
|
||||||
|
WINPR_ASSERT(stream);
|
||||||
|
|
||||||
|
if (segmentSize < 2)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
cbSegment = segmentSize - 1;
|
cbSegment = segmentSize - 1;
|
||||||
@ -259,7 +262,11 @@ static BOOL zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, wStream* stream, size_t
|
|||||||
zgfx->pbInputCurrent = pbSegment;
|
zgfx->pbInputCurrent = pbSegment;
|
||||||
zgfx->pbInputEnd = &pbSegment[cbSegment - 1];
|
zgfx->pbInputEnd = &pbSegment[cbSegment - 1];
|
||||||
/* NumberOfBitsToDecode = ((NumberOfBytesToDecode - 1) * 8) - ValueOfLastByte */
|
/* 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->cBitsCurrent = 0;
|
||||||
zgfx->BitsCurrent = 0;
|
zgfx->BitsCurrent = 0;
|
||||||
|
|
||||||
@ -345,8 +352,9 @@ static BOOL zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, wStream* stream, size_t
|
|||||||
|
|
||||||
if (count > sizeof(zgfx->OutputBuffer) - zgfx->OutputCount)
|
if (count > sizeof(zgfx->OutputBuffer) - zgfx->OutputCount)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
else if (count > zgfx->cBitsRemaining / 8)
|
||||||
if (count > zgfx->cBitsRemaining / 8)
|
return FALSE;
|
||||||
|
else if (zgfx->pbInputCurrent + count > zgfx->pbInputEnd)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
CopyMemory(&(zgfx->OutputBuffer[zgfx->OutputCount]), zgfx->pbInputCurrent,
|
CopyMemory(&(zgfx->OutputBuffer[zgfx->OutputCount]), zgfx->pbInputCurrent,
|
||||||
@ -377,15 +385,45 @@ static BYTE* aligned_zgfx_malloc(size_t size)
|
|||||||
return malloc(size + 64);
|
return malloc(size + 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL zgfx_append(ZGFX_CONTEXT* zgfx, BYTE** ppConcatenated, size_t uncompressedSize,
|
||||||
|
size_t* pUsed)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(zgfx);
|
||||||
|
WINPR_ASSERT(ppConcatenated);
|
||||||
|
WINPR_ASSERT(pUsed);
|
||||||
|
|
||||||
|
const size_t used = *pUsed;
|
||||||
|
if (zgfx->OutputCount > UINT32_MAX - used)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (used + zgfx->OutputCount > uncompressedSize)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
BYTE* tmp = realloc(*ppConcatenated, used + zgfx->OutputCount + 64ull);
|
||||||
|
if (!tmp)
|
||||||
|
return FALSE;
|
||||||
|
*ppConcatenated = tmp;
|
||||||
|
CopyMemory(&tmp[used], zgfx->OutputBuffer, zgfx->OutputCount);
|
||||||
|
*pUsed = used + zgfx->OutputCount;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData,
|
int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData,
|
||||||
UINT32* pDstSize, UINT32 flags)
|
UINT32* pDstSize, UINT32 flags)
|
||||||
{
|
{
|
||||||
int status = -1;
|
int status = -1;
|
||||||
BYTE descriptor;
|
BYTE descriptor = 0;
|
||||||
|
size_t used = 0;
|
||||||
|
BYTE* pConcatenated = NULL;
|
||||||
wStream* stream = Stream_New((BYTE*)pSrcData, SrcSize);
|
wStream* stream = Stream_New((BYTE*)pSrcData, SrcSize);
|
||||||
|
|
||||||
if (!stream)
|
WINPR_ASSERT(zgfx);
|
||||||
return -1;
|
WINPR_ASSERT(stream);
|
||||||
|
WINPR_ASSERT(ppDstData);
|
||||||
|
WINPR_ASSERT(pDstSize);
|
||||||
|
|
||||||
|
*ppDstData = NULL;
|
||||||
|
*pDstSize = 0;
|
||||||
|
|
||||||
if (Stream_GetRemainingLength(stream) < 1)
|
if (Stream_GetRemainingLength(stream) < 1)
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -397,16 +435,15 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
|
|||||||
if (!zgfx_decompress_segment(zgfx, stream, Stream_GetRemainingLength(stream)))
|
if (!zgfx_decompress_segment(zgfx, stream, Stream_GetRemainingLength(stream)))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
*ppDstData = NULL;
|
|
||||||
|
|
||||||
if (zgfx->OutputCount > 0)
|
if (zgfx->OutputCount > 0)
|
||||||
*ppDstData = aligned_zgfx_malloc(zgfx->OutputCount);
|
{
|
||||||
|
if (!zgfx_append(zgfx, &pConcatenated, zgfx->OutputCount, &used))
|
||||||
if (!*ppDstData)
|
goto fail;
|
||||||
goto fail;
|
if (used != zgfx->OutputCount)
|
||||||
|
goto fail;
|
||||||
*pDstSize = zgfx->OutputCount;
|
*ppDstData = pConcatenated;
|
||||||
CopyMemory(*ppDstData, zgfx->OutputBuffer, zgfx->OutputCount);
|
*pDstSize = zgfx->OutputCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (descriptor == ZGFX_SEGMENTED_MULTIPART)
|
else if (descriptor == ZGFX_SEGMENTED_MULTIPART)
|
||||||
{
|
{
|
||||||
@ -414,8 +451,6 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
|
|||||||
UINT16 segmentNumber;
|
UINT16 segmentNumber;
|
||||||
UINT16 segmentCount;
|
UINT16 segmentCount;
|
||||||
UINT32 uncompressedSize;
|
UINT32 uncompressedSize;
|
||||||
BYTE* pConcatenated;
|
|
||||||
size_t used = 0;
|
|
||||||
|
|
||||||
if (Stream_GetRemainingLength(stream) < 6)
|
if (Stream_GetRemainingLength(stream) < 6)
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -423,17 +458,6 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
|
|||||||
Stream_Read_UINT16(stream, segmentCount); /* segmentCount (2 bytes) */
|
Stream_Read_UINT16(stream, segmentCount); /* segmentCount (2 bytes) */
|
||||||
Stream_Read_UINT32(stream, uncompressedSize); /* uncompressedSize (4 bytes) */
|
Stream_Read_UINT32(stream, uncompressedSize); /* uncompressedSize (4 bytes) */
|
||||||
|
|
||||||
if (Stream_GetRemainingLength(stream) < segmentCount * sizeof(UINT32))
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
pConcatenated = aligned_zgfx_malloc(uncompressedSize);
|
|
||||||
|
|
||||||
if (!pConcatenated)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
*ppDstData = pConcatenated;
|
|
||||||
*pDstSize = uncompressedSize;
|
|
||||||
|
|
||||||
for (segmentNumber = 0; segmentNumber < segmentCount; segmentNumber++)
|
for (segmentNumber = 0; segmentNumber < segmentCount; segmentNumber++)
|
||||||
{
|
{
|
||||||
if (Stream_GetRemainingLength(stream) < sizeof(UINT32))
|
if (Stream_GetRemainingLength(stream) < sizeof(UINT32))
|
||||||
@ -444,16 +468,15 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
|
|||||||
if (!zgfx_decompress_segment(zgfx, stream, segmentSize))
|
if (!zgfx_decompress_segment(zgfx, stream, segmentSize))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (zgfx->OutputCount > UINT32_MAX - used)
|
if (!zgfx_append(zgfx, &pConcatenated, uncompressedSize, &used))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (used + zgfx->OutputCount > uncompressedSize)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
CopyMemory(pConcatenated, zgfx->OutputBuffer, zgfx->OutputCount);
|
|
||||||
pConcatenated += zgfx->OutputCount;
|
|
||||||
used += zgfx->OutputCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (used != uncompressedSize)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
*ppDstData = pConcatenated;
|
||||||
|
*pDstSize = uncompressedSize;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -462,6 +485,8 @@ int zgfx_decompress(ZGFX_CONTEXT* zgfx, const BYTE* pSrcData, UINT32 SrcSize, BY
|
|||||||
|
|
||||||
status = 1;
|
status = 1;
|
||||||
fail:
|
fail:
|
||||||
|
if (status < 0)
|
||||||
|
free(pConcatenated);
|
||||||
Stream_Free(stream, FALSE);
|
Stream_Free(stream, FALSE);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -231,6 +231,9 @@ BOOL freerdp_settings_get_bool(const rdpSettings* settings, size_t id)
|
|||||||
case FreeRDP_GrabKeyboard:
|
case FreeRDP_GrabKeyboard:
|
||||||
return settings->GrabKeyboard;
|
return settings->GrabKeyboard;
|
||||||
|
|
||||||
|
case FreeRDP_GrabMouse:
|
||||||
|
return settings->GrabMouse;
|
||||||
|
|
||||||
case FreeRDP_HasExtendedMouseEvent:
|
case FreeRDP_HasExtendedMouseEvent:
|
||||||
return settings->HasExtendedMouseEvent;
|
return settings->HasExtendedMouseEvent;
|
||||||
|
|
||||||
@ -809,6 +812,10 @@ BOOL freerdp_settings_set_bool(rdpSettings* settings, size_t id, BOOL val)
|
|||||||
settings->GrabKeyboard = val;
|
settings->GrabKeyboard = val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FreeRDP_GrabMouse:
|
||||||
|
settings->GrabMouse = val;
|
||||||
|
break;
|
||||||
|
|
||||||
case FreeRDP_HasExtendedMouseEvent:
|
case FreeRDP_HasExtendedMouseEvent:
|
||||||
settings->HasExtendedMouseEvent = val;
|
settings->HasExtendedMouseEvent = val;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -87,6 +87,7 @@ static const struct settings_str_entry settings_map[] = {
|
|||||||
{ FreeRDP_GfxSmallCache, 0, "FreeRDP_GfxSmallCache" },
|
{ FreeRDP_GfxSmallCache, 0, "FreeRDP_GfxSmallCache" },
|
||||||
{ FreeRDP_GfxThinClient, 0, "FreeRDP_GfxThinClient" },
|
{ FreeRDP_GfxThinClient, 0, "FreeRDP_GfxThinClient" },
|
||||||
{ FreeRDP_GrabKeyboard, 0, "FreeRDP_GrabKeyboard" },
|
{ FreeRDP_GrabKeyboard, 0, "FreeRDP_GrabKeyboard" },
|
||||||
|
{ FreeRDP_GrabMouse, 0, "FreeRDP_GrabMouse" },
|
||||||
{ FreeRDP_HasExtendedMouseEvent, 0, "FreeRDP_HasExtendedMouseEvent" },
|
{ FreeRDP_HasExtendedMouseEvent, 0, "FreeRDP_HasExtendedMouseEvent" },
|
||||||
{ FreeRDP_HasHorizontalWheel, 0, "FreeRDP_HasHorizontalWheel" },
|
{ FreeRDP_HasHorizontalWheel, 0, "FreeRDP_HasHorizontalWheel" },
|
||||||
{ FreeRDP_HasMonitorAttributes, 0, "FreeRDP_HasMonitorAttributes" },
|
{ FreeRDP_HasMonitorAttributes, 0, "FreeRDP_HasMonitorAttributes" },
|
||||||
|
|||||||
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include <winpr/wtypes.h>
|
#include <winpr/wtypes.h>
|
||||||
#include <winpr/crt.h>
|
#include <winpr/crt.h>
|
||||||
|
#include <winpr/assert.h>
|
||||||
|
|
||||||
#include <freerdp/api.h>
|
#include <freerdp/api.h>
|
||||||
#include <freerdp/log.h>
|
#include <freerdp/log.h>
|
||||||
@ -796,6 +797,7 @@ static INLINE BOOL update_write_4byte_unsigned(wStream* s, UINT32 value)
|
|||||||
static INLINE BOOL update_read_delta(wStream* s, INT32* value)
|
static INLINE BOOL update_read_delta(wStream* s, INT32* value)
|
||||||
{
|
{
|
||||||
BYTE byte;
|
BYTE byte;
|
||||||
|
UINT32 uvalue = 0;
|
||||||
|
|
||||||
if (Stream_GetRemainingLength(s) < 1)
|
if (Stream_GetRemainingLength(s) < 1)
|
||||||
{
|
{
|
||||||
@ -806,9 +808,9 @@ static INLINE BOOL update_read_delta(wStream* s, INT32* value)
|
|||||||
Stream_Read_UINT8(s, byte);
|
Stream_Read_UINT8(s, byte);
|
||||||
|
|
||||||
if (byte & 0x40)
|
if (byte & 0x40)
|
||||||
*value = (byte | ~0x3F);
|
uvalue = (byte | ~0x3F);
|
||||||
else
|
else
|
||||||
*value = (byte & 0x3F);
|
uvalue = (byte & 0x3F);
|
||||||
|
|
||||||
if (byte & 0x80)
|
if (byte & 0x80)
|
||||||
{
|
{
|
||||||
@ -819,8 +821,9 @@ static INLINE BOOL update_read_delta(wStream* s, INT32* value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Stream_Read_UINT8(s, byte);
|
Stream_Read_UINT8(s, byte);
|
||||||
*value = (*value << 8) | byte;
|
uvalue = (uvalue << 8) | byte;
|
||||||
}
|
}
|
||||||
|
*value = (INT32)uvalue;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -1373,12 +1376,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,
|
static BOOL update_read_multi_dstblt_order(wStream* s, const ORDER_INFO* orderInfo,
|
||||||
MULTI_DSTBLT_ORDER* multi_dstblt)
|
MULTI_DSTBLT_ORDER* multi_dstblt)
|
||||||
{
|
{
|
||||||
|
UINT32 numRectangles = multi_dstblt->numRectangles;
|
||||||
if (!read_order_field_coord(orderInfo, s, 1, &multi_dstblt->nLeftRect, FALSE) ||
|
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, 2, &multi_dstblt->nTopRect, FALSE) ||
|
||||||
!read_order_field_coord(orderInfo, s, 3, &multi_dstblt->nWidth, 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_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, 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;
|
return FALSE;
|
||||||
|
|
||||||
if ((orderInfo->fieldFlags & ORDER_FIELD_07) != 0)
|
if ((orderInfo->fieldFlags & ORDER_FIELD_07) != 0)
|
||||||
@ -1386,12 +1390,21 @@ static BOOL update_read_multi_dstblt_order(wStream* s, const ORDER_INFO* orderIn
|
|||||||
if (Stream_GetRemainingLength(s) < 2)
|
if (Stream_GetRemainingLength(s) < 2)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
multi_dstblt->numRectangles = numRectangles;
|
||||||
Stream_Read_UINT16(s, multi_dstblt->cbData);
|
Stream_Read_UINT16(s, multi_dstblt->cbData);
|
||||||
return update_read_delta_rects(s, multi_dstblt->rectangles, &multi_dstblt->numRectangles);
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL update_read_multi_patblt_order(wStream* s, const ORDER_INFO* orderInfo,
|
static BOOL update_read_multi_patblt_order(wStream* s, const ORDER_INFO* orderInfo,
|
||||||
MULTI_PATBLT_ORDER* multi_patblt)
|
MULTI_PATBLT_ORDER* multi_patblt)
|
||||||
{
|
{
|
||||||
@ -1407,7 +1420,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))
|
if (!update_read_brush(s, &multi_patblt->brush, orderInfo->fieldFlags >> 7))
|
||||||
return FALSE;
|
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;
|
return FALSE;
|
||||||
|
|
||||||
if ((orderInfo->fieldFlags & ORDER_FIELD_14) != 0)
|
if ((orderInfo->fieldFlags & ORDER_FIELD_14) != 0)
|
||||||
@ -1415,17 +1429,31 @@ static BOOL update_read_multi_patblt_order(wStream* s, const ORDER_INFO* orderIn
|
|||||||
if (Stream_GetRemainingLength(s) < 2)
|
if (Stream_GetRemainingLength(s) < 2)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
multi_patblt->numRectangles = numRectangles;
|
||||||
Stream_Read_UINT16(s, multi_patblt->cbData);
|
Stream_Read_UINT16(s, multi_patblt->cbData);
|
||||||
|
|
||||||
if (!update_read_delta_rects(s, multi_patblt->rectangles, &multi_patblt->numRectangles))
|
if (!update_read_delta_rects(s, multi_patblt->rectangles, &multi_patblt->numRectangles))
|
||||||
return FALSE;
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
static BOOL update_read_multi_scrblt_order(wStream* s, const ORDER_INFO* orderInfo,
|
static BOOL update_read_multi_scrblt_order(wStream* s, const ORDER_INFO* orderInfo,
|
||||||
MULTI_SCRBLT_ORDER* multi_scrblt)
|
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) ||
|
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, 2, &multi_scrblt->nTopRect, FALSE) ||
|
||||||
!read_order_field_coord(orderInfo, s, 3, &multi_scrblt->nWidth, FALSE) ||
|
!read_order_field_coord(orderInfo, s, 3, &multi_scrblt->nWidth, FALSE) ||
|
||||||
@ -1433,7 +1461,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_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, 6, &multi_scrblt->nXSrc, FALSE) ||
|
||||||
!read_order_field_coord(orderInfo, s, 7, &multi_scrblt->nYSrc, 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;
|
return FALSE;
|
||||||
|
|
||||||
if ((orderInfo->fieldFlags & ORDER_FIELD_09) != 0)
|
if ((orderInfo->fieldFlags & ORDER_FIELD_09) != 0)
|
||||||
@ -1441,10 +1469,20 @@ static BOOL update_read_multi_scrblt_order(wStream* s, const ORDER_INFO* orderIn
|
|||||||
if (Stream_GetRemainingLength(s) < 2)
|
if (Stream_GetRemainingLength(s) < 2)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
multi_scrblt->numRectangles = numRectangles;
|
||||||
Stream_Read_UINT16(s, multi_scrblt->cbData);
|
Stream_Read_UINT16(s, multi_scrblt->cbData);
|
||||||
return update_read_delta_rects(s, multi_scrblt->rectangles, &multi_scrblt->numRectangles);
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
static BOOL update_read_multi_opaque_rect_order(wStream* s, const ORDER_INFO* orderInfo,
|
static BOOL update_read_multi_opaque_rect_order(wStream* s, const ORDER_INFO* orderInfo,
|
||||||
@ -1484,7 +1522,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);
|
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;
|
return FALSE;
|
||||||
|
|
||||||
if ((orderInfo->fieldFlags & ORDER_FIELD_09) != 0)
|
if ((orderInfo->fieldFlags & ORDER_FIELD_09) != 0)
|
||||||
@ -1492,22 +1531,32 @@ static BOOL update_read_multi_opaque_rect_order(wStream* s, const ORDER_INFO* or
|
|||||||
if (Stream_GetRemainingLength(s) < 2)
|
if (Stream_GetRemainingLength(s) < 2)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
multi_opaque_rect->numRectangles = numRectangles;
|
||||||
Stream_Read_UINT16(s, multi_opaque_rect->cbData);
|
Stream_Read_UINT16(s, multi_opaque_rect->cbData);
|
||||||
return update_read_delta_rects(s, multi_opaque_rect->rectangles,
|
return update_read_delta_rects(s, multi_opaque_rect->rectangles,
|
||||||
&multi_opaque_rect->numRectangles);
|
&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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
static BOOL update_read_multi_draw_nine_grid_order(wStream* s, const ORDER_INFO* orderInfo,
|
static BOOL update_read_multi_draw_nine_grid_order(wStream* s, const ORDER_INFO* orderInfo,
|
||||||
MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid)
|
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) ||
|
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, 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, 3, &multi_draw_nine_grid->srcRight, FALSE) ||
|
||||||
!read_order_field_coord(orderInfo, s, 4, &multi_draw_nine_grid->srcBottom, 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_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;
|
return FALSE;
|
||||||
|
|
||||||
if ((orderInfo->fieldFlags & ORDER_FIELD_07) != 0)
|
if ((orderInfo->fieldFlags & ORDER_FIELD_07) != 0)
|
||||||
@ -1515,11 +1564,21 @@ static BOOL update_read_multi_draw_nine_grid_order(wStream* s, const ORDER_INFO*
|
|||||||
if (Stream_GetRemainingLength(s) < 2)
|
if (Stream_GetRemainingLength(s) < 2)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
multi_draw_nine_grid->nDeltaEntries = nDeltaEntries;
|
||||||
Stream_Read_UINT16(s, multi_draw_nine_grid->cbData);
|
Stream_Read_UINT16(s, multi_draw_nine_grid->cbData);
|
||||||
return update_read_delta_rects(s, multi_draw_nine_grid->rectangles,
|
return update_read_delta_rects(s, multi_draw_nine_grid->rectangles,
|
||||||
&multi_draw_nine_grid->nDeltaEntries);
|
&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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
static BOOL update_read_line_to_order(wStream* s, const ORDER_INFO* orderInfo,
|
static BOOL update_read_line_to_order(wStream* s, const ORDER_INFO* orderInfo,
|
||||||
@ -1610,6 +1669,14 @@ static BOOL update_read_polyline_order(wStream* s, const ORDER_INFO* orderInfo,
|
|||||||
return update_read_delta_points(s, polyline->points, polyline->numDeltaEntries,
|
return update_read_delta_points(s, polyline->points, polyline->numDeltaEntries,
|
||||||
polyline->xStart, polyline->yStart);
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -1942,6 +2009,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,
|
return update_read_delta_points(s, polygon_sc->points, polygon_sc->numPoints,
|
||||||
polygon_sc->xStart, polygon_sc->yStart);
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -1987,6 +2061,14 @@ static BOOL update_read_polygon_cb_order(wStream* s, const ORDER_INFO* orderInfo
|
|||||||
return FALSE;
|
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->backMode = (polygon_cb->bRop2 & 0x80) ? BACKMODE_TRANSPARENT : BACKMODE_OPAQUE;
|
||||||
polygon_cb->bRop2 = (polygon_cb->bRop2 & 0x1F);
|
polygon_cb->bRop2 = (polygon_cb->bRop2 & 0x1F);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|||||||
@ -493,7 +493,7 @@ BOOL WTSVirtualChannelManagerCheckFileDescriptor(HANDLE hServer)
|
|||||||
{
|
{
|
||||||
ULONG written;
|
ULONG written;
|
||||||
vcm->drdynvc_channel = channel;
|
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))
|
if (!WTSVirtualChannelWrite(channel, (PCHAR)&dynvc_caps, sizeof(dynvc_caps), &written))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|||||||
@ -76,6 +76,7 @@ static const size_t bool_list_indices[] = {
|
|||||||
FreeRDP_GfxSmallCache,
|
FreeRDP_GfxSmallCache,
|
||||||
FreeRDP_GfxThinClient,
|
FreeRDP_GfxThinClient,
|
||||||
FreeRDP_GrabKeyboard,
|
FreeRDP_GrabKeyboard,
|
||||||
|
FreeRDP_GrabMouse,
|
||||||
FreeRDP_HasExtendedMouseEvent,
|
FreeRDP_HasExtendedMouseEvent,
|
||||||
FreeRDP_HasHorizontalWheel,
|
FreeRDP_HasHorizontalWheel,
|
||||||
FreeRDP_HasMonitorAttributes,
|
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) */
|
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;
|
if (!newRect)
|
||||||
newRect = (RECTANGLE_16*)realloc(windowState->windowRects, size);
|
{
|
||||||
|
free(windowState->windowRects);
|
||||||
|
windowState->windowRects = NULL;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (!newRect)
|
windowState->windowRects = newRect;
|
||||||
{
|
|
||||||
free(windowState->windowRects);
|
|
||||||
windowState->windowRects = NULL;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
windowState->windowRects = newRect;
|
if (Stream_GetRemainingLength(s) < 8 * windowState->numWindowRects)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (Stream_GetRemainingLength(s) < 8 * windowState->numWindowRects)
|
/* windowRects */
|
||||||
return FALSE;
|
for (i = 0; i < windowState->numWindowRects; i++)
|
||||||
|
{
|
||||||
/* windowRects */
|
Stream_Read_UINT16(s, windowState->windowRects[i].left); /* left (2 bytes) */
|
||||||
for (i = 0; i < windowState->numWindowRects; i++)
|
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].left); /* left (2 bytes) */
|
Stream_Read_UINT16(s, windowState->windowRects[i].bottom); /* bottom (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,13 @@ WINPR_MD_TYPE crypto_cert_get_signature_alg(X509* xcert)
|
|||||||
{
|
{
|
||||||
WINPR_ASSERT(xcert);
|
WINPR_ASSERT(xcert);
|
||||||
|
|
||||||
const int nid = X509_get_signature_nid(xcert);
|
EVP_PKEY* evp = X509_get_pubkey(xcert);
|
||||||
|
WINPR_ASSERT(evp);
|
||||||
|
|
||||||
int hash_nid = 0;
|
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);
|
||||||
|
EVP_PKEY_free(evp);
|
||||||
|
if (res <= 0)
|
||||||
return WINPR_MD_NONE;
|
return WINPR_MD_NONE;
|
||||||
|
|
||||||
switch (hash_nid)
|
switch (hash_nid)
|
||||||
@ -976,7 +979,7 @@ WINPR_MD_TYPE crypto_cert_get_signature_alg(X509* xcert)
|
|||||||
return WINPR_MD_SHA512;
|
return WINPR_MD_SHA512;
|
||||||
case NID_ripemd160:
|
case NID_ripemd160:
|
||||||
return WINPR_MD_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:
|
case NID_sha3_224:
|
||||||
return WINPR_MD_SHA3_224;
|
return WINPR_MD_SHA3_224;
|
||||||
case NID_sha3_256:
|
case NID_sha3_256:
|
||||||
@ -985,11 +988,11 @@ WINPR_MD_TYPE crypto_cert_get_signature_alg(X509* xcert)
|
|||||||
return WINPR_MD_SHA3_384;
|
return WINPR_MD_SHA3_384;
|
||||||
case NID_sha3_512:
|
case NID_sha3_512:
|
||||||
return WINPR_MD_SHA3_512;
|
return WINPR_MD_SHA3_512;
|
||||||
#endif
|
|
||||||
case NID_shake128:
|
case NID_shake128:
|
||||||
return WINPR_MD_SHAKE128;
|
return WINPR_MD_SHAKE128;
|
||||||
case NID_shake256:
|
case NID_shake256:
|
||||||
return WINPR_MD_SHAKE256;
|
return WINPR_MD_SHAKE256;
|
||||||
|
#endif
|
||||||
case NID_undef:
|
case NID_undef:
|
||||||
default:
|
default:
|
||||||
return WINPR_MD_NONE;
|
return WINPR_MD_NONE;
|
||||||
|
|||||||
@ -148,7 +148,7 @@ HGDI_BITMAP gdi_CreateCompatibleBitmap(HGDI_DC hdc, UINT32 nWidth, UINT32 nHeigh
|
|||||||
hBitmap->width = nWidth;
|
hBitmap->width = nWidth;
|
||||||
hBitmap->height = nHeight;
|
hBitmap->height = nHeight;
|
||||||
hBitmap->data =
|
hBitmap->data =
|
||||||
_aligned_malloc(nWidth * nHeight * GetBytesPerPixel(hBitmap->format) * 1ULL, 16);
|
_aligned_malloc(1ull * nWidth * nHeight * GetBytesPerPixel(hBitmap->format), 16);
|
||||||
hBitmap->free = _aligned_free;
|
hBitmap->free = _aligned_free;
|
||||||
|
|
||||||
if (!hBitmap->data)
|
if (!hBitmap->data)
|
||||||
|
|||||||
@ -997,16 +997,46 @@ static BOOL gdi_surface_frame_marker(rdpContext* context,
|
|||||||
return TRUE;
|
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)
|
static BOOL gdi_surface_bits(rdpContext* context, const SURFACE_BITS_COMMAND* cmd)
|
||||||
{
|
{
|
||||||
BOOL result = FALSE;
|
BOOL result = FALSE;
|
||||||
DWORD format;
|
DWORD format;
|
||||||
rdpGdi* gdi;
|
rdpGdi* gdi = NULL;
|
||||||
size_t size;
|
size_t size;
|
||||||
REGION16 region;
|
REGION16 region;
|
||||||
RECTANGLE_16 cmdRect;
|
RECTANGLE_16 cmdRect = { 0 };
|
||||||
UINT32 i, nbRects;
|
UINT32 nbRects;
|
||||||
const RECTANGLE_16* rects;
|
const RECTANGLE_16* rects = NULL;
|
||||||
|
|
||||||
if (!context || !cmd)
|
if (!context || !cmd)
|
||||||
return FALSE;
|
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->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);
|
cmd->bmp.codecID, cmd->bmp.width, cmd->bmp.height, cmd->bmp.bitmapDataLength);
|
||||||
region16_init(®ion);
|
region16_init(®ion);
|
||||||
cmdRect.left = cmd->destLeft;
|
|
||||||
cmdRect.top = cmd->destTop;
|
if (!intersect_rect(gdi, cmd, &cmdRect))
|
||||||
cmdRect.right = cmdRect.left + cmd->bmp.width;
|
goto out;
|
||||||
cmdRect.bottom = cmdRect.top + cmd->bmp.height;
|
|
||||||
|
|
||||||
switch (cmd->bmp.codecID)
|
switch (cmd->bmp.codecID)
|
||||||
{
|
{
|
||||||
case RDP_CODEC_ID_REMOTEFX:
|
case RDP_CODEC_ID_REMOTEFX:
|
||||||
if (!rfx_process_message(context->codecs->rfx, cmd->bmp.bitmapData,
|
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,
|
gdi->primary_buffer, gdi->dstFormat, gdi->stride, gdi->height,
|
||||||
®ion))
|
®ion))
|
||||||
{
|
{
|
||||||
@ -1042,11 +1071,11 @@ static BOOL gdi_surface_bits(rdpContext* context, const SURFACE_BITS_COMMAND* cm
|
|||||||
case RDP_CODEC_ID_NSCODEC:
|
case RDP_CODEC_ID_NSCODEC:
|
||||||
format = gdi->dstFormat;
|
format = gdi->dstFormat;
|
||||||
|
|
||||||
if (!nsc_process_message(context->codecs->nsc, cmd->bmp.bpp, cmd->bmp.width,
|
if (!nsc_process_message(
|
||||||
cmd->bmp.height, cmd->bmp.bitmapData,
|
context->codecs->nsc, cmd->bmp.bpp, cmd->bmp.width, cmd->bmp.height,
|
||||||
cmd->bmp.bitmapDataLength, gdi->primary_buffer, format,
|
cmd->bmp.bitmapData, cmd->bmp.bitmapDataLength, gdi->primary_buffer, format,
|
||||||
gdi->stride, cmd->destLeft, cmd->destTop, cmd->bmp.width,
|
gdi->stride, cmdRect.left, cmdRect.top, cmdRect.right - cmdRect.left,
|
||||||
cmd->bmp.height, FREERDP_FLIP_VERTICAL))
|
cmdRect.bottom - cmdRect.top, FREERDP_FLIP_VERTICAL))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Failed to process NSCodec message");
|
WLog_ERR(TAG, "Failed to process NSCodec message");
|
||||||
goto out;
|
goto out;
|
||||||
@ -1057,17 +1086,18 @@ static BOOL gdi_surface_bits(rdpContext* context, const SURFACE_BITS_COMMAND* cm
|
|||||||
|
|
||||||
case RDP_CODEC_ID_NONE:
|
case RDP_CODEC_ID_NONE:
|
||||||
format = gdi_get_pixel_format(cmd->bmp.bpp);
|
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)
|
if (size > cmd->bmp.bitmapDataLength)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Short nocodec message: got %" PRIu32 " bytes, require %" PRIuz,
|
WLog_ERR(TAG, "Short nocodec message: got %" PRIu32 " bytes, require %" PRIuz,
|
||||||
cmd->bmp.bitmapDataLength, size);
|
cmd->bmp.bitmapDataLength, size);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (!freerdp_image_copy(gdi->primary_buffer, gdi->dstFormat, gdi->stride, cmd->destLeft,
|
|
||||||
cmd->destTop, cmd->bmp.width, cmd->bmp.height,
|
if (!freerdp_image_copy(gdi->primary_buffer, gdi->dstFormat, gdi->stride, cmdRect.left,
|
||||||
cmd->bmp.bitmapData, format, 0, 0, 0, &gdi->palette,
|
cmdRect.top, cmdRect.right - cmdRect.left,
|
||||||
FREERDP_FLIP_VERTICAL))
|
cmdRect.bottom - cmdRect.top, cmd->bmp.bitmapData, format, 0, 0,
|
||||||
|
0, &gdi->palette, FREERDP_FLIP_VERTICAL))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Failed to process nocodec message");
|
WLog_ERR(TAG, "Failed to process nocodec message");
|
||||||
goto out;
|
goto out;
|
||||||
@ -1084,7 +1114,7 @@ static BOOL gdi_surface_bits(rdpContext* context, const SURFACE_BITS_COMMAND* cm
|
|||||||
if (!(rects = region16_rects(®ion, &nbRects)))
|
if (!(rects = region16_rects(®ion, &nbRects)))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
for (i = 0; i < nbRects; i++)
|
for (UINT32 i = 0; i < nbRects; i++)
|
||||||
{
|
{
|
||||||
UINT32 left = rects[i].left;
|
UINT32 left = rects[i].left;
|
||||||
UINT32 top = rects[i].top;
|
UINT32 top = rects[i].top;
|
||||||
|
|||||||
@ -726,7 +726,7 @@ static UINT gdi_SurfaceCommand_Alpha(rdpGdi* gdi, RdpgfxClientContext* context,
|
|||||||
{
|
{
|
||||||
UINT32 x, y;
|
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;
|
return ERROR_INVALID_DATA;
|
||||||
|
|
||||||
for (y = cmd->top; y < cmd->top + cmd->height; y++)
|
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->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)
|
if (!surface->data)
|
||||||
{
|
{
|
||||||
@ -1079,6 +1079,28 @@ static UINT gdi_DeleteSurface(RdpgfxClientContext* context,
|
|||||||
return rc;
|
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
|
* Function description
|
||||||
*
|
*
|
||||||
@ -1087,40 +1109,36 @@ static UINT gdi_DeleteSurface(RdpgfxClientContext* context,
|
|||||||
static UINT gdi_SolidFill(RdpgfxClientContext* context, const RDPGFX_SOLID_FILL_PDU* solidFill)
|
static UINT gdi_SolidFill(RdpgfxClientContext* context, const RDPGFX_SOLID_FILL_PDU* solidFill)
|
||||||
{
|
{
|
||||||
UINT status = ERROR_INTERNAL_ERROR;
|
UINT status = ERROR_INTERNAL_ERROR;
|
||||||
UINT16 index;
|
BYTE a = 0;
|
||||||
UINT32 color;
|
RECTANGLE_16 invalidRect = { 0 };
|
||||||
BYTE a, r, g, b;
|
|
||||||
UINT32 nWidth, nHeight;
|
|
||||||
RECTANGLE_16* rect;
|
|
||||||
gdiGfxSurface* surface;
|
|
||||||
RECTANGLE_16 invalidRect;
|
|
||||||
rdpGdi* gdi = (rdpGdi*)context->custom;
|
rdpGdi* gdi = (rdpGdi*)context->custom;
|
||||||
|
|
||||||
EnterCriticalSection(&context->mux);
|
EnterCriticalSection(&context->mux);
|
||||||
surface = (gdiGfxSurface*)context->GetSurfaceData(context, solidFill->surfaceId);
|
|
||||||
|
WINPR_ASSERT(context->GetSurfaceData);
|
||||||
|
gdiGfxSurface* surface = (gdiGfxSurface*)context->GetSurfaceData(context, solidFill->surfaceId);
|
||||||
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
b = solidFill->fillPixel.B;
|
const BYTE b = solidFill->fillPixel.B;
|
||||||
g = solidFill->fillPixel.G;
|
const BYTE g = solidFill->fillPixel.G;
|
||||||
r = solidFill->fillPixel.R;
|
const BYTE r = solidFill->fillPixel.R;
|
||||||
/* a = solidFill->fillPixel.XA;
|
|
||||||
* Ignore alpha channel, this is a solid fill. */
|
|
||||||
a = 0xFF;
|
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]);
|
const RECTANGLE_16* 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;
|
|
||||||
|
|
||||||
if (!freerdp_image_fill(surface->data, surface->format, surface->scanline, rect->left,
|
if (!intersect_rect(rect, surface, &invalidRect))
|
||||||
rect->top, nWidth, nHeight, color))
|
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;
|
goto fail;
|
||||||
|
|
||||||
region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect);
|
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;
|
return NULL;
|
||||||
|
|
||||||
nDstStep = nWidth * GetBytesPerPixel(gdi->dstFormat);
|
nDstStep = nWidth * GetBytesPerPixel(gdi->dstFormat);
|
||||||
pDstData = _aligned_malloc(nHeight * nDstStep * 1ULL, 16);
|
pDstData = _aligned_malloc(1ull * nHeight * nDstStep, 16);
|
||||||
|
|
||||||
if (!pDstData)
|
if (!pDstData)
|
||||||
return NULL;
|
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++)
|
for (y = 1; y < nHeight; y++)
|
||||||
{
|
{
|
||||||
BYTE* dstp = gdi_get_bitmap_pointer(hdc, nXDest, nYDest + y);
|
BYTE* dstp = gdi_get_bitmap_pointer(hdc, nXDest, nYDest + y);
|
||||||
memcpy(dstp, srcp, nWidth * formatSize * 1ULL);
|
memcpy(dstp, srcp, 1ull * nWidth * formatSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -66,7 +66,7 @@ static VideoSurface* gdiVideoCreateSurface(VideoClientContext* video, BYTE* data
|
|||||||
ret->base.w = width;
|
ret->base.w = width;
|
||||||
ret->base.h = height;
|
ret->base.h = height;
|
||||||
ret->scanline = width * bpp;
|
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)
|
if (!ret->image)
|
||||||
{
|
{
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user