libfreerdp-core: expose new API to allow FreeRDS virtual channel hooking
This commit is contained in:
parent
8865077b40
commit
11ae267518
@ -48,9 +48,15 @@ typedef BOOL (*psPeerLogon)(freerdp_peer* client, SEC_WINNT_AUTH_IDENTITY* ident
|
|||||||
typedef int (*psPeerSendChannelData)(freerdp_peer* client, UINT16 channelId, BYTE* data, int size);
|
typedef int (*psPeerSendChannelData)(freerdp_peer* client, UINT16 channelId, BYTE* data, int size);
|
||||||
typedef int (*psPeerReceiveChannelData)(freerdp_peer* client, UINT16 channelId, BYTE* data, int size, int flags, int totalSize);
|
typedef int (*psPeerReceiveChannelData)(freerdp_peer* client, UINT16 channelId, BYTE* data, int size, int flags, int totalSize);
|
||||||
|
|
||||||
|
typedef HANDLE (*psPeerVirtualChannelOpen)(freerdp_peer* client, const char* name, UINT32 flags);
|
||||||
|
typedef BOOL (*psPeerVirtualChannelClose)(freerdp_peer* client, HANDLE hChannel);
|
||||||
|
typedef int (*psPeerVirtualChannelRead)(freerdp_peer* client, HANDLE hChannel, BYTE* buffer, UINT32 length);
|
||||||
|
typedef int (*psPeerVirtualChannelWrite)(freerdp_peer* client, HANDLE hChannel, BYTE* buffer, UINT32 length);
|
||||||
|
|
||||||
struct rdp_freerdp_peer
|
struct rdp_freerdp_peer
|
||||||
{
|
{
|
||||||
rdpContext* context;
|
rdpContext* context;
|
||||||
|
|
||||||
int sockfd;
|
int sockfd;
|
||||||
char hostname[50];
|
char hostname[50];
|
||||||
|
|
||||||
@ -79,6 +85,11 @@ struct rdp_freerdp_peer
|
|||||||
psPeerSendChannelData SendChannelData;
|
psPeerSendChannelData SendChannelData;
|
||||||
psPeerReceiveChannelData ReceiveChannelData;
|
psPeerReceiveChannelData ReceiveChannelData;
|
||||||
|
|
||||||
|
psPeerVirtualChannelOpen VirtualChannelOpen;
|
||||||
|
psPeerVirtualChannelClose VirtualChannelClose;
|
||||||
|
psPeerVirtualChannelRead VirtualChannelRead;
|
||||||
|
psPeerVirtualChannelWrite VirtualChannelWrite;
|
||||||
|
|
||||||
int pId;
|
int pId;
|
||||||
UINT32 ack_frame_id;
|
UINT32 ack_frame_id;
|
||||||
BOOL local;
|
BOOL local;
|
||||||
|
@ -1059,7 +1059,8 @@ rdpMcs* mcs_new(rdpTransport* transport)
|
|||||||
{
|
{
|
||||||
rdpMcs* mcs;
|
rdpMcs* mcs;
|
||||||
|
|
||||||
mcs = (rdpMcs *)calloc(1, sizeof(rdpMcs));
|
mcs = (rdpMcs*) calloc(1, sizeof(rdpMcs));
|
||||||
|
|
||||||
if (!mcs)
|
if (!mcs)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -1073,7 +1074,11 @@ rdpMcs* mcs_new(rdpTransport* transport)
|
|||||||
|
|
||||||
mcs->channelCount = 0;
|
mcs->channelCount = 0;
|
||||||
mcs->channelMaxCount = CHANNEL_MAX_COUNT;
|
mcs->channelMaxCount = CHANNEL_MAX_COUNT;
|
||||||
mcs->channels = (rdpMcsChannel *)calloc(mcs->channelMaxCount, sizeof(rdpMcsChannel));
|
|
||||||
|
mcs->baseChannelId = MCS_GLOBAL_CHANNEL_ID + 1;
|
||||||
|
|
||||||
|
mcs->channels = (rdpMcsChannel*) calloc(mcs->channelMaxCount, sizeof(rdpMcsChannel));
|
||||||
|
|
||||||
if (!mcs->channels)
|
if (!mcs->channels)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
||||||
|
@ -139,6 +139,7 @@ struct rdp_mcs
|
|||||||
rdpSettings* settings;
|
rdpSettings* settings;
|
||||||
|
|
||||||
UINT16 userId;
|
UINT16 userId;
|
||||||
|
UINT16 baseChannelId;
|
||||||
UINT16 messageChannelId;
|
UINT16 messageChannelId;
|
||||||
|
|
||||||
DomainParameters domainParameters;
|
DomainParameters domainParameters;
|
||||||
|
@ -37,6 +37,139 @@
|
|||||||
extern const char* DATA_PDU_TYPE_STRINGS[80];
|
extern const char* DATA_PDU_TYPE_STRINGS[80];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static HANDLE freerdp_peer_virtual_channel_open(freerdp_peer* client, const char* name, UINT32 flags)
|
||||||
|
{
|
||||||
|
int length;
|
||||||
|
UINT32 index;
|
||||||
|
BOOL joined = FALSE;
|
||||||
|
rdpMcsChannel* mcsChannel = NULL;
|
||||||
|
rdpPeerChannel* peerChannel = NULL;
|
||||||
|
rdpMcs* mcs = client->context->rdp->mcs;
|
||||||
|
|
||||||
|
if (flags & WTS_CHANNEL_OPTION_DYNAMIC)
|
||||||
|
return NULL; /* not yet supported */
|
||||||
|
|
||||||
|
length = strlen(name);
|
||||||
|
|
||||||
|
if (length > 8)
|
||||||
|
return NULL; /* SVC maximum name length is 8 */
|
||||||
|
|
||||||
|
for (index = 0; index < mcs->channelCount; index++)
|
||||||
|
{
|
||||||
|
mcsChannel = &(mcs->channels[index]);
|
||||||
|
|
||||||
|
if (!mcsChannel->joined)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strncmp(name, mcsChannel->Name, length) == 0)
|
||||||
|
{
|
||||||
|
joined = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!joined)
|
||||||
|
return NULL; /* channel is not joined */
|
||||||
|
|
||||||
|
peerChannel = (rdpPeerChannel*) mcsChannel->handle;
|
||||||
|
|
||||||
|
if (peerChannel)
|
||||||
|
{
|
||||||
|
/* channel is already open */
|
||||||
|
return (HANDLE) peerChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
peerChannel = (rdpPeerChannel*) calloc(1, sizeof(rdpPeerChannel));
|
||||||
|
|
||||||
|
if (peerChannel)
|
||||||
|
{
|
||||||
|
peerChannel->index = index;
|
||||||
|
peerChannel->client = client;
|
||||||
|
peerChannel->channelFlags = flags;
|
||||||
|
peerChannel->channelId = mcsChannel->ChannelId;
|
||||||
|
peerChannel->mcsChannel = mcsChannel;
|
||||||
|
mcsChannel->handle = (void*) peerChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (HANDLE) peerChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL freerdp_peer_virtual_channel_close(freerdp_peer* client, HANDLE hChannel)
|
||||||
|
{
|
||||||
|
rdpMcsChannel* mcsChannel = NULL;
|
||||||
|
rdpPeerChannel* peerChannel = NULL;
|
||||||
|
|
||||||
|
if (!hChannel)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
peerChannel = (rdpPeerChannel*) hChannel;
|
||||||
|
mcsChannel = peerChannel->mcsChannel;
|
||||||
|
|
||||||
|
mcsChannel->handle = NULL;
|
||||||
|
free(peerChannel);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int freerdp_peer_virtual_channel_read(freerdp_peer* client, HANDLE hChannel, BYTE* buffer, UINT32 length)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int freerdp_peer_virtual_channel_write(freerdp_peer* client, HANDLE hChannel, BYTE* buffer, UINT32 length)
|
||||||
|
{
|
||||||
|
wStream* s;
|
||||||
|
UINT32 flags;
|
||||||
|
UINT32 chunkSize;
|
||||||
|
UINT32 maxChunkSize;
|
||||||
|
UINT32 totalLength;
|
||||||
|
rdpRdp* rdp = client->context->rdp;
|
||||||
|
rdpPeerChannel* peerChannel = (rdpPeerChannel*) hChannel;
|
||||||
|
rdpMcsChannel* mcsChannel = peerChannel->mcsChannel;
|
||||||
|
|
||||||
|
if (!hChannel)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (peerChannel->channelFlags & WTS_CHANNEL_OPTION_DYNAMIC)
|
||||||
|
return -1; /* not yet supported */
|
||||||
|
|
||||||
|
maxChunkSize = rdp->settings->VirtualChannelChunkSize;
|
||||||
|
|
||||||
|
totalLength = length;
|
||||||
|
flags = CHANNEL_FLAG_FIRST;
|
||||||
|
|
||||||
|
while (length > 0)
|
||||||
|
{
|
||||||
|
s = rdp_send_stream_init(rdp);
|
||||||
|
|
||||||
|
if (length > maxChunkSize)
|
||||||
|
{
|
||||||
|
chunkSize = rdp->settings->VirtualChannelChunkSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chunkSize = length;
|
||||||
|
flags |= CHANNEL_FLAG_LAST;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mcsChannel->options & CHANNEL_OPTION_SHOW_PROTOCOL)
|
||||||
|
flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
|
||||||
|
|
||||||
|
Stream_Write_UINT32(s, totalLength);
|
||||||
|
Stream_Write_UINT32(s, flags);
|
||||||
|
Stream_EnsureRemainingCapacity(s, chunkSize);
|
||||||
|
Stream_Write(s, buffer, chunkSize);
|
||||||
|
|
||||||
|
rdp_send(rdp, s, peerChannel->channelId);
|
||||||
|
|
||||||
|
buffer += chunkSize;
|
||||||
|
length -= chunkSize;
|
||||||
|
flags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL freerdp_peer_initialize(freerdp_peer* client)
|
static BOOL freerdp_peer_initialize(freerdp_peer* client)
|
||||||
{
|
{
|
||||||
rdpRdp* rdp = client->context->rdp;
|
rdpRdp* rdp = client->context->rdp;
|
||||||
@ -427,8 +560,7 @@ static BOOL freerdp_peer_is_write_blocked(freerdp_peer* peer)
|
|||||||
|
|
||||||
static int freerdp_peer_drain_output_buffer(freerdp_peer* peer)
|
static int freerdp_peer_drain_output_buffer(freerdp_peer* peer)
|
||||||
{
|
{
|
||||||
|
rdpTransport* transport = peer->context->rdp->transport;
|
||||||
rdpTransport *transport = peer->context->rdp->transport;
|
|
||||||
|
|
||||||
return tranport_drain_output_buffer(transport);
|
return tranport_drain_output_buffer(transport);
|
||||||
}
|
}
|
||||||
@ -500,6 +632,9 @@ freerdp_peer* freerdp_peer_new(int sockfd)
|
|||||||
client->SendChannelData = freerdp_peer_send_channel_data;
|
client->SendChannelData = freerdp_peer_send_channel_data;
|
||||||
client->IsWriteBlocked = freerdp_peer_is_write_blocked;
|
client->IsWriteBlocked = freerdp_peer_is_write_blocked;
|
||||||
client->DrainOutputBuffer = freerdp_peer_drain_output_buffer;
|
client->DrainOutputBuffer = freerdp_peer_drain_output_buffer;
|
||||||
|
client->VirtualChannelOpen = freerdp_peer_virtual_channel_open;
|
||||||
|
client->VirtualChannelClose = freerdp_peer_virtual_channel_close;
|
||||||
|
client->VirtualChannelWrite = freerdp_peer_virtual_channel_write;
|
||||||
}
|
}
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
|
@ -21,6 +21,9 @@
|
|||||||
#define __PEER
|
#define __PEER
|
||||||
|
|
||||||
#include "rdp.h"
|
#include "rdp.h"
|
||||||
|
#include "mcs.h"
|
||||||
|
#include "server.h"
|
||||||
|
|
||||||
#include <freerdp/peer.h>
|
#include <freerdp/peer.h>
|
||||||
|
|
||||||
#endif /* __PEER */
|
#endif /* __PEER */
|
||||||
|
@ -32,6 +32,7 @@ typedef struct rdp_peer_channel rdpPeerChannel;
|
|||||||
typedef struct WTSVirtualChannelManager WTSVirtualChannelManager;
|
typedef struct WTSVirtualChannelManager WTSVirtualChannelManager;
|
||||||
|
|
||||||
#include "rdp.h"
|
#include "rdp.h"
|
||||||
|
#include "mcs.h"
|
||||||
|
|
||||||
#define CREATE_REQUEST_PDU 0x01
|
#define CREATE_REQUEST_PDU 0x01
|
||||||
#define DATA_FIRST_PDU 0x02
|
#define DATA_FIRST_PDU 0x02
|
||||||
@ -65,15 +66,17 @@ struct rdp_peer_channel
|
|||||||
WTSVirtualChannelManager* vcm;
|
WTSVirtualChannelManager* vcm;
|
||||||
freerdp_peer* client;
|
freerdp_peer* client;
|
||||||
|
|
||||||
|
UINT16 index;
|
||||||
UINT32 channelId;
|
UINT32 channelId;
|
||||||
UINT16 channelType;
|
UINT16 channelType;
|
||||||
UINT16 index;
|
UINT32 channelFlags;
|
||||||
|
|
||||||
wStream* receiveData;
|
wStream* receiveData;
|
||||||
wMessageQueue* queue;
|
wMessageQueue* queue;
|
||||||
|
|
||||||
BYTE dvc_open_state;
|
BYTE dvc_open_state;
|
||||||
UINT32 dvc_total_length;
|
UINT32 dvc_total_length;
|
||||||
|
rdpMcsChannel* mcsChannel;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WTSVirtualChannelManager
|
struct WTSVirtualChannelManager
|
||||||
|
@ -138,6 +138,7 @@ typedef struct _wArrayList wArrayList;
|
|||||||
|
|
||||||
WINPR_API int ArrayList_Capacity(wArrayList* arrayList);
|
WINPR_API int ArrayList_Capacity(wArrayList* arrayList);
|
||||||
WINPR_API int ArrayList_Count(wArrayList* arrayList);
|
WINPR_API int ArrayList_Count(wArrayList* arrayList);
|
||||||
|
WINPR_API int ArrayList_Items(wArrayList* arrayList, ULONG_PTR** ppItems);
|
||||||
WINPR_API BOOL ArrayList_IsFixedSized(wArrayList* arrayList);
|
WINPR_API BOOL ArrayList_IsFixedSized(wArrayList* arrayList);
|
||||||
WINPR_API BOOL ArrayList_IsReadOnly(wArrayList* arrayList);
|
WINPR_API BOOL ArrayList_IsReadOnly(wArrayList* arrayList);
|
||||||
WINPR_API BOOL ArrayList_IsSynchronized(wArrayList* arrayList);
|
WINPR_API BOOL ArrayList_IsSynchronized(wArrayList* arrayList);
|
||||||
|
@ -52,6 +52,16 @@ int ArrayList_Count(wArrayList *arrayList)
|
|||||||
return arrayList->size;
|
return arrayList->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the internal list of items contained in the ArrayList.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ArrayList_Items(wArrayList* arrayList, ULONG_PTR** ppItems)
|
||||||
|
{
|
||||||
|
*ppItems = (ULONG_PTR*) arrayList->array;
|
||||||
|
return arrayList->size;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a value indicating whether the ArrayList has a fixed size.
|
* Gets a value indicating whether the ArrayList has a fixed size.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user