mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
[core] restructure redirection
* Expose redirection functions via public API * Add getter/setter for public API
This commit is contained in:
80
include/freerdp/redirection.h
Normal file
80
include/freerdp/redirection.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* RDP Server Redirection
|
||||
*
|
||||
* Copyright 2023 Armin Novak <anovak@thincast.com>
|
||||
* Copyright 2023 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_REDIRECTION_H
|
||||
#define FREERDP_REDIRECTION_H
|
||||
|
||||
#include <freerdp/api.h>
|
||||
|
||||
/* Redirection Flags */
|
||||
#define LB_TARGET_NET_ADDRESS 0x00000001
|
||||
#define LB_LOAD_BALANCE_INFO 0x00000002
|
||||
#define LB_USERNAME 0x00000004
|
||||
#define LB_DOMAIN 0x00000008
|
||||
#define LB_PASSWORD 0x00000010
|
||||
#define LB_DONTSTOREUSERNAME 0x00000020
|
||||
#define LB_SMARTCARD_LOGON 0x00000040
|
||||
#define LB_NOREDIRECT 0x00000080
|
||||
#define LB_TARGET_FQDN 0x00000100
|
||||
#define LB_TARGET_NETBIOS_NAME 0x00000200
|
||||
#define LB_TARGET_NET_ADDRESSES 0x00000800
|
||||
#define LB_CLIENT_TSV_URL 0x00001000
|
||||
#define LB_SERVER_TSV_CAPABLE 0x00002000
|
||||
#define LB_PASSWORD_IS_PK_ENCRYPTED 0x00004000
|
||||
#define LB_REDIRECTION_GUID 0x00008000
|
||||
#define LB_TARGET_CERTIFICATE 0x00010000
|
||||
|
||||
#define LB_PASSWORD_MAX_LENGTH 512
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef struct rdp_redirection rdpRedirection;
|
||||
|
||||
FREERDP_API rdpRedirection* redirection_new(void);
|
||||
FREERDP_API void redirection_free(rdpRedirection* redirection);
|
||||
|
||||
/** \brief This function checks if all necessary settings for a given \b rdpRedirection are
|
||||
* available.
|
||||
*
|
||||
* \param redirection The redirection settings to check
|
||||
* \param pFlags An (optional) pointer to UINT32. Is set to the flags that do not have
|
||||
* necessary data available.
|
||||
*
|
||||
* \return \b TRUE if the redirection settings are ready to use, \b FALSE otherwise.
|
||||
*/
|
||||
FREERDP_API BOOL redirection_settings_are_valid(rdpRedirection* redirection, UINT32* pFlags);
|
||||
|
||||
FREERDP_API BOOL redirection_set_flags(rdpRedirection* redirection, UINT32 flags);
|
||||
FREERDP_API BOOL redirection_set_session_id(rdpRedirection* redirection, UINT32 session_id);
|
||||
FREERDP_API BOOL redirection_set_byte_option(rdpRedirection* redirection, UINT32 flag,
|
||||
const BYTE* data, size_t length);
|
||||
FREERDP_API BOOL redirection_set_string_option(rdpRedirection* redirection, UINT32 flag,
|
||||
const char* str);
|
||||
FREERDP_API BOOL redirection_set_array_option(rdpRedirection* redirection, UINT32 flag,
|
||||
const char** str, size_t count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FREERDP_REDIRECTION_H */
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/redirection.h>
|
||||
|
||||
/** \file
|
||||
* \brief This is the FreeRDP settings module.
|
||||
@@ -264,26 +265,6 @@ typedef enum
|
||||
#define TSC_PROXY_CREDS_MODE_SMARTCARD 0x1
|
||||
#define TSC_PROXY_CREDS_MODE_ANY 0x2
|
||||
|
||||
/* Redirection Flags */
|
||||
#define LB_TARGET_NET_ADDRESS 0x00000001
|
||||
#define LB_LOAD_BALANCE_INFO 0x00000002
|
||||
#define LB_USERNAME 0x00000004
|
||||
#define LB_DOMAIN 0x00000008
|
||||
#define LB_PASSWORD 0x00000010
|
||||
#define LB_DONTSTOREUSERNAME 0x00000020
|
||||
#define LB_SMARTCARD_LOGON 0x00000040
|
||||
#define LB_NOREDIRECT 0x00000080
|
||||
#define LB_TARGET_FQDN 0x00000100
|
||||
#define LB_TARGET_NETBIOS_NAME 0x00000200
|
||||
#define LB_TARGET_NET_ADDRESSES 0x00000800
|
||||
#define LB_CLIENT_TSV_URL 0x00001000
|
||||
#define LB_SERVER_TSV_CAPABLE 0x00002000
|
||||
#define LB_PASSWORD_IS_PK_ENCRYPTED 0x00004000
|
||||
#define LB_REDIRECTION_GUID 0x00008000
|
||||
#define LB_TARGET_CERTIFICATE 0x00010000
|
||||
|
||||
#define LB_PASSWORD_MAX_LENGTH 512
|
||||
|
||||
/* Keyboard Hook */
|
||||
#define KEYBOARD_HOOK_LOCAL 0
|
||||
#define KEYBOARD_HOOK_REMOTE 1
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <freerdp/log.h>
|
||||
#include <freerdp/redirection.h>
|
||||
#include <freerdp/utils/string.h>
|
||||
|
||||
#include "connection.h"
|
||||
@@ -84,6 +85,60 @@ static void redirection_free_data(BYTE** str, UINT32* length)
|
||||
*str = NULL;
|
||||
}
|
||||
|
||||
static BOOL redirection_copy_string(char** dst, const char* str)
|
||||
{
|
||||
redirection_free_string(dst);
|
||||
if (!str)
|
||||
return TRUE;
|
||||
|
||||
*dst = _strdup(str);
|
||||
return *dst != NULL;
|
||||
}
|
||||
|
||||
static BOOL redirection_copy_data(BYTE** dst, UINT32* plen, const BYTE* str, size_t len)
|
||||
{
|
||||
redirection_free_data(dst, plen);
|
||||
|
||||
if (!str || (len == 0))
|
||||
return TRUE;
|
||||
if (len > UINT32_MAX)
|
||||
return FALSE;
|
||||
|
||||
*dst = malloc(len);
|
||||
if (!*dst)
|
||||
return FALSE;
|
||||
memcpy(*dst, str, len);
|
||||
*plen = (UINT32)len;
|
||||
return *dst != NULL;
|
||||
}
|
||||
|
||||
static BOOL redirection_copy_array(char*** dst, UINT32* plen, const char** str, size_t len)
|
||||
{
|
||||
redirection_free_array(dst, plen);
|
||||
|
||||
if (!str || (len == 0))
|
||||
return TRUE;
|
||||
|
||||
*dst = calloc(len, sizeof(char));
|
||||
if (!*dst)
|
||||
return FALSE;
|
||||
*plen = len;
|
||||
|
||||
for (UINT32 x = 0; x < len; x++)
|
||||
{
|
||||
if (str[x])
|
||||
(*dst)[x] = _strdup(str[x]);
|
||||
|
||||
if (!((*dst)[x]))
|
||||
{
|
||||
redirection_free_array(dst, plen);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return *dst != NULL;
|
||||
}
|
||||
|
||||
static void rdp_print_redirection_flags(UINT32 flags)
|
||||
{
|
||||
WLog_DBG(TAG, "redirectionFlags = {");
|
||||
@@ -555,3 +610,339 @@ void redirection_free(rdpRedirection* redirection)
|
||||
free(redirection);
|
||||
}
|
||||
}
|
||||
|
||||
static SSIZE_T redir_write_string(UINT32 flag, wStream* s, const char* str)
|
||||
{
|
||||
const size_t length = (strlen(str) + 1);
|
||||
if (!Stream_EnsureRemainingCapacity(s, 4ull + length * sizeof(WCHAR)))
|
||||
return -1;
|
||||
|
||||
const size_t pos = Stream_GetPosition(s);
|
||||
Stream_Write_UINT32(s, (UINT32)length * sizeof(WCHAR));
|
||||
if (Stream_Write_UTF16_String_From_UTF8(s, length, str, length, TRUE) < 0)
|
||||
return -1;
|
||||
return (SSIZE_T)(Stream_GetPosition(s) - pos);
|
||||
}
|
||||
|
||||
static BOOL redir_write_data(UINT32 flag, wStream* s, UINT32 length, const BYTE* data)
|
||||
{
|
||||
if (!Stream_EnsureRemainingCapacity(s, 4ull + length))
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT32(s, length);
|
||||
Stream_Write(s, data, length);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL rdp_write_enhanced_security_redirection_packet(wStream* s, const rdpRedirection* redirection)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
|
||||
WINPR_ASSERT(s);
|
||||
WINPR_ASSERT(redirection);
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(s, 14))
|
||||
goto fail;
|
||||
|
||||
Stream_Write_UINT16(s, 0);
|
||||
Stream_Write_UINT16(s, SEC_REDIRECTION_PKT);
|
||||
|
||||
const size_t lengthOffset = Stream_GetPosition(s);
|
||||
Stream_Seek_UINT16(s); /* placeholder for length */
|
||||
|
||||
if (redirection->sessionID)
|
||||
Stream_Write_UINT32(s, redirection->sessionID);
|
||||
else
|
||||
Stream_Write_UINT32(s, 0);
|
||||
|
||||
Stream_Write_UINT32(s, redirection->flags);
|
||||
|
||||
if (redirection->flags & LB_TARGET_NET_ADDRESS)
|
||||
{
|
||||
if (redir_write_string(LB_TARGET_NET_ADDRESS, s, redirection->TargetNetAddress) < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (redirection->flags & LB_LOAD_BALANCE_INFO)
|
||||
{
|
||||
const UINT32 length = 13 + redirection->LoadBalanceInfoLength + 2;
|
||||
if (!Stream_EnsureRemainingCapacity(s, length))
|
||||
goto fail;
|
||||
Stream_Write_UINT32(s, length);
|
||||
Stream_Write(s, "Cookie: msts=", 13);
|
||||
Stream_Write(s, redirection->LoadBalanceInfo, redirection->LoadBalanceInfoLength);
|
||||
Stream_Write_UINT8(s, 0x0d);
|
||||
Stream_Write_UINT8(s, 0x0a);
|
||||
}
|
||||
|
||||
if (redirection->flags & LB_USERNAME)
|
||||
{
|
||||
if (redir_write_string(LB_USERNAME, s, redirection->Username) < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (redirection->flags & LB_DOMAIN)
|
||||
{
|
||||
if (redir_write_string(LB_DOMAIN, s, redirection->Domain) < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (redirection->flags & LB_PASSWORD)
|
||||
{
|
||||
/* Password is eighter UNICODE or opaque data */
|
||||
if (!redir_write_data(LB_PASSWORD, s, redirection->PasswordLength, redirection->Password))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (redirection->flags & LB_TARGET_FQDN)
|
||||
{
|
||||
if (redir_write_string(LB_TARGET_FQDN, s, redirection->TargetFQDN) < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (redirection->flags & LB_TARGET_NETBIOS_NAME)
|
||||
{
|
||||
if (redir_write_string(LB_TARGET_NETBIOS_NAME, s, redirection->TargetNetBiosName) < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (redirection->flags & LB_CLIENT_TSV_URL)
|
||||
{
|
||||
if (!redir_write_data(LB_CLIENT_TSV_URL, s, redirection->TsvUrlLength, redirection->TsvUrl))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (redirection->flags & LB_REDIRECTION_GUID)
|
||||
{
|
||||
if (!redir_write_data(LB_REDIRECTION_GUID, s, redirection->RedirectionGuidLength,
|
||||
redirection->RedirectionGuid))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (redirection->flags & LB_TARGET_CERTIFICATE)
|
||||
{
|
||||
if (!redir_write_data(LB_REDIRECTION_GUID, s, redirection->TargetCertificateLength,
|
||||
redirection->TargetCertificate))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (redirection->flags & LB_TARGET_NET_ADDRESSES)
|
||||
{
|
||||
UINT32 i;
|
||||
UINT32 length = 0;
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(s, 2 * sizeof(UINT32)))
|
||||
goto fail;
|
||||
|
||||
const size_t start = Stream_GetPosition(s);
|
||||
Stream_Seek_UINT32(s); /* length of field */
|
||||
Stream_Write_UINT32(s, redirection->TargetNetAddressesCount);
|
||||
for (i = 0; i < redirection->TargetNetAddressesCount; i++)
|
||||
{
|
||||
const SSIZE_T rcc =
|
||||
redir_write_string(LB_TARGET_NET_ADDRESSES, s, redirection->TargetNetAddresses[i]);
|
||||
if (rcc < 0)
|
||||
goto fail;
|
||||
length += (UINT32)rcc;
|
||||
}
|
||||
|
||||
/* Write length field */
|
||||
const size_t end = Stream_GetPosition(s);
|
||||
Stream_SetPosition(s, start);
|
||||
Stream_Write_UINT32(s, length);
|
||||
Stream_SetPosition(s, end);
|
||||
}
|
||||
|
||||
/* Padding 8 bytes */
|
||||
if (!Stream_EnsureRemainingCapacity(s, 8))
|
||||
goto fail;
|
||||
Stream_Zero(s, 8);
|
||||
|
||||
const size_t length = Stream_GetPosition(s);
|
||||
Stream_SetPosition(s, lengthOffset);
|
||||
Stream_Write_UINT16(s, (UINT16)length);
|
||||
Stream_SetPosition(s, length);
|
||||
|
||||
rc = TRUE;
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
BOOL redirection_settings_are_valid(rdpRedirection* redirection, UINT32* pFlags)
|
||||
{
|
||||
UINT32 flags = 0;
|
||||
|
||||
WINPR_ASSERT(redirection);
|
||||
|
||||
if (redirection->flags & LB_CLIENT_TSV_URL)
|
||||
{
|
||||
if (!redirection->TsvUrl || (redirection->TsvUrlLength == 0))
|
||||
flags |= LB_CLIENT_TSV_URL;
|
||||
}
|
||||
|
||||
if (redirection->flags & LB_SERVER_TSV_CAPABLE)
|
||||
{
|
||||
if ((redirection->flags & LB_CLIENT_TSV_URL) == 0)
|
||||
flags |= LB_SERVER_TSV_CAPABLE;
|
||||
}
|
||||
|
||||
if (redirection->flags & LB_USERNAME)
|
||||
{
|
||||
if (utils_str_is_empty(redirection->Username))
|
||||
flags |= LB_USERNAME;
|
||||
}
|
||||
|
||||
if (redirection->flags & LB_DOMAIN)
|
||||
{
|
||||
if (utils_str_is_empty(redirection->Domain))
|
||||
flags |= LB_DOMAIN;
|
||||
}
|
||||
|
||||
if (redirection->flags & LB_PASSWORD)
|
||||
{
|
||||
if (!redirection->Password || (redirection->PasswordLength == 0))
|
||||
flags |= LB_PASSWORD;
|
||||
}
|
||||
|
||||
if (redirection->flags & LB_TARGET_FQDN)
|
||||
{
|
||||
if (utils_str_is_empty(redirection->TargetFQDN))
|
||||
flags |= LB_TARGET_FQDN;
|
||||
}
|
||||
|
||||
if (redirection->flags & LB_LOAD_BALANCE_INFO)
|
||||
{
|
||||
if (!redirection->LoadBalanceInfo || (redirection->LoadBalanceInfoLength == 0))
|
||||
flags |= LB_LOAD_BALANCE_INFO;
|
||||
}
|
||||
|
||||
if (redirection->flags & LB_TARGET_NETBIOS_NAME)
|
||||
{
|
||||
if (utils_str_is_empty(redirection->TargetNetBiosName))
|
||||
flags |= LB_TARGET_NETBIOS_NAME;
|
||||
}
|
||||
|
||||
if (redirection->flags & LB_TARGET_NET_ADDRESS)
|
||||
{
|
||||
if (utils_str_is_empty(redirection->TargetNetAddress))
|
||||
flags |= LB_TARGET_NET_ADDRESS;
|
||||
}
|
||||
|
||||
if (redirection->flags & LB_TARGET_NET_ADDRESSES)
|
||||
{
|
||||
if (!redirection->TargetNetAddresses || (redirection->TargetNetAddressesCount == 0))
|
||||
flags |= LB_TARGET_NET_ADDRESSES;
|
||||
else
|
||||
{
|
||||
for (UINT32 x = 0; x < redirection->TargetNetAddressesCount; x++)
|
||||
{
|
||||
if (!redirection->TargetNetAddresses[x])
|
||||
flags |= LB_TARGET_NET_ADDRESSES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (redirection->flags & LB_REDIRECTION_GUID)
|
||||
{
|
||||
if (!redirection->RedirectionGuid || (redirection->RedirectionGuidLength == 0))
|
||||
flags |= LB_REDIRECTION_GUID;
|
||||
}
|
||||
|
||||
if (redirection->flags & LB_TARGET_CERTIFICATE)
|
||||
{
|
||||
if (!redirection->TargetCertificate || (redirection->TargetCertificateLength == 0))
|
||||
flags |= LB_TARGET_CERTIFICATE;
|
||||
}
|
||||
|
||||
if (pFlags)
|
||||
*pFlags = flags;
|
||||
return flags == 0;
|
||||
}
|
||||
|
||||
BOOL redirection_set_flags(rdpRedirection* redirection, UINT32 flags)
|
||||
{
|
||||
WINPR_ASSERT(redirection);
|
||||
redirection->flags = flags;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL redirection_set_session_id(rdpRedirection* redirection, UINT32 session_id)
|
||||
{
|
||||
WINPR_ASSERT(redirection);
|
||||
redirection->sessionID = session_id;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL redirection_unsupported(const char* fkt, UINT32 flag, UINT32 mask)
|
||||
{
|
||||
char buffer[1024] = { 0 };
|
||||
char buffer2[1024] = { 0 };
|
||||
WLog_WARN(TAG, "[%s] supported flags are {%s}, have {%s}", fkt,
|
||||
rdp_redirection_flags_to_string(mask, buffer, sizeof(buffer)),
|
||||
rdp_redirection_flags_to_string(flag, buffer2, sizeof(buffer2)));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL redirection_set_byte_option(rdpRedirection* redirection, UINT32 flag, const BYTE* data,
|
||||
size_t length)
|
||||
{
|
||||
WINPR_ASSERT(redirection);
|
||||
switch (flag)
|
||||
{
|
||||
case LB_CLIENT_TSV_URL:
|
||||
return redirection_copy_data(&redirection->TsvUrl, &redirection->TsvUrlLength, data,
|
||||
length);
|
||||
case LB_PASSWORD:
|
||||
return redirection_copy_data(&redirection->Password, &redirection->PasswordLength, data,
|
||||
length);
|
||||
case LB_LOAD_BALANCE_INFO:
|
||||
return redirection_copy_data(&redirection->LoadBalanceInfo,
|
||||
&redirection->LoadBalanceInfoLength, data, length);
|
||||
case LB_REDIRECTION_GUID:
|
||||
return redirection_copy_data(&redirection->RedirectionGuid,
|
||||
&redirection->RedirectionGuidLength, data, length);
|
||||
case LB_TARGET_CERTIFICATE:
|
||||
return redirection_copy_data(&redirection->TargetCertificate,
|
||||
&redirection->TargetCertificateLength, data, length);
|
||||
default:
|
||||
return redirection_unsupported(__FUNCTION__, flag,
|
||||
LB_CLIENT_TSV_URL | LB_PASSWORD | LB_LOAD_BALANCE_INFO |
|
||||
LB_REDIRECTION_GUID | LB_TARGET_CERTIFICATE);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL redirection_set_string_option(rdpRedirection* redirection, UINT32 flag, const char* str)
|
||||
{
|
||||
WINPR_ASSERT(redirection);
|
||||
switch (flag)
|
||||
{
|
||||
case LB_USERNAME:
|
||||
return redirection_copy_string(&redirection->Username, str);
|
||||
case LB_DOMAIN:
|
||||
return redirection_copy_string(&redirection->Domain, str);
|
||||
case LB_TARGET_FQDN:
|
||||
return redirection_copy_string(&redirection->TargetFQDN, str);
|
||||
case LB_TARGET_NETBIOS_NAME:
|
||||
return redirection_copy_string(&redirection->TargetNetBiosName, str);
|
||||
case LB_TARGET_NET_ADDRESS:
|
||||
return redirection_copy_string(&redirection->TargetNetAddress, str);
|
||||
default:
|
||||
return redirection_unsupported(__FUNCTION__, flag,
|
||||
LB_USERNAME | LB_DOMAIN | LB_TARGET_FQDN |
|
||||
LB_TARGET_NETBIOS_NAME | LB_TARGET_NET_ADDRESS);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL redirection_set_array_option(rdpRedirection* redirection, UINT32 flag, const char** str,
|
||||
size_t count)
|
||||
{
|
||||
WINPR_ASSERT(redirection);
|
||||
switch (flag)
|
||||
{
|
||||
case LB_TARGET_NET_ADDRESSES:
|
||||
return redirection_copy_array(&redirection->TargetNetAddresses,
|
||||
&redirection->TargetNetAddressesCount, str, count);
|
||||
default:
|
||||
return redirection_unsupported(__FUNCTION__, flag, LB_TARGET_NET_ADDRESSES);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,12 +31,11 @@ typedef struct rdp_redirection rdpRedirection;
|
||||
#include <winpr/wlog.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
FREERDP_LOCAL state_run_t rdp_recv_enhanced_security_redirection_packet(rdpRdp* rdp, wStream* s);
|
||||
|
||||
FREERDP_LOCAL int rdp_redirection_apply_settings(rdpRdp* rdp);
|
||||
|
||||
FREERDP_LOCAL rdpRedirection* redirection_new(void);
|
||||
FREERDP_LOCAL void redirection_free(rdpRedirection* redirection);
|
||||
FREERDP_LOCAL state_run_t rdp_recv_enhanced_security_redirection_packet(rdpRdp* rdp, wStream* s);
|
||||
FREERDP_LOCAL BOOL
|
||||
rdp_write_enhanced_security_redirection_packet(wStream* s, const rdpRedirection* redirection);
|
||||
|
||||
#define REDIR_TAG FREERDP_TAG("core.redirection")
|
||||
#ifdef WITH_DEBUG_REDIR
|
||||
|
||||
Reference in New Issue
Block a user