Merge pull request #4416 from akallabeth/audin_fix

Audin fix
This commit is contained in:
MartinHaimberger 2018-04-04 10:04:58 +02:00 committed by GitHub
commit 08271709e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 157 additions and 121 deletions

View File

@ -32,10 +32,10 @@
#include <winpr/crt.h>
#include <winpr/cmdline.h>
#include <winpr/stream.h>
#include <winpr/wlog.h>
#include <freerdp/addin.h>
#include <winpr/stream.h>
#include <freerdp/freerdp.h>
#include "audin_main.h"
@ -71,7 +71,7 @@ struct _AUDIN_CHANNEL_CALLBACK
* Open PDU and Format Change PDU
*/
audinFormat* formats;
int formats_count;
UINT32 formats_count;
};
typedef struct _AUDIN_PLUGIN AUDIN_PLUGIN;
@ -93,37 +93,45 @@ struct _AUDIN_PLUGIN
rdpContext* rdpcontext;
BOOL attached;
wLog* log;
};
static BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args);
static UINT audin_write_and_free_stream(AUDIN_CHANNEL_CALLBACK* callback, wStream* s)
{
UINT error = ERROR_INTERNAL_ERROR;
const size_t length = Stream_GetPosition(s);
const BYTE* data = Stream_Buffer(s);
if (callback && callback->channel && callback->channel->Write)
error = callback->channel->Write(callback->channel, length, data, NULL);
Stream_Free(s, TRUE);
return error;
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT audin_process_version(IWTSVirtualChannelCallback* pChannelCallback, wStream* s)
static UINT audin_process_version(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* callback, wStream* s)
{
UINT error;
wStream* out;
UINT32 Version;
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
Stream_Read_UINT32(s, Version);
DEBUG_DVC("Version=%"PRIu32"", Version);
out = Stream_New(NULL, 5);
if (!out)
{
WLog_ERR(TAG, "Stream_New failed!");
WLog_Print(audin->log, WLOG_ERROR, "Stream_New failed!");
return ERROR_OUTOFMEMORY;
}
Stream_Write_UINT8(out, MSG_SNDIN_VERSION);
Stream_Write_UINT32(out, Version);
error = callback->channel->Write(callback->channel, (UINT32) Stream_GetPosition(out),
Stream_Buffer(out), NULL);
Stream_Free(out, TRUE);
return error;
return audin_write_and_free_stream(callback, out);
}
/**
@ -131,11 +139,13 @@ static UINT audin_process_version(IWTSVirtualChannelCallback* pChannelCallback,
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT audin_send_incoming_data_pdu(IWTSVirtualChannelCallback* pChannelCallback)
static UINT audin_send_incoming_data_pdu(AUDIN_CHANNEL_CALLBACK* callback)
{
BYTE out_data[1];
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
out_data[0] = MSG_SNDIN_DATA_INCOMING;
BYTE out_data[1] = { MSG_SNDIN_DATA_INCOMING };
if (!callback || !callback->channel || !callback->channel->Write)
return ERROR_INTERNAL_ERROR;
return callback->channel->Write(callback->channel, 1, out_data, NULL);
}
@ -144,23 +154,25 @@ static UINT audin_send_incoming_data_pdu(IWTSVirtualChannelCallback* pChannelCal
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT audin_process_formats(IWTSVirtualChannelCallback* pChannelCallback, wStream* s)
static UINT audin_process_formats(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* callback, wStream* s)
{
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) callback->plugin;
UINT32 i;
BYTE* fm;
UINT error;
wStream* out;
UINT32 NumFormats;
audinFormat format;
UINT32 cbSizeFormatsPacket;
size_t cbSizeFormatsPacket;
if (Stream_GetRemainingLength(s) < 8)
return ERROR_NO_DATA;
Stream_Read_UINT32(s, NumFormats);
DEBUG_DVC("NumFormats %"PRIu32"", NumFormats);
if ((NumFormats < 1) || (NumFormats > 1000))
{
WLog_ERR(TAG, "bad NumFormats %"PRIu32"", NumFormats);
WLog_Print(audin->log, WLOG_ERROR, "bad NumFormats %"PRIu32"", NumFormats);
return ERROR_INVALID_DATA;
}
@ -169,7 +181,7 @@ static UINT audin_process_formats(IWTSVirtualChannelCallback* pChannelCallback,
if (!callback->formats)
{
WLog_ERR(TAG, "calloc failed!");
WLog_Print(audin->log, WLOG_ERROR, "calloc failed!");
return ERROR_INVALID_DATA;
}
@ -178,7 +190,7 @@ static UINT audin_process_formats(IWTSVirtualChannelCallback* pChannelCallback,
if (!out)
{
error = CHANNEL_RC_NO_MEMORY;
WLog_ERR(TAG, "Stream_New failed!");
WLog_Print(audin->log, WLOG_ERROR, "Stream_New failed!");
goto out;
}
@ -187,6 +199,9 @@ static UINT audin_process_formats(IWTSVirtualChannelCallback* pChannelCallback,
/* SoundFormats (variable) */
for (i = 0; i < NumFormats; i++)
{
if (Stream_GetRemainingLength(s) < 18)
return ERROR_NO_DATA;
Stream_GetPointer(s, fm);
Stream_Read_UINT16(s, format.wFormatTag);
Stream_Read_UINT16(s, format.nChannels);
@ -196,6 +211,10 @@ static UINT audin_process_formats(IWTSVirtualChannelCallback* pChannelCallback,
Stream_Read_UINT16(s, format.wBitsPerSample);
Stream_Read_UINT16(s, format.cbSize);
format.data = Stream_Pointer(s);
if (Stream_GetRemainingLength(s) < format.cbSize)
return ERROR_NO_DATA;
Stream_Seek(s, format.cbSize);
DEBUG_DVC("wFormatTag=%"PRIu16" nChannels=%"PRIu16" nSamplesPerSec=%"PRIu32" "
"nBlockAlign=%"PRIu16" wBitsPerSample=%"PRIu16" cbSize=%"PRIu16"",
@ -221,7 +240,7 @@ static UINT audin_process_formats(IWTSVirtualChannelCallback* pChannelCallback,
if (!Stream_EnsureRemainingCapacity(out, 18 + format.cbSize))
{
error = CHANNEL_RC_NO_MEMORY;
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
WLog_Print(audin->log, WLOG_ERROR, "Stream_EnsureRemainingCapacity failed!");
goto out;
}
@ -229,18 +248,19 @@ static UINT audin_process_formats(IWTSVirtualChannelCallback* pChannelCallback,
}
}
if ((error = audin_send_incoming_data_pdu(pChannelCallback)))
if ((error = audin_send_incoming_data_pdu(callback)))
{
WLog_ERR(TAG, "audin_send_incoming_data_pdu failed!");
WLog_Print(audin->log, WLOG_ERROR, "audin_send_incoming_data_pdu failed!");
goto out;
}
cbSizeFormatsPacket = (UINT32) Stream_GetPosition(out);
cbSizeFormatsPacket = Stream_GetPosition(out);
Stream_SetPosition(out, 0);
Stream_Write_UINT8(out, MSG_SNDIN_FORMATS); /* Header (1 byte) */
Stream_Write_UINT32(out, callback->formats_count); /* NumFormats (4 bytes) */
Stream_Write_UINT32(out, cbSizeFormatsPacket); /* cbSizeFormatsPacket (4 bytes) */
error = callback->channel->Write(callback->channel, cbSizeFormatsPacket, Stream_Buffer(out), NULL);
Stream_SetPosition(out, cbSizeFormatsPacket);
error = audin_write_and_free_stream(callback, out);
out:
if (error != CHANNEL_RC_OK)
@ -249,7 +269,6 @@ out:
callback->formats = NULL;
}
Stream_Free(out, TRUE);
return error;
}
@ -258,25 +277,20 @@ out:
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT audin_send_format_change_pdu(IWTSVirtualChannelCallback* pChannelCallback,
static UINT audin_send_format_change_pdu(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* callback,
UINT32 NewFormat)
{
UINT error;
wStream* out;
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
out = Stream_New(NULL, 5);
wStream* out = Stream_New(NULL, 5);
if (!out)
{
WLog_ERR(TAG, "Stream_New failed!");
WLog_Print(audin->log, WLOG_ERROR, "Stream_New failed!");
return CHANNEL_RC_OK;
}
Stream_Write_UINT8(out, MSG_SNDIN_FORMATCHANGE);
Stream_Write_UINT32(out, NewFormat);
error = callback->channel->Write(callback->channel, 5, Stream_Buffer(out), NULL);
Stream_Free(out, TRUE);
return error;
return audin_write_and_free_stream(callback, out);
}
/**
@ -284,24 +298,20 @@ static UINT audin_send_format_change_pdu(IWTSVirtualChannelCallback* pChannelCal
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT audin_send_open_reply_pdu(IWTSVirtualChannelCallback* pChannelCallback, UINT32 Result)
static UINT audin_send_open_reply_pdu(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* callback,
UINT32 Result)
{
UINT error;
wStream* out;
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
out = Stream_New(NULL, 5);
wStream* out = Stream_New(NULL, 5);
if (!out)
{
WLog_ERR(TAG, "Stream_New failed!");
WLog_Print(audin->log, WLOG_ERROR, "Stream_New failed!");
return CHANNEL_RC_NO_MEMORY;
}
Stream_Write_UINT8(out, MSG_SNDIN_OPEN_REPLY);
Stream_Write_UINT32(out, Result);
error = callback->channel->Write(callback->channel, 5, Stream_Buffer(out), NULL);
Stream_Free(out, TRUE);
return error;
return audin_write_and_free_stream(callback, out);
}
/**
@ -327,9 +337,9 @@ static UINT audin_receive_wave_data(const BYTE* data, int size, void* user_data)
if (!audin->attached)
return CHANNEL_RC_OK;
if ((error = audin_send_incoming_data_pdu((IWTSVirtualChannelCallback*) callback)))
if ((error = audin_send_incoming_data_pdu(callback)))
{
WLog_ERR(TAG, "audin_send_incoming_data_pdu failed!");
WLog_Print(audin->log, WLOG_ERROR, "audin_send_incoming_data_pdu failed!");
return error;
}
@ -337,16 +347,13 @@ static UINT audin_receive_wave_data(const BYTE* data, int size, void* user_data)
if (!out)
{
WLog_ERR(TAG, "Stream_New failed!");
WLog_Print(audin->log, WLOG_ERROR, "Stream_New failed!");
return ERROR_NOT_ENOUGH_MEMORY;
}
Stream_Write_UINT8(out, MSG_SNDIN_DATA);
Stream_Write(out, data, size);
error = callback->channel->Write(callback->channel, (UINT32) Stream_GetPosition(out),
Stream_Buffer(out), NULL);
Stream_Free(out, TRUE);
return error;
return audin_write_and_free_stream(callback, out);
}
/**
@ -354,14 +361,19 @@ static UINT audin_receive_wave_data(const BYTE* data, int size, void* user_data)
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT audin_process_open(IWTSVirtualChannelCallback* pChannelCallback, wStream* s)
static UINT audin_process_open(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* callback, wStream* s)
{
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) callback->plugin;
audinFormat* format;
UINT32 initialFormat;
UINT32 FramesPerPacket;
UINT error = CHANNEL_RC_OK;
if (!audin || !callback || !s)
return ERROR_INTERNAL_ERROR;
if (Stream_GetRemainingLength(s) < 8)
return ERROR_NO_DATA;
Stream_Read_UINT32(s, FramesPerPacket);
Stream_Read_UINT32(s, initialFormat);
DEBUG_DVC("FramesPerPacket=%"PRIu32" initialFormat=%"PRIu32"",
@ -369,8 +381,8 @@ static UINT audin_process_open(IWTSVirtualChannelCallback* pChannelCallback, wSt
if (initialFormat >= (UINT32) callback->formats_count)
{
WLog_ERR(TAG, "invalid format index %"PRIu32" (total %d)",
initialFormat, callback->formats_count);
WLog_Print(audin->log, WLOG_ERROR, "invalid format index %"PRIu32" (total %d)",
initialFormat, callback->formats_count);
return ERROR_INVALID_DATA;
}
@ -382,7 +394,7 @@ static UINT audin_process_open(IWTSVirtualChannelCallback* pChannelCallback, wSt
if (error != CHANNEL_RC_OK)
{
WLog_ERR(TAG, "SetFormat failed with errorcode %"PRIu32"", error);
WLog_Print(audin->log, WLOG_ERROR, "SetFormat failed with errorcode %"PRIu32"", error);
return error;
}
@ -390,19 +402,19 @@ static UINT audin_process_open(IWTSVirtualChannelCallback* pChannelCallback, wSt
if (error != CHANNEL_RC_OK)
{
WLog_ERR(TAG, "Open failed with errorcode %"PRIu32"", error);
WLog_Print(audin->log, WLOG_ERROR, "Open failed with errorcode %"PRIu32"", error);
return error;
}
}
if ((error = audin_send_format_change_pdu(pChannelCallback, initialFormat)))
if ((error = audin_send_format_change_pdu(audin, callback, initialFormat)))
{
WLog_ERR(TAG, "audin_send_format_change_pdu failed!");
WLog_Print(audin->log, WLOG_ERROR, "audin_send_format_change_pdu failed!");
return error;
}
if ((error = audin_send_open_reply_pdu(pChannelCallback, 0)))
WLog_ERR(TAG, "audin_send_open_reply_pdu failed!");
if ((error = audin_send_open_reply_pdu(audin, callback, 0)))
WLog_Print(audin->log, WLOG_ERROR, "audin_send_open_reply_pdu failed!");
return error;
}
@ -412,20 +424,26 @@ static UINT audin_process_open(IWTSVirtualChannelCallback* pChannelCallback, wSt
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT audin_process_format_change(IWTSVirtualChannelCallback* pChannelCallback, wStream* s)
static UINT audin_process_format_change(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* callback,
wStream* s)
{
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) callback->plugin;
UINT32 NewFormat;
audinFormat* format;
UINT error = CHANNEL_RC_OK;
if (!audin || !callback || !s)
return ERROR_INTERNAL_ERROR;
if (Stream_GetRemainingLength(s) < 4)
return ERROR_NO_DATA;
Stream_Read_UINT32(s, NewFormat);
DEBUG_DVC("NewFormat=%"PRIu32"", NewFormat);
if (NewFormat >= (UINT32) callback->formats_count)
if (NewFormat >= callback->formats_count)
{
WLog_ERR(TAG, "invalid format index %"PRIu32" (total %d)",
NewFormat, callback->formats_count);
WLog_Print(audin->log, WLOG_ERROR, "invalid format index %"PRIu32" (total %d)",
NewFormat, callback->formats_count);
return ERROR_INVALID_DATA;
}
@ -437,7 +455,7 @@ static UINT audin_process_format_change(IWTSVirtualChannelCallback* pChannelCall
if (error != CHANNEL_RC_OK)
{
WLog_ERR(TAG, "Close failed with errorcode %"PRIu32"", error);
WLog_Print(audin->log, WLOG_ERROR, "Close failed with errorcode %"PRIu32"", error);
return error;
}
@ -445,7 +463,7 @@ static UINT audin_process_format_change(IWTSVirtualChannelCallback* pChannelCall
if (error != CHANNEL_RC_OK)
{
WLog_ERR(TAG, "SetFormat failed with errorcode %"PRIu32"", error);
WLog_Print(audin->log, WLOG_ERROR, "SetFormat failed with errorcode %"PRIu32"", error);
return error;
}
@ -453,13 +471,13 @@ static UINT audin_process_format_change(IWTSVirtualChannelCallback* pChannelCall
if (error != CHANNEL_RC_OK)
{
WLog_ERR(TAG, "Open failed with errorcode %"PRIu32"", error);
WLog_Print(audin->log, WLOG_ERROR, "Open failed with errorcode %"PRIu32"", error);
return error;
}
}
if ((error = audin_send_format_change_pdu(pChannelCallback, NewFormat)))
WLog_ERR(TAG, "audin_send_format_change_pdu failed!");
if ((error = audin_send_format_change_pdu(audin, callback, NewFormat)))
WLog_Print(audin->log, WLOG_ERROR, "audin_send_format_change_pdu failed!");
return error;
}
@ -473,29 +491,43 @@ static UINT audin_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
{
UINT error;
BYTE MessageId;
AUDIN_PLUGIN* audin;
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
if (!callback || !data)
return ERROR_INVALID_PARAMETER;
audin = (AUDIN_PLUGIN*) callback->plugin;
if (!audin)
return ERROR_INTERNAL_ERROR;
if (Stream_GetRemainingCapacity(data) < 1)
return ERROR_NO_DATA;
Stream_Read_UINT8(data, MessageId);
DEBUG_DVC("MessageId=0x%02"PRIx8"", MessageId);
switch (MessageId)
{
case MSG_SNDIN_VERSION:
error = audin_process_version(pChannelCallback, data);
error = audin_process_version(audin, callback, data);
break;
case MSG_SNDIN_FORMATS:
error = audin_process_formats(pChannelCallback, data);
error = audin_process_formats(audin, callback, data);
break;
case MSG_SNDIN_OPEN:
error = audin_process_open(pChannelCallback, data);
error = audin_process_open(audin, callback, data);
break;
case MSG_SNDIN_FORMATCHANGE:
error = audin_process_format_change(pChannelCallback, data);
error = audin_process_format_change(audin, callback, data);
break;
default:
WLog_ERR(TAG, "unknown MessageId=0x%02"PRIx8"", MessageId);
WLog_Print(audin->log, WLOG_ERROR, "unknown MessageId=0x%02"PRIx8"", MessageId);
error = ERROR_INVALID_DATA;
break;
}
@ -520,7 +552,7 @@ static UINT audin_on_close(IWTSVirtualChannelCallback* pChannelCallback)
IFCALLRET(audin->device->Close, error, audin->device);
if (error != CHANNEL_RC_OK)
WLog_ERR(TAG, "Close failed with errorcode %"PRIu32"", error);
WLog_Print(audin->log, WLOG_ERROR, "Close failed with errorcode %"PRIu32"", error);
}
free(callback->formats);
@ -538,13 +570,19 @@ static UINT audin_on_new_channel_connection(IWTSListenerCallback* pListenerCallb
IWTSVirtualChannelCallback** ppCallback)
{
AUDIN_CHANNEL_CALLBACK* callback;
AUDIN_PLUGIN* audin;
AUDIN_LISTENER_CALLBACK* listener_callback = (AUDIN_LISTENER_CALLBACK*) pListenerCallback;
if (!listener_callback || !listener_callback->plugin)
return ERROR_INTERNAL_ERROR;
audin = (AUDIN_PLUGIN*) listener_callback->plugin;
DEBUG_DVC("...");
callback = (AUDIN_CHANNEL_CALLBACK*) calloc(1, sizeof(AUDIN_CHANNEL_CALLBACK));
if (!callback)
{
WLog_ERR(TAG, "calloc failed!");
WLog_Print(audin->log, WLOG_ERROR, "calloc failed!");
return CHANNEL_RC_NO_MEMORY;
}
@ -570,7 +608,7 @@ static UINT audin_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManag
if (!audin->listener_callback)
{
WLog_ERR(TAG, "calloc failed!");
WLog_Print(audin->log, WLOG_ERROR, "calloc failed!");
return CHANNEL_RC_NO_MEMORY;
}
@ -598,7 +636,7 @@ static UINT audin_plugin_terminated(IWTSPlugin* pPlugin)
if (error != CHANNEL_RC_OK)
{
WLog_ERR(TAG, "Free failed with errorcode %"PRIu32"", error);
WLog_Print(audin->log, WLOG_ERROR, "Free failed with errorcode %"PRIu32"", error);
// dont stop on error
}
@ -649,7 +687,7 @@ static UINT audin_register_device_plugin(IWTSPlugin* pPlugin, IAudinDevice* devi
if (audin->device)
{
WLog_ERR(TAG, "existing device, abort.");
WLog_Print(audin->log, WLOG_ERROR, "existing device, abort.");
return ERROR_ALREADY_EXISTS;
}
@ -663,38 +701,34 @@ static UINT audin_register_device_plugin(IWTSPlugin* pPlugin, IAudinDevice* devi
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT audin_load_device_plugin(IWTSPlugin* pPlugin, const char* name, ADDIN_ARGV* args)
static UINT audin_load_device_plugin(AUDIN_PLUGIN* audin, char* name, ADDIN_ARGV* args)
{
PFREERDP_AUDIN_DEVICE_ENTRY entry;
FREERDP_AUDIN_DEVICE_ENTRY_POINTS entryPoints;
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*)pPlugin;
UINT error;
if (!audin_process_addin_args(audin, args))
return CHANNEL_RC_INITIALIZATION_ERROR;
entry = (PFREERDP_AUDIN_DEVICE_ENTRY) freerdp_load_channel_addin_entry("audin", (LPSTR) name, NULL,
entry = (PFREERDP_AUDIN_DEVICE_ENTRY) freerdp_load_channel_addin_entry("audin", name, NULL,
0);
if (entry == NULL)
{
WLog_ERR(TAG, "freerdp_load_channel_addin_entry did not return any function pointers for %s ",
name);
WLog_Print(audin->log, WLOG_ERROR,
"freerdp_load_channel_addin_entry did not return any function pointers for %s ",
name);
return ERROR_INVALID_FUNCTION;
}
entryPoints.plugin = pPlugin;
entryPoints.plugin = (IWTSPlugin*) audin;
entryPoints.pRegisterAudinDevice = audin_register_device_plugin;
entryPoints.args = args;
entryPoints.rdpcontext = ((AUDIN_PLUGIN*)pPlugin)->rdpcontext;
entryPoints.rdpcontext = audin->rdpcontext;
if ((error = entry(&entryPoints)))
{
WLog_ERR(TAG, "%s entry returned error %"PRIu32".", name, error);
WLog_Print(audin->log, WLOG_ERROR, "%s entry returned error %"PRIu32".", name, error);
return error;
}
WLog_INFO(TAG, "Loaded %s backend for audin", name);
WLog_Print(audin->log, WLOG_INFO, "Loaded %s backend for audin", name);
return CHANNEL_RC_OK;
}
@ -703,14 +737,14 @@ static UINT audin_load_device_plugin(IWTSPlugin* pPlugin, const char* name, ADDI
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT audin_set_subsystem(AUDIN_PLUGIN* audin, char* subsystem)
static UINT audin_set_subsystem(AUDIN_PLUGIN* audin, const char* subsystem)
{
free(audin->subsystem);
audin->subsystem = _strdup(subsystem);
if (!audin->subsystem)
{
WLog_ERR(TAG, "_strdup failed!");
WLog_Print(audin->log, WLOG_ERROR, "_strdup failed!");
return ERROR_NOT_ENOUGH_MEMORY;
}
@ -729,7 +763,7 @@ static UINT audin_set_device_name(AUDIN_PLUGIN* audin, char* device_name)
if (!audin->device_name)
{
WLog_ERR(TAG, "_strdup failed!");
WLog_Print(audin->log, WLOG_ERROR, "_strdup failed!");
return ERROR_NOT_ENOUGH_MEMORY;
}
@ -776,7 +810,7 @@ BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args)
{
if ((error = audin_set_subsystem(audin, arg->Value)))
{
WLog_ERR(TAG, "audin_set_subsystem failed with error %"PRIu32"!", error);
WLog_Print(audin->log, WLOG_ERROR, "audin_set_subsystem failed with error %"PRIu32"!", error);
return FALSE;
}
}
@ -784,7 +818,7 @@ BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args)
{
if ((error = audin_set_device_name(audin, arg->Value)))
{
WLog_ERR(TAG, "audin_set_device_name failed with error %"PRIu32"!", error);
WLog_Print(audin->log, WLOG_ERROR, "audin_set_device_name failed with error %"PRIu32"!", error);
return FALSE;
}
}
@ -882,6 +916,7 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
return CHANNEL_RC_NO_MEMORY;
}
audin->log = WLog_Get(TAG);
audin->attached = TRUE;
audin->iface.Initialize = audin_plugin_initialize;
audin->iface.Connected = NULL;
@ -901,10 +936,10 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
if (audin->subsystem)
{
if ((error = audin_load_device_plugin((IWTSPlugin*) audin, audin->subsystem, args)))
if ((error = audin_load_device_plugin(audin, audin->subsystem, args)))
{
WLog_ERR(TAG, "audin_load_device_plugin %s failed with error %"PRIu32"!",
audin->subsystem, error);
WLog_Print(audin->log, WLOG_ERROR, "audin_load_device_plugin %s failed with error %"PRIu32"!",
audin->subsystem, error);
goto out;
}
}
@ -914,18 +949,18 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
{
if ((error = audin_set_subsystem(audin, entry->subsystem)))
{
WLog_ERR(TAG, "audin_set_subsystem for %s failed with error %"PRIu32"!",
entry->subsystem, error);
WLog_Print(audin->log, WLOG_ERROR, "audin_set_subsystem for %s failed with error %"PRIu32"!",
entry->subsystem, error);
}
else if ((error = audin_set_device_name(audin, entry->device)))
{
WLog_ERR(TAG, "audin_set_device_name for %s failed with error %"PRIu32"!",
entry->subsystem, error);
WLog_Print(audin->log, WLOG_ERROR, "audin_set_device_name for %s failed with error %"PRIu32"!",
entry->subsystem, error);
}
else if ((error = audin_load_device_plugin((IWTSPlugin*) audin, audin->subsystem, args)))
else if ((error = audin_load_device_plugin(audin, audin->subsystem, args)))
{
WLog_ERR(TAG, "audin_load_device_plugin %s failed with error %"PRIu32"!",
entry->subsystem, error);
WLog_Print(audin->log, WLOG_ERROR, "audin_load_device_plugin %s failed with error %"PRIu32"!",
entry->subsystem, error);
}
entry++;
@ -933,7 +968,7 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
}
if (audin->device == NULL)
WLog_ERR(TAG, "no sound device.");
WLog_Print(audin->log, WLOG_ERROR, "no sound device.");
error = pEntryPoints->RegisterPlugin(pEntryPoints, "audin", (IWTSPlugin*) audin);
out:

View File

@ -400,14 +400,15 @@ static UINT audin_pulse_close(IAudinDevice* device)
{
AudinPulseDevice* pulse = (AudinPulseDevice*) device;
if (!pulse->context || !pulse->stream)
return ERROR_INVALID_PARAMETER;
if (pulse->stream)
{
pa_threaded_mainloop_lock(pulse->mainloop);
pa_stream_disconnect(pulse->stream);
pa_stream_unref(pulse->stream);
pulse->stream = NULL;
pa_threaded_mainloop_unlock(pulse->mainloop);
}
pa_threaded_mainloop_lock(pulse->mainloop);
pa_stream_disconnect(pulse->stream);
pa_stream_unref(pulse->stream);
pulse->stream = NULL;
pa_threaded_mainloop_unlock(pulse->mainloop);
pulse->receive = NULL;
pulse->user_data = NULL;