Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow folder and fix crash #116

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions uploader/uploader/LocalizationBase.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace uploader
namespace uploader
{
class LocalizationBase
{
public string MainForm_DragFile = "Drag file here";
public string MainForm_DragFileOrFolder = "Drag file or folder here";
public string MainForm_More = "More";

public string SettingsForm_Title = "Settings";
Expand All @@ -19,14 +12,18 @@ class LocalizationBase
public string SettingsForm_Language = "Language";
public string SettingsForm_Save = "Save";
public string SettingsForm_Open = "Open settings file";
public string SettingsForm_DirectUpload = "Direct file upload";
public string SettingsForm_DirectUpload = "Direct file or folder upload";

public string UploadForm_Info = "File information";
public string UploadForm_FileInfo = "File information";
public string UploadForm_FolderInfo = "Folder information";
public string UploadForm_Folder = "Folder:";
public string UploadForm_Upload = "Upload";
public string UploadForm_Cancel = "Cancel";
public string UploadForm_NoApiKey = "You have not entered an API key. Please go to settings and add one.";
public string UploadForm_InvalidLength = "Invalid API key length. The key must contain 64 characters.";
public string UploadForm_InvalidKey = "Invalid API key";
public string UploadForm_NoAccessToDirectory = "Not all files in the dropped directory can be accessed.";
public string UploadForm_NoAccessToFile = "File could not be opened.";

public string Message_Idle = "Idle.";
public string Message_Init = "Initializing...";
Expand All @@ -35,5 +32,6 @@ class LocalizationBase
public string Message_NoLink = "No permalink found in response!";
public string Message_NoSettings = "No settings file exists.";
public string Message_Saved = "Settings saved.";
public string Message_FileTooBig = "File too big.";
}
}
39 changes: 17 additions & 22 deletions uploader/uploader/MainForm.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DarkUI.Forms;

Expand All @@ -25,12 +17,12 @@ public MainForm()
private void MainForm_Load(object sender, EventArgs e)
{
// Set working directory to exe location because of language files
Directory.SetCurrentDirectory(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
Directory.SetCurrentDirectory(Path.GetDirectoryName(Application.ExecutablePath));
//LocalizationHelper.Export();

LocalizationHelper.Update();

dragLabel.Text = LocalizationHelper.Base.MainForm_DragFile;
dragLabel.Text = LocalizationHelper.Base.MainForm_DragFileOrFolder;
moreLabel.Text = LocalizationHelper.Base.MainForm_More;
}

Expand All @@ -52,27 +44,30 @@ private void MainForm_DragDrop(object sender, DragEventArgs e)
{
var settings = Settings.LoadSettings();

var files = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach (var file in files)
{
var uploadForm = new UploadForm(this, settings, true, file);
uploadForm.Show();
this.Hide();
var filesOrFolders = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach (var fileOrFolder in filesOrFolders)
{
ProcessPath(settings, fileOrFolder, true);
}
}

}
private void MainForm_Shown(object sender, EventArgs e)
{
var settings = Settings.LoadSettings();
var args = Environment.GetCommandLineArgs();

if (args.Length == 2)
{
var file = args[1]; // Second argument because .NET puts program filename to the first
var uploadForm = new UploadForm(this, settings, false, file);
uploadForm.Show();
this.Hide();
var fileOrFolder = args[1]; // Second argument because .NET puts program filename to the first
ProcessPath(settings, fileOrFolder, false);
}
}

private void ProcessPath(Settings settings, string fileOrFolder, bool reopen)
{
var uploadForm = new UploadForm(this, settings, reopen, fileOrFolder);
uploadForm.Show();
Hide();
}
}
}
168 changes: 100 additions & 68 deletions uploader/uploader/UploadForm.cs
Original file line number Diff line number Diff line change
@@ -1,34 +1,29 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using DarkUI.Forms;
using Microsoft.CSharp.RuntimeBinder;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RestSharp;

namespace uploader
{
public partial class UploadForm : DarkForm
{
private readonly bool _reopen;
private readonly string _fileName;
private readonly string _fileOrFolderName;
private readonly MainForm _mainForm;
private readonly Settings _settings;
private Thread _uploadThread;
private RestClient _client;
private string _resource;

public UploadForm(MainForm mainForm, Settings settings, bool reopen, string fileName)
public UploadForm(MainForm mainForm, Settings settings, bool reopen, string fileOrFolderName)
{
_fileName = fileName;
_fileOrFolderName = fileOrFolderName;
_mainForm = mainForm;
_settings = settings;
_reopen = reopen;
Expand All @@ -38,40 +33,24 @@ public UploadForm(MainForm mainForm, Settings settings, bool reopen, string file

private void ChangeStatus(string text)
{
if (InvokeRequired)
{
this.Invoke(new Action(() => ChangeStatus(text)));
return;
}

statusLabel.Text = text;
this.InvokeIfRequired(() => { statusLabel.Text = text; });
}

private void Finish(bool resetText)
{
if (InvokeRequired)
{
this.Invoke(new Action(() => Finish(resetText)));
return;
}

if (resetText)
{
ChangeStatus(LocalizationHelper.Base.Message_Idle);
}
this.InvokeIfRequired(() => {
if (resetText)
{
ChangeStatus(LocalizationHelper.Base.Message_Idle);
}

uploadButton.Text = LocalizationHelper.Base.UploadForm_Upload;
uploadButton.Text = LocalizationHelper.Base.UploadForm_Upload;
});
}

private void CloseWindow()
{
if (InvokeRequired)
{
this.Invoke(new Action(() => CloseWindow()));
return;
}

this.Close();
this.InvokeIfRequired(Close);
}

private void Upload()
Expand All @@ -91,64 +70,91 @@ private void Upload()
ChangeStatus(LocalizationHelper.Base.Message_Init);
_client = new RestClient("https://www.virustotal.com");

if (!File.Exists(_fileName))
string[] paths;
if (Directory.Exists(_fileOrFolderName))
{
try
{
paths = Directory.GetFiles(_fileOrFolderName, "*", SearchOption.AllDirectories);
}
catch (UnauthorizedAccessException)
{
ChangeStatus(LocalizationHelper.Base.UploadForm_NoAccessToDirectory);
Finish(false);
return;
}
}
else if (File.Exists(_fileOrFolderName))
{
paths = new [] { _fileOrFolderName };
}
else
{
throw new FileNotFoundException();
}

ChangeStatus(LocalizationHelper.Base.Message_Check);
var reportRequest = new RestRequest("vtapi/v2/file/report", Method.POST);
reportRequest.AddParameter("apikey", _settings.ApiKey);
reportRequest.AddParameter("resource", Utils.GetMD5(_fileName));
var result = true;
foreach (var path in paths)
{
var reportRequest = new RestRequest("vtapi/v2/file/report", Method.POST);
reportRequest.AddParameter("apikey", _settings.ApiKey);
reportRequest.AddParameter("resource", _resource);

var reportResponse = _client.Execute(reportRequest);
var reportContent = reportResponse.Content;
dynamic reportJson = JsonConvert.DeserializeObject(reportContent);
var reportResponse = _client.Execute(reportRequest);

try
{
var reportLink = reportJson.permalink.ToString();
Process.Start(reportLink);
// Here you can see quote or api key limits: var message = reportResponse.Headers.FirstOrDefault(x => x.Name == "X-Api-Message");
if (!string.IsNullOrEmpty(reportResponse.Content))
{
try
{
var reportJson = (JObject)JsonConvert.DeserializeObject(reportResponse.Content);
Process.Start(reportJson.SelectToken("permalink").Value<string>());
continue;
}
catch
{
// not yet received, but weird exceptions out there
}
}

if (_settings.DirectUpload) CloseWindow();
}
catch (RuntimeBinderException)
{
// Json does not contain permalink which means it's a new file (or the request failed)
ChangeStatus(LocalizationHelper.Base.Message_Upload);
var scanRequest = new RestRequest("vtapi/v2/file/scan", Method.POST);
scanRequest.AddParameter("apikey", _settings.ApiKey);
scanRequest.AddFile("file", _fileName);
scanRequest.AddFile("file", path);

var scanResponse = _client.Execute(scanRequest);
var scanContent = scanResponse.Content;
// TODO: check for HTML (file too large)
dynamic scanJson = JsonConvert.DeserializeObject(scanContent);

if (scanResponse.ErrorException is OutOfMemoryException || scanResponse.ErrorException is IOException && scanResponse.ErrorException?.InnerException is SocketException sEx && sEx.ErrorCode == (int)SocketError.ConnectionReset)
{
ChangeStatus(LocalizationHelper.Base.Message_FileTooBig);
result = false;
continue;
}
try
{
string scanLink = scanJson.permalink.ToString();
var scanJson = (JObject)JsonConvert.DeserializeObject(scanResponse.Content);
var scanLink = scanJson.SelectToken("permalink").Value<string>();

// An example link can look like this:
// https://www.virustotal.com/gui/file/<filehash_or_resource_id>/detection/<scanid>
// If we don't remove the the scanid, then it will fail on new files since the scan did not finish
// Removing it like this will show the analysis progress for new files
scanLink = scanLink.Remove(scanLink.IndexOf("/detection"));

Process.Start(scanLink);

if (_settings.DirectUpload) CloseWindow();
Process.Start(scanLink);
}
catch (Exception)
{
// Response does not contain permalink so it failed
ChangeStatus(LocalizationHelper.Base.Message_NoLink);
Finish(false);
return;
result = false;
}
}

Finish(true);
if (_settings.DirectUpload) CloseWindow();

Finish(result);
}

private void StartUploadThread()
Expand All @@ -161,17 +167,43 @@ private void StartUploadThread()
}
uploadButton.Text = LocalizationHelper.Base.UploadForm_Cancel;

_resource = mdTextbox.Text;
_uploadThread = new Thread(Upload);
_uploadThread.Start();
}

private void UploadForm_Load(object sender, EventArgs e)
{
mdTextbox.Text = Utils.GetMD5(_fileName);
shaTextbox.Text = Utils.GetSHA1(_fileName);
sha2Textbox.Text = Utils.GetSHA256(_fileName);
if (Directory.Exists(_fileOrFolderName))
{
mdTextbox.Text = _fileOrFolderName;
shaTextbox.Visible = false;
sha2Textbox.Visible = false;

darkLabel1.Text = LocalizationHelper.Base.UploadForm_Folder;
darkLabel2.Visible = false;
darkLabel3.Visible = false;

settingsGroup.Text = LocalizationHelper.Base.UploadForm_FolderInfo;
}
else
{
settingsGroup.Text = LocalizationHelper.Base.UploadForm_FileInfo;

try
{
mdTextbox.Text = Utils.GetMD5(_fileOrFolderName);
shaTextbox.Text = Utils.GetSHA1(_fileOrFolderName);
sha2Textbox.Text = Utils.GetSHA256(_fileOrFolderName);
}
catch (UnauthorizedAccessException)
{
mdTextbox.Text = LocalizationHelper.Base.UploadForm_NoAccessToFile;
shaTextbox.Text = LocalizationHelper.Base.UploadForm_NoAccessToFile;
sha2Textbox.Text = LocalizationHelper.Base.UploadForm_NoAccessToFile;
}
}

settingsGroup.Text = LocalizationHelper.Base.UploadForm_Info;
uploadButton.Text = LocalizationHelper.Base.UploadForm_Upload;
statusLabel.Text = LocalizationHelper.Base.Message_Idle;

Expand All @@ -198,4 +230,4 @@ private void UploadForm_FormClosing(object sender, FormClosingEventArgs e)
}
}
}
}
}
Loading