165 lines
6.4 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |