diff --git a/FileViewer.cs b/FileViewer.cs index dc1d44f..e0c2dcf 100644 --- a/FileViewer.cs +++ b/FileViewer.cs @@ -1,5 +1,5 @@ /* -Copyright 2009-2022 Intel Corporation +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. @@ -27,1295 +27,581 @@ using System.Web.Script.Serialization; namespace MeshCentralRouter { - public partial class FileViewer : Form + 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 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) { - 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 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; + InitializeComponent(); + Translate.TranslateControl(this); + if(node != null) { this.Text += " - " + node.name; } + this.node = node; + this.server = server; + UpdateStatus(); - // Stats - public long bytesIn = 0; - public long bytesInCompressed = 0; - public long bytesOut = 0; - public long bytesOutCompressed = 0; + rightListView.Columns[0].Width = rightListView.Width - rightListView.Columns[1].Width - 22; - // 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; + // Load the local path from the registry + string lp = Settings.GetRegValue("LocalPath", ""); + if((lp != "") && (Directory.Exists(lp))) { localFolder = new DirectoryInfo(lp); } + } - // 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 bool updateLocalFileView() + { + // Save the list of selected items + List selectedItems = new List(); + foreach(ListViewItem l in leftListView.SelectedItems) { selectedItems.Add(l.Text); } - public FileViewer(MeshCentralServer server, NodeClass node) + // Refresh the list + leftListView.Items.Clear(); + if(localFolder == null) + { + localRootButton.Enabled = false; + localNewFolderButton.Enabled = false; + localDeleteButton.Enabled = false; + try { - 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); } + 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)); } - - public bool updateLocalFileView() + catch(Exception) { return false; } + } + else + { + localRootButton.Enabled = true; + localNewFolderButton.Enabled = true; + localDeleteButton.Enabled = false; + try { - // Save the list of selected items - List selectedItems = new List(); - foreach (ListViewItem l in leftListView.SelectedItems) { selectedItems.Add(l.Text); } + 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(); - // Refresh the list - leftListView.Items.Clear(); - if (localFolder == null) + // 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 selectedItems = new List(); + 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 fileItem = (Dictionary)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 fileItem = (Dictionary)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)) { - 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; } + Location = p; + if((w > 50) && (h > 50)) { Size = new Size(w, h); } } - 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; + } + catch(Exception) { } } + } + } - 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 void MenuItemExit_Click(object sender, EventArgs e) + { + Close(); + } - private delegate void updateRemoteFileViewHandler(); - public void updateRemoteFileView() - { - if (this.InvokeRequired) { this.Invoke(new updateRemoteFileViewHandler(updateRemoteFileView)); return; } + 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); - // Save the list of selected items - List selectedItems = new List(); - 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 fileItem = (Dictionary)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 fileItem = (Dictionary)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; - 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); - } + displayMessage(null); + break; + } + case webSocketClient.ConnectionStates.Connected: + { + // Reset stats + bytesIn = 0; + bytesInCompressed = 0; + bytesOut = 0; + bytesOutCompressed = 0; - private void Wc_onStateChanged(webSocketClient sender, webSocketClient.ConnectionStates wsstate) + 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 jsonAction = new Dictionary(); + jsonAction = new JavaScriptSerializer().Deserialize>(data); + if(jsonAction == null) return; + + if(jsonAction.ContainsKey("action") && (jsonAction["action"].GetType() == typeof(string))) + { + string action = jsonAction["action"].ToString(); + switch(action) { - switch (wsstate) + case "download": { - 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; + if(downloadStop) { downloadCancel(); return; } - 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"; + 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 { } } - // Ask for root level - requestRemoteFolder(""); - return; - } - if (state != 3) 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); + 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) { } - // Parse the received JSON - Dictionary jsonAction = new Dictionary(); - jsonAction = new JavaScriptSerializer().Deserialize>(data); - if (jsonAction == null) return; - - if (jsonAction.ContainsKey("action") && (jsonAction["action"].GetType() == typeof(string))) - { - string action = jsonAction["action"].ToString(); - switch (action) + // Go to next file + if(downloadFileArray.Count > downloadFileArrayPtr + 1) { - 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) { transferStatusForm.addErrorMessage(String.Format(Translate.T(Properties.Resources.ErrorDownloadingFileX), downloadFileArray[downloadFileArrayPtr].ToString())); } - - // 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, 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 usersex = (Dictionary)jsonAction["users"]; - userSessions = new Dictionary(); - 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 jsonAction = new Dictionary(); - jsonAction = new JavaScriptSerializer().Deserialize>(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)); - } + // Download the next file + downloadFileArrayPtr++; + downloadNextFile(); } else { - msgForm.UpdateStatus(msg, file, progress); + // Done with all files + downloadActive = false; + downloadStop = false; + downloadFileArrayPtr = -1; + downloadFileArray = null; + downloadLocalPath = null; + downloadRemotePath = null; + closeTransferDialog(); + localRefresh(); } + } + break; } } - - private delegate void remoteRefreshHandler(); - - private void remoteRefresh() + } + else if(jsonAction.ContainsKey("type") && (jsonAction["type"].GetType() == typeof(string))) + { + string action = jsonAction["type"].ToString(); + switch(action) { - 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) + case "metadata": { - // Disconnect - state = 0; - wc.Dispose(); - wc = null; - UpdateStatus(); + if((jsonAction.ContainsKey("users") == false) || (jsonAction["users"] == null)) return; + Dictionary usersex = (Dictionary)jsonAction["users"]; + userSessions = new Dictionary(); + foreach(string user in usersex.Keys) { userSessions.Add(user, (int)usersex[user]); } + UpdateStatus(); + break; } - else + case "console": { - // 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; + 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 consoleTimer_Tick(object sender, EventArgs e) + } + } + + 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 jsonAction = new Dictionary(); + jsonAction = new JavaScriptSerializer().Deserialize>(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") { - consoleMessage.Visible = false; - consoleTimer.Enabled = false; + if(uploadStop) { uploadCancel(); return; } + uploadNextPart(false); + for(var i = 0; i < 8; i++) { uploadNextPart(true); } } - - private void connectButton_Click(object sender, EventArgs e) + else if(action == "uploadack") { - if (wc != null) - { - // Disconnect - state = 0; - wc.Dispose(); - wc = null; - UpdateStatus(); - } - else - { - // Connect - MenuItemConnect_Click(null, null); - } - displayMessage(null); + if(uploadStop) { uploadCancel(); return; } + uploadNextPart(false); } - - private void leftListView_MouseDoubleClick(object sender, MouseEventArgs e) + else if((action == "uploaddone") || (action == "uploaderror")) { - 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); - } - } - } + // Clean up current upload + uploadFilePtr = 0; + uploadFileStartPtr = 0; + uploadFileSize = 0; + if(uploadFileStream != null) { uploadFileStream.Close(); uploadFileStream = null; } - 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; - } - } - - private void rightListView_ColumnWidthChanged(object sender, ColumnWidthChangedEventArgs e) - { - if (rightListView.Columns[0].Width != (rightListView.Width - rightListView.Columns[1].Width - 22)) - { - rightListView.Columns[0].Width = rightListView.Width - rightListView.Columns[1].Width - 22; - } - } - - 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; - } - } - - private void leftListView_ColumnWidthChanged(object sender, ColumnWidthChangedEventArgs e) - { - if (leftListView.Columns[0].Width != (leftListView.Width - leftListView.Columns[1].Width - 22)) - { - leftListView.Columns[0].Width = leftListView.Width - leftListView.Columns[1].Width - 22; - } - } - - 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 != 2) { downloadAllowed = false; } } - 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); + // 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(); - } - - 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 + } + else + { + // Done with all files uploadActive = false; uploadStop = false; uploadFileArrayPtr = -1; @@ -1326,530 +612,1483 @@ namespace MeshCentralRouter uploadFilePtr = 0; uploadFileStartPtr = 0; uploadFileSize = 0; - if (uploadFileStream != null) { uploadFileStream.Close(); uploadFileStream = null; } + uploadFileName = null; closeTransferDialog(); remoteRefresh(); + } } - - private void uploadNextPart(bool dataPriming) + else if(action == "uploadhash") { - 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(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; } - 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) + // Hash the local file + string localHashHex = null; + try + { + string filePath = Path.Combine(localFolder.FullName, uploadFileName); + using(SHA384 SHA384 = SHA384Managed.Create()) { - // Everything was succesful, close the form - transferStatusForm.Close(); - transferStatusForm = null; - } else { - // Error are displayed, keep the form open - transferStatusForm.transferCompleted(); + 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) { } - private void downloadButton_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 rightListView.SelectedItems) + if((localHashHex != null) && (localHashHex.Equals(remoteHashHex))) + { + if(remoteFileSize == uploadFileStream.Length) { - 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 downloadNextFile() - { - if ((downloadFileArray == null) || (downloadFileArray.Count == 0)) return; - - string localFilePath; - localFilePath = Path.Combine(downloadLocalPath.FullName, (string)downloadFileArray[downloadFileArrayPtr]); - 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; - } - downloadFileSize = (int)downloadFileSizeArray[downloadFileArrayPtr]; - downloadFilePtr = 0; - downloadFileStartTime = DateTime.Now; - - string r; - if (downloadRemotePath.EndsWith("/")) { r = downloadRemotePath + downloadFileArray[downloadFileArrayPtr]; } else { r = downloadRemotePath + "/" + 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(); - } + // 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 { - // Send DOWNLOAD command - string cmd = "{\"action\":\"download\",\"sub\":\"ack\",\"id\":" + (downloadFileArrayPtr + 1000) + "}"; - byte[] bincmd = UTF8Encoding.UTF8.GetBytes(cmd); - wc.SendBinary(bincmd, 0, bincmd.Length); + // 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); } - } - - public void downloadCancel() - { - if (downloadActive == false) return; - - // Send DOWNLOAD command - string cmd = "{\"action\":\"download\",\"sub\":\"stop\",\"id\":" + (downloadFileArrayPtr + 1000) + "}"; + } + 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); - - // 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) + else if((action == "dialogmessage")) { - 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(); - } + // 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); } - - private void localDeleteButton_Click(object sender, EventArgs e) + else if(reqid == 1) { - 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(); - } + // Result of a LS command + if(jsonAction.ContainsKey("path")) { remoteFolder = (string)jsonAction["path"]; } + if(jsonAction.ContainsKey("dir")) { remoteFolderList = (ArrayList)jsonAction["dir"]; } + updateRemoteFileView(); } - - private void rightListView_DragEnter(object sender, DragEventArgs e) + } + else + { + if(downloadActive) { - 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(); - } + 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(); + } + + 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 FileList = new List(); + for(int i = 0; i < remoteFolderList.Count; i++) + { + Dictionary fileItem = (Dictionary)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; + } }