mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2025-06-03 00:00:20 +00:00
Added attach/detach support for channels.
This commit is contained in:
parent
8d0809cf26
commit
9f19da798c
@ -91,6 +91,7 @@ struct _AUDIN_PLUGIN
|
|||||||
IAudinDevice* device;
|
IAudinDevice* device;
|
||||||
|
|
||||||
rdpContext* rdpcontext;
|
rdpContext* rdpcontext;
|
||||||
|
BOOL attached;
|
||||||
};
|
};
|
||||||
|
|
||||||
static BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args);
|
static BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args);
|
||||||
@ -106,11 +107,8 @@ static UINT audin_process_version(IWTSVirtualChannelCallback* pChannelCallback,
|
|||||||
wStream* out;
|
wStream* out;
|
||||||
UINT32 Version;
|
UINT32 Version;
|
||||||
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
|
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
|
||||||
|
|
||||||
Stream_Read_UINT32(s, Version);
|
Stream_Read_UINT32(s, Version);
|
||||||
|
|
||||||
DEBUG_DVC("Version=%"PRIu32"", Version);
|
DEBUG_DVC("Version=%"PRIu32"", Version);
|
||||||
|
|
||||||
out = Stream_New(NULL, 5);
|
out = Stream_New(NULL, 5);
|
||||||
|
|
||||||
if (!out)
|
if (!out)
|
||||||
@ -121,9 +119,9 @@ static UINT audin_process_version(IWTSVirtualChannelCallback* pChannelCallback,
|
|||||||
|
|
||||||
Stream_Write_UINT8(out, MSG_SNDIN_VERSION);
|
Stream_Write_UINT8(out, MSG_SNDIN_VERSION);
|
||||||
Stream_Write_UINT32(out, Version);
|
Stream_Write_UINT32(out, Version);
|
||||||
error = callback->channel->Write(callback->channel, (UINT32) Stream_GetPosition(out), Stream_Buffer(out), NULL);
|
error = callback->channel->Write(callback->channel, (UINT32) Stream_GetPosition(out),
|
||||||
|
Stream_Buffer(out), NULL);
|
||||||
Stream_Free(out, TRUE);
|
Stream_Free(out, TRUE);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,7 +134,6 @@ static UINT audin_send_incoming_data_pdu(IWTSVirtualChannelCallback* pChannelCal
|
|||||||
{
|
{
|
||||||
BYTE out_data[1];
|
BYTE out_data[1];
|
||||||
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
|
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
|
||||||
|
|
||||||
out_data[0] = MSG_SNDIN_DATA_INCOMING;
|
out_data[0] = MSG_SNDIN_DATA_INCOMING;
|
||||||
return callback->channel->Write(callback->channel, 1, out_data, NULL);
|
return callback->channel->Write(callback->channel, 1, out_data, NULL);
|
||||||
}
|
}
|
||||||
@ -157,17 +154,18 @@ static UINT audin_process_formats(IWTSVirtualChannelCallback* pChannelCallback,
|
|||||||
UINT32 NumFormats;
|
UINT32 NumFormats;
|
||||||
audinFormat format;
|
audinFormat format;
|
||||||
UINT32 cbSizeFormatsPacket;
|
UINT32 cbSizeFormatsPacket;
|
||||||
|
|
||||||
Stream_Read_UINT32(s, NumFormats);
|
Stream_Read_UINT32(s, NumFormats);
|
||||||
DEBUG_DVC("NumFormats %"PRIu32"", NumFormats);
|
DEBUG_DVC("NumFormats %"PRIu32"", NumFormats);
|
||||||
|
|
||||||
if ((NumFormats < 1) || (NumFormats > 1000))
|
if ((NumFormats < 1) || (NumFormats > 1000))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "bad NumFormats %"PRIu32"", NumFormats);
|
WLog_ERR(TAG, "bad NumFormats %"PRIu32"", NumFormats);
|
||||||
return ERROR_INVALID_DATA;
|
return ERROR_INVALID_DATA;
|
||||||
}
|
}
|
||||||
Stream_Seek_UINT32(s); /* cbSizeFormatsPacket */
|
|
||||||
|
|
||||||
|
Stream_Seek_UINT32(s); /* cbSizeFormatsPacket */
|
||||||
callback->formats = (audinFormat*) calloc(1, NumFormats * sizeof(audinFormat));
|
callback->formats = (audinFormat*) calloc(1, NumFormats * sizeof(audinFormat));
|
||||||
|
|
||||||
if (!callback->formats)
|
if (!callback->formats)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "calloc failed!");
|
WLog_ERR(TAG, "calloc failed!");
|
||||||
@ -198,7 +196,6 @@ static UINT audin_process_formats(IWTSVirtualChannelCallback* pChannelCallback,
|
|||||||
Stream_Read_UINT16(s, format.cbSize);
|
Stream_Read_UINT16(s, format.cbSize);
|
||||||
format.data = Stream_Pointer(s);
|
format.data = Stream_Pointer(s);
|
||||||
Stream_Seek(s, format.cbSize);
|
Stream_Seek(s, format.cbSize);
|
||||||
|
|
||||||
DEBUG_DVC("wFormatTag=%"PRIu16" nChannels=%"PRIu16" nSamplesPerSec=%"PRIu32" "
|
DEBUG_DVC("wFormatTag=%"PRIu16" nChannels=%"PRIu16" nSamplesPerSec=%"PRIu32" "
|
||||||
"nBlockAlign=%"PRIu16" wBitsPerSample=%"PRIu16" cbSize=%"PRIu16"",
|
"nBlockAlign=%"PRIu16" wBitsPerSample=%"PRIu16" cbSize=%"PRIu16"",
|
||||||
format.wFormatTag, format.nChannels, format.nSamplesPerSec,
|
format.wFormatTag, format.nChannels, format.nSamplesPerSec,
|
||||||
@ -206,16 +203,19 @@ static UINT audin_process_formats(IWTSVirtualChannelCallback* pChannelCallback,
|
|||||||
|
|
||||||
if (audin->fixed_format > 0 && audin->fixed_format != format.wFormatTag)
|
if (audin->fixed_format > 0 && audin->fixed_format != format.wFormatTag)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (audin->fixed_channel > 0 && audin->fixed_channel != format.nChannels)
|
if (audin->fixed_channel > 0 && audin->fixed_channel != format.nChannels)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (audin->fixed_rate > 0 && audin->fixed_rate != format.nSamplesPerSec)
|
if (audin->fixed_rate > 0 && audin->fixed_rate != format.nSamplesPerSec)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (audin->device && audin->device->FormatSupported(audin->device, &format))
|
if (audin->device && audin->device->FormatSupported(audin->device, &format))
|
||||||
{
|
{
|
||||||
DEBUG_DVC("format ok");
|
DEBUG_DVC("format ok");
|
||||||
|
|
||||||
/* Store the agreed format in the corresponding index */
|
/* Store the agreed format in the corresponding index */
|
||||||
callback->formats[callback->formats_count++] = format;
|
callback->formats[callback->formats_count++] = format;
|
||||||
|
|
||||||
/* Put the format to output buffer */
|
/* Put the format to output buffer */
|
||||||
if (!Stream_EnsureRemainingCapacity(out, 18 + format.cbSize))
|
if (!Stream_EnsureRemainingCapacity(out, 18 + format.cbSize))
|
||||||
{
|
{
|
||||||
@ -224,7 +224,6 @@ static UINT audin_process_formats(IWTSVirtualChannelCallback* pChannelCallback,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Stream_Write(out, fm, 18 + format.cbSize);
|
Stream_Write(out, fm, 18 + format.cbSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,20 +236,19 @@ static UINT audin_process_formats(IWTSVirtualChannelCallback* pChannelCallback,
|
|||||||
|
|
||||||
cbSizeFormatsPacket = (UINT32) Stream_GetPosition(out);
|
cbSizeFormatsPacket = (UINT32) Stream_GetPosition(out);
|
||||||
Stream_SetPosition(out, 0);
|
Stream_SetPosition(out, 0);
|
||||||
|
|
||||||
Stream_Write_UINT8(out, MSG_SNDIN_FORMATS); /* Header (1 byte) */
|
Stream_Write_UINT8(out, MSG_SNDIN_FORMATS); /* Header (1 byte) */
|
||||||
Stream_Write_UINT32(out, callback->formats_count); /* NumFormats (4 bytes) */
|
Stream_Write_UINT32(out, callback->formats_count); /* NumFormats (4 bytes) */
|
||||||
Stream_Write_UINT32(out, cbSizeFormatsPacket); /* cbSizeFormatsPacket (4 bytes) */
|
Stream_Write_UINT32(out, cbSizeFormatsPacket); /* cbSizeFormatsPacket (4 bytes) */
|
||||||
|
|
||||||
error = callback->channel->Write(callback->channel, cbSizeFormatsPacket, Stream_Buffer(out), NULL);
|
error = callback->channel->Write(callback->channel, cbSizeFormatsPacket, Stream_Buffer(out), NULL);
|
||||||
out:
|
out:
|
||||||
|
|
||||||
if (error != CHANNEL_RC_OK)
|
if (error != CHANNEL_RC_OK)
|
||||||
{
|
{
|
||||||
free(callback->formats);
|
free(callback->formats);
|
||||||
callback->formats = NULL;
|
callback->formats = NULL;
|
||||||
}
|
}
|
||||||
Stream_Free(out, TRUE);
|
|
||||||
|
|
||||||
|
Stream_Free(out, TRUE);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,12 +257,12 @@ out:
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
static UINT audin_send_format_change_pdu(IWTSVirtualChannelCallback* pChannelCallback, UINT32 NewFormat)
|
static UINT audin_send_format_change_pdu(IWTSVirtualChannelCallback* pChannelCallback,
|
||||||
|
UINT32 NewFormat)
|
||||||
{
|
{
|
||||||
UINT error;
|
UINT error;
|
||||||
wStream* out;
|
wStream* out;
|
||||||
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
|
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
|
||||||
|
|
||||||
out = Stream_New(NULL, 5);
|
out = Stream_New(NULL, 5);
|
||||||
|
|
||||||
if (!out)
|
if (!out)
|
||||||
@ -277,7 +275,6 @@ static UINT audin_send_format_change_pdu(IWTSVirtualChannelCallback* pChannelCal
|
|||||||
Stream_Write_UINT32(out, NewFormat);
|
Stream_Write_UINT32(out, NewFormat);
|
||||||
error = callback->channel->Write(callback->channel, 5, Stream_Buffer(out), NULL);
|
error = callback->channel->Write(callback->channel, 5, Stream_Buffer(out), NULL);
|
||||||
Stream_Free(out, TRUE);
|
Stream_Free(out, TRUE);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,7 +288,6 @@ static UINT audin_send_open_reply_pdu(IWTSVirtualChannelCallback* pChannelCallba
|
|||||||
UINT error;
|
UINT error;
|
||||||
wStream* out;
|
wStream* out;
|
||||||
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
|
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
|
||||||
|
|
||||||
out = Stream_New(NULL, 5);
|
out = Stream_New(NULL, 5);
|
||||||
|
|
||||||
if (!out)
|
if (!out)
|
||||||
@ -304,7 +300,6 @@ static UINT audin_send_open_reply_pdu(IWTSVirtualChannelCallback* pChannelCallba
|
|||||||
Stream_Write_UINT32(out, Result);
|
Stream_Write_UINT32(out, Result);
|
||||||
error = callback->channel->Write(callback->channel, 5, Stream_Buffer(out), NULL);
|
error = callback->channel->Write(callback->channel, 5, Stream_Buffer(out), NULL);
|
||||||
Stream_Free(out, TRUE);
|
Stream_Free(out, TRUE);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,9 +330,9 @@ static UINT audin_receive_wave_data(const BYTE* data, int size, void* user_data)
|
|||||||
|
|
||||||
Stream_Write_UINT8(out, MSG_SNDIN_DATA);
|
Stream_Write_UINT8(out, MSG_SNDIN_DATA);
|
||||||
Stream_Write(out, data, size);
|
Stream_Write(out, data, size);
|
||||||
error = callback->channel->Write(callback->channel, (UINT32) Stream_GetPosition(out), Stream_Buffer(out), NULL);
|
error = callback->channel->Write(callback->channel, (UINT32) Stream_GetPosition(out),
|
||||||
|
Stream_Buffer(out), NULL);
|
||||||
Stream_Free(out, TRUE);
|
Stream_Free(out, TRUE);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,10 +349,8 @@ static UINT audin_process_open(IWTSVirtualChannelCallback* pChannelCallback, wSt
|
|||||||
UINT32 initialFormat;
|
UINT32 initialFormat;
|
||||||
UINT32 FramesPerPacket;
|
UINT32 FramesPerPacket;
|
||||||
UINT error = CHANNEL_RC_OK;
|
UINT error = CHANNEL_RC_OK;
|
||||||
|
|
||||||
Stream_Read_UINT32(s, FramesPerPacket);
|
Stream_Read_UINT32(s, FramesPerPacket);
|
||||||
Stream_Read_UINT32(s, initialFormat);
|
Stream_Read_UINT32(s, initialFormat);
|
||||||
|
|
||||||
DEBUG_DVC("FramesPerPacket=%"PRIu32" initialFormat=%"PRIu32"",
|
DEBUG_DVC("FramesPerPacket=%"PRIu32" initialFormat=%"PRIu32"",
|
||||||
FramesPerPacket, initialFormat);
|
FramesPerPacket, initialFormat);
|
||||||
|
|
||||||
@ -369,15 +362,19 @@ static UINT audin_process_open(IWTSVirtualChannelCallback* pChannelCallback, wSt
|
|||||||
}
|
}
|
||||||
|
|
||||||
format = &callback->formats[initialFormat];
|
format = &callback->formats[initialFormat];
|
||||||
|
|
||||||
if (audin->device)
|
if (audin->device)
|
||||||
{
|
{
|
||||||
IFCALLRET(audin->device->SetFormat, error, audin->device, format, FramesPerPacket);
|
IFCALLRET(audin->device->SetFormat, error, audin->device, format, FramesPerPacket);
|
||||||
|
|
||||||
if (error != CHANNEL_RC_OK)
|
if (error != CHANNEL_RC_OK)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "SetFormat failed with errorcode %"PRIu32"", error);
|
WLog_ERR(TAG, "SetFormat failed with errorcode %"PRIu32"", error);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
IFCALLRET(audin->device->Open, error, audin->device, audin_receive_wave_data, callback);
|
IFCALLRET(audin->device->Open, error, audin->device, audin_receive_wave_data, callback);
|
||||||
|
|
||||||
if (error != CHANNEL_RC_OK)
|
if (error != CHANNEL_RC_OK)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Open failed with errorcode %"PRIu32"", error);
|
WLog_ERR(TAG, "Open failed with errorcode %"PRIu32"", error);
|
||||||
@ -405,13 +402,11 @@ static UINT audin_process_open(IWTSVirtualChannelCallback* pChannelCallback, wSt
|
|||||||
static UINT audin_process_format_change(IWTSVirtualChannelCallback* pChannelCallback, wStream* s)
|
static UINT audin_process_format_change(IWTSVirtualChannelCallback* pChannelCallback, wStream* s)
|
||||||
{
|
{
|
||||||
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
|
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
|
||||||
AUDIN_PLUGIN * audin = (AUDIN_PLUGIN*) callback->plugin;
|
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) callback->plugin;
|
||||||
UINT32 NewFormat;
|
UINT32 NewFormat;
|
||||||
audinFormat* format;
|
audinFormat* format;
|
||||||
UINT error = CHANNEL_RC_OK;
|
UINT error = CHANNEL_RC_OK;
|
||||||
|
|
||||||
Stream_Read_UINT32(s, NewFormat);
|
Stream_Read_UINT32(s, NewFormat);
|
||||||
|
|
||||||
DEBUG_DVC("NewFormat=%"PRIu32"", NewFormat);
|
DEBUG_DVC("NewFormat=%"PRIu32"", NewFormat);
|
||||||
|
|
||||||
if (NewFormat >= (UINT32) callback->formats_count)
|
if (NewFormat >= (UINT32) callback->formats_count)
|
||||||
@ -426,18 +421,23 @@ static UINT audin_process_format_change(IWTSVirtualChannelCallback* pChannelCall
|
|||||||
if (audin->device)
|
if (audin->device)
|
||||||
{
|
{
|
||||||
IFCALLRET(audin->device->Close, error, audin->device);
|
IFCALLRET(audin->device->Close, error, audin->device);
|
||||||
|
|
||||||
if (error != CHANNEL_RC_OK)
|
if (error != CHANNEL_RC_OK)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Close failed with errorcode %"PRIu32"", error);
|
WLog_ERR(TAG, "Close failed with errorcode %"PRIu32"", error);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
IFCALLRET(audin->device->SetFormat, error, audin->device, format, 0);
|
IFCALLRET(audin->device->SetFormat, error, audin->device, format, 0);
|
||||||
|
|
||||||
if (error != CHANNEL_RC_OK)
|
if (error != CHANNEL_RC_OK)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "SetFormat failed with errorcode %"PRIu32"", error);
|
WLog_ERR(TAG, "SetFormat failed with errorcode %"PRIu32"", error);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
IFCALLRET(audin->device->Open, error, audin->device, audin_receive_wave_data, callback);
|
IFCALLRET(audin->device->Open, error, audin->device, audin_receive_wave_data, callback);
|
||||||
|
|
||||||
if (error != CHANNEL_RC_OK)
|
if (error != CHANNEL_RC_OK)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Open failed with errorcode %"PRIu32"", error);
|
WLog_ERR(TAG, "Open failed with errorcode %"PRIu32"", error);
|
||||||
@ -456,13 +456,11 @@ static UINT audin_process_format_change(IWTSVirtualChannelCallback* pChannelCall
|
|||||||
*
|
*
|
||||||
* @return 0 on success, otherwise a Win32 error code
|
* @return 0 on success, otherwise a Win32 error code
|
||||||
*/
|
*/
|
||||||
static UINT audin_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, wStream *data)
|
static UINT audin_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, wStream* data)
|
||||||
{
|
{
|
||||||
UINT error;
|
UINT error;
|
||||||
BYTE MessageId;
|
BYTE MessageId;
|
||||||
|
|
||||||
Stream_Read_UINT8(data, MessageId);
|
Stream_Read_UINT8(data, MessageId);
|
||||||
|
|
||||||
DEBUG_DVC("MessageId=0x%02"PRIx8"", MessageId);
|
DEBUG_DVC("MessageId=0x%02"PRIx8"", MessageId);
|
||||||
|
|
||||||
switch (MessageId)
|
switch (MessageId)
|
||||||
@ -502,19 +500,18 @@ static UINT audin_on_close(IWTSVirtualChannelCallback* pChannelCallback)
|
|||||||
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
|
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
|
||||||
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) callback->plugin;
|
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) callback->plugin;
|
||||||
UINT error = CHANNEL_RC_OK;
|
UINT error = CHANNEL_RC_OK;
|
||||||
|
|
||||||
DEBUG_DVC("...");
|
DEBUG_DVC("...");
|
||||||
|
|
||||||
if (audin->device)
|
if (audin->device)
|
||||||
{
|
{
|
||||||
IFCALLRET(audin->device->Close, error, audin->device);
|
IFCALLRET(audin->device->Close, error, audin->device);
|
||||||
|
|
||||||
if (error != CHANNEL_RC_OK)
|
if (error != CHANNEL_RC_OK)
|
||||||
WLog_ERR(TAG, "Close failed with errorcode %"PRIu32"", error);
|
WLog_ERR(TAG, "Close failed with errorcode %"PRIu32"", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(callback->formats);
|
free(callback->formats);
|
||||||
free(callback);
|
free(callback);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,10 +526,9 @@ static UINT audin_on_new_channel_connection(IWTSListenerCallback* pListenerCallb
|
|||||||
{
|
{
|
||||||
AUDIN_CHANNEL_CALLBACK* callback;
|
AUDIN_CHANNEL_CALLBACK* callback;
|
||||||
AUDIN_LISTENER_CALLBACK* listener_callback = (AUDIN_LISTENER_CALLBACK*) pListenerCallback;
|
AUDIN_LISTENER_CALLBACK* listener_callback = (AUDIN_LISTENER_CALLBACK*) pListenerCallback;
|
||||||
|
|
||||||
DEBUG_DVC("...");
|
DEBUG_DVC("...");
|
||||||
|
|
||||||
callback = (AUDIN_CHANNEL_CALLBACK*) calloc(1, sizeof(AUDIN_CHANNEL_CALLBACK));
|
callback = (AUDIN_CHANNEL_CALLBACK*) calloc(1, sizeof(AUDIN_CHANNEL_CALLBACK));
|
||||||
|
|
||||||
if (!callback)
|
if (!callback)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "calloc failed!");
|
WLog_ERR(TAG, "calloc failed!");
|
||||||
@ -544,9 +540,7 @@ static UINT audin_on_new_channel_connection(IWTSListenerCallback* pListenerCallb
|
|||||||
callback->plugin = listener_callback->plugin;
|
callback->plugin = listener_callback->plugin;
|
||||||
callback->channel_mgr = listener_callback->channel_mgr;
|
callback->channel_mgr = listener_callback->channel_mgr;
|
||||||
callback->channel = pChannel;
|
callback->channel = pChannel;
|
||||||
|
|
||||||
*ppCallback = (IWTSVirtualChannelCallback*) callback;
|
*ppCallback = (IWTSVirtualChannelCallback*) callback;
|
||||||
|
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -558,10 +552,9 @@ static UINT audin_on_new_channel_connection(IWTSListenerCallback* pListenerCallb
|
|||||||
static UINT audin_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager* pChannelMgr)
|
static UINT audin_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager* pChannelMgr)
|
||||||
{
|
{
|
||||||
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) pPlugin;
|
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) pPlugin;
|
||||||
|
|
||||||
DEBUG_DVC("...");
|
DEBUG_DVC("...");
|
||||||
|
|
||||||
audin->listener_callback = (AUDIN_LISTENER_CALLBACK*) calloc(1, sizeof(AUDIN_LISTENER_CALLBACK));
|
audin->listener_callback = (AUDIN_LISTENER_CALLBACK*) calloc(1, sizeof(AUDIN_LISTENER_CALLBACK));
|
||||||
|
|
||||||
if (!audin->listener_callback)
|
if (!audin->listener_callback)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "calloc failed!");
|
WLog_ERR(TAG, "calloc failed!");
|
||||||
@ -571,7 +564,6 @@ static UINT audin_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManag
|
|||||||
audin->listener_callback->iface.OnNewChannelConnection = audin_on_new_channel_connection;
|
audin->listener_callback->iface.OnNewChannelConnection = audin_on_new_channel_connection;
|
||||||
audin->listener_callback->plugin = pPlugin;
|
audin->listener_callback->plugin = pPlugin;
|
||||||
audin->listener_callback->channel_mgr = pChannelMgr;
|
audin->listener_callback->channel_mgr = pChannelMgr;
|
||||||
|
|
||||||
return pChannelMgr->CreateListener(pChannelMgr, "AUDIO_INPUT", 0,
|
return pChannelMgr->CreateListener(pChannelMgr, "AUDIO_INPUT", 0,
|
||||||
(IWTSListenerCallback*) audin->listener_callback, NULL);
|
(IWTSListenerCallback*) audin->listener_callback, NULL);
|
||||||
}
|
}
|
||||||
@ -585,32 +577,54 @@ static UINT audin_plugin_terminated(IWTSPlugin* pPlugin)
|
|||||||
{
|
{
|
||||||
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) pPlugin;
|
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) pPlugin;
|
||||||
UINT error = CHANNEL_RC_OK;
|
UINT error = CHANNEL_RC_OK;
|
||||||
|
|
||||||
DEBUG_DVC("...");
|
DEBUG_DVC("...");
|
||||||
|
|
||||||
if (audin->device)
|
if (audin->device)
|
||||||
{
|
{
|
||||||
IFCALLRET(audin->device->Free, error, audin->device);
|
IFCALLRET(audin->device->Free, error, audin->device);
|
||||||
|
|
||||||
if (error != CHANNEL_RC_OK)
|
if (error != CHANNEL_RC_OK)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "Free failed with errorcode %"PRIu32"", error);
|
WLog_ERR(TAG, "Free failed with errorcode %"PRIu32"", error);
|
||||||
// dont stop on error
|
// dont stop on error
|
||||||
}
|
}
|
||||||
|
|
||||||
audin->device = NULL;
|
audin->device = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(audin->subsystem);
|
free(audin->subsystem);
|
||||||
audin->subsystem = NULL;
|
audin->subsystem = NULL;
|
||||||
|
|
||||||
free(audin->device_name);
|
free(audin->device_name);
|
||||||
audin->device_name = NULL;
|
audin->device_name = NULL;
|
||||||
|
|
||||||
free(audin->listener_callback);
|
free(audin->listener_callback);
|
||||||
free(audin);
|
free(audin);
|
||||||
|
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT audin_plugin_attached(IWTSPlugin* pPlugin)
|
||||||
|
{
|
||||||
|
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) pPlugin;
|
||||||
|
UINT error = CHANNEL_RC_OK;
|
||||||
|
|
||||||
|
if (!audin)
|
||||||
|
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
||||||
|
|
||||||
|
audin->attached = TRUE;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT audin_plugin_detached(IWTSPlugin* pPlugin)
|
||||||
|
{
|
||||||
|
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) pPlugin;
|
||||||
|
UINT error = CHANNEL_RC_OK;
|
||||||
|
|
||||||
|
if (!audin)
|
||||||
|
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
||||||
|
|
||||||
|
audin->attached = FALSE;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function description
|
* Function description
|
||||||
*
|
*
|
||||||
@ -627,7 +641,6 @@ static UINT audin_register_device_plugin(IWTSPlugin* pPlugin, IAudinDevice* devi
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_DVC("device registered.");
|
DEBUG_DVC("device registered.");
|
||||||
|
|
||||||
audin->device = device;
|
audin->device = device;
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
@ -647,11 +660,13 @@ static UINT audin_load_device_plugin(IWTSPlugin* pPlugin, const char* name, ADDI
|
|||||||
if (!audin_process_addin_args(audin, args))
|
if (!audin_process_addin_args(audin, args))
|
||||||
return CHANNEL_RC_INITIALIZATION_ERROR;
|
return CHANNEL_RC_INITIALIZATION_ERROR;
|
||||||
|
|
||||||
entry = (PFREERDP_AUDIN_DEVICE_ENTRY) freerdp_load_channel_addin_entry("audin", (LPSTR) name, NULL, 0);
|
entry = (PFREERDP_AUDIN_DEVICE_ENTRY) freerdp_load_channel_addin_entry("audin", (LPSTR) name, NULL,
|
||||||
|
0);
|
||||||
|
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "freerdp_load_channel_addin_entry did not return any function pointers for %s ", name);
|
WLog_ERR(TAG, "freerdp_load_channel_addin_entry did not return any function pointers for %s ",
|
||||||
|
name);
|
||||||
return ERROR_INVALID_FUNCTION;
|
return ERROR_INVALID_FUNCTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -679,11 +694,13 @@ static UINT audin_set_subsystem(AUDIN_PLUGIN* audin, char* subsystem)
|
|||||||
{
|
{
|
||||||
free(audin->subsystem);
|
free(audin->subsystem);
|
||||||
audin->subsystem = _strdup(subsystem);
|
audin->subsystem = _strdup(subsystem);
|
||||||
|
|
||||||
if (!audin->subsystem)
|
if (!audin->subsystem)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "_strdup failed!");
|
WLog_ERR(TAG, "_strdup failed!");
|
||||||
return ERROR_NOT_ENOUGH_MEMORY;
|
return ERROR_NOT_ENOUGH_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -696,11 +713,13 @@ static UINT audin_set_device_name(AUDIN_PLUGIN* audin, char* device_name)
|
|||||||
{
|
{
|
||||||
free(audin->device_name);
|
free(audin->device_name);
|
||||||
audin->device_name = _strdup(device_name);
|
audin->device_name = _strdup(device_name);
|
||||||
|
|
||||||
if (!audin->device_name)
|
if (!audin->device_name)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "_strdup failed!");
|
WLog_ERR(TAG, "_strdup failed!");
|
||||||
return ERROR_NOT_ENOUGH_MEMORY;
|
return ERROR_NOT_ENOUGH_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -725,9 +744,9 @@ BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_IGN_UNKNOWN_KEYWORD;
|
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_IGN_UNKNOWN_KEYWORD;
|
||||||
|
|
||||||
status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv,
|
status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv,
|
||||||
audin_args, flags, audin, NULL, NULL);
|
audin_args, flags, audin, NULL, NULL);
|
||||||
|
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@ -739,7 +758,6 @@ BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
CommandLineSwitchStart(arg)
|
CommandLineSwitchStart(arg)
|
||||||
|
|
||||||
CommandLineSwitchCase(arg, "sys")
|
CommandLineSwitchCase(arg, "sys")
|
||||||
{
|
{
|
||||||
if ((error = audin_set_subsystem(audin, arg->Value)))
|
if ((error = audin_set_subsystem(audin, arg->Value)))
|
||||||
@ -770,9 +788,7 @@ BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args)
|
|||||||
}
|
}
|
||||||
CommandLineSwitchDefault(arg)
|
CommandLineSwitchDefault(arg)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandLineSwitchEnd(arg)
|
CommandLineSwitchEnd(arg)
|
||||||
}
|
}
|
||||||
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
|
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
|
||||||
@ -795,10 +811,9 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
|||||||
{
|
{
|
||||||
struct SubsystemEntry
|
struct SubsystemEntry
|
||||||
{
|
{
|
||||||
char *subsystem;
|
char* subsystem;
|
||||||
char *device;
|
char* device;
|
||||||
};
|
};
|
||||||
|
|
||||||
UINT error = CHANNEL_RC_INITIALIZATION_ERROR;
|
UINT error = CHANNEL_RC_INITIALIZATION_ERROR;
|
||||||
ADDIN_ARGV* args;
|
ADDIN_ARGV* args;
|
||||||
AUDIN_PLUGIN* audin;
|
AUDIN_PLUGIN* audin;
|
||||||
@ -822,31 +837,34 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
|||||||
#if defined(WITH_MACAUDIO)
|
#if defined(WITH_MACAUDIO)
|
||||||
{"mac", "default"},
|
{"mac", "default"},
|
||||||
#endif
|
#endif
|
||||||
{NULL,NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
struct SubsystemEntry *entry = &entries[0];
|
struct SubsystemEntry* entry = &entries[0];
|
||||||
|
|
||||||
assert(pEntryPoints);
|
assert(pEntryPoints);
|
||||||
assert(pEntryPoints->GetPlugin);
|
assert(pEntryPoints->GetPlugin);
|
||||||
|
|
||||||
audin = (AUDIN_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "audin");
|
audin = (AUDIN_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "audin");
|
||||||
|
|
||||||
if (audin != NULL)
|
if (audin != NULL)
|
||||||
return CHANNEL_RC_ALREADY_INITIALIZED;
|
return CHANNEL_RC_ALREADY_INITIALIZED;
|
||||||
|
|
||||||
audin = (AUDIN_PLUGIN*) calloc(1, sizeof(AUDIN_PLUGIN));
|
audin = (AUDIN_PLUGIN*) calloc(1, sizeof(AUDIN_PLUGIN));
|
||||||
|
|
||||||
if (!audin)
|
if (!audin)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "calloc failed!");
|
WLog_ERR(TAG, "calloc failed!");
|
||||||
return CHANNEL_RC_NO_MEMORY;
|
return CHANNEL_RC_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
audin->attached = TRUE;
|
||||||
audin->iface.Initialize = audin_plugin_initialize;
|
audin->iface.Initialize = audin_plugin_initialize;
|
||||||
audin->iface.Connected = NULL;
|
audin->iface.Connected = NULL;
|
||||||
audin->iface.Disconnected = NULL;
|
audin->iface.Disconnected = NULL;
|
||||||
audin->iface.Terminated = audin_plugin_terminated;
|
audin->iface.Terminated = audin_plugin_terminated;
|
||||||
|
audin->iface.Attached = audin_plugin_attached;
|
||||||
|
audin->iface.Detached = audin_plugin_detached;
|
||||||
args = pEntryPoints->GetPluginData(pEntryPoints);
|
args = pEntryPoints->GetPluginData(pEntryPoints);
|
||||||
audin->rdpcontext = ((freerdp*)((rdpSettings*) pEntryPoints->GetRdpSettings(pEntryPoints))->instance)->context;
|
audin->rdpcontext = ((freerdp*)((rdpSettings*) pEntryPoints->GetRdpSettings(
|
||||||
|
pEntryPoints))->instance)->context;
|
||||||
|
|
||||||
if (args)
|
if (args)
|
||||||
{
|
{
|
||||||
@ -891,8 +909,8 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
|||||||
WLog_ERR(TAG, "no sound device.");
|
WLog_ERR(TAG, "no sound device.");
|
||||||
|
|
||||||
error = pEntryPoints->RegisterPlugin(pEntryPoints, "audin", (IWTSPlugin*) audin);
|
error = pEntryPoints->RegisterPlugin(pEntryPoints, "audin", (IWTSPlugin*) audin);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
||||||
if (error != CHANNEL_RC_OK)
|
if (error != CHANNEL_RC_OK)
|
||||||
audin_plugin_terminated((IWTSPlugin*)audin);
|
audin_plugin_terminated((IWTSPlugin*)audin);
|
||||||
|
|
||||||
|
@ -706,7 +706,8 @@ static UINT drdynvc_send(drdynvcPlugin* drdynvc, wStream* s)
|
|||||||
if (status != CHANNEL_RC_OK)
|
if (status != CHANNEL_RC_OK)
|
||||||
{
|
{
|
||||||
Stream_Free(s, TRUE);
|
Stream_Free(s, TRUE);
|
||||||
WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08"PRIX32"]", WTSErrorToString(status), status);
|
WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08"PRIX32"]", WTSErrorToString(status),
|
||||||
|
status);
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@ -1073,7 +1074,7 @@ static UINT drdynvc_order_recv(drdynvcPlugin* drdynvc, wStream* s)
|
|||||||
Cmd = (value & 0xf0) >> 4;
|
Cmd = (value & 0xf0) >> 4;
|
||||||
Sp = (value & 0x0c) >> 2;
|
Sp = (value & 0x0c) >> 2;
|
||||||
cbChId = (value & 0x03) >> 0;
|
cbChId = (value & 0x03) >> 0;
|
||||||
WLog_DBG(TAG, "order_recv: Cmd=0x%x, Sp=%d cbChId=%d", Cmd, Sp,cbChId);
|
WLog_DBG(TAG, "order_recv: Cmd=0x%x, Sp=%d cbChId=%d", Cmd, Sp, cbChId);
|
||||||
|
|
||||||
switch (Cmd)
|
switch (Cmd)
|
||||||
{
|
{
|
||||||
@ -1379,6 +1380,64 @@ static UINT drdynvc_virtual_channel_event_terminated(drdynvcPlugin* drdynvc)
|
|||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT drdynvc_virtual_channel_event_attached(drdynvcPlugin* drdynvc)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
DVCMAN* dvcman;
|
||||||
|
|
||||||
|
if (!drdynvc)
|
||||||
|
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
||||||
|
|
||||||
|
dvcman = (DVCMAN*) drdynvc->channel_mgr;
|
||||||
|
|
||||||
|
if (!dvcman)
|
||||||
|
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
||||||
|
|
||||||
|
for (i = 0; i < dvcman->num_plugins; i++)
|
||||||
|
{
|
||||||
|
UINT error;
|
||||||
|
IWTSPlugin* pPlugin = dvcman->plugins[i];
|
||||||
|
|
||||||
|
if (pPlugin->Attached)
|
||||||
|
if ((error = pPlugin->Attached(pPlugin)))
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "Attach failed with error %"PRIu32"!", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CHANNEL_RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT drdynvc_virtual_channel_event_detached(drdynvcPlugin* drdynvc)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
DVCMAN* dvcman;
|
||||||
|
|
||||||
|
if (!drdynvc)
|
||||||
|
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
||||||
|
|
||||||
|
dvcman = (DVCMAN*) drdynvc->channel_mgr;
|
||||||
|
|
||||||
|
if (!dvcman)
|
||||||
|
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
||||||
|
|
||||||
|
for (i = 0; i < dvcman->num_plugins; i++)
|
||||||
|
{
|
||||||
|
UINT error;
|
||||||
|
IWTSPlugin* pPlugin = dvcman->plugins[i];
|
||||||
|
|
||||||
|
if (pPlugin->Detached)
|
||||||
|
if ((error = pPlugin->Detached(pPlugin)))
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "Detach failed with error %"PRIu32"!", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CHANNEL_RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static VOID VCAPITYPE drdynvc_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle,
|
static VOID VCAPITYPE drdynvc_virtual_channel_init_event_ex(LPVOID lpUserParam, LPVOID pInitHandle,
|
||||||
UINT event, LPVOID pData, UINT dataLength)
|
UINT event, LPVOID pData, UINT dataLength)
|
||||||
{
|
{
|
||||||
@ -1410,6 +1469,21 @@ static VOID VCAPITYPE drdynvc_virtual_channel_init_event_ex(LPVOID lpUserParam,
|
|||||||
WLog_ERR(TAG, "drdynvc_virtual_channel_event_terminated failed with error %"PRIu32"", error);
|
WLog_ERR(TAG, "drdynvc_virtual_channel_event_terminated failed with error %"PRIu32"", error);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CHANNEL_EVENT_ATTACHED:
|
||||||
|
if ((error = drdynvc_virtual_channel_event_attached(drdynvc)))
|
||||||
|
WLog_ERR(TAG, "drdynvc_virtual_channel_event_attached failed with error %"PRIu32"", error);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CHANNEL_EVENT_DETACHED:
|
||||||
|
if ((error = drdynvc_virtual_channel_event_detached(drdynvc)))
|
||||||
|
WLog_ERR(TAG, "drdynvc_virtual_channel_event_detached failed with error %"PRIu32"", error);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error && drdynvc->rdpcontext)
|
if (error && drdynvc->rdpcontext)
|
||||||
|
@ -742,6 +742,11 @@ static VOID VCAPITYPE rail_virtual_channel_init_event_ex(LPVOID lpUserParam, LPV
|
|||||||
case CHANNEL_EVENT_TERMINATED:
|
case CHANNEL_EVENT_TERMINATED:
|
||||||
rail_virtual_channel_event_terminated(rail);
|
rail_virtual_channel_event_terminated(rail);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CHANNEL_EVENT_ATTACHED:
|
||||||
|
case CHANNEL_EVENT_DETACHED:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error && rail->rdpcontext)
|
if (error && rail->rdpcontext)
|
||||||
|
@ -1738,9 +1738,10 @@ static VOID VCAPITYPE rdpdr_virtual_channel_init_event_ex(LPVOID lpUserParam, LP
|
|||||||
rdpdr_virtual_channel_event_terminated(rdpdr);
|
rdpdr_virtual_channel_event_terminated(rdpdr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CHANNEL_EVENT_ATTACHED:
|
||||||
|
case CHANNEL_EVENT_DETACHED:
|
||||||
default:
|
default:
|
||||||
WLog_ERR(TAG, "unknown event %"PRIu32"!", event);
|
WLog_ERR(TAG, "unknown event %"PRIu32"!", event);
|
||||||
error = ERROR_INVALID_DATA;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +74,8 @@ struct rdpsnd_plugin
|
|||||||
AUDIO_FORMAT* ClientFormats;
|
AUDIO_FORMAT* ClientFormats;
|
||||||
UINT16 NumberOfClientFormats;
|
UINT16 NumberOfClientFormats;
|
||||||
|
|
||||||
|
BOOL attached;
|
||||||
|
|
||||||
BOOL expectingWave;
|
BOOL expectingWave;
|
||||||
BYTE waveData[4];
|
BYTE waveData[4];
|
||||||
UINT16 waveDataSize;
|
UINT16 waveDataSize;
|
||||||
@ -741,6 +743,9 @@ static UINT rdpsnd_recv_pdu(rdpsndPlugin* rdpsnd, wStream* s)
|
|||||||
Stream_Seek_UINT8(s); /* bPad */
|
Stream_Seek_UINT8(s); /* bPad */
|
||||||
Stream_Read_UINT16(s, BodySize);
|
Stream_Read_UINT16(s, BodySize);
|
||||||
|
|
||||||
|
if (!rdpsnd->attached)
|
||||||
|
goto out;
|
||||||
|
|
||||||
//WLog_ERR(TAG, "msgType %"PRIu8" BodySize %"PRIu16"", msgType, BodySize);
|
//WLog_ERR(TAG, "msgType %"PRIu8" BodySize %"PRIu16"", msgType, BodySize);
|
||||||
|
|
||||||
switch (msgType)
|
switch (msgType)
|
||||||
@ -1445,6 +1450,17 @@ static VOID VCAPITYPE rdpsnd_virtual_channel_init_event_ex(LPVOID lpUserParam, L
|
|||||||
rdpsnd_virtual_channel_event_terminated(plugin);
|
rdpsnd_virtual_channel_event_terminated(plugin);
|
||||||
plugin = NULL;
|
plugin = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CHANNEL_EVENT_ATTACHED:
|
||||||
|
plugin->attached = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CHANNEL_EVENT_DETACHED:
|
||||||
|
plugin->attached = FALSE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error && plugin && plugin->rdpcontext)
|
if (error && plugin && plugin->rdpcontext)
|
||||||
@ -1474,6 +1490,7 @@ BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID p
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rdpsnd->attached = TRUE;
|
||||||
#if !defined(_WIN32) && !defined(ANDROID)
|
#if !defined(_WIN32) && !defined(ANDROID)
|
||||||
{
|
{
|
||||||
sigset_t mask;
|
sigset_t mask;
|
||||||
@ -1497,9 +1514,7 @@ BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID p
|
|||||||
rdpsnd->log = WLog_Get("com.freerdp.channels.rdpsnd.client");
|
rdpsnd->log = WLog_Get("com.freerdp.channels.rdpsnd.client");
|
||||||
CopyMemory(&(rdpsnd->channelEntryPoints), pEntryPoints,
|
CopyMemory(&(rdpsnd->channelEntryPoints), pEntryPoints,
|
||||||
sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX));
|
sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX));
|
||||||
|
|
||||||
rdpsnd->InitHandle = pInitHandle;
|
rdpsnd->InitHandle = pInitHandle;
|
||||||
|
|
||||||
rc = rdpsnd->channelEntryPoints.pVirtualChannelInitEx(rdpsnd, NULL, pInitHandle,
|
rc = rdpsnd->channelEntryPoints.pVirtualChannelInitEx(rdpsnd, NULL, pInitHandle,
|
||||||
&rdpsnd->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000,
|
&rdpsnd->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000,
|
||||||
rdpsnd_virtual_channel_init_event_ex);
|
rdpsnd_virtual_channel_init_event_ex);
|
||||||
|
@ -1015,6 +1015,11 @@ static VOID VCAPITYPE remdesk_virtual_channel_init_event_ex(LPVOID lpUserParam,
|
|||||||
case CHANNEL_EVENT_TERMINATED:
|
case CHANNEL_EVENT_TERMINATED:
|
||||||
remdesk_virtual_channel_event_terminated(remdesk);
|
remdesk_virtual_channel_event_terminated(remdesk);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CHANNEL_EVENT_ATTACHED:
|
||||||
|
case CHANNEL_EVENT_DETACHED:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error && remdesk->rdpcontext)
|
if (error && remdesk->rdpcontext)
|
||||||
|
@ -29,8 +29,14 @@
|
|||||||
typedef struct _drdynvc_client_context DrdynvcClientContext;
|
typedef struct _drdynvc_client_context DrdynvcClientContext;
|
||||||
|
|
||||||
typedef int (*pcDrdynvcGetVersion)(DrdynvcClientContext* context);
|
typedef int (*pcDrdynvcGetVersion)(DrdynvcClientContext* context);
|
||||||
typedef UINT (*pcDrdynvcOnChannelConnected)(DrdynvcClientContext* context, const char* name, void* pInterface);
|
typedef UINT(*pcDrdynvcOnChannelConnected)(DrdynvcClientContext* context, const char* name,
|
||||||
typedef UINT (*pcDrdynvcOnChannelDisconnected)(DrdynvcClientContext* context, const char* name, void* pInterface);
|
void* pInterface);
|
||||||
|
typedef UINT(*pcDrdynvcOnChannelDisconnected)(DrdynvcClientContext* context, const char* name,
|
||||||
|
void* pInterface);
|
||||||
|
typedef UINT(*pcDrdynvcOnChannelAttached)(DrdynvcClientContext* context, const char* name,
|
||||||
|
void* pInterface);
|
||||||
|
typedef UINT(*pcDrdynvcOnChannelDetached)(DrdynvcClientContext* context, const char* name,
|
||||||
|
void* pInterface);
|
||||||
|
|
||||||
struct _drdynvc_client_context
|
struct _drdynvc_client_context
|
||||||
{
|
{
|
||||||
@ -40,6 +46,8 @@ struct _drdynvc_client_context
|
|||||||
pcDrdynvcGetVersion GetVersion;
|
pcDrdynvcGetVersion GetVersion;
|
||||||
pcDrdynvcOnChannelConnected OnChannelConnected;
|
pcDrdynvcOnChannelConnected OnChannelConnected;
|
||||||
pcDrdynvcOnChannelDisconnected OnChannelDisconnected;
|
pcDrdynvcOnChannelDisconnected OnChannelDisconnected;
|
||||||
|
pcDrdynvcOnChannelAttached OnChannelAttached;
|
||||||
|
pcDrdynvcOnChannelDetached OnChannelDetached;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FREERDP_CHANNEL_CLIENT_DRDYNVC_H */
|
#endif /* FREERDP_CHANNEL_CLIENT_DRDYNVC_H */
|
||||||
|
@ -67,97 +67,101 @@ typedef struct _IWTSVirtualChannelCallback IWTSVirtualChannelCallback;
|
|||||||
struct _IWTSListener
|
struct _IWTSListener
|
||||||
{
|
{
|
||||||
/* Retrieves the listener-specific configuration. */
|
/* Retrieves the listener-specific configuration. */
|
||||||
UINT (*GetConfiguration)(IWTSListener *pListener,
|
UINT(*GetConfiguration)(IWTSListener* pListener,
|
||||||
void **ppPropertyBag);
|
void** ppPropertyBag);
|
||||||
|
|
||||||
void *pInterface;
|
void* pInterface;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _IWTSVirtualChannel
|
struct _IWTSVirtualChannel
|
||||||
{
|
{
|
||||||
/* Starts a write request on the channel. */
|
/* Starts a write request on the channel. */
|
||||||
UINT (*Write)(IWTSVirtualChannel *pChannel,
|
UINT(*Write)(IWTSVirtualChannel* pChannel,
|
||||||
ULONG cbSize,
|
ULONG cbSize,
|
||||||
const BYTE *pBuffer,
|
const BYTE* pBuffer,
|
||||||
void *pReserved);
|
void* pReserved);
|
||||||
/* Closes the channel. */
|
/* Closes the channel. */
|
||||||
UINT (*Close)(IWTSVirtualChannel *pChannel);
|
UINT(*Close)(IWTSVirtualChannel* pChannel);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _IWTSVirtualChannelManager
|
struct _IWTSVirtualChannelManager
|
||||||
{
|
{
|
||||||
/* Returns an instance of a listener object that listens on a specific
|
/* Returns an instance of a listener object that listens on a specific
|
||||||
endpoint, or creates a static channel. */
|
endpoint, or creates a static channel. */
|
||||||
UINT (*CreateListener)(IWTSVirtualChannelManager *pChannelMgr,
|
UINT(*CreateListener)(IWTSVirtualChannelManager* pChannelMgr,
|
||||||
const char *pszChannelName,
|
const char* pszChannelName,
|
||||||
ULONG ulFlags,
|
ULONG ulFlags,
|
||||||
IWTSListenerCallback *pListenerCallback,
|
IWTSListenerCallback* pListenerCallback,
|
||||||
IWTSListener **ppListener);
|
IWTSListener** ppListener);
|
||||||
/* Find the channel or ID to send data to a specific endpoint. */
|
/* Find the channel or ID to send data to a specific endpoint. */
|
||||||
UINT32(*GetChannelId)(IWTSVirtualChannel *channel);
|
UINT32(*GetChannelId)(IWTSVirtualChannel* channel);
|
||||||
IWTSVirtualChannel *(*FindChannelById)(IWTSVirtualChannelManager *pChannelMgr,
|
IWTSVirtualChannel* (*FindChannelById)(IWTSVirtualChannelManager* pChannelMgr,
|
||||||
UINT32 ChannelId);
|
UINT32 ChannelId);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _IWTSPlugin
|
struct _IWTSPlugin
|
||||||
{
|
{
|
||||||
/* Used for the first call that is made from the client to the plug-in. */
|
/* Used for the first call that is made from the client to the plug-in. */
|
||||||
UINT (*Initialize)(IWTSPlugin *pPlugin,
|
UINT(*Initialize)(IWTSPlugin* pPlugin,
|
||||||
IWTSVirtualChannelManager *pChannelMgr);
|
IWTSVirtualChannelManager* pChannelMgr);
|
||||||
/* Notifies the plug-in that the Remote Desktop Connection (RDC) client
|
/* Notifies the plug-in that the Remote Desktop Connection (RDC) client
|
||||||
has successfully connected to the Remote Desktop Session Host (RD
|
has successfully connected to the Remote Desktop Session Host (RD
|
||||||
Session Host) server. */
|
Session Host) server. */
|
||||||
UINT (*Connected)(IWTSPlugin *pPlugin);
|
UINT(*Connected)(IWTSPlugin* pPlugin);
|
||||||
/* Notifies the plug-in that the Remote Desktop Connection (RDC) client
|
/* Notifies the plug-in that the Remote Desktop Connection (RDC) client
|
||||||
has disconnected from the RD Session Host server. */
|
has disconnected from the RD Session Host server. */
|
||||||
UINT (*Disconnected)(IWTSPlugin *pPlugin,
|
UINT(*Disconnected)(IWTSPlugin* pPlugin,
|
||||||
DWORD dwDisconnectCode);
|
DWORD dwDisconnectCode);
|
||||||
/* Notifies the plug-in that the Remote Desktop Connection (RDC) client
|
/* Notifies the plug-in that the Remote Desktop Connection (RDC) client
|
||||||
has terminated. */
|
has terminated. */
|
||||||
UINT (*Terminated)(IWTSPlugin *pPlugin);
|
UINT(*Terminated)(IWTSPlugin* pPlugin);
|
||||||
|
|
||||||
|
UINT(*Attached)(IWTSPlugin* pPlugin);
|
||||||
|
|
||||||
|
UINT(*Detached)(IWTSPlugin* pPlugin);
|
||||||
|
|
||||||
/* Extended */
|
/* Extended */
|
||||||
|
|
||||||
void *pInterface;
|
void* pInterface;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _IWTSListenerCallback
|
struct _IWTSListenerCallback
|
||||||
{
|
{
|
||||||
/* Accepts or denies a connection request for an incoming connection to
|
/* Accepts or denies a connection request for an incoming connection to
|
||||||
the associated listener. */
|
the associated listener. */
|
||||||
UINT (*OnNewChannelConnection)(IWTSListenerCallback *pListenerCallback,
|
UINT(*OnNewChannelConnection)(IWTSListenerCallback* pListenerCallback,
|
||||||
IWTSVirtualChannel *pChannel,
|
IWTSVirtualChannel* pChannel,
|
||||||
BYTE *Data,
|
BYTE* Data,
|
||||||
BOOL *pbAccept,
|
BOOL* pbAccept,
|
||||||
IWTSVirtualChannelCallback **ppCallback);
|
IWTSVirtualChannelCallback** ppCallback);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _IWTSVirtualChannelCallback
|
struct _IWTSVirtualChannelCallback
|
||||||
{
|
{
|
||||||
/* Notifies the user about data that is being received. */
|
/* Notifies the user about data that is being received. */
|
||||||
UINT (*OnDataReceived) (IWTSVirtualChannelCallback* pChannelCallback, wStream* data);
|
UINT(*OnDataReceived)(IWTSVirtualChannelCallback* pChannelCallback, wStream* data);
|
||||||
/* Notifies the user that the channel has been opened. */
|
/* Notifies the user that the channel has been opened. */
|
||||||
UINT (*OnOpen) (IWTSVirtualChannelCallback* pChannelCallback);
|
UINT(*OnOpen)(IWTSVirtualChannelCallback* pChannelCallback);
|
||||||
/* Notifies the user that the channel has been closed. */
|
/* Notifies the user that the channel has been closed. */
|
||||||
UINT (*OnClose) (IWTSVirtualChannelCallback* pChannelCallback);
|
UINT(*OnClose)(IWTSVirtualChannelCallback* pChannelCallback);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The DVC Plugin entry points */
|
/* The DVC Plugin entry points */
|
||||||
typedef struct _IDRDYNVC_ENTRY_POINTS IDRDYNVC_ENTRY_POINTS;
|
typedef struct _IDRDYNVC_ENTRY_POINTS IDRDYNVC_ENTRY_POINTS;
|
||||||
struct _IDRDYNVC_ENTRY_POINTS
|
struct _IDRDYNVC_ENTRY_POINTS
|
||||||
{
|
{
|
||||||
UINT (*RegisterPlugin)(IDRDYNVC_ENTRY_POINTS *pEntryPoints,
|
UINT(*RegisterPlugin)(IDRDYNVC_ENTRY_POINTS* pEntryPoints,
|
||||||
const char *name, IWTSPlugin *pPlugin);
|
const char* name, IWTSPlugin* pPlugin);
|
||||||
IWTSPlugin *(*GetPlugin)(IDRDYNVC_ENTRY_POINTS *pEntryPoints,
|
IWTSPlugin* (*GetPlugin)(IDRDYNVC_ENTRY_POINTS* pEntryPoints,
|
||||||
const char *name);
|
const char* name);
|
||||||
ADDIN_ARGV* (*GetPluginData)(IDRDYNVC_ENTRY_POINTS* pEntryPoints);
|
ADDIN_ARGV* (*GetPluginData)(IDRDYNVC_ENTRY_POINTS* pEntryPoints);
|
||||||
void* (*GetRdpSettings)(IDRDYNVC_ENTRY_POINTS* pEntryPoints);
|
void* (*GetRdpSettings)(IDRDYNVC_ENTRY_POINTS* pEntryPoints);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef UINT (*PDVC_PLUGIN_ENTRY)(IDRDYNVC_ENTRY_POINTS *);
|
typedef UINT(*PDVC_PLUGIN_ENTRY)(IDRDYNVC_ENTRY_POINTS*);
|
||||||
|
|
||||||
void *get_callback_by_name(const char *name, void **context);
|
void* get_callback_by_name(const char* name, void** context);
|
||||||
void add_callback_by_name(const char *name, void *fkt, void *context);
|
void add_callback_by_name(const char* name, void* fkt, void* context);
|
||||||
void remove_callback_by_name(const char *name, void *context);
|
void remove_callback_by_name(const char* name, void* context);
|
||||||
|
|
||||||
#endif /* FREERDP_DVC_H */
|
#endif /* FREERDP_DVC_H */
|
||||||
|
@ -34,60 +34,70 @@ extern "C" {
|
|||||||
#define FREERDP_WINDOW_STATE_ACTIVE 4
|
#define FREERDP_WINDOW_STATE_ACTIVE 4
|
||||||
|
|
||||||
DEFINE_EVENT_BEGIN(WindowStateChange)
|
DEFINE_EVENT_BEGIN(WindowStateChange)
|
||||||
int state;
|
int state;
|
||||||
DEFINE_EVENT_END(WindowStateChange)
|
DEFINE_EVENT_END(WindowStateChange)
|
||||||
|
|
||||||
DEFINE_EVENT_BEGIN(ResizeWindow)
|
DEFINE_EVENT_BEGIN(ResizeWindow)
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
DEFINE_EVENT_END(ResizeWindow)
|
DEFINE_EVENT_END(ResizeWindow)
|
||||||
|
|
||||||
DEFINE_EVENT_BEGIN(PanningChange)
|
DEFINE_EVENT_BEGIN(PanningChange)
|
||||||
int dx;
|
int dx;
|
||||||
int dy;
|
int dy;
|
||||||
DEFINE_EVENT_END(PanningChange)
|
DEFINE_EVENT_END(PanningChange)
|
||||||
|
|
||||||
DEFINE_EVENT_BEGIN(ZoomingChange)
|
DEFINE_EVENT_BEGIN(ZoomingChange)
|
||||||
int dx;
|
int dx;
|
||||||
int dy;
|
int dy;
|
||||||
DEFINE_EVENT_END(ZoomingChange)
|
DEFINE_EVENT_END(ZoomingChange)
|
||||||
|
|
||||||
DEFINE_EVENT_BEGIN(LocalResizeWindow)
|
DEFINE_EVENT_BEGIN(LocalResizeWindow)
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
DEFINE_EVENT_END(LocalResizeWindow)
|
DEFINE_EVENT_END(LocalResizeWindow)
|
||||||
|
|
||||||
DEFINE_EVENT_BEGIN(EmbedWindow)
|
DEFINE_EVENT_BEGIN(EmbedWindow)
|
||||||
BOOL embed;
|
BOOL embed;
|
||||||
void* handle;
|
void* handle;
|
||||||
DEFINE_EVENT_END(EmbedWindow)
|
DEFINE_EVENT_END(EmbedWindow)
|
||||||
|
|
||||||
DEFINE_EVENT_BEGIN(ErrorInfo)
|
DEFINE_EVENT_BEGIN(ErrorInfo)
|
||||||
UINT32 code;
|
UINT32 code;
|
||||||
DEFINE_EVENT_END(ErrorInfo)
|
DEFINE_EVENT_END(ErrorInfo)
|
||||||
|
|
||||||
DEFINE_EVENT_BEGIN(Terminate)
|
DEFINE_EVENT_BEGIN(Terminate)
|
||||||
int code;
|
int code;
|
||||||
DEFINE_EVENT_END(Terminate)
|
DEFINE_EVENT_END(Terminate)
|
||||||
|
|
||||||
DEFINE_EVENT_BEGIN(ConnectionResult)
|
DEFINE_EVENT_BEGIN(ConnectionResult)
|
||||||
int result;
|
int result;
|
||||||
DEFINE_EVENT_END(ConnectionResult)
|
DEFINE_EVENT_END(ConnectionResult)
|
||||||
|
|
||||||
DEFINE_EVENT_BEGIN(ChannelConnected)
|
DEFINE_EVENT_BEGIN(ChannelConnected)
|
||||||
const char* name;
|
const char* name;
|
||||||
void* pInterface;
|
void* pInterface;
|
||||||
DEFINE_EVENT_END(ChannelConnected)
|
DEFINE_EVENT_END(ChannelConnected)
|
||||||
|
|
||||||
DEFINE_EVENT_BEGIN(ChannelDisconnected)
|
DEFINE_EVENT_BEGIN(ChannelDisconnected)
|
||||||
const char* name;
|
const char* name;
|
||||||
void* pInterface;
|
void* pInterface;
|
||||||
DEFINE_EVENT_END(ChannelDisconnected)
|
DEFINE_EVENT_END(ChannelDisconnected)
|
||||||
|
|
||||||
|
DEFINE_EVENT_BEGIN(ChannelAttached)
|
||||||
|
const char* name;
|
||||||
|
void* pInterface;
|
||||||
|
DEFINE_EVENT_END(ChannelAttached)
|
||||||
|
|
||||||
|
DEFINE_EVENT_BEGIN(ChannelDetached)
|
||||||
|
const char* name;
|
||||||
|
void* pInterface;
|
||||||
|
DEFINE_EVENT_END(ChannelDetached)
|
||||||
|
|
||||||
DEFINE_EVENT_BEGIN(MouseEvent)
|
DEFINE_EVENT_BEGIN(MouseEvent)
|
||||||
UINT16 flags;
|
UINT16 flags;
|
||||||
UINT16 x;
|
UINT16 x;
|
||||||
UINT16 y;
|
UINT16 y;
|
||||||
DEFINE_EVENT_END(MouseEvent)
|
DEFINE_EVENT_END(MouseEvent)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -307,13 +307,22 @@ FREERDP_API BOOL freerdp_shall_disconnect(freerdp* instance);
|
|||||||
FREERDP_API BOOL freerdp_disconnect(freerdp* instance);
|
FREERDP_API BOOL freerdp_disconnect(freerdp* instance);
|
||||||
FREERDP_API BOOL freerdp_reconnect(freerdp* instance);
|
FREERDP_API BOOL freerdp_reconnect(freerdp* instance);
|
||||||
|
|
||||||
FREERDP_API UINT freerdp_channel_add_init_handle_data(rdpChannelHandles* handles, void* pInitHandle, void* pUserData);
|
FREERDP_API UINT freerdp_channel_add_init_handle_data(rdpChannelHandles* handles, void* pInitHandle,
|
||||||
FREERDP_API void* freerdp_channel_get_init_handle_data(rdpChannelHandles* handles, void* pInitHandle);
|
void* pUserData);
|
||||||
FREERDP_API void freerdp_channel_remove_init_handle_data(rdpChannelHandles* handles, void* pInitHandle);
|
FREERDP_API void* freerdp_channel_get_init_handle_data(rdpChannelHandles* handles,
|
||||||
|
void* pInitHandle);
|
||||||
|
FREERDP_API void freerdp_channel_remove_init_handle_data(rdpChannelHandles* handles,
|
||||||
|
void* pInitHandle);
|
||||||
|
|
||||||
FREERDP_API UINT freerdp_channel_add_open_handle_data(rdpChannelHandles* handles, DWORD openHandle, void* pUserData);
|
FREERDP_API UINT freerdp_channel_add_open_handle_data(rdpChannelHandles* handles, DWORD openHandle,
|
||||||
FREERDP_API void* freerdp_channel_get_open_handle_data(rdpChannelHandles* handles, DWORD openHandle);
|
void* pUserData);
|
||||||
FREERDP_API void freerdp_channel_remove_open_handle_data(rdpChannelHandles* handles, DWORD openHandle);
|
FREERDP_API void* freerdp_channel_get_open_handle_data(rdpChannelHandles* handles,
|
||||||
|
DWORD openHandle);
|
||||||
|
FREERDP_API void freerdp_channel_remove_open_handle_data(rdpChannelHandles* handles,
|
||||||
|
DWORD openHandle);
|
||||||
|
|
||||||
|
FREERDP_API UINT freerdp_channels_attach(freerdp* instance);
|
||||||
|
FREERDP_API UINT freerdp_channels_detach(freerdp* instance);
|
||||||
|
|
||||||
FREERDP_API BOOL freerdp_get_fds(freerdp* instance, void** rfds, int* rcount,
|
FREERDP_API BOOL freerdp_get_fds(freerdp* instance, void** rfds, int* rcount,
|
||||||
void** wfds, int* wcount);
|
void** wfds, int* wcount);
|
||||||
|
@ -182,6 +182,36 @@ static UINT freerdp_drdynvc_on_channel_disconnected(DrdynvcClientContext*
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT freerdp_drdynvc_on_channel_attached(DrdynvcClientContext*
|
||||||
|
context,
|
||||||
|
const char* name, void* pInterface)
|
||||||
|
{
|
||||||
|
UINT status = CHANNEL_RC_OK;
|
||||||
|
ChannelAttachedEventArgs e;
|
||||||
|
rdpChannels* channels = (rdpChannels*) context->custom;
|
||||||
|
freerdp* instance = channels->instance;
|
||||||
|
EventArgsInit(&e, "freerdp");
|
||||||
|
e.name = name;
|
||||||
|
e.pInterface = pInterface;
|
||||||
|
PubSub_OnChannelAttached(instance->context->pubSub, instance->context, &e);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT freerdp_drdynvc_on_channel_detached(DrdynvcClientContext*
|
||||||
|
context,
|
||||||
|
const char* name, void* pInterface)
|
||||||
|
{
|
||||||
|
UINT status = CHANNEL_RC_OK;
|
||||||
|
ChannelDetachedEventArgs e;
|
||||||
|
rdpChannels* channels = (rdpChannels*) context->custom;
|
||||||
|
freerdp* instance = channels->instance;
|
||||||
|
EventArgsInit(&e, "freerdp");
|
||||||
|
e.name = name;
|
||||||
|
e.pInterface = pInterface;
|
||||||
|
PubSub_OnChannelDetached(instance->context->pubSub, instance->context, &e);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* go through and inform all the libraries that we are initialized
|
* go through and inform all the libraries that we are initialized
|
||||||
* called only from main thread
|
* called only from main thread
|
||||||
@ -214,6 +244,122 @@ UINT freerdp_channels_pre_connect(rdpChannels* channels, freerdp* instance)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT freerdp_channels_attach(freerdp* instance)
|
||||||
|
{
|
||||||
|
UINT error = CHANNEL_RC_OK;
|
||||||
|
int index;
|
||||||
|
char* name = NULL;
|
||||||
|
char* hostname;
|
||||||
|
int hostnameLength;
|
||||||
|
rdpChannels* channels;
|
||||||
|
CHANNEL_CLIENT_DATA* pChannelClientData;
|
||||||
|
channels = instance->context->channels;
|
||||||
|
channels->connected = 1;
|
||||||
|
hostname = instance->settings->ServerHostname;
|
||||||
|
hostnameLength = (int) strlen(hostname);
|
||||||
|
|
||||||
|
for (index = 0; index < channels->clientDataCount; index++)
|
||||||
|
{
|
||||||
|
ChannelConnectedEventArgs e;
|
||||||
|
CHANNEL_OPEN_DATA* pChannelOpenData = NULL;
|
||||||
|
pChannelClientData = &channels->clientDataList[index];
|
||||||
|
|
||||||
|
if (pChannelClientData->pChannelInitEventProc)
|
||||||
|
{
|
||||||
|
pChannelClientData->pChannelInitEventProc(
|
||||||
|
pChannelClientData->pInitHandle, CHANNEL_EVENT_ATTACHED, hostname, hostnameLength);
|
||||||
|
}
|
||||||
|
else if (pChannelClientData->pChannelInitEventProcEx)
|
||||||
|
{
|
||||||
|
pChannelClientData->pChannelInitEventProcEx(pChannelClientData->lpUserParam,
|
||||||
|
pChannelClientData->pInitHandle, CHANNEL_EVENT_ATTACHED, hostname, hostnameLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getChannelError(instance->context) != CHANNEL_RC_OK)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
pChannelOpenData = &channels->openDataList[index];
|
||||||
|
name = (char*) malloc(9);
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
{
|
||||||
|
error = CHANNEL_RC_NO_MEMORY;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMemory(name, pChannelOpenData->name, 8);
|
||||||
|
name[8] = '\0';
|
||||||
|
EventArgsInit(&e, "freerdp");
|
||||||
|
e.name = name;
|
||||||
|
e.pInterface = pChannelOpenData->pInterface;
|
||||||
|
PubSub_OnChannelAttached(instance->context->pubSub, instance->context, &e);
|
||||||
|
free(name);
|
||||||
|
name = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fail:
|
||||||
|
free(name);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT freerdp_channels_detach(freerdp* instance)
|
||||||
|
{
|
||||||
|
UINT error = CHANNEL_RC_OK;
|
||||||
|
int index;
|
||||||
|
char* name = NULL;
|
||||||
|
char* hostname;
|
||||||
|
int hostnameLength;
|
||||||
|
rdpChannels* channels;
|
||||||
|
CHANNEL_CLIENT_DATA* pChannelClientData;
|
||||||
|
channels = instance->context->channels;
|
||||||
|
channels->connected = 1;
|
||||||
|
hostname = instance->settings->ServerHostname;
|
||||||
|
hostnameLength = (int) strlen(hostname);
|
||||||
|
|
||||||
|
for (index = 0; index < channels->clientDataCount; index++)
|
||||||
|
{
|
||||||
|
ChannelConnectedEventArgs e;
|
||||||
|
CHANNEL_OPEN_DATA* pChannelOpenData;
|
||||||
|
pChannelClientData = &channels->clientDataList[index];
|
||||||
|
|
||||||
|
if (pChannelClientData->pChannelInitEventProc)
|
||||||
|
{
|
||||||
|
pChannelClientData->pChannelInitEventProc(
|
||||||
|
pChannelClientData->pInitHandle, CHANNEL_EVENT_DETACHED, hostname, hostnameLength);
|
||||||
|
}
|
||||||
|
else if (pChannelClientData->pChannelInitEventProcEx)
|
||||||
|
{
|
||||||
|
pChannelClientData->pChannelInitEventProcEx(pChannelClientData->lpUserParam,
|
||||||
|
pChannelClientData->pInitHandle, CHANNEL_EVENT_DETACHED, hostname, hostnameLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getChannelError(instance->context) != CHANNEL_RC_OK)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
pChannelOpenData = &channels->openDataList[index];
|
||||||
|
name = (char*) malloc(9);
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
{
|
||||||
|
error = CHANNEL_RC_NO_MEMORY;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMemory(name, pChannelOpenData->name, 8);
|
||||||
|
name[8] = '\0';
|
||||||
|
EventArgsInit(&e, "freerdp");
|
||||||
|
e.name = name;
|
||||||
|
e.pInterface = pChannelOpenData->pInterface;
|
||||||
|
PubSub_OnChannelDetached(instance->context->pubSub, instance->context, &e);
|
||||||
|
free(name);
|
||||||
|
name = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fail:
|
||||||
|
free(name);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* go through and inform all the libraries that we are connected
|
* go through and inform all the libraries that we are connected
|
||||||
* this will tell the libraries that its ok to call MyVirtualChannelOpen
|
* this will tell the libraries that its ok to call MyVirtualChannelOpen
|
||||||
@ -234,7 +380,7 @@ UINT freerdp_channels_post_connect(rdpChannels* channels, freerdp* instance)
|
|||||||
for (index = 0; index < channels->clientDataCount; index++)
|
for (index = 0; index < channels->clientDataCount; index++)
|
||||||
{
|
{
|
||||||
ChannelConnectedEventArgs e;
|
ChannelConnectedEventArgs e;
|
||||||
CHANNEL_OPEN_DATA* pChannelOpenData = NULL;
|
CHANNEL_OPEN_DATA* pChannelOpenData;
|
||||||
pChannelClientData = &channels->clientDataList[index];
|
pChannelClientData = &channels->clientDataList[index];
|
||||||
|
|
||||||
if (pChannelClientData->pChannelInitEventProc)
|
if (pChannelClientData->pChannelInitEventProc)
|
||||||
@ -279,6 +425,8 @@ UINT freerdp_channels_post_connect(rdpChannels* channels, freerdp* instance)
|
|||||||
channels->drdynvc->OnChannelConnected = freerdp_drdynvc_on_channel_connected;
|
channels->drdynvc->OnChannelConnected = freerdp_drdynvc_on_channel_connected;
|
||||||
channels->drdynvc->OnChannelDisconnected =
|
channels->drdynvc->OnChannelDisconnected =
|
||||||
freerdp_drdynvc_on_channel_disconnected;
|
freerdp_drdynvc_on_channel_disconnected;
|
||||||
|
channels->drdynvc->OnChannelAttached = freerdp_drdynvc_on_channel_attached;
|
||||||
|
channels->drdynvc->OnChannelDetached = freerdp_drdynvc_on_channel_detached;
|
||||||
}
|
}
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
@ -133,6 +133,8 @@ typedef CHANNEL_INIT_EVENT_EX_FN* PCHANNEL_INIT_EVENT_EX_FN;
|
|||||||
#define CHANNEL_EVENT_TERMINATED 4
|
#define CHANNEL_EVENT_TERMINATED 4
|
||||||
#define CHANNEL_EVENT_REMOTE_CONTROL_START 5
|
#define CHANNEL_EVENT_REMOTE_CONTROL_START 5
|
||||||
#define CHANNEL_EVENT_REMOTE_CONTROL_STOP 6
|
#define CHANNEL_EVENT_REMOTE_CONTROL_STOP 6
|
||||||
|
#define CHANNEL_EVENT_ATTACHED 7
|
||||||
|
#define CHANNEL_EVENT_DETACHED 8
|
||||||
#define CHANNEL_EVENT_DATA_RECEIVED 10
|
#define CHANNEL_EVENT_DATA_RECEIVED 10
|
||||||
#define CHANNEL_EVENT_WRITE_COMPLETE 11
|
#define CHANNEL_EVENT_WRITE_COMPLETE 11
|
||||||
#define CHANNEL_EVENT_WRITE_CANCELLED 12
|
#define CHANNEL_EVENT_WRITE_CANCELLED 12
|
||||||
|
Loading…
Reference in New Issue
Block a user