mirror of
https://github.com/Ylianst/MeshCentralRouter
synced 2025-12-06 00:13:33 +00:00
2096 lines
76 KiB
C#
2096 lines
76 KiB
C#
/*
|
|
Copyright 2009-2021 Intel Corporation
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Net;
|
|
using System.Text;
|
|
using System.Drawing;
|
|
using System.Collections;
|
|
using System.Windows.Forms;
|
|
using System.Collections.Generic;
|
|
using System.Security.Cryptography;
|
|
using System.Web.Script.Serialization;
|
|
|
|
namespace MeshCentralRouter
|
|
{
|
|
public partial class FileViewer : Form
|
|
{
|
|
private MeshCentralServer server = null;
|
|
private NodeClass node = null;
|
|
private int state = 0;
|
|
private RandomNumberGenerator rand = RandomNumberGenerator.Create();
|
|
private string randomIdHex = null;
|
|
public webSocketClient wc = null;
|
|
public Dictionary<string, int> userSessions = null;
|
|
public bool sessionIsRecorded = false;
|
|
public DirectoryInfo localFolder = null;
|
|
public string remoteFolder = null;
|
|
public ArrayList remoteFolderList = null;
|
|
private static string rndString = getRandomString(12);
|
|
private bool skipExistingFiles = false;
|
|
private FileDialogMsgForm msgForm = null;
|
|
|
|
// Stats
|
|
public long bytesIn = 0;
|
|
public long bytesInCompressed = 0;
|
|
public long bytesOut = 0;
|
|
public long bytesOutCompressed = 0;
|
|
|
|
// Upload state
|
|
public FileTransferStatusForm transferStatusForm = null;
|
|
public bool uploadActive = false;
|
|
public bool uploadStop = false;
|
|
public int uploadFileArrayPtr = -1;
|
|
public ArrayList uploadFileArray;
|
|
public Hashtable uploadFileDuplicateArray; // Name --> Size
|
|
public DirectoryInfo uploadLocalPath;
|
|
public string uploadRemotePath;
|
|
public FileStream uploadFileStream = null;
|
|
public long uploadFilePtr = 0;
|
|
public long uploadFileStartPtr = 0;
|
|
public long uploadFileSize = 0;
|
|
public DateTime uploadFileStartTime = DateTime.MinValue;
|
|
public string uploadFileName = null;
|
|
|
|
// Download state
|
|
public bool downloadActive = false;
|
|
public bool downloadStop = false;
|
|
public int downloadFileArrayPtr = -1;
|
|
public ArrayList downloadFileArray;
|
|
public ArrayList downloadFileSizeArray;
|
|
public DirectoryInfo downloadLocalPath;
|
|
public string downloadRemotePath;
|
|
public FileStream downloadFileStream = null;
|
|
public long downloadFilePtr = 0;
|
|
public long downloadFileSize = 0;
|
|
public DateTime downloadFileStartTime = DateTime.MinValue;
|
|
|
|
public FileViewer(MeshCentralServer server, NodeClass node)
|
|
{
|
|
InitializeComponent();
|
|
Translate.TranslateControl(this);
|
|
if(node != null) { this.Text += " - " + node.name; }
|
|
this.node = node;
|
|
this.server = server;
|
|
UpdateStatus();
|
|
|
|
rightListView.Columns[0].Width = rightListView.Width - rightListView.Columns[1].Width - 22;
|
|
|
|
// Load the local path from the registry
|
|
string lp = Settings.GetRegValue("LocalPath", "");
|
|
if((lp != "") && (Directory.Exists(lp))) { localFolder = new DirectoryInfo(lp); }
|
|
}
|
|
|
|
public bool updateLocalFileView()
|
|
{
|
|
// Save the list of selected items
|
|
List<String> selectedItems = new List<String>();
|
|
foreach(ListViewItem l in leftListView.SelectedItems) { selectedItems.Add(l.Text); }
|
|
|
|
// Refresh the list
|
|
leftListView.Items.Clear();
|
|
if(localFolder == null)
|
|
{
|
|
localRootButton.Enabled = false;
|
|
localNewFolderButton.Enabled = false;
|
|
localDeleteButton.Enabled = false;
|
|
try
|
|
{
|
|
DriveInfo[] drives = DriveInfo.GetDrives();
|
|
foreach(DriveInfo drive in drives)
|
|
{
|
|
ListViewItem x = new ListViewItem(drive.Name, 0);
|
|
x.Tag = drive;
|
|
leftListView.Items.Add(x);
|
|
}
|
|
localUpButton.Enabled = false;
|
|
localLabel.Text = Translate.T(Properties.Resources.Local);
|
|
mainToolTip.SetToolTip(localLabel, Translate.T(Properties.Resources.Local));
|
|
}
|
|
catch(Exception) { return false; }
|
|
}
|
|
else
|
|
{
|
|
localRootButton.Enabled = true;
|
|
localNewFolderButton.Enabled = true;
|
|
localDeleteButton.Enabled = false;
|
|
try
|
|
{
|
|
DirectoryInfo[] directories = localFolder.GetDirectories();
|
|
foreach(DirectoryInfo directory in directories)
|
|
{
|
|
ListViewItem x = new ListViewItem(directory.Name, 1);
|
|
x.Tag = directory;
|
|
leftListView.Items.Add(x);
|
|
}
|
|
FileInfo[] files = localFolder.GetFiles();
|
|
foreach(FileInfo file in files)
|
|
{
|
|
if(file.Attributes.HasFlag(FileAttributes.Hidden)) continue;
|
|
string[] si = new string[2];
|
|
si[0] = file.Name;
|
|
si[1] = "" + file.Length;
|
|
ListViewItem x = new ListViewItem(si, 2);
|
|
x.Tag = file;
|
|
leftListView.Items.Add(x);
|
|
}
|
|
localUpButton.Enabled = true;
|
|
localLabel.Text = string.Format(Translate.T(Properties.Resources.LocalPlus), localFolder.FullName);
|
|
mainToolTip.SetToolTip(localLabel, string.Format(Translate.T(Properties.Resources.LocalPlus), localFolder.FullName));
|
|
}
|
|
catch(Exception) { return false; }
|
|
}
|
|
updateTransferButtons();
|
|
|
|
// Reselect items
|
|
foreach(ListViewItem l in leftListView.Items) { l.Selected = selectedItems.Contains(l.Text); }
|
|
|
|
return true;
|
|
}
|
|
|
|
public class ListViewItemSortClass : IComparer
|
|
{
|
|
int IComparer.Compare(Object x, Object y)
|
|
{
|
|
return ((new CaseInsensitiveComparer()).Compare(((ListViewItem)x).SubItems[0].Text, ((ListViewItem)y).SubItems[0].Text));
|
|
}
|
|
}
|
|
|
|
private delegate void updateRemoteFileViewHandler();
|
|
public bool bDontupdateRemoteFileView = false; // Flynn
|
|
public void updateRemoteFileView()
|
|
{
|
|
if(bDontupdateRemoteFileView) return; // Flynn
|
|
if(this.InvokeRequired) { this.Invoke(new updateRemoteFileViewHandler(updateRemoteFileView)); return; }
|
|
|
|
// Save the list of selected items
|
|
List<String> selectedItems = new List<String>();
|
|
foreach(ListViewItem l in rightListView.SelectedItems) { selectedItems.Add(l.Text); }
|
|
|
|
rightListView.Items.Clear();
|
|
|
|
if((remoteFolder == null) || (remoteFolder == ""))
|
|
{
|
|
remoteLabel.Text = Translate.T(Properties.Resources.Remote);
|
|
mainToolTip.SetToolTip(remoteLabel, Translate.T(Properties.Resources.Remote));
|
|
}
|
|
else
|
|
{
|
|
if(node.agentid < 5)
|
|
{
|
|
remoteLabel.Text = string.Format(Translate.T(Properties.Resources.RemotePlus), remoteFolder.Replace("/", "\\"));
|
|
mainToolTip.SetToolTip(remoteLabel, string.Format(Translate.T(Properties.Resources.RemotePlus), remoteFolder.Replace("/", "\\")));
|
|
}
|
|
else
|
|
{
|
|
remoteLabel.Text = string.Format(Translate.T(Properties.Resources.RemotePlus), remoteFolder);
|
|
mainToolTip.SetToolTip(remoteLabel, string.Format(Translate.T(Properties.Resources.RemotePlus), remoteFolder));
|
|
}
|
|
}
|
|
|
|
remoteRefreshButton.Enabled = true;
|
|
remoteRootButton.Enabled = !((remoteFolder == null) || (remoteFolder == ""));
|
|
remoteUpButton.Enabled = !((remoteFolder == null) || (remoteFolder == ""));
|
|
if(node.agentid < 5)
|
|
{
|
|
remoteNewFolderButton.Enabled = !((remoteFolder == null) || (remoteFolder == ""));
|
|
remoteDeleteButton.Enabled = remoteZipButton.Enabled = (!((remoteFolder == null) || (remoteFolder == ""))) && (rightListView.SelectedItems.Count > 0);
|
|
}
|
|
else
|
|
{
|
|
remoteNewFolderButton.Enabled = true;
|
|
remoteDeleteButton.Enabled = remoteZipButton.Enabled = (rightListView.SelectedItems.Count > 0);
|
|
}
|
|
|
|
if(remoteFolderList != null)
|
|
{
|
|
ArrayList sortlist = new ArrayList();
|
|
|
|
// Display all folders
|
|
for(int i = 0; i < remoteFolderList.Count; i++)
|
|
{
|
|
Dictionary<string, object> fileItem = (Dictionary<string, object>)remoteFolderList[i];
|
|
int fileIcon = 0;
|
|
string fileName = null;
|
|
string fileDate = null;
|
|
long fileSize = -1;
|
|
if(fileItem.ContainsKey("t")) { fileIcon = (int)fileItem["t"]; }
|
|
if(fileItem.ContainsKey("n")) { fileName = (string)fileItem["n"]; }
|
|
if(fileItem.ContainsKey("d")) { fileDate = (string)fileItem["d"]; }
|
|
if(fileItem.ContainsKey("s"))
|
|
{
|
|
if(fileItem["s"].GetType() == typeof(System.Int32)) { fileSize = (int)fileItem["s"]; }
|
|
if(fileItem["s"].GetType() == typeof(System.Int64)) { fileSize = (long)fileItem["s"]; }
|
|
}
|
|
if(fileIcon == 1)
|
|
{
|
|
sortlist.Add(new ListViewItem(fileName, 0)); // Drive
|
|
}
|
|
else if(fileIcon == 2)
|
|
{
|
|
sortlist.Add(new ListViewItem(fileName, 1)); // Folder
|
|
}
|
|
}
|
|
sortlist.Sort(new ListViewItemSortClass());
|
|
foreach(ListViewItem l in sortlist) { rightListView.Items.Add(l); }
|
|
sortlist.Clear();
|
|
|
|
// Display all files
|
|
for(int i = 0; i < remoteFolderList.Count; i++)
|
|
{
|
|
Dictionary<string, object> fileItem = (Dictionary<string, object>)remoteFolderList[i];
|
|
int fileIcon = 0;
|
|
string fileName = null;
|
|
string fileDate = null;
|
|
long fileSize = -1;
|
|
if(fileItem.ContainsKey("t")) { fileIcon = (int)fileItem["t"]; }
|
|
if(fileItem.ContainsKey("n")) { fileName = (string)fileItem["n"]; }
|
|
if(fileItem.ContainsKey("d")) { fileDate = (string)fileItem["d"]; }
|
|
if(fileItem.ContainsKey("s"))
|
|
{
|
|
if(fileItem["s"].GetType() == typeof(System.Int32)) { fileSize = (int)fileItem["s"]; }
|
|
if(fileItem["s"].GetType() == typeof(System.Int64)) { fileSize = (long)fileItem["s"]; }
|
|
}
|
|
if(fileIcon == 3)
|
|
{
|
|
// File
|
|
string[] si = new string[2];
|
|
si[0] = fileName;
|
|
si[1] = "" + fileSize;
|
|
sortlist.Add(new ListViewItem(si, 2)); // File
|
|
}
|
|
}
|
|
sortlist.Sort(new ListViewItemSortClass());
|
|
foreach(ListViewItem l in sortlist) { rightListView.Items.Add(l); }
|
|
}
|
|
updateTransferButtons();
|
|
|
|
// Reselect items
|
|
foreach(ListViewItem l in rightListView.Items) { l.Selected = selectedItems.Contains(l.Text); }
|
|
}
|
|
|
|
private void Server_onStateChanged(int state)
|
|
{
|
|
UpdateStatus();
|
|
}
|
|
|
|
private void MainForm_Load(object sender, EventArgs e)
|
|
{
|
|
updateLocalFileView();
|
|
|
|
// Restore Window Location
|
|
string locationStr = Settings.GetRegValue("filelocation", "");
|
|
if(locationStr != null)
|
|
{
|
|
string[] locationSplit = locationStr.Split(',');
|
|
if(locationSplit.Length == 4)
|
|
{
|
|
try
|
|
{
|
|
var x = int.Parse(locationSplit[0]);
|
|
var y = int.Parse(locationSplit[1]);
|
|
var w = int.Parse(locationSplit[2]);
|
|
var h = int.Parse(locationSplit[3]);
|
|
Point p = new Point(x, y);
|
|
if(isPointVisibleOnAScreen(p))
|
|
{
|
|
Location = p;
|
|
if((w > 50) && (h > 50)) { Size = new Size(w, h); }
|
|
}
|
|
}
|
|
catch(Exception) { }
|
|
}
|
|
}
|
|
}
|
|
|
|
private void MenuItemExit_Click(object sender, EventArgs e)
|
|
{
|
|
Close();
|
|
}
|
|
|
|
public void MenuItemConnect_Click(object sender, EventArgs e)
|
|
{
|
|
if((wc != null) || (node == null)) return;
|
|
byte[] randomid = new byte[10];
|
|
rand.GetBytes(randomid);
|
|
randomIdHex = BitConverter.ToString(randomid).Replace("-", string.Empty);
|
|
|
|
state = 1;
|
|
string ux = server.wsurl.ToString().Replace("/control.ashx", "/");
|
|
int i = ux.IndexOf("?");
|
|
if(i >= 0) { ux = ux.Substring(0, i); }
|
|
Uri u = new Uri(ux + "meshrelay.ashx?browser=1&p=5&nodeid=" + node.nodeid + "&id=" + randomIdHex + "&auth=" + server.authCookie);
|
|
wc = new webSocketClient();
|
|
wc.debug = server.debug;
|
|
wc.onStateChanged += Wc_onStateChanged;
|
|
wc.onBinaryData += Wc_onBinaryData;
|
|
wc.onStringData += Wc_onStringData;
|
|
wc.TLSCertCheck = webSocketClient.TLSCertificateCheck.Fingerprint;
|
|
wc.Start(u, server.wshash, null);
|
|
}
|
|
|
|
private void Wc_onStateChanged(webSocketClient sender, webSocketClient.ConnectionStates wsstate)
|
|
{
|
|
switch(wsstate)
|
|
{
|
|
case webSocketClient.ConnectionStates.Disconnected:
|
|
{
|
|
// Disconnect
|
|
state = 0;
|
|
wc.Dispose();
|
|
wc = null;
|
|
break;
|
|
}
|
|
case webSocketClient.ConnectionStates.Connecting:
|
|
{
|
|
state = 1;
|
|
displayMessage(null);
|
|
break;
|
|
}
|
|
case webSocketClient.ConnectionStates.Connected:
|
|
{
|
|
// Reset stats
|
|
bytesIn = 0;
|
|
bytesInCompressed = 0;
|
|
bytesOut = 0;
|
|
bytesOutCompressed = 0;
|
|
|
|
state = 2;
|
|
|
|
string u = "*" + server.wsurl.AbsolutePath.Replace("control.ashx", "meshrelay.ashx") + "?p=5&nodeid=" + node.nodeid + "&id=" + randomIdHex + "&rauth=" + server.rauthCookie;
|
|
server.sendCommand("{ \"action\": \"msg\", \"type\": \"tunnel\", \"nodeid\": \"" + node.nodeid + "\", \"value\": \"" + u.ToString() + "\", \"usage\": 5 }");
|
|
displayMessage(null);
|
|
break;
|
|
}
|
|
}
|
|
UpdateStatus();
|
|
updateTransferButtons();
|
|
}
|
|
|
|
private void requestRemoteFolder(string path)
|
|
{
|
|
// Send LS command
|
|
string cmd = "{\"action\":\"ls\",\"reqid\":1,\"path\":\"" + path.Replace("\\", "/") + "\"}";
|
|
byte[] bincmd = UTF8Encoding.UTF8.GetBytes(cmd);
|
|
wc.SendBinary(bincmd, 0, bincmd.Length);
|
|
}
|
|
|
|
private void requestCreateFolder(string path)
|
|
{
|
|
// Send MKDIR command
|
|
string cmd = "{\"action\":\"mkdir\",\"reqid\":2,\"path\":\"" + path.Replace("\\", "/") + "\"}";
|
|
byte[] bincmd = UTF8Encoding.UTF8.GetBytes(cmd);
|
|
wc.SendBinary(bincmd, 0, bincmd.Length);
|
|
}
|
|
|
|
public void requestCancel()
|
|
{
|
|
string cmd = "{\"action\":\"cancel\"}";
|
|
byte[] bincmd = UTF8Encoding.UTF8.GetBytes(cmd);
|
|
wc.SendBinary(bincmd, 0, bincmd.Length);
|
|
updateMsgForm(null, null, 0);
|
|
}
|
|
|
|
private void requestCreateZipFileFolder(string path, string zip, string[] files)
|
|
{
|
|
// Send ZIP command
|
|
string cmd = "{\"action\":\"zip\",\"reqid\":5,\"path\":\"" + path.Replace("\\", "/") + "\",\"output\":\"" + zip.Replace("\\", "/") + "\",\"files\":[";
|
|
bool first = true;
|
|
foreach(string file in files)
|
|
{
|
|
if(first) { first = false; } else { cmd += ","; }
|
|
cmd += "\"" + file + "\"";
|
|
}
|
|
cmd += "]}";
|
|
byte[] bincmd = UTF8Encoding.UTF8.GetBytes(cmd);
|
|
wc.SendBinary(bincmd, 0, bincmd.Length);
|
|
}
|
|
|
|
private void requestRename(string path, string oldname, string newname)
|
|
{
|
|
// Send RENAME command
|
|
string cmd = "{\"action\":\"rename\",\"reqid\":3,\"path\":\"" + path.Replace("\\", "/") + "\",\"oldname\":\"" + oldname + "\",\"newname\":\"" + newname + "\"}";
|
|
byte[] bincmd = UTF8Encoding.UTF8.GetBytes(cmd);
|
|
wc.SendBinary(bincmd, 0, bincmd.Length);
|
|
}
|
|
|
|
private void requestDelete(string path, string[] files, bool recursive)
|
|
{
|
|
// Send RM command
|
|
string delfiles = "";
|
|
foreach(string file in files) { if(delfiles.Length != 0) { delfiles += ","; } delfiles += "\"" + file + "\""; }
|
|
string cmd = "{\"action\":\"rm\",\"reqid\":4,\"path\":\"" + path.Replace("\\", "/") + "\",\"rec\":" + recursive.ToString().ToLower() + ",\"delfiles\":[" + delfiles + "]}";
|
|
byte[] bincmd = UTF8Encoding.UTF8.GetBytes(cmd);
|
|
wc.SendBinary(bincmd, 0, bincmd.Length);
|
|
}
|
|
|
|
private void Wc_onStringData(webSocketClient sender, string data, int orglen)
|
|
{
|
|
bytesIn += data.Length;
|
|
bytesInCompressed += orglen;
|
|
|
|
if((state == 2) && ((data == "c") || (data == "cr")))
|
|
{
|
|
if(data == "cr") { sessionIsRecorded = true; }
|
|
state = 3;
|
|
UpdateStatus();
|
|
displayMessage(null);
|
|
|
|
// Send protocol
|
|
string cmd = "5";
|
|
byte[] bincmd = UTF8Encoding.UTF8.GetBytes(cmd);
|
|
wc.SendBinary(bincmd, 0, bincmd.Length);
|
|
|
|
// Ask for root level
|
|
requestRemoteFolder("");
|
|
return;
|
|
}
|
|
if(state != 3) return;
|
|
|
|
// Parse the received JSON
|
|
Dictionary<string, object> jsonAction = new Dictionary<string, object>();
|
|
jsonAction = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(data);
|
|
if(jsonAction == null) return;
|
|
|
|
if(jsonAction.ContainsKey("action") && (jsonAction["action"].GetType() == typeof(string)))
|
|
{
|
|
string action = jsonAction["action"].ToString();
|
|
switch(action)
|
|
{
|
|
case "download":
|
|
{
|
|
if(downloadStop) { downloadCancel(); return; }
|
|
|
|
string sub = null;
|
|
if(jsonAction.ContainsKey("sub")) { sub = (string)jsonAction["sub"]; }
|
|
if(sub == "start")
|
|
{
|
|
// Send DOWNLOAD startack command
|
|
string cmd = "{\"action\":\"download\",\"sub\":\"startack\",\"id\":" + (downloadFileArrayPtr + 1000) + "}";
|
|
byte[] bincmd = UTF8Encoding.UTF8.GetBytes(cmd);
|
|
wc.SendBinary(bincmd, 0, bincmd.Length);
|
|
}
|
|
else if(sub == "cancel")
|
|
{
|
|
// Unable to download this file
|
|
if(transferStatusForm != null) { try { transferStatusForm.addErrorMessage(String.Format(Translate.T(Properties.Resources.ErrorDownloadingFileX), downloadFileArray[downloadFileArrayPtr].ToString())); } catch { } }
|
|
|
|
// Send DOWNLOAD command
|
|
string cmd = "{\"action\":\"download\",\"sub\":\"stop\",\"id\":" + (downloadFileArrayPtr + 1000) + "}";
|
|
byte[] bincmd = UTF8Encoding.UTF8.GetBytes(cmd);
|
|
wc.SendBinary(bincmd, 0, bincmd.Length);
|
|
if(downloadFileStream != null) { downloadFileStream.Close(); downloadFileStream = null; } // Close the file
|
|
try { File.Delete(Path.Combine(downloadLocalPath.FullName, Path.GetFileName((String)downloadFileArray[downloadFileArrayPtr]).ToString())); } catch(Exception) { }
|
|
|
|
// Go to next file
|
|
if(downloadFileArray.Count > downloadFileArrayPtr + 1)
|
|
{
|
|
// Download the next file
|
|
downloadFileArrayPtr++;
|
|
downloadNextFile();
|
|
}
|
|
else
|
|
{
|
|
// Done with all files
|
|
downloadActive = false;
|
|
downloadStop = false;
|
|
downloadFileArrayPtr = -1;
|
|
downloadFileArray = null;
|
|
downloadLocalPath = null;
|
|
downloadRemotePath = null;
|
|
closeTransferDialog();
|
|
localRefresh();
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else if(jsonAction.ContainsKey("type") && (jsonAction["type"].GetType() == typeof(string)))
|
|
{
|
|
string action = jsonAction["type"].ToString();
|
|
switch(action)
|
|
{
|
|
case "metadata":
|
|
{
|
|
if((jsonAction.ContainsKey("users") == false) || (jsonAction["users"] == null)) return;
|
|
Dictionary<string, object> usersex = (Dictionary<string, object>)jsonAction["users"];
|
|
userSessions = new Dictionary<string, int>();
|
|
foreach(string user in usersex.Keys) { userSessions.Add(user, (int)usersex[user]); }
|
|
UpdateStatus();
|
|
break;
|
|
}
|
|
case "console":
|
|
{
|
|
string msg = null;
|
|
int msgid = -1;
|
|
if((jsonAction.ContainsKey("msg")) && (jsonAction["msg"] != null)) { msg = jsonAction["msg"].ToString(); }
|
|
if(jsonAction.ContainsKey("msgid")) { msgid = (int)jsonAction["msgid"]; }
|
|
if(msgid == 1) { msg = Translate.T(Properties.Resources.WaitingForUserToGrantAccess); }
|
|
if(msgid == 2) { msg = Translate.T(Properties.Resources.Denied); }
|
|
if(msgid == 3) { msg = Translate.T(Properties.Resources.FailedToStartRemoteTerminalSession); }
|
|
if(msgid == 4) { msg = Translate.T(Properties.Resources.Timeout); }
|
|
if(msgid == 5) { msg = Translate.T(Properties.Resources.ReceivedInvalidNetworkData); }
|
|
displayMessage(msg);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Wc_onBinaryData(webSocketClient sender, byte[] data, int offset, int length, int orglen)
|
|
{
|
|
bytesIn += length;
|
|
bytesInCompressed += orglen;
|
|
|
|
if(state != 3) return;
|
|
|
|
if(data[offset] == 123)
|
|
{
|
|
// Parse the received JSON
|
|
Dictionary<string, object> jsonAction = new Dictionary<string, object>();
|
|
jsonAction = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(UTF8Encoding.UTF8.GetString(data, offset, length));
|
|
if(jsonAction == null) return;
|
|
int reqid = 0;
|
|
if(jsonAction.ContainsKey("reqid")) { reqid = (int)jsonAction["reqid"]; }
|
|
string action = null;
|
|
if(jsonAction.ContainsKey("action")) { action = (string)jsonAction["action"]; }
|
|
|
|
if(action == "uploadstart")
|
|
{
|
|
if(uploadStop) { uploadCancel(); return; }
|
|
uploadNextPart(false);
|
|
for(var i = 0; i < 8; i++) { uploadNextPart(true); }
|
|
}
|
|
else if(action == "uploadack")
|
|
{
|
|
if(uploadStop) { uploadCancel(); return; }
|
|
uploadNextPart(false);
|
|
}
|
|
else if((action == "uploaddone") || (action == "uploaderror"))
|
|
{
|
|
// Clean up current upload
|
|
uploadFilePtr = 0;
|
|
uploadFileStartPtr = 0;
|
|
uploadFileSize = 0;
|
|
if(uploadFileStream != null) { uploadFileStream.Close(); uploadFileStream = null; }
|
|
|
|
// If this is an error, show it in the dialog
|
|
if((action == "uploaderror") && (transferStatusForm != null)) { transferStatusForm.addErrorMessage(String.Format(Translate.T(Properties.Resources.ErrorUploadingFileX), uploadFileName)); }
|
|
|
|
// Check if another file needs to be uploaded
|
|
if(uploadFileArray.Count > (uploadFileArrayPtr + 1))
|
|
{
|
|
// Upload the next file
|
|
uploadFileArrayPtr++;
|
|
uploadNextFile();
|
|
}
|
|
else
|
|
{
|
|
// Done with all files
|
|
uploadActive = false;
|
|
uploadStop = false;
|
|
uploadFileArrayPtr = -1;
|
|
uploadFileArray = null;
|
|
uploadFileDuplicateArray = null;
|
|
uploadLocalPath = null;
|
|
uploadRemotePath = null;
|
|
uploadFilePtr = 0;
|
|
uploadFileStartPtr = 0;
|
|
uploadFileSize = 0;
|
|
uploadFileName = null;
|
|
closeTransferDialog();
|
|
remoteRefresh();
|
|
}
|
|
}
|
|
else if(action == "uploadhash")
|
|
{
|
|
if(uploadStop) { uploadCancel(); return; }
|
|
string name = null;
|
|
if(jsonAction.ContainsKey("name")) { name = (string)jsonAction["name"]; }
|
|
string path = null;
|
|
if(jsonAction.ContainsKey("path")) { path = (string)jsonAction["path"]; }
|
|
string remoteHashHex = null;
|
|
if(jsonAction.ContainsKey("hash")) { remoteHashHex = (string)jsonAction["hash"]; }
|
|
long remoteFileSize = 0;
|
|
if(jsonAction.ContainsKey("tag"))
|
|
{
|
|
if(jsonAction["tag"].GetType() == typeof(int)) { remoteFileSize = (int)jsonAction["tag"]; }
|
|
if(jsonAction["tag"].GetType() == typeof(long)) { remoteFileSize = (long)jsonAction["tag"]; }
|
|
}
|
|
if((uploadRemotePath != path) || (uploadFileName != name)) { uploadCancel(); return; }
|
|
|
|
// Hash the local file
|
|
string localHashHex = null;
|
|
try
|
|
{
|
|
string filePath = Path.Combine(localFolder.FullName, uploadFileName);
|
|
using(SHA384 SHA384 = SHA384Managed.Create())
|
|
{
|
|
uploadFileStream.Seek(0, SeekOrigin.Begin);
|
|
byte[] buf = new byte[65536];
|
|
long ptr = 0;
|
|
int len = 1;
|
|
while(len != 0)
|
|
{
|
|
int l = buf.Length;
|
|
if(l > (remoteFileSize - ptr)) { l = (int)(remoteFileSize - ptr); }
|
|
if(l == 0) { len = 0; } else { len = uploadFileStream.Read(buf, 0, l); }
|
|
if(len > 0) { SHA384.TransformBlock(buf, 0, len, buf, 0); }
|
|
ptr += len;
|
|
}
|
|
SHA384.TransformFinalBlock(buf, 0, 0);
|
|
localHashHex = BitConverter.ToString(SHA384.Hash).Replace("-", string.Empty);
|
|
uploadFileStream.Seek(0, SeekOrigin.Begin);
|
|
}
|
|
}
|
|
catch(Exception) { }
|
|
|
|
if((localHashHex != null) && (localHashHex.Equals(remoteHashHex)))
|
|
{
|
|
if(remoteFileSize == uploadFileStream.Length)
|
|
{
|
|
// Files are the same length, skip the file.
|
|
// Check if another file needs to be uploaded
|
|
if(uploadFileArray.Count > (uploadFileArrayPtr + 1))
|
|
{
|
|
// Upload the next file
|
|
uploadFileArrayPtr++;
|
|
uploadNextFile();
|
|
}
|
|
else
|
|
{
|
|
// Done with all files
|
|
uploadActive = false;
|
|
uploadStop = false;
|
|
uploadFileArrayPtr = -1;
|
|
uploadFileArray = null;
|
|
uploadFileDuplicateArray = null;
|
|
uploadLocalPath = null;
|
|
uploadRemotePath = null;
|
|
uploadFilePtr = 0;
|
|
uploadFileStartPtr = 0;
|
|
uploadFileSize = 0;
|
|
uploadFileName = null;
|
|
closeTransferDialog();
|
|
remoteRefresh();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Files are not the same length, append the rest
|
|
uploadFileStream.Seek(remoteFileSize, SeekOrigin.Begin);
|
|
uploadFilePtr = uploadFileStartPtr = remoteFileSize;
|
|
|
|
// Send UPLOAD command with append turned on
|
|
string cmd = "{\"action\":\"upload\",\"reqid\":" + (uploadFileArrayPtr + 1000) + ",\"path\":\"" + uploadRemotePath + "\",\"name\":\"" + name + "\",\"size\":" + uploadFileSize + ",\"append\":true}";
|
|
byte[] bincmd = UTF8Encoding.UTF8.GetBytes(cmd);
|
|
wc.SendBinary(bincmd, 0, bincmd.Length);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Send UPLOAD command
|
|
string cmd = "{\"action\":\"upload\",\"reqid\":" + (uploadFileArrayPtr + 1000) + ",\"path\":\"" + uploadRemotePath + "\",\"name\":\"" + name + "\",\"size\":" + uploadFileSize + "}";
|
|
byte[] bincmd = UTF8Encoding.UTF8.GetBytes(cmd);
|
|
wc.SendBinary(bincmd, 0, bincmd.Length);
|
|
}
|
|
}
|
|
else if((action == "dialogmessage"))
|
|
{
|
|
// Dialog box message
|
|
string msg = null;
|
|
string file = null;
|
|
int progress = 0;
|
|
if(jsonAction.ContainsKey("msg") && (jsonAction["msg"] == null)) { msg = ""; }
|
|
else if(jsonAction.ContainsKey("msg") && (jsonAction["msg"].GetType() == typeof(string))) { msg = (string)jsonAction["msg"]; }
|
|
if(jsonAction.ContainsKey("file") && (jsonAction["file"].GetType() == typeof(string))) { file = (string)jsonAction["file"]; }
|
|
if(jsonAction.ContainsKey("progress") && (jsonAction["progress"].GetType() == typeof(System.Int32))) { progress = (int)jsonAction["progress"]; }
|
|
updateMsgForm(msg, file, progress);
|
|
}
|
|
else if(reqid == 1)
|
|
{
|
|
// Result of a LS command
|
|
if(jsonAction.ContainsKey("path")) { remoteFolder = (string)jsonAction["path"]; }
|
|
if(jsonAction.ContainsKey("dir")) { remoteFolderList = (ArrayList)jsonAction["dir"]; }
|
|
updateRemoteFileView();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(downloadActive)
|
|
{
|
|
if(downloadStop) { downloadCancel(); return; }
|
|
downloadGotBinaryData(data, offset, length);
|
|
}
|
|
}
|
|
}
|
|
|
|
public delegate void updateMsgFormHandler(string msg, string file, int progress);
|
|
|
|
private void updateMsgForm(string msg, string file, int progress)
|
|
{
|
|
if(this.InvokeRequired) { this.Invoke(new updateMsgFormHandler(updateMsgForm), msg, file, progress); return; }
|
|
if((msg == null) || (msg == ""))
|
|
{
|
|
// Close the dialog box
|
|
if(msgForm != null) { msgForm.Close(); msgForm = null; remoteRefresh(); }
|
|
}
|
|
else
|
|
{
|
|
// Open or update the dialog box
|
|
if(msgForm == null)
|
|
{
|
|
msgForm = new FileDialogMsgForm(this);
|
|
msgForm.Show(this);
|
|
msgForm.UpdateStatus(msg, file, progress);
|
|
if(msgForm.StartPosition == FormStartPosition.CenterParent)
|
|
{
|
|
var x = Location.X + (Width - msgForm.Width) / 2;
|
|
var y = Location.Y + (Height - msgForm.Height) / 2;
|
|
msgForm.Location = new Point(Math.Max(x, 0), Math.Max(y, 0));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
msgForm.UpdateStatus(msg, file, progress);
|
|
}
|
|
}
|
|
}
|
|
|
|
private delegate void remoteRefreshHandler();
|
|
|
|
private void remoteRefresh()
|
|
{
|
|
if(this.InvokeRequired) { this.Invoke(new remoteRefreshHandler(remoteRefresh)); return; }
|
|
updateTimer.Enabled = true;
|
|
}
|
|
|
|
private delegate void localRefreshHandler();
|
|
|
|
private void localRefresh()
|
|
{
|
|
if(this.InvokeRequired) { this.Invoke(new localRefreshHandler(localRefresh)); return; }
|
|
updateLocalFileView();
|
|
}
|
|
|
|
private void MenuItemDisconnect_Click(object sender, EventArgs e)
|
|
{
|
|
if(wc != null)
|
|
{
|
|
// Disconnect
|
|
state = 0;
|
|
wc.Dispose();
|
|
wc = null;
|
|
UpdateStatus();
|
|
}
|
|
else
|
|
{
|
|
// Connect
|
|
MenuItemConnect_Click(null, null);
|
|
}
|
|
displayMessage(null);
|
|
}
|
|
|
|
|
|
public delegate void UpdateStatusHandler();
|
|
|
|
private void UpdateStatus()
|
|
{
|
|
if(this.IsDisposed) return;
|
|
if(this.InvokeRequired) { this.Invoke(new UpdateStatusHandler(UpdateStatus)); return; }
|
|
|
|
//if (kvmControl == null) return;
|
|
switch(state)
|
|
{
|
|
case 0: // Disconnected
|
|
mainToolStripStatusLabel.Text = Translate.T(Properties.Resources.Disconnected);
|
|
connectButton.Text = Translate.T(Properties.Resources.Connect);
|
|
remoteRefreshButton.Enabled = false;
|
|
remoteUpButton.Enabled = false;
|
|
remoteRootButton.Enabled = false;
|
|
remoteNewFolderButton.Enabled = false;
|
|
remoteDeleteButton.Enabled = false;
|
|
remoteZipButton.Enabled = false;
|
|
remoteFolder = null;
|
|
break;
|
|
case 1: // Connecting
|
|
mainToolStripStatusLabel.Text = Translate.T(Properties.Resources.Connecting);
|
|
connectButton.Text = Translate.T(Properties.Resources.Disconnect);
|
|
break;
|
|
case 2: // Setup
|
|
mainToolStripStatusLabel.Text = Translate.T(Properties.Resources.Setup);
|
|
connectButton.Text = Translate.T(Properties.Resources.Disconnect);
|
|
break;
|
|
case 3: // Connected
|
|
string label = Translate.T(Properties.Resources.Connected);
|
|
if(sessionIsRecorded) { label += Translate.T(Properties.Resources.RecordedSession); }
|
|
if((userSessions != null) && (userSessions.Count > 1)) { label += string.Format(Translate.T(Properties.Resources.AddXUsers), userSessions.Count); }
|
|
label += ".";
|
|
mainToolStripStatusLabel.Text = label;
|
|
connectButton.Text = Translate.T(Properties.Resources.Disconnect);
|
|
break;
|
|
}
|
|
|
|
rightListView.Enabled = (state == 3);
|
|
if(state != 3) { rightListView.Items.Clear(); }
|
|
}
|
|
|
|
private void Main_FormClosing(object sender, FormClosingEventArgs e)
|
|
{
|
|
if(wc != null)
|
|
{
|
|
// Disconnect
|
|
state = 0;
|
|
wc.Dispose();
|
|
wc = null;
|
|
UpdateStatus();
|
|
}
|
|
node.fileViewer = null;
|
|
|
|
// Clean up any downloads
|
|
if(downloadFileStream != null) { downloadFileStream.Close(); downloadFileStream = null; }
|
|
downloadFilePtr = 0;
|
|
downloadFileSize = 0;
|
|
downloadActive = false;
|
|
downloadStop = false;
|
|
downloadFileArrayPtr = -1;
|
|
downloadFileArray = null;
|
|
downloadLocalPath = null;
|
|
downloadRemotePath = null;
|
|
|
|
// Clean up any uploads
|
|
uploadActive = false;
|
|
uploadStop = false;
|
|
uploadFileArrayPtr = -1;
|
|
uploadFileArray = null;
|
|
uploadFileDuplicateArray = null;
|
|
uploadLocalPath = null;
|
|
uploadRemotePath = null;
|
|
uploadFilePtr = 0;
|
|
uploadFileStartPtr = 0;
|
|
uploadFileSize = 0;
|
|
if(uploadFileStream != null) { uploadFileStream.Close(); uploadFileStream = null; }
|
|
|
|
// Save window location
|
|
Settings.SetRegValue("filelocation", Location.X + "," + Location.Y + "," + Size.Width + "," + Size.Height);
|
|
}
|
|
|
|
public delegate void displayMessageHandler(string msg);
|
|
public void displayMessage(string msg)
|
|
{
|
|
if(this.InvokeRequired) { this.Invoke(new displayMessageHandler(displayMessage), msg); return; }
|
|
if(msg == null)
|
|
{
|
|
consoleMessage.Visible = false;
|
|
consoleTimer.Enabled = false;
|
|
}
|
|
else
|
|
{
|
|
consoleMessage.Text = msg;
|
|
consoleMessage.Visible = true;
|
|
consoleTimer.Enabled = true;
|
|
}
|
|
}
|
|
private void consoleTimer_Tick(object sender, EventArgs e)
|
|
{
|
|
consoleMessage.Visible = false;
|
|
consoleTimer.Enabled = false;
|
|
}
|
|
|
|
private void connectButton_Click(object sender, EventArgs e)
|
|
{
|
|
if(wc != null)
|
|
{
|
|
// Disconnect
|
|
state = 0;
|
|
wc.Dispose();
|
|
wc = null;
|
|
UpdateStatus();
|
|
}
|
|
else
|
|
{
|
|
// Connect
|
|
MenuItemConnect_Click(null, null);
|
|
}
|
|
displayMessage(null);
|
|
}
|
|
|
|
private void leftListView_MouseDoubleClick(object sender, MouseEventArgs e)
|
|
{
|
|
ListViewItem item = leftListView.GetItemAt(e.X, e.Y);
|
|
if(item != null)
|
|
{
|
|
if(item.Tag.GetType() == typeof(DriveInfo))
|
|
{
|
|
DirectoryInfo old = localFolder;
|
|
localFolder = ((DriveInfo)item.Tag).RootDirectory;
|
|
if(updateLocalFileView() == false) { localFolder = old; updateLocalFileView(); }
|
|
Settings.SetRegValue("LocalPath", (localFolder == null) ? "" : localFolder.FullName);
|
|
}
|
|
else if(item.Tag.GetType() == typeof(DirectoryInfo))
|
|
{
|
|
DirectoryInfo old = localFolder;
|
|
localFolder = (DirectoryInfo)item.Tag;
|
|
if(updateLocalFileView() == false) { localFolder = old; updateLocalFileView(); }
|
|
Settings.SetRegValue("LocalPath", (localFolder == null) ? "" : localFolder.FullName);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void localUpButton_Click(object sender, EventArgs e)
|
|
{
|
|
localFolder = localFolder.Parent;
|
|
Settings.SetRegValue("LocalPath", (localFolder == null) ? "" : localFolder.FullName);
|
|
updateLocalFileView();
|
|
}
|
|
|
|
private void rightListView_MouseDoubleClick(object sender, MouseEventArgs e)
|
|
{
|
|
ListViewItem item = rightListView.GetItemAt(e.X, e.Y);
|
|
if(item != null)
|
|
{
|
|
string r = remoteFolder;
|
|
if((item.ImageIndex == 0) || (item.ImageIndex == 1))
|
|
{
|
|
if((r == null) || (r == ""))
|
|
{
|
|
r = item.Text;
|
|
}
|
|
else
|
|
{
|
|
if(remoteFolder.EndsWith("/")) { r = remoteFolder + item.Text; } else { r = remoteFolder + "/" + item.Text; }
|
|
}
|
|
requestRemoteFolder(r);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void remoteUpButton_Click(object sender, EventArgs e)
|
|
{
|
|
string r = remoteFolder;
|
|
if(r.EndsWith("/")) { r = r.Substring(0, r.Length - 1); }
|
|
int i = r.LastIndexOf("/");
|
|
if(i >= 0) { r = r.Substring(0, i + 1); } else { r = ""; }
|
|
requestRemoteFolder(r);
|
|
}
|
|
|
|
private void leftRefreshButton_Click(object sender, EventArgs e)
|
|
{
|
|
updateLocalFileView();
|
|
}
|
|
|
|
private void rightRefreshButton_Click(object sender, EventArgs e)
|
|
{
|
|
requestRemoteFolder(remoteFolder);
|
|
}
|
|
|
|
private void remoteNewFolderButton_Click(object sender, EventArgs e)
|
|
{
|
|
if(remoteFolder == null) return;
|
|
FilenamePromptForm f = new FilenamePromptForm(Translate.T(Properties.Resources.CreateFolder), "");
|
|
if(f.ShowDialog(this) == DialogResult.OK)
|
|
{
|
|
string r;
|
|
if(remoteFolder.EndsWith("/")) { r = remoteFolder + f.filename; } else { r = remoteFolder + "/" + f.filename; }
|
|
requestCreateFolder(r);
|
|
remoteRefresh();
|
|
}
|
|
}
|
|
|
|
private void remoteZipButton_Click(object sender, EventArgs e)
|
|
{
|
|
if(remoteFolder == null) return;
|
|
FilenamePromptForm f = new FilenamePromptForm(Translate.T(Properties.Resources.ZipSelectedFiles), "");
|
|
if(f.ShowDialog(this) == DialogResult.OK)
|
|
{
|
|
string r = f.filename;
|
|
if(!r.ToLower().EndsWith(".zip")) { r += ".zip"; }
|
|
ArrayList filesArray = new ArrayList();
|
|
foreach(ListViewItem l in rightListView.SelectedItems) { filesArray.Add(l.Text); }
|
|
string[] files = (string[])filesArray.ToArray(typeof(string));
|
|
requestCreateZipFileFolder(remoteFolder, r, files);
|
|
}
|
|
}
|
|
|
|
private void localRootButton_Click(object sender, EventArgs e)
|
|
{
|
|
localFolder = null;
|
|
Settings.SetRegValue("LocalPath", "");
|
|
updateLocalFileView();
|
|
}
|
|
|
|
private void remoteRootButton_Click(object sender, EventArgs e)
|
|
{
|
|
requestRemoteFolder("");
|
|
}
|
|
|
|
private void rightListView_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
if(node.agentid < 5)
|
|
{
|
|
remoteDeleteButton.Enabled = remoteZipButton.Enabled = (!((remoteFolder == null) || (remoteFolder == ""))) && (rightListView.SelectedItems.Count > 0);
|
|
}
|
|
else
|
|
{
|
|
remoteDeleteButton.Enabled = remoteZipButton.Enabled = (rightListView.SelectedItems.Count > 0);
|
|
}
|
|
updateTransferButtons();
|
|
}
|
|
|
|
private void rightListView_Resize(object sender, EventArgs e)
|
|
{
|
|
if(rightListView.Columns[0].Width != (rightListView.Width - rightListView.Columns[1].Width - 22))
|
|
{
|
|
rightListView.Columns[0].Width = rightListView.Width - rightListView.Columns[1].Width - 22;
|
|
}
|
|
}
|
|
|
|
bool bRightCWChangedBusy = false;
|
|
private void rightListView_ColumnWidthChanged(object sender, ColumnWidthChangedEventArgs e)
|
|
{
|
|
if(bRightCWChangedBusy) return;
|
|
bRightCWChangedBusy=true;
|
|
try
|
|
{
|
|
if(rightListView.Columns[0].Width != (rightListView.Width - rightListView.Columns[1].Width - 22))
|
|
{
|
|
rightListView.Columns[0].Width = rightListView.Width - rightListView.Columns[1].Width - 22;
|
|
}
|
|
}
|
|
catch { }
|
|
bRightCWChangedBusy = false;
|
|
}
|
|
|
|
private void leftListView_Resize(object sender, EventArgs e)
|
|
{
|
|
if(leftListView.Columns[0].Width != (leftListView.Width - leftListView.Columns[1].Width - 22))
|
|
{
|
|
leftListView.Columns[0].Width = leftListView.Width - leftListView.Columns[1].Width - 22;
|
|
}
|
|
}
|
|
|
|
bool bLeftCWChangedBusy = false;
|
|
private void leftListView_ColumnWidthChanged(object sender, ColumnWidthChangedEventArgs e)
|
|
{
|
|
if(bLeftCWChangedBusy) return;
|
|
bLeftCWChangedBusy=true;
|
|
try
|
|
{
|
|
if(leftListView.Columns[0].Width != (leftListView.Width - leftListView.Columns[1].Width - 22))
|
|
{
|
|
leftListView.Columns[0].Width = leftListView.Width - leftListView.Columns[1].Width - 22;
|
|
}
|
|
}
|
|
catch { }
|
|
bLeftCWChangedBusy = false;
|
|
}
|
|
|
|
private void updateTimer_Tick(object sender, EventArgs e)
|
|
{
|
|
updateTimer.Enabled = false;
|
|
if(remoteFolder != null) { requestRemoteFolder(remoteFolder); }
|
|
}
|
|
|
|
private void remoteDeleteButton_Click(object sender, EventArgs e)
|
|
{
|
|
bool rec = false;
|
|
ArrayList filesArray = new ArrayList();
|
|
foreach(ListViewItem l in rightListView.SelectedItems) { filesArray.Add(l.Text); if(l.ImageIndex == 1) { rec = true; } }
|
|
string[] files = (string[])filesArray.ToArray(typeof(string));
|
|
string msg = string.Format(Translate.T(Properties.Resources.RemoveXItems), files.Length);
|
|
if(files.Length == 1) { msg = Translate.T(Properties.Resources.Remove1Item); }
|
|
FileDeletePromptForm f = new FileDeletePromptForm(msg, rec);
|
|
if(f.ShowDialog(this) == DialogResult.OK)
|
|
{
|
|
requestDelete(remoteFolder, files, f.recursive);
|
|
remoteRefresh();
|
|
}
|
|
}
|
|
|
|
private void remoteContextMenuStrip_Opening(object sender, System.ComponentModel.CancelEventArgs e)
|
|
{
|
|
if((rightListView.SelectedItems.Count == 0) || ((node.agentid < 5) && ((remoteFolder == null) || (remoteFolder == ""))))
|
|
{
|
|
deleteToolStripMenuItem.Visible = toolStripMenuItem1.Visible = renameToolStripMenuItem.Visible = compressToolStripMenuItem.Visible = false;
|
|
}
|
|
else if(rightListView.SelectedItems.Count == 1)
|
|
{
|
|
deleteToolStripMenuItem.Visible = toolStripMenuItem1.Visible = renameToolStripMenuItem.Visible = compressToolStripMenuItem.Visible = true;
|
|
}
|
|
else if(rightListView.SelectedItems.Count > 1)
|
|
{
|
|
renameToolStripMenuItem.Visible = false;
|
|
deleteToolStripMenuItem.Visible = toolStripMenuItem1.Visible = compressToolStripMenuItem.Visible = true;
|
|
}
|
|
}
|
|
|
|
private void renameToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
string oldname = rightListView.SelectedItems[0].Text;
|
|
if((rightListView.SelectedItems.Count != 1) || (remoteFolder == null)) return;
|
|
FilenamePromptForm f = new FilenamePromptForm(Translate.T(Properties.Resources.Rename), oldname);
|
|
if(f.ShowDialog(this) == DialogResult.OK)
|
|
{
|
|
if(oldname == f.filename) return;
|
|
//string r;
|
|
//if (remoteFolder.EndsWith("/")) { r = remoteFolder + f.filename; } else { r = remoteFolder + "/" + f.filename; }
|
|
requestRename(remoteFolder, oldname, f.filename);
|
|
remoteRefresh();
|
|
}
|
|
}
|
|
|
|
private delegate void updateTransferButtonsHandler();
|
|
|
|
private void updateTransferButtons()
|
|
{
|
|
if(this.InvokeRequired) { this.Invoke(new updateTransferButtonsHandler(updateTransferButtons)); return; }
|
|
if((wc == null) || (wc.State != webSocketClient.ConnectionStates.Connected))
|
|
{
|
|
uploadButton.Enabled = false;
|
|
downloadButton.Enabled = false;
|
|
}
|
|
else
|
|
{
|
|
// Set upload button
|
|
bool uploadAllowed = true;
|
|
if(localFolder == null) { uploadAllowed = false; }
|
|
if(leftListView.SelectedItems.Count == 0) { uploadAllowed = false; }
|
|
foreach(ListViewItem l in leftListView.SelectedItems) { if(l.ImageIndex != 2) { uploadAllowed = false; } }
|
|
if((node.agentid < 5) && ((remoteFolder == null) || (remoteFolder == ""))) { uploadAllowed = false; }
|
|
uploadButton.Enabled = uploadAllowed;
|
|
|
|
// Set download button
|
|
bool downloadAllowed = true;
|
|
if(localFolder == null) { downloadAllowed = false; }
|
|
if(rightListView.SelectedItems.Count == 0) { downloadAllowed = false; }
|
|
foreach(ListViewItem l in rightListView.SelectedItems) { if(l.ImageIndex != 1 && l.ImageIndex != 2) { downloadAllowed = false; } } // Flynn
|
|
if((node.agentid < 5) && ((remoteFolder == null) || (remoteFolder == ""))) { downloadAllowed = false; }
|
|
downloadButton.Enabled = downloadAllowed;
|
|
}
|
|
}
|
|
|
|
private void leftListView_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
updateTransferButtons();
|
|
localDeleteButton.Enabled = ((localFolder != null) && (leftListView.SelectedItems.Count > 0));
|
|
}
|
|
|
|
private void uploadButton_Click(object sender, EventArgs e)
|
|
{
|
|
// If a transfer is currently active, ignore this.
|
|
if(uploadActive || downloadActive || (transferStatusForm != null)) return;
|
|
|
|
// If any files are going to be overwritten
|
|
int overWriteCount = 0;
|
|
foreach(ListViewItem l in leftListView.SelectedItems)
|
|
{
|
|
if(l.ImageIndex == 2)
|
|
{
|
|
string filename = l.Text;
|
|
|
|
foreach(ListViewItem l2 in rightListView.Items)
|
|
{
|
|
if(l2.ImageIndex == 2)
|
|
{
|
|
string filename2 = l2.Text;
|
|
if(node.agentid < 5) { filename = filename.ToLower(); filename2 = filename2.ToLower(); }
|
|
if(filename.Equals(filename2)) { overWriteCount++; }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
skipExistingFiles = true;
|
|
if(overWriteCount > 0)
|
|
{
|
|
FileConfirmOverwriteForm f = new FileConfirmOverwriteForm();
|
|
if(overWriteCount == 1) { f.mainTextLabel = String.Format(Translate.T(Properties.Resources.OverwriteOneFile), overWriteCount); } else { f.mainTextLabel = String.Format(Translate.T(Properties.Resources.OverwriteXfiles), overWriteCount); }
|
|
if(f.ShowDialog(this) != DialogResult.OK) return;
|
|
skipExistingFiles = f.skipExistingFiles;
|
|
}
|
|
|
|
uploadFileArrayPtr = 0;
|
|
uploadFileArray = new ArrayList();
|
|
uploadFileDuplicateArray = new Hashtable();
|
|
|
|
foreach(ListViewItem l in leftListView.SelectedItems)
|
|
{
|
|
if(l.ImageIndex == 2)
|
|
{
|
|
bool overwrite = false;
|
|
bool overwriteNotLarger = false;
|
|
long remoteLength = 0;
|
|
string filename = l.Text;
|
|
foreach(ListViewItem l2 in rightListView.Items)
|
|
{
|
|
if(l2.ImageIndex == 2)
|
|
{
|
|
string filename2 = l2.Text;
|
|
if(node.agentid < 5) { filename = filename.ToLower(); filename2 = filename2.ToLower(); }
|
|
if(filename.Equals(filename2))
|
|
{
|
|
overwrite = true;
|
|
if(skipExistingFiles == false)
|
|
{
|
|
long localLength = new FileInfo(Path.Combine(localFolder.FullName, l.Text)).Length;
|
|
remoteLength = long.Parse(l2.SubItems[1].Text);
|
|
if(localLength >= remoteLength) { overwriteNotLarger = true; }
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if((skipExistingFiles == false) || (overwrite == false))
|
|
{
|
|
uploadFileArray.Add(l.Text);
|
|
if(overwriteNotLarger) { uploadFileDuplicateArray.Add(Path.Combine(localFolder.FullName, l.Text), remoteLength); }
|
|
}
|
|
}
|
|
}
|
|
|
|
if(uploadFileArray.Count == 0) return;
|
|
uploadLocalPath = localFolder;
|
|
uploadRemotePath = remoteFolder;
|
|
uploadActive = true;
|
|
uploadStop = false;
|
|
|
|
// Show transfer status dialog
|
|
transferStatusForm = new FileTransferStatusForm(this);
|
|
transferStatusForm.Show(this);
|
|
|
|
uploadNextFile();
|
|
}
|
|
|
|
private void uploadNextFile()
|
|
{
|
|
if((uploadFileArray == null) || (uploadFileArray.Count == 0)) return;
|
|
|
|
string localFilePath, localFileName;
|
|
if(uploadLocalPath != null)
|
|
{
|
|
localFilePath = Path.Combine(uploadLocalPath.FullName, (string)uploadFileArray[uploadFileArrayPtr]);
|
|
localFileName = (string)uploadFileArray[uploadFileArrayPtr];
|
|
}
|
|
else
|
|
{
|
|
localFilePath = (string)uploadFileArray[uploadFileArrayPtr];
|
|
localFileName = Path.GetFileName(localFilePath);
|
|
}
|
|
try { uploadFileStream = File.OpenRead(localFilePath); }
|
|
catch(Exception)
|
|
{
|
|
// Display the error
|
|
if(transferStatusForm != null) { transferStatusForm.addErrorMessage(String.Format(Translate.T(Properties.Resources.UnableToOpenFileX), localFileName)); }
|
|
|
|
// Skip to the next file
|
|
// Check if another file needs to be uploaded
|
|
if(uploadFileArray.Count > (uploadFileArrayPtr + 1))
|
|
{
|
|
// Upload the next file
|
|
uploadFileArrayPtr++;
|
|
uploadNextFile();
|
|
}
|
|
else
|
|
{
|
|
// Done with all files
|
|
uploadActive = false;
|
|
uploadStop = false;
|
|
uploadFileArrayPtr = -1;
|
|
uploadFileArray = null;
|
|
uploadFileDuplicateArray = null;
|
|
uploadLocalPath = null;
|
|
uploadRemotePath = null;
|
|
uploadFilePtr = 0;
|
|
uploadFileStartPtr = 0;
|
|
uploadFileSize = 0;
|
|
uploadFileName = null;
|
|
closeTransferDialog();
|
|
remoteRefresh();
|
|
}
|
|
return;
|
|
}
|
|
uploadFileSize = new FileInfo(localFilePath).Length;
|
|
uploadFilePtr = 0;
|
|
uploadFileStartPtr = 0;
|
|
uploadFileStartTime = DateTime.Now;
|
|
uploadFileName = localFileName;
|
|
|
|
// Check if the files already exist on the remote side
|
|
if(uploadFileDuplicateArray[localFilePath] != null)
|
|
{
|
|
// Send UPLOADHASH command
|
|
string cmd = "{\"action\":\"uploadhash\",\"reqid\":" + (uploadFileArrayPtr + 1000) + ",\"path\":\"" + uploadRemotePath + "\",\"name\":\"" + localFileName + "\",\"tag\":" + uploadFileDuplicateArray[localFilePath] + "}";
|
|
byte[] bincmd = UTF8Encoding.UTF8.GetBytes(cmd);
|
|
wc.SendBinary(bincmd, 0, bincmd.Length);
|
|
}
|
|
else
|
|
{
|
|
// Send UPLOAD command
|
|
string cmd = "{\"action\":\"upload\",\"reqid\":" + (uploadFileArrayPtr + 1000) + ",\"path\":\"" + uploadRemotePath + "\",\"name\":\"" + localFileName + "\",\"size\":" + uploadFileSize + "}";
|
|
byte[] bincmd = UTF8Encoding.UTF8.GetBytes(cmd);
|
|
wc.SendBinary(bincmd, 0, bincmd.Length);
|
|
}
|
|
}
|
|
|
|
public void uploadCancel()
|
|
{
|
|
if(uploadActive == false) return;
|
|
|
|
// Send UPLOADCANCEL command
|
|
string cmd = "{\"action\":\"uploadcancel\",\"reqid\":" + (uploadFileArrayPtr + 1000) + "}";
|
|
byte[] bincmd = UTF8Encoding.UTF8.GetBytes(cmd);
|
|
wc.SendBinary(bincmd, 0, bincmd.Length);
|
|
|
|
// Clear state
|
|
uploadActive = false;
|
|
uploadStop = false;
|
|
uploadFileArrayPtr = -1;
|
|
uploadFileArray = null;
|
|
uploadFileDuplicateArray = null;
|
|
uploadLocalPath = null;
|
|
uploadRemotePath = null;
|
|
uploadFilePtr = 0;
|
|
uploadFileStartPtr = 0;
|
|
uploadFileSize = 0;
|
|
if(uploadFileStream != null) { uploadFileStream.Close(); uploadFileStream = null; }
|
|
closeTransferDialog();
|
|
remoteRefresh();
|
|
}
|
|
|
|
private void uploadNextPart(bool dataPriming)
|
|
{
|
|
if(uploadActive == false) return;
|
|
byte[] buffer = new byte[16385];
|
|
int len = uploadFileStream.Read(buffer, 1, buffer.Length - 1);
|
|
if(dataPriming && (len == 0)) return;
|
|
uploadFilePtr += len;
|
|
|
|
if(len == 0)
|
|
{
|
|
// Send UPLOADDONE command
|
|
string cmd = "{\"action\":\"uploaddone\",\"reqid\":" + (uploadFileArrayPtr + 1000) + "}";
|
|
byte[] bincmd = UTF8Encoding.UTF8.GetBytes(cmd);
|
|
wc.SendBinary(bincmd, 0, bincmd.Length);
|
|
}
|
|
else
|
|
{
|
|
// Send part of the file
|
|
// If starts with 0 or {, add a zero char at the start of the send, this will indicate that it's not a JSON command.
|
|
if((buffer[1] == 123) || (buffer[1] == 0)) { wc.SendBinary(buffer, 0, len + 1); } else { wc.SendBinary(buffer, 1, len); }
|
|
}
|
|
}
|
|
|
|
private delegate void closeTransferDialogHandler();
|
|
|
|
private void closeTransferDialog()
|
|
{
|
|
if(transferStatusForm == null) return;
|
|
if(this.InvokeRequired) { this.Invoke(new closeTransferDialogHandler(closeTransferDialog)); return; }
|
|
if(transferStatusForm.showingError == false)
|
|
{
|
|
// Everything was succesful, close the form
|
|
transferStatusForm.Close();
|
|
transferStatusForm = null;
|
|
}
|
|
else
|
|
{
|
|
// Error are displayed, keep the form open
|
|
transferStatusForm.transferCompleted();
|
|
}
|
|
|
|
if (downloadActive)
|
|
remoteFolder = strDownloadRel; // Zurücksetzen
|
|
remoteRefresh();
|
|
}
|
|
|
|
private void downloadButton_Click(object sender, EventArgs e)
|
|
{
|
|
downloadButton_ClickFlynn(sender, e);
|
|
return;
|
|
// If a transfer is currently active, ignore this.
|
|
if(uploadActive || downloadActive || (transferStatusForm != null)) return;
|
|
|
|
// If any files are going to be overwritten
|
|
int overWriteCount = 0;
|
|
foreach(ListViewItem l in rightListView.SelectedItems)
|
|
{
|
|
if(l.ImageIndex == 2)
|
|
{
|
|
string filename = l.Text;
|
|
|
|
foreach(ListViewItem l2 in leftListView.Items)
|
|
{
|
|
if(l2.ImageIndex == 2)
|
|
{
|
|
string filename2 = l2.Text;
|
|
if(node.agentid < 5) { filename = filename.ToLower(); filename2 = filename2.ToLower(); }
|
|
if(filename.Equals(filename2)) { overWriteCount++; }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
skipExistingFiles = true;
|
|
if(overWriteCount > 0)
|
|
{
|
|
FileConfirmOverwriteForm f = new FileConfirmOverwriteForm();
|
|
if(overWriteCount == 1) { f.mainTextLabel = String.Format(Translate.T(Properties.Resources.OverwriteOneFile), overWriteCount); } else { f.mainTextLabel = String.Format(Translate.T(Properties.Resources.OverwriteXfiles), overWriteCount); }
|
|
if(f.ShowDialog(this) != DialogResult.OK) return;
|
|
skipExistingFiles = f.skipExistingFiles;
|
|
}
|
|
|
|
// Perform the download
|
|
downloadFileArrayPtr = 0;
|
|
downloadFileArray = new ArrayList();
|
|
downloadFileSizeArray = new ArrayList();
|
|
foreach(ListViewItem l in rightListView.SelectedItems)
|
|
{
|
|
if(l.ImageIndex == 2)
|
|
{
|
|
if(skipExistingFiles == false)
|
|
{
|
|
downloadFileArray.Add(l.Text);
|
|
downloadFileSizeArray.Add(int.Parse(l.SubItems[1].Text));
|
|
}
|
|
else
|
|
{
|
|
bool overwrite = false;
|
|
string filename = l.Text;
|
|
foreach(ListViewItem l2 in leftListView.Items)
|
|
{
|
|
if(l2.ImageIndex == 2)
|
|
{
|
|
string filename2 = l2.Text;
|
|
if(node.agentid < 5) { filename = filename.ToLower(); filename2 = filename2.ToLower(); }
|
|
if(filename.Equals(filename2)) { overwrite = true; }
|
|
}
|
|
}
|
|
if(overwrite == false)
|
|
{
|
|
downloadFileArray.Add(l.Text);
|
|
downloadFileSizeArray.Add(int.Parse(l.SubItems[1].Text));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(downloadFileArray.Count == 0) return;
|
|
downloadLocalPath = localFolder;
|
|
downloadRemotePath = remoteFolder;
|
|
downloadActive = true;
|
|
downloadStop = false;
|
|
|
|
// Show transfer status dialog
|
|
transferStatusForm = new FileTransferStatusForm(this);
|
|
transferStatusForm.Show(this);
|
|
|
|
downloadNextFile();
|
|
}
|
|
|
|
private void downloadButton_ClickFlynn(object sender, EventArgs e)
|
|
{
|
|
// If a transfer is currently active, ignore this.
|
|
if(uploadActive || downloadActive || (transferStatusForm != null)) return;
|
|
|
|
strDownloadRel = remoteFolder;
|
|
|
|
// Perform the download
|
|
downloadFileArrayPtr = 0;
|
|
downloadFileArray = new ArrayList();
|
|
downloadFileSizeArray = new ArrayList();
|
|
|
|
bDontupdateRemoteFileView = true;
|
|
|
|
foreach(ListViewItem l in rightListView.SelectedItems)
|
|
{
|
|
if(l.ImageIndex == 1) // Folder
|
|
{
|
|
RekursivelyCollectDownloadFiles(strDownloadRel+"/"+l.Text);
|
|
}
|
|
else if(l.ImageIndex == 2) // File
|
|
{
|
|
if(skipExistingFiles == false)
|
|
{
|
|
downloadFileArray.Add(strDownloadRel+"/"+l.Text);
|
|
downloadFileSizeArray.Add(int.Parse(l.SubItems[1].Text));
|
|
}
|
|
else
|
|
{
|
|
bool overwrite = false;
|
|
string filename = l.Text;
|
|
foreach(ListViewItem l2 in leftListView.Items)
|
|
{
|
|
if(l2.ImageIndex == 2)
|
|
{
|
|
string filename2 = l2.Text;
|
|
if(node.agentid < 5) { filename = filename.ToLower(); filename2 = filename2.ToLower(); }
|
|
if(filename.Equals(filename2)) { overwrite = true; }
|
|
}
|
|
}
|
|
if(overwrite == false)
|
|
{
|
|
downloadFileArray.Add(strDownloadRel+"/"+l.Text);
|
|
downloadFileSizeArray.Add(int.Parse(l.SubItems[1].Text));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
bDontupdateRemoteFileView = false;
|
|
|
|
#region SKIP existing?
|
|
downloadLocalPath = localFolder;
|
|
// If any files are going to be overwritten
|
|
int overWriteCount = 0;
|
|
for(int i = 0; i < downloadFileArray.Count; i++)
|
|
{
|
|
string localFilePath;
|
|
String strDownloadFileString = (string)downloadFileArray[downloadFileArrayPtr];
|
|
if(strDownloadRel.Length > 0)
|
|
{
|
|
strDownloadFileString = strDownloadFileString.Substring(strDownloadRel.Length);
|
|
if(strDownloadFileString.StartsWith("/")) strDownloadFileString = strDownloadFileString.Substring(1);
|
|
}
|
|
localFilePath = Path.Combine(downloadLocalPath.FullName, strDownloadFileString.Replace("/", "\\"));
|
|
|
|
if(File.Exists(localFilePath) && new System.IO.FileInfo(localFilePath).Length.Equals(downloadFileSizeArray[i])) { overWriteCount++; }
|
|
}
|
|
|
|
skipExistingFiles = true;
|
|
if(overWriteCount > 0)
|
|
{
|
|
FileConfirmOverwriteForm f = new FileConfirmOverwriteForm();
|
|
if(overWriteCount == 1) { f.mainTextLabel = String.Format(Translate.T(Properties.Resources.OverwriteOneFile), overWriteCount); } else { f.mainTextLabel = String.Format(Translate.T(Properties.Resources.OverwriteXfiles), overWriteCount); }
|
|
if(f.ShowDialog(this) != DialogResult.OK) return;
|
|
skipExistingFiles = f.skipExistingFiles;
|
|
}
|
|
|
|
if(skipExistingFiles)
|
|
{
|
|
for(int i = 0; i < downloadFileArray.Count; i++)
|
|
{
|
|
string localFilePath;
|
|
String strDownloadFileString = (string)downloadFileArray[downloadFileArrayPtr];
|
|
if(strDownloadRel.Length > 0)
|
|
{
|
|
strDownloadFileString = strDownloadFileString.Substring(strDownloadRel.Length);
|
|
if(strDownloadFileString.StartsWith("/")) strDownloadFileString = strDownloadFileString.Substring(1);
|
|
}
|
|
localFilePath = Path.Combine(downloadLocalPath.FullName, strDownloadFileString.Replace("/", "\\"));
|
|
|
|
if(File.Exists(localFilePath) && new System.IO.FileInfo(localFilePath).Length.Equals(downloadFileSizeArray[i]))
|
|
{
|
|
downloadFileArray.RemoveAt(i);
|
|
downloadFileSizeArray.RemoveAt(i);
|
|
i--;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
if(downloadFileArray.Count == 0) return;
|
|
downloadLocalPath = localFolder;
|
|
downloadRemotePath = remoteFolder;
|
|
downloadActive = true;
|
|
downloadStop = false;
|
|
|
|
// Show transfer status dialog
|
|
transferStatusForm = new FileTransferStatusForm(this);
|
|
transferStatusForm.Show(this);
|
|
|
|
downloadNextFile();
|
|
}
|
|
|
|
private void RekursivelyCollectDownloadFiles(String strFolder)
|
|
{
|
|
requestRemoteFolder(strFolder);
|
|
DateTime to = DateTime.Now.AddSeconds(5);
|
|
while(DateTime.Now < to && remoteFolder != strFolder)
|
|
Application.DoEvents();
|
|
List<Fle> FileList = new List<Fle>();
|
|
for(int i = 0; i < remoteFolderList.Count; i++)
|
|
{
|
|
Dictionary<string, object> fileItem = (Dictionary<string, object>)remoteFolderList[i];
|
|
Fle file = new Fle();
|
|
file.Size = -1;
|
|
file.Path = strFolder.Replace("//", "/");
|
|
if(fileItem.ContainsKey("t")) { file.Icon = (int)fileItem["t"]; }
|
|
if(fileItem.ContainsKey("n")) { file.Name = (string)fileItem["n"]; }
|
|
if(fileItem.ContainsKey("d")) { file.Date = (string)fileItem["d"]; }
|
|
if(fileItem.ContainsKey("s"))
|
|
{
|
|
if(fileItem["s"].GetType() == typeof(System.Int32)) { file.Size = (int)fileItem["s"]; }
|
|
if(fileItem["s"].GetType() == typeof(System.Int64)) { file.Size = (long)fileItem["s"]; }
|
|
}
|
|
FileList.Add(file); // Folder
|
|
}
|
|
|
|
for(int i = 0; i < FileList.Count; i++)
|
|
{
|
|
Fle file = FileList[i];
|
|
if(file.Icon == 2) // Folder
|
|
{
|
|
RekursivelyCollectDownloadFiles(file.Path+"/"+file.Name);
|
|
}
|
|
else if(file.Icon == 3) // File
|
|
{
|
|
if(true) // Abfrage Skip
|
|
{
|
|
downloadFileArray.Add(file.Path+"/"+file.Name);
|
|
downloadFileSizeArray.Add(file.Size);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
String strDownloadRel = "";
|
|
private void downloadNextFile()
|
|
{
|
|
if((downloadFileArray == null) || (downloadFileArray.Count == 0)) return;
|
|
|
|
string localFilePath;
|
|
String strDownloadFileString = (string)downloadFileArray[downloadFileArrayPtr];
|
|
if(strDownloadRel.Length > 0)
|
|
{
|
|
strDownloadFileString = strDownloadFileString.Substring(strDownloadRel.Length);
|
|
if(strDownloadFileString.StartsWith("/")) strDownloadFileString = strDownloadFileString.Substring(1);
|
|
}
|
|
localFilePath = Path.Combine(downloadLocalPath.FullName, strDownloadFileString.Replace("/", "\\"));
|
|
if(!Directory.Exists(Path.GetDirectoryName(localFilePath))) Directory.CreateDirectory(Path.GetDirectoryName(localFilePath));
|
|
try { downloadFileStream = File.OpenWrite(localFilePath); }
|
|
catch(Exception)
|
|
{
|
|
// Download error, show it in the dialog
|
|
FileInfo f = new FileInfo(localFilePath);
|
|
if(transferStatusForm != null) { transferStatusForm.addErrorMessage(String.Format(Translate.T(Properties.Resources.UnableToWriteFileX), f.Name)); }
|
|
|
|
// Unable to download the file, skip it.
|
|
if(downloadFileArray.Count > downloadFileArrayPtr + 1)
|
|
{
|
|
// Download the next file
|
|
downloadFileArrayPtr++;
|
|
downloadNextFile();
|
|
}
|
|
else
|
|
{
|
|
// Done with all files
|
|
downloadActive = false;
|
|
downloadStop = false;
|
|
downloadFileArrayPtr = -1;
|
|
downloadFileArray = null;
|
|
downloadLocalPath = null;
|
|
downloadRemotePath = null;
|
|
closeTransferDialog();
|
|
localRefresh();
|
|
}
|
|
return;
|
|
}
|
|
|
|
if(downloadFileSizeArray[downloadFileArrayPtr].GetType() == typeof(System.Int32)) { downloadFileSize = (int)downloadFileSizeArray[downloadFileArrayPtr]; }
|
|
if(downloadFileSizeArray[downloadFileArrayPtr].GetType() == typeof(System.Int64)) { downloadFileSize = (long)downloadFileSizeArray[downloadFileArrayPtr]; }
|
|
|
|
downloadFilePtr = 0;
|
|
downloadFileStartTime = DateTime.Now;
|
|
|
|
string r;
|
|
if(downloadRemotePath.EndsWith("/")) { r = downloadRemotePath + Path.GetFileName((String)downloadFileArray[downloadFileArrayPtr]); } else { r = downloadRemotePath + "/" + Path.GetFileName((String)downloadFileArray[downloadFileArrayPtr]); }
|
|
r=(String)downloadFileArray[downloadFileArrayPtr];
|
|
// Send DOWNLOAD command
|
|
string cmd = "{\"action\":\"download\",\"sub\":\"start\",\"id\":" + (downloadFileArrayPtr + 1000) + ",\"path\":\"" + r + "\"}";
|
|
byte[] bincmd = UTF8Encoding.UTF8.GetBytes(cmd);
|
|
wc.SendBinary(bincmd, 0, bincmd.Length);
|
|
}
|
|
|
|
private void downloadGotBinaryData(byte[] data, int offset, int length)
|
|
{
|
|
if((length < 4) || (downloadFileStream == null)) return;
|
|
if(length > 4)
|
|
{
|
|
// Save part to disk
|
|
downloadFileStream.Write(data, offset + 4, length - 4);
|
|
downloadFilePtr += (length - 4);
|
|
}
|
|
int controlBits = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, offset));
|
|
if((controlBits & 1) != 0)
|
|
{
|
|
if(downloadFileStream != null) { downloadFileStream.Close(); downloadFileStream = null; }
|
|
downloadFilePtr = 0;
|
|
downloadFileSize = 0;
|
|
|
|
if(downloadFileArray.Count > downloadFileArrayPtr + 1)
|
|
{
|
|
// Download the next file
|
|
downloadFileArrayPtr++;
|
|
downloadNextFile();
|
|
}
|
|
else
|
|
{
|
|
// Done with all files
|
|
downloadActive = false;
|
|
downloadStop = false;
|
|
downloadFileArrayPtr = -1;
|
|
downloadFileArray = null;
|
|
downloadLocalPath = null;
|
|
downloadRemotePath = null;
|
|
closeTransferDialog();
|
|
localRefresh();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Send DOWNLOAD command
|
|
string cmd = "{\"action\":\"download\",\"sub\":\"ack\",\"id\":" + (downloadFileArrayPtr + 1000) + "}";
|
|
byte[] bincmd = UTF8Encoding.UTF8.GetBytes(cmd);
|
|
wc.SendBinary(bincmd, 0, bincmd.Length);
|
|
}
|
|
}
|
|
|
|
public void downloadCancel()
|
|
{
|
|
if(downloadActive == false) return;
|
|
|
|
// Send DOWNLOAD command
|
|
string cmd = "{\"action\":\"download\",\"sub\":\"stop\",\"id\":" + (downloadFileArrayPtr + 1000) + "}";
|
|
byte[] bincmd = UTF8Encoding.UTF8.GetBytes(cmd);
|
|
wc.SendBinary(bincmd, 0, bincmd.Length);
|
|
|
|
// Done with all files
|
|
if(downloadFileStream != null) { downloadFileStream.Close(); downloadFileStream = null; }
|
|
downloadFilePtr = 0;
|
|
downloadFileSize = 0;
|
|
downloadActive = false;
|
|
downloadStop = false;
|
|
downloadFileArrayPtr = -1;
|
|
downloadFileArray = null;
|
|
downloadLocalPath = null;
|
|
downloadRemotePath = null;
|
|
closeTransferDialog();
|
|
localRefresh();
|
|
}
|
|
|
|
private void localNewFolderButton_Click(object sender, EventArgs e)
|
|
{
|
|
if(localFolder == null) return;
|
|
FilenamePromptForm f = new FilenamePromptForm(Translate.T(Properties.Resources.CreateFolder), "");
|
|
if(f.ShowDialog(this) == DialogResult.OK)
|
|
{
|
|
Directory.CreateDirectory(Path.Combine(localFolder.FullName, f.filename));
|
|
updateLocalFileView();
|
|
}
|
|
}
|
|
|
|
private void localDeleteButton_Click(object sender, EventArgs e)
|
|
{
|
|
bool rec = false;
|
|
ArrayList filesArray = new ArrayList();
|
|
foreach(ListViewItem l in leftListView.SelectedItems) { filesArray.Add(l.Text); if(l.ImageIndex == 1) { rec = true; } }
|
|
string[] files = (string[])filesArray.ToArray(typeof(string));
|
|
string msg = string.Format(Translate.T(Properties.Resources.RemoveXItems), files.Length);
|
|
if(files.Length == 1) { msg = Translate.T(Properties.Resources.Remove1Item); }
|
|
FileDeletePromptForm f = new FileDeletePromptForm(msg, rec);
|
|
if(f.ShowDialog(this) == DialogResult.OK)
|
|
{
|
|
foreach(string file in filesArray)
|
|
{
|
|
try
|
|
{
|
|
string fullpath = Path.Combine(localFolder.FullName, file);
|
|
FileAttributes attr = File.GetAttributes(fullpath);
|
|
if((attr & FileAttributes.Directory) == FileAttributes.Directory) { Directory.Delete(fullpath, f.recursive); } else { File.Delete(fullpath); }
|
|
}
|
|
catch(Exception) { }
|
|
}
|
|
updateLocalFileView();
|
|
}
|
|
}
|
|
|
|
private void rightListView_DragEnter(object sender, DragEventArgs e)
|
|
{
|
|
if(uploadActive || downloadActive || (transferStatusForm != null)) return;
|
|
if((node.agentid < 5) && ((remoteFolder == null) || (remoteFolder == ""))) { return; }
|
|
if(e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy;
|
|
}
|
|
|
|
private void rightListView_DragDrop(object sender, DragEventArgs e)
|
|
{
|
|
if(uploadActive || downloadActive || (transferStatusForm != null)) return;
|
|
if((node.agentid < 5) && ((remoteFolder == null) || (remoteFolder == ""))) { return; }
|
|
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
|
|
|
|
// If any files are going to be overwritten
|
|
int overWriteCount = 0;
|
|
foreach(string file in files)
|
|
{
|
|
FileInfo f = new FileInfo(file);
|
|
string filename = f.Name;
|
|
foreach(ListViewItem l2 in rightListView.Items)
|
|
{
|
|
if(l2.ImageIndex == 2)
|
|
{
|
|
string filename2 = l2.Text;
|
|
if(node.agentid < 5) { filename = filename.ToLower(); filename2 = filename2.ToLower(); }
|
|
if(filename.Equals(filename2)) { overWriteCount++; }
|
|
}
|
|
}
|
|
}
|
|
skipExistingFiles = true;
|
|
if(overWriteCount > 0)
|
|
{
|
|
FileConfirmOverwriteForm f = new FileConfirmOverwriteForm();
|
|
if(overWriteCount == 1) { f.mainTextLabel = String.Format(Translate.T(Properties.Resources.OverwriteOneFile), overWriteCount); } else { f.mainTextLabel = String.Format(Translate.T(Properties.Resources.OverwriteXfiles), overWriteCount); }
|
|
if(f.ShowDialog(this) != DialogResult.OK) return;
|
|
skipExistingFiles = f.skipExistingFiles;
|
|
}
|
|
|
|
// Perform the upload
|
|
uploadFileArrayPtr = 0;
|
|
uploadFileArray = new ArrayList();
|
|
uploadFileDuplicateArray = new Hashtable();
|
|
|
|
foreach(string file in files)
|
|
{
|
|
bool overwrite = false;
|
|
bool overwriteNotLarger = false;
|
|
long remoteLength = 0;
|
|
string filename = Path.GetFileName(file);
|
|
foreach(ListViewItem l2 in rightListView.Items)
|
|
{
|
|
if(l2.ImageIndex == 2)
|
|
{
|
|
string filename2 = l2.Text;
|
|
if(node.agentid < 5) { filename = filename.ToLower(); filename2 = filename2.ToLower(); }
|
|
if(filename.Equals(filename2))
|
|
{
|
|
overwrite = true;
|
|
if(skipExistingFiles == false)
|
|
{
|
|
long localLength = new FileInfo(file).Length;
|
|
remoteLength = long.Parse(l2.SubItems[1].Text);
|
|
if(localLength >= remoteLength) { overwriteNotLarger = true; }
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if((skipExistingFiles == false) || (overwrite == false))
|
|
{
|
|
uploadFileArray.Add(file);
|
|
if(overwriteNotLarger) { uploadFileDuplicateArray.Add(file, remoteLength); }
|
|
}
|
|
}
|
|
|
|
if(uploadFileArray.Count == 0) return;
|
|
uploadLocalPath = null;
|
|
uploadRemotePath = remoteFolder;
|
|
uploadActive = true;
|
|
uploadStop = false;
|
|
|
|
// Show transfer status dialog
|
|
transferStatusForm = new FileTransferStatusForm(this);
|
|
transferStatusForm.Show(this);
|
|
|
|
uploadNextFile();
|
|
}
|
|
|
|
private void leftListView_MouseMove(object sender, MouseEventArgs e)
|
|
{
|
|
if(e.Button == MouseButtons.Left)
|
|
{
|
|
ArrayList files = new ArrayList();
|
|
foreach(ListViewItem l in leftListView.SelectedItems) { if(l.ImageIndex == 2) { files.Add(Path.Combine(localFolder.FullName, l.Text)); } }
|
|
if(files.Count > 0)
|
|
{
|
|
leftListView.DoDragDrop(new DataObject(DataFormats.FileDrop, (string[])files.ToArray(typeof(string))), DragDropEffects.Copy);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void rightListView_MouseMove(object sender, MouseEventArgs e)
|
|
{
|
|
if(e.Button == MouseButtons.Left)
|
|
{
|
|
ArrayList XdownloadFileArray = new ArrayList();
|
|
ArrayList XdownloadFileSizeArray = new ArrayList();
|
|
foreach(ListViewItem l in rightListView.SelectedItems)
|
|
{
|
|
if(l.ImageIndex == 2)
|
|
{
|
|
XdownloadFileArray.Add(l.Text);
|
|
XdownloadFileSizeArray.Add(int.Parse(l.SubItems[1].Text));
|
|
}
|
|
}
|
|
if(XdownloadFileArray.Count > 0)
|
|
{
|
|
DataObject dataObj = new DataObject();
|
|
dataObj.SetData("Type", "MeshCentralRouterRemoteFiles-" + rndString);
|
|
dataObj.SetData("RemoteFiles", XdownloadFileArray);
|
|
dataObj.SetData("RemoteSizes", XdownloadFileSizeArray);
|
|
dataObj.SetData("RemoteFolder", remoteFolder);
|
|
rightListView.DoDragDrop(dataObj, DragDropEffects.Copy);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void leftListView_DragEnter(object sender, DragEventArgs e)
|
|
{
|
|
if(uploadActive || downloadActive || (localFolder == null) || (transferStatusForm != null)) return;
|
|
if((e.Data.GetDataPresent("Type") == true) && ((string)e.Data.GetData("Type") == ("MeshCentralRouterRemoteFiles-" + rndString))) { e.Effect = DragDropEffects.Copy; }
|
|
}
|
|
|
|
private void leftListView_DragDrop(object sender, DragEventArgs e)
|
|
{
|
|
if(uploadActive || downloadActive || (transferStatusForm != null)) return;
|
|
if((e.Data.GetDataPresent("Type") == false) || ((string)e.Data.GetData("Type") != ("MeshCentralRouterRemoteFiles-" + rndString))) return;
|
|
|
|
ArrayList files = (ArrayList)e.Data.GetData("RemoteFiles");
|
|
|
|
// If any files are going to be overwritten
|
|
int overWriteCount = 0;
|
|
foreach(string file in files)
|
|
{
|
|
string filename = file;
|
|
foreach(ListViewItem l2 in leftListView.Items)
|
|
{
|
|
if(l2.ImageIndex == 2)
|
|
{
|
|
string filename2 = l2.Text;
|
|
if(node.agentid < 5) { filename = filename.ToLower(); filename2 = filename2.ToLower(); }
|
|
if(filename.Equals(filename2)) { overWriteCount++; }
|
|
}
|
|
}
|
|
}
|
|
skipExistingFiles = true;
|
|
if(overWriteCount > 0)
|
|
{
|
|
FileConfirmOverwriteForm f = new FileConfirmOverwriteForm();
|
|
if(overWriteCount == 1) { f.mainTextLabel = String.Format(Translate.T(Properties.Resources.OverwriteOneFile), overWriteCount); } else { f.mainTextLabel = String.Format(Translate.T(Properties.Resources.OverwriteXfiles), overWriteCount); }
|
|
if(f.ShowDialog(this) != DialogResult.OK) return;
|
|
skipExistingFiles = f.skipExistingFiles;
|
|
}
|
|
|
|
// Perform downloads
|
|
downloadFileArrayPtr = 0;
|
|
downloadFileArray = (ArrayList)e.Data.GetData("RemoteFiles");
|
|
downloadFileSizeArray = (ArrayList)e.Data.GetData("RemoteSizes");
|
|
|
|
if(skipExistingFiles == true)
|
|
{
|
|
ArrayList downloadFileArray2 = new ArrayList();
|
|
ArrayList downloadFileSizeArray2 = new ArrayList();
|
|
|
|
for(int i = 0; i < downloadFileArray.Count; i++)
|
|
{
|
|
bool overwrite = false;
|
|
string filename = (string)downloadFileArray[i];
|
|
foreach(ListViewItem l2 in leftListView.Items)
|
|
{
|
|
if(l2.ImageIndex == 2)
|
|
{
|
|
string filename2 = l2.Text;
|
|
if(node.agentid < 5) { filename = filename.ToLower(); filename2 = filename2.ToLower(); }
|
|
if(filename.Equals(filename2)) { overwrite = true; }
|
|
}
|
|
}
|
|
if(overwrite == false)
|
|
{
|
|
downloadFileArray2.Add(downloadFileArray[i]);
|
|
downloadFileSizeArray2.Add(downloadFileSizeArray[i]);
|
|
}
|
|
}
|
|
|
|
downloadFileArray = downloadFileArray2;
|
|
downloadFileSizeArray = downloadFileSizeArray2;
|
|
}
|
|
|
|
if(downloadFileArray.Count == 0) return;
|
|
|
|
downloadLocalPath = localFolder;
|
|
downloadRemotePath = (string)e.Data.GetData("RemoteFolder");
|
|
downloadActive = true;
|
|
downloadStop = false;
|
|
|
|
// Show transfer status dialog
|
|
transferStatusForm = new FileTransferStatusForm(this);
|
|
transferStatusForm.Show(this);
|
|
|
|
downloadNextFile();
|
|
}
|
|
private static string getRandomString(int length)
|
|
{
|
|
using(var rng = new RNGCryptoServiceProvider())
|
|
{
|
|
var bytes = new byte[(((length * 6) + 7) / 8)];
|
|
rng.GetBytes(bytes);
|
|
return Convert.ToBase64String(bytes);
|
|
}
|
|
}
|
|
|
|
bool isPointVisibleOnAScreen(Point p)
|
|
{
|
|
foreach(Screen s in Screen.AllScreens) { if((p.X < s.Bounds.Right) && (p.X > s.Bounds.Left) && (p.Y > s.Bounds.Top) && (p.Y < s.Bounds.Bottom)) return true; }
|
|
return false;
|
|
}
|
|
|
|
private void localContextMenuStrip_Opening(object sender, System.ComponentModel.CancelEventArgs e)
|
|
{
|
|
if((leftListView.SelectedItems.Count == 0) || (localFolder == null))
|
|
{
|
|
deleteToolStripMenuItem1.Visible = toolStripMenuItem2.Visible = renameToolStripMenuItem1.Visible = false;
|
|
}
|
|
else if(leftListView.SelectedItems.Count == 1)
|
|
{
|
|
deleteToolStripMenuItem1.Visible = toolStripMenuItem2.Visible = renameToolStripMenuItem1.Visible = true;
|
|
}
|
|
else if(leftListView.SelectedItems.Count > 1)
|
|
{
|
|
renameToolStripMenuItem1.Visible = false;
|
|
deleteToolStripMenuItem1.Visible = toolStripMenuItem2.Visible = true;
|
|
}
|
|
}
|
|
|
|
private void renameToolStripMenuItem1_Click(object sender, EventArgs e)
|
|
{
|
|
if((leftListView.SelectedItems.Count != 1) || (localFolder == null)) return;
|
|
string oldname = leftListView.SelectedItems[0].Text;
|
|
FilenamePromptForm f = new FilenamePromptForm(Translate.T(Properties.Resources.Rename), oldname);
|
|
if(f.ShowDialog(this) == DialogResult.OK)
|
|
{
|
|
if(oldname == f.filename) return;
|
|
FileInfo fileinfo = new FileInfo(Path.Combine(localFolder.FullName, oldname));
|
|
if(fileinfo.Exists == false) return;
|
|
try { fileinfo.MoveTo(Path.Combine(localFolder.FullName, f.filename)); } catch(Exception) { }
|
|
localRefresh();
|
|
}
|
|
}
|
|
}
|
|
|
|
public class Fle
|
|
{
|
|
public String Path = "";
|
|
public String Name = "";
|
|
public String Date = "";
|
|
public long Size = 0;
|
|
public int Icon = 0;
|
|
}
|
|
}
|