RDPAddins.NET/RDPAddins/RDPClient.cs

120 lines
4.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Win32.WtsApi32;
using System.Windows.Forms;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition;
using System.IO;
using System.Runtime.InteropServices;
using System.Drawing;
using RDPAddins.Common;
namespace RDPAddins
{
class RDPClient
{
IntPtr initHandle = IntPtr.Zero;
ChannelInitEventDelegate channelInitEventDelegate;
[ImportMany(typeof(IAddin))]
IEnumerable<Lazy<IAddin, IAddinMetadata>> Addins { get; set; }
List<Channel> Channels;
public ChannelEntryPoints EntryPoint { get; private set; }
internal SlaveMode MainForm { get; set; }
RDPClient Client;
public ChannelReturnCodes Initialize(string Path, IntPtr entry)
{
Client = this;
var pluginspath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(Path), "Plugins");
try
{
if (Directory.Exists(pluginspath))
{
EntryPoint = (ChannelEntryPoints)Marshal.PtrToStructure(entry, typeof(ChannelEntryPoints));
channelInitEventDelegate = new ChannelInitEventDelegate(VirtualChannelInitEventProc);
var batch = new CompositionBatch();
batch.AddPart(this);
var catalog = new DirectoryCatalog(pluginspath);
var container = new CompositionContainer(catalog);
container.Compose(batch);
Channels = Addins.Select(addin =>
{
return new Channel(this, addin);
}).ToList();
Channels.ForEach(channel =>
{
MainForm.Invoke(new Action(() =>
{
channel.CreateUI();
}));
});
var cds = Channels.Select(channel => channel.ChannelDef).ToArray();
return EntryPoint.VirtualChannelInit(ref initHandle, cds, cds.Length, 1, channelInitEventDelegate);
}
}
catch (Exception ex) { MessageBox.Show(ex.Message, "RDPAddins", MessageBoxButtons.OK, MessageBoxIcon.Error); }
return ChannelReturnCodes.NullData;
}
void ChannelsInitialized()
{
MainForm.Invoke(new Action(() =>
{
if (MainForm.Opacity == 0)
{
MainForm.Hide();
MainForm.Opacity = 100;
}
}));
}
void VirtualChannelInitEventProc(IntPtr initHandle, ChannelEvents initEvent, byte[] data, uint dataLength)
{
switch (initEvent)
{
case ChannelEvents.Initialized:
ChannelsInitialized();
Client.Channels.ForEach(channel => channel.InitializedInternal());
break;
case ChannelEvents.Connected:
string server = System.Text.Encoding.Unicode.GetString(data);
server = server.Substring(0, server.IndexOf('\0'));
Client.Channels.ForEach(channel =>
{
ChannelReturnCodes ret = channel.ConnectedInternal(initHandle);
if (ret != ChannelReturnCodes.Ok)
{
MessageBox.Show(string.Format("{0}: VirtualChannelOpen error: {1}", channel.Metadata.ChannelName, ret), "RDPAddins", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
});
MainForm.Invoke(new Action(() =>
{
MainForm.Text = "RDPAddnins: " + server;
}));
break;
case ChannelEvents.V1Connected:
MessageBox.Show("Bad RDP server version.", "RDPAddins", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case ChannelEvents.Disconnected:
MainForm.Invoke(new Action(() => MainForm.Text = "RDPAddnins"));
Channels.ForEach(channel => channel.DisconnectedInternal());
GC.Collect();
GC.WaitForPendingFinalizers();
break;
case ChannelEvents.Terminated:
Channels.ForEach(channel => channel.TerminatedInternal());
MainForm.RealClosing = true;
MainForm.Invoke(new Action(() => MainForm.Close()));
break;
}
}
}
}