120 lines
4.7 KiB
C#
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;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
} |