channels/rdpsnd: make use of MessagePipe
[platform/upstream/freerdp.git] / channels / rdpsnd / client / rdpsnd_main.c
index b709972..46d9e71 100644 (file)
@@ -4,6 +4,7 @@
  *
  * Copyright 2009-2011 Jay Sorg
  * Copyright 2010-2011 Vic Lee
+ * Copyright 2012-2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -34,6 +35,8 @@
 #include <winpr/crt.h>
 #include <winpr/synch.h>
 #include <winpr/print.h>
+#include <winpr/thread.h>
+#include <winpr/stream.h>
 #include <winpr/cmdline.h>
 #include <winpr/sysinfo.h>
 #include <winpr/collections.h>
@@ -41,9 +44,8 @@
 #include <freerdp/types.h>
 #include <freerdp/addin.h>
 #include <freerdp/constants.h>
-#include <winpr/stream.h>
+#include <freerdp/utils/debug.h>
 #include <freerdp/utils/signal.h>
-#include <freerdp/utils/svc_plugin.h>
 
 #include "rdpsnd_main.h"
 
 
 struct rdpsnd_plugin
 {
-       rdpSvcPlugin plugin;
+       CHANNEL_DEF channelDef;
+       CHANNEL_ENTRY_POINTS_EX channelEntryPoints;
 
        HANDLE thread;
-       wMessageQueue* queue;
+       wStream* data_in;
+       void* InitHandle;
+       UINT32 OpenHandle;
+       wMessagePipe* MsgPipe;
+
+       HANDLE ScheduleThread;
 
        BYTE cBlockNo;
        int wCurrentFormatNo;
@@ -83,7 +91,7 @@ struct rdpsnd_plugin
        rdpsndDevicePlugin* device;
 };
 
-void rdpsnd_send_wave_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp, BYTE cConfirmedBlockNo);
+static void rdpsnd_send_wave_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp, BYTE cConfirmedBlockNo);
 
 static void* rdpsnd_schedule_thread(void* arg)
 {
@@ -96,10 +104,10 @@ static void* rdpsnd_schedule_thread(void* arg)
 
        while (1)
        {
-               if (!MessageQueue_Wait(rdpsnd->queue))
+               if (!MessageQueue_Wait(rdpsnd->MsgPipe->Out))
                        break;
 
-               if (!MessageQueue_Peek(rdpsnd->queue, &message, TRUE))
+               if (!MessageQueue_Peek(rdpsnd->MsgPipe->Out, &message, TRUE))
                        break;
 
                if (message.id == WMQ_QUIT)
@@ -117,6 +125,7 @@ static void* rdpsnd_schedule_thread(void* arg)
 
                rdpsnd_send_wave_confirm_pdu(rdpsnd, wave->wTimeStampB, wave->cBlockNo);
                free(wave);
+               message.wParam = NULL;
        }
 
        return NULL;
@@ -133,7 +142,7 @@ void rdpsnd_send_quality_mode_pdu(rdpsndPlugin* rdpsnd)
        Stream_Write_UINT16(pdu, HIGH_QUALITY); /* wQualityMode */
        Stream_Write_UINT16(pdu, 0); /* Reserved */
 
-       svc_plugin_send((rdpSvcPlugin*) rdpsnd, pdu);
+       rdpsnd_virtual_channel_write(rdpsnd, pdu);
 }
 
 void rdpsnd_select_supported_audio_formats(rdpsndPlugin* rdpsnd)
@@ -249,7 +258,7 @@ void rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd)
                        Stream_Write(pdu, clientFormat->data, clientFormat->cbSize);
        }
 
-       svc_plugin_send((rdpSvcPlugin*) rdpsnd, pdu);
+       rdpsnd_virtual_channel_write(rdpsnd, pdu);
 }
 
 void rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* s)
@@ -258,13 +267,14 @@ void rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* s)
        UINT16 wVersion;
        AUDIO_FORMAT* format;
        UINT16 wNumberOfFormats;
+       UINT32 dwVolume;
 
        rdpsnd_free_audio_formats(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats);
        rdpsnd->NumberOfServerFormats = 0;
        rdpsnd->ServerFormats = NULL;
 
        Stream_Seek_UINT32(s); /* dwFlags */
-       Stream_Seek_UINT32(s); /* dwVolume */
+       Stream_Read_UINT32(s, dwVolume); /* dwVolume */
        Stream_Seek_UINT32(s); /* dwPitch */
        Stream_Seek_UINT16(s); /* wDGramPort */
        Stream_Read_UINT16(s, wNumberOfFormats);
@@ -297,6 +307,9 @@ void rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* s)
 
        if (wVersion >= 6)
                rdpsnd_send_quality_mode_pdu(rdpsnd);
+       
+       if (rdpsnd->device)
+               IFCALL(rdpsnd->device->SetVolume, rdpsnd->device, dwVolume);
 }
 
 void rdpsnd_send_training_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp, UINT16 wPackSize)
@@ -310,7 +323,7 @@ void rdpsnd_send_training_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp, U
        Stream_Write_UINT16(pdu, wTimeStamp);
        Stream_Write_UINT16(pdu, wPackSize);
 
-       svc_plugin_send((rdpSvcPlugin*) rdpsnd, pdu);
+       rdpsnd_virtual_channel_write(rdpsnd, pdu);
 }
 
 static void rdpsnd_recv_training_pdu(rdpsndPlugin* rdpsnd, wStream* s)
@@ -376,12 +389,12 @@ void rdpsnd_send_wave_confirm_pdu(rdpsndPlugin* rdpsnd, UINT16 wTimeStamp, BYTE
        Stream_Write_UINT8(pdu, cConfirmedBlockNo); /* cConfirmedBlockNo */
        Stream_Write_UINT8(pdu, 0); /* bPad */
 
-       svc_plugin_send((rdpSvcPlugin*) rdpsnd, pdu);
+       rdpsnd_virtual_channel_write(rdpsnd, pdu);
 }
 
-void rdpsnd_device_send_wave_confirm_pdu(rdpsndDevicePlugin* device, RDPSND_WAVE* wave)
+static void rdpsnd_device_send_wave_confirm_pdu(rdpsndDevicePlugin* device, RDPSND_WAVE* wave)
 {
-       MessageQueue_Post(device->rdpsnd->queue, NULL, 0, (void*) wave, NULL);
+       MessageQueue_Post(device->rdpsnd->MsgPipe->Out, NULL, 0, (void*) wave, NULL);
 }
 
 static void rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, wStream* s)
@@ -442,14 +455,12 @@ static void rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, wStream* s)
        {
                wave->wTimeStampB = rdpsnd->wTimeStamp + wave->wAudioLength + TIME_DELAY_MS;
                wave->wLocalTimeB = wave->wLocalTimeA + wave->wAudioLength + TIME_DELAY_MS;
-               rdpsnd->device->WaveConfirm(rdpsnd->device, wave);
        }
+       rdpsnd->device->WaveConfirm(rdpsnd->device, wave);
 }
 
 static void rdpsnd_recv_close_pdu(rdpsndPlugin* rdpsnd)
 {
-       DEBUG_SVC("server closes.");
-
        if (rdpsnd->device)
        {
                IFCALL(rdpsnd->device->Close, rdpsnd->device);
@@ -463,7 +474,6 @@ static void rdpsnd_recv_volume_pdu(rdpsndPlugin* rdpsnd, wStream* s)
        UINT32 dwVolume;
 
        Stream_Read_UINT32(s, dwVolume);
-       DEBUG_SVC("dwVolume 0x%X", dwVolume);
 
        if (rdpsnd->device)
        {
@@ -471,11 +481,10 @@ static void rdpsnd_recv_volume_pdu(rdpsndPlugin* rdpsnd, wStream* s)
        }
 }
 
-static void rdpsnd_recv_pdu(rdpSvcPlugin* plugin, wStream* s)
+static void rdpsnd_recv_pdu(rdpsndPlugin* rdpsnd, wStream* s)
 {
        BYTE msgType;
        UINT16 BodySize;
-       rdpsndPlugin* rdpsnd = (rdpsndPlugin*) plugin;
 
        if (rdpsnd->expectingWave)
        {
@@ -594,6 +603,8 @@ static void rdpsnd_process_addin_args(rdpsndPlugin* rdpsnd, ADDIN_ARGV* args)
 
        status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv,
                        rdpsnd_args, flags, rdpsnd, NULL, NULL);
+       if (status < 0)
+               return;
 
        arg = rdpsnd_args;
 
@@ -638,18 +649,17 @@ static void rdpsnd_process_addin_args(rdpsndPlugin* rdpsnd, ADDIN_ARGV* args)
        while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
 }
 
-static void rdpsnd_process_connect(rdpSvcPlugin* plugin)
+static void rdpsnd_process_connect(rdpsndPlugin* rdpsnd)
 {
        ADDIN_ARGV* args;
-       rdpsndPlugin* rdpsnd = (rdpsndPlugin*) plugin;
-
-       DEBUG_SVC("connecting");
 
        rdpsnd->latency = -1;
-       rdpsnd->queue = MessageQueue_New();
-       rdpsnd->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) rdpsnd_schedule_thread, (void*) plugin, 0, NULL);
 
-       args = (ADDIN_ARGV*) plugin->channel_entry_points.pExtendedData;
+       rdpsnd->ScheduleThread = CreateThread(NULL, 0,
+                       (LPTHREAD_START_ROUTINE) rdpsnd_schedule_thread,
+                       (void*) rdpsnd, 0, NULL);
+
+       args = (ADDIN_ARGV*) rdpsnd->channelEntryPoints.pExtendedData;
 
        if (args)
                rdpsnd_process_addin_args(rdpsnd, args);
@@ -662,40 +672,59 @@ static void rdpsnd_process_connect(rdpSvcPlugin* plugin)
                rdpsnd_load_device_plugin(rdpsnd, rdpsnd->subsystem, args);
        }
 
+#if defined(WITH_IOSAUDIO)
        if (!rdpsnd->device)
        {
-               rdpsnd_set_subsystem(rdpsnd, "pulse");
+               rdpsnd_set_subsystem(rdpsnd, "ios");
                rdpsnd_set_device_name(rdpsnd, "");
                rdpsnd_load_device_plugin(rdpsnd, rdpsnd->subsystem, args);
        }
+#endif
 
+#if defined(WITH_OPENSLES)
        if (!rdpsnd->device)
        {
-               rdpsnd_set_subsystem(rdpsnd, "alsa");
-               rdpsnd_set_device_name(rdpsnd, "default");
+               rdpsnd_set_subsystem(rdpsnd, "opensles");
+               rdpsnd_set_device_name(rdpsnd, "");
                rdpsnd_load_device_plugin(rdpsnd, rdpsnd->subsystem, args);
        }
+#endif
 
+#if defined(WITH_PULSE)
        if (!rdpsnd->device)
        {
-               rdpsnd_set_subsystem(rdpsnd, "macaudio");
+               rdpsnd_set_subsystem(rdpsnd, "pulse");
+               rdpsnd_set_device_name(rdpsnd, "");
+               rdpsnd_load_device_plugin(rdpsnd, rdpsnd->subsystem, args);
+       }
+#endif
+
+#if defined(WITH_ALSA)
+       if (!rdpsnd->device)
+       {
+               rdpsnd_set_subsystem(rdpsnd, "alsa");
                rdpsnd_set_device_name(rdpsnd, "default");
                rdpsnd_load_device_plugin(rdpsnd, rdpsnd->subsystem, args);
        }
+#endif
 
+#if defined(WITH_MACAUDIO)
        if (!rdpsnd->device)
        {
-               rdpsnd_set_subsystem(rdpsnd, "winmm");
-               rdpsnd_set_device_name(rdpsnd, "");
+               rdpsnd_set_subsystem(rdpsnd, "macaudio");
+               rdpsnd_set_device_name(rdpsnd, "default");
                rdpsnd_load_device_plugin(rdpsnd, rdpsnd->subsystem, args);
        }
+#endif
 
+#if defined(WITH_WINMM)
        if (!rdpsnd->device)
        {
-               rdpsnd_set_subsystem(rdpsnd, "audiotrack");
+               rdpsnd_set_subsystem(rdpsnd, "winmm");
                rdpsnd_set_device_name(rdpsnd, "");
                rdpsnd_load_device_plugin(rdpsnd, rdpsnd->subsystem, args);
        }
+#endif
 
        if (!rdpsnd->device)
        {
@@ -704,23 +733,15 @@ static void rdpsnd_process_connect(rdpSvcPlugin* plugin)
        }
 }
 
-static void rdpsnd_process_event(rdpSvcPlugin* plugin, wMessage* event)
-{
-       freerdp_event_free(event);
-}
-
-static void rdpsnd_process_terminate(rdpSvcPlugin* plugin)
+static void rdpsnd_process_terminate(rdpsndPlugin* rdpsnd)
 {
-       rdpsndPlugin* rdpsnd = (rdpsndPlugin*) plugin;
-
        if (rdpsnd->device)
                IFCALL(rdpsnd->device->Free, rdpsnd->device);
 
-       MessageQueue_PostQuit(rdpsnd->queue, 0);
-       WaitForSingleObject(rdpsnd->thread, INFINITE);
+       MessageQueue_PostQuit(rdpsnd->MsgPipe->Out, 0);
 
-       MessageQueue_Free(rdpsnd->queue);
-       CloseHandle(rdpsnd->thread);
+       WaitForSingleObject(rdpsnd->ScheduleThread, INFINITE);
+       CloseHandle(rdpsnd->ScheduleThread);
 
        if (rdpsnd->subsystem)
                free(rdpsnd->subsystem);
@@ -737,37 +758,276 @@ static void rdpsnd_process_terminate(rdpSvcPlugin* plugin)
        rdpsnd->ClientFormats = NULL;
 }
 
-/* rdpsnd is always built-in */
-#define VirtualChannelEntry    rdpsnd_VirtualChannelEntry
 
-int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
+/****************************************************************************************/
+
+
+static wListDictionary* g_InitHandles;
+static wListDictionary* g_OpenHandles;
+
+void rdpsnd_add_init_handle_data(void* pInitHandle, void* pUserData)
 {
-       rdpsndPlugin* _p;
+       if (!g_InitHandles)
+               g_InitHandles = ListDictionary_New(TRUE);
 
-       _p = (rdpsndPlugin*) malloc(sizeof(rdpsndPlugin));
-       ZeroMemory(_p, sizeof(rdpsndPlugin));
+       ListDictionary_Add(g_InitHandles, pInitHandle, pUserData);
+}
 
-       _p->plugin.channel_def.options =
-                       CHANNEL_OPTION_INITIALIZED |
-                       CHANNEL_OPTION_ENCRYPT_RDP;
+void* rdpsnd_get_init_handle_data(void* pInitHandle)
+{
+       void* pUserData = NULL;
+       pUserData = ListDictionary_GetItemValue(g_InitHandles, pInitHandle);
+       return pUserData;
+}
 
-       strcpy(_p->plugin.channel_def.name, "rdpsnd");
+void rdpsnd_remove_init_handle_data(void* pInitHandle)
+{
+       ListDictionary_Remove(g_InitHandles, pInitHandle);
+}
 
-       _p->plugin.connect_callback = rdpsnd_process_connect;
-       _p->plugin.receive_callback = rdpsnd_recv_pdu;
-       _p->plugin.event_callback = rdpsnd_process_event;
-       _p->plugin.terminate_callback = rdpsnd_process_terminate;
+void rdpsnd_add_open_handle_data(DWORD openHandle, void* pUserData)
+{
+       void* pOpenHandle = (void*) (size_t) openHandle;
 
-#if !defined(_WIN32) && !defined(ANDROID)
+       if (!g_OpenHandles)
+               g_OpenHandles = ListDictionary_New(TRUE);
+
+       ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData);
+}
+
+void* rdpsnd_get_open_handle_data(DWORD openHandle)
+{
+       void* pUserData = NULL;
+       void* pOpenHandle = (void*) (size_t) openHandle;
+       pUserData = ListDictionary_GetItemValue(g_OpenHandles, pOpenHandle);
+       return pUserData;
+}
+
+void rdpsnd_remove_open_handle_data(DWORD openHandle)
+{
+       void* pOpenHandle = (void*) (size_t) openHandle;
+       ListDictionary_Remove(g_OpenHandles, pOpenHandle);
+}
+
+int rdpsnd_virtual_channel_write(rdpsndPlugin* rdpsnd, wStream* s)
+{
+       UINT32 status = 0;
+
+       if (!rdpsnd)
+               status = CHANNEL_RC_BAD_INIT_HANDLE;
+       else
+               status = rdpsnd->channelEntryPoints.pVirtualChannelWrite(rdpsnd->OpenHandle,
+                       Stream_Buffer(s), Stream_GetPosition(s), s);
+
+       if (status != CHANNEL_RC_OK)
+       {
+               Stream_Free(s, TRUE);
+               fprintf(stderr, "rdpdr_virtual_channel_write: VirtualChannelWrite failed %d\n", status);
+       }
+
+       return status;
+}
+
+static void rdpsnd_virtual_channel_event_data_received(rdpsndPlugin* plugin,
+               void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
+{
+       wStream* s;
+
+       if ((dataFlags & CHANNEL_FLAG_SUSPEND) || (dataFlags & CHANNEL_FLAG_RESUME))
+       {
+               return;
+       }
+
+       if (dataFlags & CHANNEL_FLAG_FIRST)
+       {
+               if (plugin->data_in != NULL)
+                       Stream_Free(plugin->data_in, TRUE);
+
+               plugin->data_in = Stream_New(NULL, totalLength);
+       }
+
+       s = plugin->data_in;
+       Stream_EnsureRemainingCapacity(s, (int) dataLength);
+       Stream_Write(s, pData, dataLength);
+
+       if (dataFlags & CHANNEL_FLAG_LAST)
        {
-               sigset_t mask;
-               sigemptyset(&mask);
-               sigaddset(&mask, SIGIO);
-               pthread_sigmask(SIG_BLOCK, &mask, NULL);
+               if (Stream_Capacity(s) != Stream_GetPosition(s))
+               {
+                       fprintf(stderr, "rdpsnd_virtual_channel_event_data_received: read error\n");
+               }
+
+               plugin->data_in = NULL;
+               Stream_SealLength(s);
+               Stream_SetPosition(s, 0);
+
+               MessageQueue_Post(plugin->MsgPipe->In, NULL, 0, (void*) s, NULL);
        }
+}
+
+static void rdpsnd_virtual_channel_open_event(UINT32 openHandle, UINT32 event,
+               void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
+{
+       rdpsndPlugin* plugin;
+
+       plugin = (rdpsndPlugin*) rdpsnd_get_open_handle_data(openHandle);
+
+       if (!plugin)
+       {
+               fprintf(stderr, "rdpsnd_virtual_channel_open_event: error no match\n");
+               return;
+       }
+
+       switch (event)
+       {
+               case CHANNEL_EVENT_DATA_RECEIVED:
+                       rdpsnd_virtual_channel_event_data_received(plugin, pData, dataLength, totalLength, dataFlags);
+                       break;
+
+               case CHANNEL_EVENT_WRITE_COMPLETE:
+                       Stream_Free((wStream*) pData, TRUE);
+                       break;
+
+               case CHANNEL_EVENT_USER:
+                       break;
+       }
+}
+
+static void* rdpsnd_virtual_channel_client_thread(void* arg)
+{
+       wStream* data;
+       wMessage message;
+       rdpsndPlugin* plugin = (rdpsndPlugin*) arg;
+
+       rdpsnd_process_connect(plugin);
+
+       while (1)
+       {
+               if (!MessageQueue_Wait(plugin->MsgPipe->In))
+                       break;
+
+               if (MessageQueue_Peek(plugin->MsgPipe->In, &message, TRUE))
+               {
+                       if (message.id == WMQ_QUIT)
+                               break;
+
+                       if (message.id == 0)
+                       {
+                               data = (wStream*) message.wParam;
+                               rdpsnd_recv_pdu(plugin, data);
+                       }
+               }
+       }
+
+       ExitThread(0);
+       return NULL;
+}
+
+static void rdpsnd_virtual_channel_event_connected(rdpsndPlugin* plugin, void* pData, UINT32 dataLength)
+{
+       UINT32 status;
+
+       status = plugin->channelEntryPoints.pVirtualChannelOpen(plugin->InitHandle,
+               &plugin->OpenHandle, plugin->channelDef.name, rdpsnd_virtual_channel_open_event);
+
+       rdpsnd_add_open_handle_data(plugin->OpenHandle, plugin);
+
+       if (status != CHANNEL_RC_OK)
+       {
+               fprintf(stderr, "rdpsnd_virtual_channel_event_connected: open failed: status: %d\n", status);
+               return;
+       }
+
+       plugin->MsgPipe = MessagePipe_New();
+
+       plugin->thread = CreateThread(NULL, 0,
+                       (LPTHREAD_START_ROUTINE) rdpsnd_virtual_channel_client_thread, (void*) plugin, 0, NULL);
+}
+
+static void rdpsnd_virtual_channel_event_terminated(rdpsndPlugin* plugin)
+{
+       MessagePipe_PostQuit(plugin->MsgPipe, 0);
+       WaitForSingleObject(plugin->thread, INFINITE);
+
+       MessagePipe_Free(plugin->MsgPipe);
+       CloseHandle(plugin->thread);
+
+       plugin->channelEntryPoints.pVirtualChannelClose(plugin->OpenHandle);
+
+       if (plugin->data_in)
+       {
+               Stream_Free(plugin->data_in, TRUE);
+               plugin->data_in = NULL;
+       }
+
+       rdpsnd_process_terminate(plugin);
+
+       rdpsnd_remove_open_handle_data(plugin->OpenHandle);
+       rdpsnd_remove_init_handle_data(plugin->InitHandle);
+}
+
+static void rdpsnd_virtual_channel_init_event(void* pInitHandle, UINT32 event, void* pData, UINT32 dataLength)
+{
+       rdpsndPlugin* plugin;
+
+       plugin = (rdpsndPlugin*) rdpsnd_get_init_handle_data(pInitHandle);
+
+       if (!plugin)
+       {
+               fprintf(stderr, "rdpsnd_virtual_channel_init_event: error no match\n");
+               return;
+       }
+
+       switch (event)
+       {
+               case CHANNEL_EVENT_CONNECTED:
+                       rdpsnd_virtual_channel_event_connected(plugin, pData, dataLength);
+                       break;
+
+               case CHANNEL_EVENT_DISCONNECTED:
+                       break;
+
+               case CHANNEL_EVENT_TERMINATED:
+                       rdpsnd_virtual_channel_event_terminated(plugin);
+                       break;
+       }
+}
+
+/* rdpsnd is always built-in */
+#define VirtualChannelEntry    rdpsnd_VirtualChannelEntry
+
+int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
+{
+       rdpsndPlugin* rdpsnd;
+
+       rdpsnd = (rdpsndPlugin*) malloc(sizeof(rdpsndPlugin));
+
+       if (rdpsnd)
+       {
+               ZeroMemory(rdpsnd, sizeof(rdpsndPlugin));
+
+#if !defined(_WIN32) && !defined(ANDROID)
+               {
+                       sigset_t mask;
+                       sigemptyset(&mask);
+                       sigaddset(&mask, SIGIO);
+                       pthread_sigmask(SIG_BLOCK, &mask, NULL);
+               }
 #endif
 
-       svc_plugin_init((rdpSvcPlugin*) _p, pEntryPoints);
+               rdpsnd->channelDef.options =
+                               CHANNEL_OPTION_INITIALIZED |
+                               CHANNEL_OPTION_ENCRYPT_RDP;
+
+               strcpy(rdpsnd->channelDef.name, "rdpsnd");
+
+               CopyMemory(&(rdpsnd->channelEntryPoints), pEntryPoints, pEntryPoints->cbSize);
+
+               rdpsnd->channelEntryPoints.pVirtualChannelInit(&rdpsnd->InitHandle,
+                       &rdpsnd->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, rdpsnd_virtual_channel_init_event);
+
+               rdpsnd_add_init_handle_data(rdpsnd->InitHandle, (void*) rdpsnd);
+       }
 
        return 1;
 }