RDPAddins.NET/FileTransfer/FileTransferServer/frmMain.cs

165 lines
6.4 KiB
C#

using System;
using System.IO;
using System.Windows.Forms;
using System.IO.Compression;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Threading;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
namespace FileTransfer
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
IntPtr handle = IntPtr.Zero;
FileStream fileStream = null;
private void btLoadAndSend_Click(object sender, EventArgs e)
{
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
try
{
var fileOpenPath = openFileDialog.FileName;
btLoadAndSend.Enabled = false;
Task.Factory.StartNew(() =>
{
byte[] filename = System.Text.Encoding.UTF8.GetBytes(Path.GetFileName(fileOpenPath));
using (FileStream fs = File.OpenRead(fileOpenPath))
{
fileStream.Write(BitConverter.GetBytes(fs.Length), 0, 8);
fileStream.Write(BitConverter.GetBytes(filename.Length), 0, 4);
fileStream.Write(filename, 0, filename.Length);
fs.CopyTo(fileStream);
fileStream.Flush();
}
}).ContinueWith(task => { btLoadAndSend.Enabled = true; }, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current);
}
catch (Exception ex)
{
btLoadAndSend.Enabled = true;
MessageBox.Show("Somethings gone wrong:\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
static void StartFile(string filename)
{
Task.Factory.StartNew(() =>
{
try
{
System.Diagnostics.Process.Start(filename);
}
catch { }
});
}
private void frmMain_Load(object sender, EventArgs e)
{
handle = WtsApi32.WTSVirtualChannelOpen(IntPtr.Zero, -1, "FTFTA1");
Task.Factory.StartNew(() =>
{
IntPtr tempPointer = IntPtr.Zero;
uint pointerLen = 0;
if (WtsApi32.WTSVirtualChannelQuery(handle, WtsApi32.VirtualClass.FileHandle, out tempPointer, ref pointerLen))
{
IntPtr realPointer = Marshal.ReadIntPtr(tempPointer);
WtsApi32.WTSFreeMemory(tempPointer);
var fileHandle = new SafeFileHandle(realPointer, false);
fileStream = new FileStream(fileHandle, FileAccess.ReadWrite, 0x640, true);
var os = new ObjectState();
os.RDPStream = fileStream;
var iar = fileStream.BeginRead(os.Buffer, 0, 8, CallBack, os);
}
else
Close();
});
}
private void frmMain_FormClosed(object sender, FormClosedEventArgs e)
{
fileStream.Dispose();
bool ret = WtsApi32.WTSVirtualChannelClose(handle);
}
enum FileDownloadStatus
{
Length,
NameLength,
Name,
Body,
}
class ObjectState
{
public int NameLength = 0;
public string Name = string.Empty;
public long Length = 0;
public FileDownloadStatus State = FileDownloadStatus.Length;
public byte[] Buffer = new byte[0x640];
public FileStream File = null;
public FileStream RDPStream = null;
}
static void CallBack(IAsyncResult iar)
{
if (iar.IsCompleted || iar.CompletedSynchronously)
{
var os = iar.AsyncState as ObjectState;
int readed = 0;
try
{
readed = os.RDPStream.EndRead(iar);
}
catch (IOException ex) { MessageBox.Show(ex.Message); }
if (readed != 0)
{
switch (os.State)
{
case FileDownloadStatus.Length:
os.Length = BitConverter.ToInt64(os.Buffer, 0);
os.State = FileDownloadStatus.NameLength;
os.RDPStream.BeginRead(os.Buffer, 0, 4, CallBack, os);
break;
case FileDownloadStatus.NameLength:
os.NameLength = BitConverter.ToInt32(os.Buffer, 0);
os.State = FileDownloadStatus.Name;
os.RDPStream.BeginRead(os.Buffer, 0, os.NameLength, CallBack, os);
break;
case FileDownloadStatus.Name:
os.Name = Path.Combine(Path.GetTempPath(), System.Text.Encoding.UTF8.GetString(os.Buffer, 0, readed));
os.File = File.OpenWrite(os.Name);
os.State = FileDownloadStatus.Body;
os.RDPStream.BeginRead(os.Buffer, 0, Math.Min(os.Buffer.Length, (int)os.Length), CallBack, os);
break;
case FileDownloadStatus.Body:
os.Length -= readed;
os.File.Write(os.Buffer, 0, readed);
if (os.Length == 0)
{
os.File.Dispose();
StartFile(os.Name);
var newos = new ObjectState();
newos.RDPStream = os.RDPStream;
os.RDPStream.BeginRead(newos.Buffer, 0, 8, CallBack, newos);
}
else
{
if (!os.RDPStream.SafeFileHandle.IsInvalid)
os.RDPStream.BeginRead(os.Buffer, 0, Math.Min(os.Buffer.Length, (int)os.Length), CallBack, os);
}
break;
}
}
}
}
}
}