diff --git a/BSHash/BSHash/App.config b/BSHash/BSHash/App.config
index 583c63d..2874a46 100644
--- a/BSHash/BSHash/App.config
+++ b/BSHash/BSHash/App.config
@@ -1,30 +1,204 @@
-
+
-
+
-
+
+
+
+
+
+ localhost
+
+
+ HashKeeperPro
+
+
+ sa
+
+
+
+
+
+ 1433
+
+
+ SQL Server
+
+
+
+
+
+ False
+
+
+ 60
+
+
+ https://api.hashkeeper.com/v1/hashes
+
+
+
+
+
+ False
+
+
+ 100
+
+
+ False
+
+
+ True
+
+
+
+
+
+ False
+
+
+
+
-
+
-
-
-
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BSHash/BSHash/BSHash.csproj b/BSHash/BSHash/BSHash.csproj
index 2ed6cbf..76081cf 100644
--- a/BSHash/BSHash/BSHash.csproj
+++ b/BSHash/BSHash/BSHash.csproj
@@ -8,11 +8,12 @@
WinExe
BSHash
BSHash
- v4.8
+ v4.8.1
512
true
true
-
+
+
AnyCPU
@@ -34,8 +35,141 @@
4
+
+ ..\packages\Azure.Core.1.46.2\lib\net472\Azure.Core.dll
+
+
+ ..\packages\Azure.Identity.1.14.1\lib\netstandard2.0\Azure.Identity.dll
+
+
+ ..\packages\MaterialSkin.2.2.3.1\lib\net48\MaterialSkin.dll
+
+
+ ..\packages\Microsoft.Bcl.AsyncInterfaces.10.0.0-preview.5.25277.114\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll
+
+
+ ..\packages\Microsoft.Bcl.Cryptography.10.0.0-preview.5.25277.114\lib\net462\Microsoft.Bcl.Cryptography.dll
+
+
+ ..\packages\Microsoft.Bcl.TimeProvider.10.0.0-preview.5.25277.114\lib\net462\Microsoft.Bcl.TimeProvider.dll
+
+
+ ..\packages\Microsoft.Data.SqlClient.6.1.0-preview2.25178.5\lib\net462\Microsoft.Data.SqlClient.dll
+
+
+ ..\packages\Microsoft.Data.Sqlite.Core.9.0.7\lib\netstandard2.0\Microsoft.Data.Sqlite.dll
+
+
+ ..\packages\Microsoft.Extensions.Caching.Abstractions.10.0.0-preview.5.25277.114\lib\net462\Microsoft.Extensions.Caching.Abstractions.dll
+
+
+ ..\packages\Microsoft.Extensions.Caching.Memory.10.0.0-preview.5.25277.114\lib\net462\Microsoft.Extensions.Caching.Memory.dll
+
+
+ ..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.10.0.0-preview.5.25277.114\lib\net462\Microsoft.Extensions.DependencyInjection.Abstractions.dll
+
+
+ ..\packages\Microsoft.Extensions.Logging.Abstractions.10.0.0-preview.5.25277.114\lib\net462\Microsoft.Extensions.Logging.Abstractions.dll
+
+
+ ..\packages\Microsoft.Extensions.Options.10.0.0-preview.5.25277.114\lib\net462\Microsoft.Extensions.Options.dll
+
+
+ ..\packages\Microsoft.Extensions.Primitives.10.0.0-preview.5.25277.114\lib\net462\Microsoft.Extensions.Primitives.dll
+
+
+ ..\packages\Microsoft.Identity.Client.4.73.1\lib\net472\Microsoft.Identity.Client.dll
+
+
+ ..\packages\Microsoft.Identity.Client.Extensions.Msal.4.73.1\lib\netstandard2.0\Microsoft.Identity.Client.Extensions.Msal.dll
+
+
+ ..\packages\Microsoft.IdentityModel.Abstractions.8.12.1\lib\net472\Microsoft.IdentityModel.Abstractions.dll
+
+
+ ..\packages\Microsoft.IdentityModel.JsonWebTokens.8.12.1\lib\net472\Microsoft.IdentityModel.JsonWebTokens.dll
+
+
+ ..\packages\Microsoft.IdentityModel.Logging.8.12.1\lib\net472\Microsoft.IdentityModel.Logging.dll
+
+
+ ..\packages\Microsoft.IdentityModel.Protocols.8.12.1\lib\net472\Microsoft.IdentityModel.Protocols.dll
+
+
+ ..\packages\Microsoft.IdentityModel.Protocols.OpenIdConnect.8.12.1\lib\net472\Microsoft.IdentityModel.Protocols.OpenIdConnect.dll
+
+
+ ..\packages\Microsoft.IdentityModel.Tokens.8.12.1\lib\net472\Microsoft.IdentityModel.Tokens.dll
+
+
+ ..\packages\SQLitePCLRaw.core.2.1.10\lib\netstandard2.0\SQLitePCLRaw.core.dll
+
+
+ ..\packages\System.Buffers.4.6.1\lib\net462\System.Buffers.dll
+
+
+ ..\packages\System.ClientModel.1.5.0-beta.1\lib\netstandard2.0\System.ClientModel.dll
+
+
+
+ ..\packages\System.Data.Common.4.3.0\lib\net451\System.Data.Common.dll
+ True
+ True
+
+
+
+ ..\packages\System.Diagnostics.DiagnosticSource.10.0.0-preview.5.25277.114\lib\net462\System.Diagnostics.DiagnosticSource.dll
+
+
+ ..\packages\System.Formats.Asn1.10.0.0-preview.5.25277.114\lib\net462\System.Formats.Asn1.dll
+
+
+
+ ..\packages\System.IdentityModel.Tokens.Jwt.8.12.1\lib\net472\System.IdentityModel.Tokens.Jwt.dll
+
+
+ ..\packages\System.IO.FileSystem.AccessControl.5.0.0\lib\net461\System.IO.FileSystem.AccessControl.dll
+
+
+ ..\packages\System.IO.Pipelines.10.0.0-preview.5.25277.114\lib\net462\System.IO.Pipelines.dll
+
+
+ ..\packages\System.Memory.4.6.3\lib\net462\System.Memory.dll
+
+
+ ..\packages\System.Memory.Data.10.0.0-preview.5.25277.114\lib\net462\System.Memory.Data.dll
+
+
+
+ ..\packages\System.Numerics.Vectors.4.6.1\lib\net462\System.Numerics.Vectors.dll
+
+
+ ..\packages\System.Runtime.CompilerServices.Unsafe.6.1.2\lib\net462\System.Runtime.CompilerServices.Unsafe.dll
+
+
+
+ ..\packages\System.Security.AccessControl.6.0.1\lib\net461\System.Security.AccessControl.dll
+
+
+ ..\packages\System.Security.Cryptography.Pkcs.10.0.0-preview.5.25277.114\lib\net462\System.Security.Cryptography.Pkcs.dll
+
+
+ ..\packages\System.Security.Cryptography.ProtectedData.10.0.0-preview.5.25277.114\lib\net462\System.Security.Cryptography.ProtectedData.dll
+
+
+ ..\packages\System.Security.Principal.Windows.5.0.0\lib\net461\System.Security.Principal.Windows.dll
+
+
+ ..\packages\System.Text.Encodings.Web.10.0.0-preview.5.25277.114\lib\net462\System.Text.Encodings.Web.dll
+
+
+ ..\packages\System.Text.Json.10.0.0-preview.5.25277.114\lib\net462\System.Text.Json.dll
+
+
+ ..\packages\System.Threading.Tasks.Extensions.4.6.3\lib\net462\System.Threading.Tasks.Extensions.dll
+
@@ -47,11 +181,23 @@
-
-
-
-
-
+
+ Form
+
+
+ Form
+
+
+ Form
+
+
+
+
+
+
+
+
+
Form
@@ -72,6 +218,7 @@
True
Resources.resx
+
SettingsSingleFileGenerator
Settings.Designer.cs
@@ -86,4 +233,13 @@
+
+
+
+ Questo progetto fa riferimento a uno o più pacchetti NuGet che non sono presenti in questo computer. Usare lo strumento di ripristino dei pacchetti NuGet per scaricarli. Per altre informazioni, vedere http://go.microsoft.com/fwlink/?LinkID=322105. Il file mancante è {0}.
+
+
+
+
+
\ No newline at end of file
diff --git a/BSHash/BSHash/Calculator.cs b/BSHash/BSHash/Calculator.cs
deleted file mode 100644
index c7c0e2a..0000000
--- a/BSHash/BSHash/Calculator.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Security.Cryptography;
-using System.Windows.Forms;
-
-namespace BSHash
-{
- public class Calculator
- {
- private Logger _logger;
-
- public Calculator(Logger logger)
- {
- _logger = logger;
- }
-
- public string CalculateHash(string filePath)
- {
- try
- {
- using (SHA256 sha256 = SHA256.Create())
- {
- using (FileStream fileStream = File.OpenRead(filePath))
- {
- byte[] hashBytes = sha256.ComputeHash(fileStream);
- string hash = BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant();
-
- _logger.Log("Hash " + hash + " calcolato per il file " + filePath.ToString(), LogType.INFO);
-
- return hash;
- }
- }
- }
- catch (Exception ex)
- {
- // Log the exception or handle it as needed
- _logger.Log("Errore nella lettura o hash del file " + filePath.ToString() + ".\nErrore: " + ex.Message.ToString(), LogType.ERROR);
-
- return null;
- }
- }
- }
-}
diff --git a/BSHash/BSHash/Database.cs b/BSHash/BSHash/Database.cs
deleted file mode 100644
index 1ddae0b..0000000
--- a/BSHash/BSHash/Database.cs
+++ /dev/null
@@ -1,242 +0,0 @@
-using System;
-using System.Data;
-using System.Data.SqlClient;
-
-namespace BSHash
-{
- public class Database
- {
- private readonly string _connectionString;
-
- public Database()
- {
- string serverstring = Properties.Settings.Default.Server;
- string databasestring = Properties.Settings.Default.Database;
- string userstring = Properties.Settings.Default.User;
- string passwordstring = Properties.Settings.Default.Password;
-
- // Ricompongo la stringa di connessione
- _connectionString = $"Server={serverstring};Database={databasestring};User Id={userstring};Password={passwordstring};";
- }
-
- public bool ClearHash()
- {
- using (SqlConnection connection = new SqlConnection(_connectionString))
- {
- connection.Open();
- using (SqlTransaction transaction = connection.BeginTransaction())
- {
- try
- {
- // Delete all rows from the Hash table
- string deleteQuery = "DELETE FROM Hash";
- using (SqlCommand deleteCommand = new SqlCommand(deleteQuery, connection, transaction))
- {
- deleteCommand.ExecuteNonQuery();
- }
-
- transaction.Commit();
- return true;
- }
- catch
- {
- transaction.Rollback();
- return false;
- throw;
- }
- }
- }
- }
-
- public bool HashExists(string hash)
- {
- using (SqlConnection connection = new SqlConnection(_connectionString))
- {
- try
- {
- connection.Open();
-
- // Controlla se l'hash esiste già nel database
- string checkQuery = "SELECT COUNT(*) FROM Hash WHERE Hash = (@Hash)";
- using (SqlCommand checkCommand = new SqlCommand(checkQuery, connection))
- {
- checkCommand.Parameters.AddWithValue("@Hash", hash);
- int count = (int)checkCommand.ExecuteScalar();
-
- return count != 0;
- }
- }
- catch
- {
- return true;
- throw;
- }
- }
- }
-
- public bool InsertHash(string path, string hash)
- {
- using (SqlConnection connection = new SqlConnection(_connectionString))
- {
- connection.Open();
- using (SqlTransaction transaction = connection.BeginTransaction())
- {
- try
- {
- // L'hash non esiste quindi lo inserisco
- string insertQuery = "INSERT INTO Hash (Path, Hash) VALUES (@Path, @Hash)";
- using (SqlCommand insertCommand = new SqlCommand(insertQuery, connection, transaction))
- {
- insertCommand.Parameters.AddWithValue("@Path", path);
- insertCommand.Parameters.AddWithValue("@Hash", hash);
- insertCommand.ExecuteNonQuery();
- }
-
- transaction.Commit();
-
- return true;
- }
- catch
- {
- transaction.Rollback();
- return false;
- throw;
- }
- }
- }
- }
-
- public bool UpdateHash(string path, string hash)
- {
- using (SqlConnection connection = new SqlConnection(_connectionString))
- {
- connection.Open();
- using (SqlTransaction transaction = connection.BeginTransaction())
- {
- try
- {
- // L'hash esiste quindi aggiorno la data di ultima scansione
- string updateQuery = "UPDATE Hash SET Path = (@Path) WHERE Hash = (@Hash)";
- using (SqlCommand updateCommand = new SqlCommand(updateQuery, connection, transaction))
- {
- updateCommand.Parameters.AddWithValue("@Path", path);
- updateCommand.Parameters.AddWithValue("@Hash", hash);
- updateCommand.ExecuteNonQuery();
- }
-
- transaction.Commit();
-
- return true;
- }
- catch
- {
- transaction.Rollback();
-
- return false;
- throw;
- }
- }
- }
- }
-
- public bool InsertHistory(string hash)
- {
- using (SqlConnection connection = new SqlConnection(_connectionString))
- {
- connection.Open();
- using (SqlTransaction transaction = connection.BeginTransaction())
- {
- try
- {
-
- // L'hash esiste quindi aggiorno la data di ultima scansione
- string updateQuery = "INSERT INTO History (Hash) VALUES (@Hash)";
- using (SqlCommand updateCommand = new SqlCommand(updateQuery, connection, transaction))
- {
- updateCommand.Parameters.AddWithValue("@Hash", hash);
- updateCommand.ExecuteNonQuery();
- }
-
- transaction.Commit();
-
- return true;
- }
- catch
- {
- transaction.Rollback();
-
- return false;
- throw;
- }
- }
- }
- }
-
- public void InsertLog(string message, LogType type = LogType.INFO)
- {
- using (SqlConnection connection = new SqlConnection(_connectionString))
- {
- connection.Open();
- using (SqlTransaction transaction = connection.BeginTransaction())
- {
- try
- {
- string query = "INSERT INTO Log (Message, Type) VALUES (@Message, @Type)";
- using (SqlCommand command = new SqlCommand(query, connection, transaction))
- {
- command.Parameters.AddWithValue("@Message", message);
- command.Parameters.AddWithValue("@Type", type);
- command.ExecuteNonQuery();
- }
- transaction.Commit();
- }
- catch
- {
- transaction.Rollback();
- throw;
- }
- }
- }
- }
-
- public DataTable GetHashes()
- {
- DataTable hashes = new DataTable();
-
- using (SqlConnection connection = new SqlConnection(_connectionString))
- {
- string query = "SELECT * FROM Hash";
-
- using (SqlCommand command = new SqlCommand(query, connection))
- {
- connection.Open();
- using (SqlDataReader reader = command.ExecuteReader())
- {
- hashes.Load(reader);
- }
- }
- }
-
- return hashes;
- }
-
- public DataTable GetLogs(string query)
- {
- DataTable logs = new DataTable();
-
- using (SqlConnection connection = new SqlConnection(_connectionString))
- {
- using (SqlCommand command = new SqlCommand(query, connection))
- {
- connection.Open();
- using (SqlDataReader reader = command.ExecuteReader())
- {
- logs.Load(reader);
- }
- }
- }
-
- return logs;
- }
- }
-}
diff --git a/BSHash/BSHash/Forms/DatabaseSettingsForm.cs b/BSHash/BSHash/Forms/DatabaseSettingsForm.cs
new file mode 100644
index 0000000..43a529e
--- /dev/null
+++ b/BSHash/BSHash/Forms/DatabaseSettingsForm.cs
@@ -0,0 +1,303 @@
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace BSHash
+{
+ public partial class DatabaseSettingsForm : Form
+ {
+ private TextBox txtServer;
+ private TextBox txtDatabase;
+ private TextBox txtUsername;
+ private TextBox txtPassword;
+ private TextBox txtPort;
+ private ComboBox cmbProvider;
+ private Button btnSave;
+ private Button btnCancel;
+ private Button btnTest;
+ private Label lblStatus;
+
+ public DatabaseSettingsForm()
+ {
+ InitializeComponent();
+ LoadSettings();
+ }
+
+ private void InitializeComponent()
+ {
+ this.Size = new Size(500, 450);
+ this.Text = "Impostazioni Database";
+ this.StartPosition = FormStartPosition.CenterParent;
+ this.FormBorderStyle = FormBorderStyle.FixedDialog;
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.BackColor = Color.FromArgb(248, 249, 250);
+
+ // Provider
+ var lblProvider = new Label
+ {
+ Text = "Provider Database:",
+ Location = new Point(20, 20),
+ Size = new Size(120, 20),
+ Font = new Font("Segoe UI", 9)
+ };
+
+ cmbProvider = new ComboBox
+ {
+ Location = new Point(150, 18),
+ Size = new Size(300, 25),
+ DropDownStyle = ComboBoxStyle.DropDownList,
+ Font = new Font("Segoe UI", 9)
+ };
+ cmbProvider.Items.AddRange(new[] { "SQL Server", "MySQL", "PostgreSQL" });
+ cmbProvider.SelectedIndex = 0;
+
+ // Server
+ var lblServer = new Label
+ {
+ Text = "Server:",
+ Location = new Point(20, 60),
+ Size = new Size(120, 20),
+ Font = new Font("Segoe UI", 9)
+ };
+
+ txtServer = new TextBox
+ {
+ Location = new Point(150, 58),
+ Size = new Size(200, 25),
+ Font = new Font("Segoe UI", 9)
+ };
+
+ // Port
+ var lblPort = new Label
+ {
+ Text = "Porta:",
+ Location = new Point(360, 60),
+ Size = new Size(40, 20),
+ Font = new Font("Segoe UI", 9)
+ };
+
+ txtPort = new TextBox
+ {
+ Location = new Point(410, 58),
+ Size = new Size(60, 25),
+ Font = new Font("Segoe UI", 9)
+ };
+
+ // Database
+ var lblDatabase = new Label
+ {
+ Text = "Database:",
+ Location = new Point(20, 100),
+ Size = new Size(120, 20),
+ Font = new Font("Segoe UI", 9)
+ };
+
+ txtDatabase = new TextBox
+ {
+ Location = new Point(150, 98),
+ Size = new Size(300, 25),
+ Font = new Font("Segoe UI", 9)
+ };
+
+ // Username
+ var lblUsername = new Label
+ {
+ Text = "Username:",
+ Location = new Point(20, 140),
+ Size = new Size(120, 20),
+ Font = new Font("Segoe UI", 9)
+ };
+
+ txtUsername = new TextBox
+ {
+ Location = new Point(150, 138),
+ Size = new Size(300, 25),
+ Font = new Font("Segoe UI", 9)
+ };
+
+ // Password
+ var lblPassword = new Label
+ {
+ Text = "Password:",
+ Location = new Point(20, 180),
+ Size = new Size(120, 20),
+ Font = new Font("Segoe UI", 9)
+ };
+
+ txtPassword = new TextBox
+ {
+ Location = new Point(150, 178),
+ Size = new Size(300, 25),
+ Font = new Font("Segoe UI", 9),
+ UseSystemPasswordChar = true
+ };
+
+ // Status
+ lblStatus = new Label
+ {
+ Location = new Point(20, 220),
+ Size = new Size(450, 40),
+ Font = new Font("Segoe UI", 9),
+ ForeColor = Color.FromArgb(107, 114, 128)
+ };
+
+ // Buttons
+ btnTest = new Button
+ {
+ Text = "Testa Connessione",
+ Location = new Point(20, 280),
+ Size = new Size(140, 35),
+ Font = new Font("Segoe UI", 9),
+ BackColor = Color.FromArgb(99, 102, 241),
+ ForeColor = Color.White,
+ FlatStyle = FlatStyle.Flat
+ };
+ btnTest.FlatAppearance.BorderSize = 0;
+ btnTest.Click += BtnTest_Click;
+
+ btnCancel = new Button
+ {
+ Text = "Annulla",
+ Location = new Point(280, 330),
+ Size = new Size(80, 35),
+ Font = new Font("Segoe UI", 9),
+ BackColor = Color.FromArgb(107, 114, 128),
+ ForeColor = Color.White,
+ FlatStyle = FlatStyle.Flat
+ };
+ btnCancel.FlatAppearance.BorderSize = 0;
+ btnCancel.Click += BtnCancel_Click;
+
+ btnSave = new Button
+ {
+ Text = "Salva",
+ Location = new Point(370, 330),
+ Size = new Size(80, 35),
+ Font = new Font("Segoe UI", 9),
+ BackColor = Color.FromArgb(34, 197, 94),
+ ForeColor = Color.White,
+ FlatStyle = FlatStyle.Flat
+ };
+ btnSave.FlatAppearance.BorderSize = 0;
+ btnSave.Click += BtnSave_Click;
+
+ // Add controls
+ this.Controls.AddRange(new Control[]
+ {
+ lblProvider, cmbProvider,
+ lblServer, txtServer, lblPort, txtPort,
+ lblDatabase, txtDatabase,
+ lblUsername, txtUsername,
+ lblPassword, txtPassword,
+ lblStatus,
+ btnTest, btnCancel, btnSave
+ });
+ }
+
+ private async void BtnTest_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ btnTest.Enabled = false;
+ lblStatus.Text = "Testando connessione...";
+ lblStatus.ForeColor = Color.Blue;
+
+ var database = new BSHash.Manager.Database();
+ bool success = await database.TestConnectionAsync(GetConnectionString());
+
+ if (success)
+ {
+ lblStatus.Text = "Connessione riuscita!";
+ lblStatus.ForeColor = Color.Green;
+ }
+ else
+ {
+ lblStatus.Text = "Connessione fallita. Verificare i parametri.";
+ lblStatus.ForeColor = Color.Red;
+ }
+ }
+ catch (Exception ex)
+ {
+ lblStatus.Text = $"Errore: {ex.Message}";
+ lblStatus.ForeColor = Color.Red;
+ }
+ finally
+ {
+ btnTest.Enabled = true;
+ }
+ }
+
+ private void BtnSave_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ SaveSettings();
+ lblStatus.Text = "Impostazioni salvate!";
+ lblStatus.ForeColor = Color.Green;
+
+ // Close form after brief delay
+ Timer timer = new Timer();
+ timer.Interval = 1000;
+ timer.Tick += (s, args) => { timer.Stop(); this.Close(); };
+ timer.Start();
+ }
+ catch (Exception ex)
+ {
+ lblStatus.Text = $"Errore nel salvataggio: {ex.Message}";
+ lblStatus.ForeColor = Color.Red;
+ }
+ }
+
+ private void BtnCancel_Click(object sender, EventArgs e)
+ {
+ this.Close();
+ }
+
+ private void LoadSettings()
+ {
+ txtServer.Text = Properties.Settings.Default.DatabaseServer;
+ txtDatabase.Text = Properties.Settings.Default.DatabaseName;
+ txtUsername.Text = Properties.Settings.Default.DatabaseUser;
+ txtPassword.Text = Properties.Settings.Default.DatabasePassword;
+ txtPort.Text = Properties.Settings.Default.DatabasePort.ToString();
+ cmbProvider.Text = Properties.Settings.Default.DatabaseProvider;
+ }
+
+ private void SaveSettings()
+ {
+ Properties.Settings.Default.DatabaseServer = txtServer.Text;
+ Properties.Settings.Default.DatabaseName = txtDatabase.Text;
+ Properties.Settings.Default.DatabaseUser = txtUsername.Text;
+ Properties.Settings.Default.DatabasePassword = txtPassword.Text;
+
+ if (int.TryParse(txtPort.Text, out int port))
+ Properties.Settings.Default.DatabasePort = port;
+
+ Properties.Settings.Default.DatabaseProvider = cmbProvider.Text;
+ Properties.Settings.Default.Save();
+ }
+
+ private string GetConnectionString()
+ {
+ string provider = cmbProvider.Text;
+ string server = txtServer.Text;
+ string database = txtDatabase.Text;
+ string username = txtUsername.Text;
+ string password = txtPassword.Text;
+ string port = txtPort.Text;
+
+ switch (provider)
+ {
+ case "SQL Server":
+ return $"Server={server},{port};Database={database};User Id={username};Password={password};";
+ case "MySQL":
+ return $"Server={server};Port={port};Database={database};Uid={username};Pwd={password};";
+ case "PostgreSQL":
+ return $"Host={server};Port={port};Database={database};Username={username};Password={password};";
+ default:
+ return $"Server={server};Database={database};User Id={username};Password={password};";
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/BSHash/BSHash/Forms/LoginForm.cs b/BSHash/BSHash/Forms/LoginForm.cs
new file mode 100644
index 0000000..1087dd1
--- /dev/null
+++ b/BSHash/BSHash/Forms/LoginForm.cs
@@ -0,0 +1,319 @@
+using System;
+using System.Drawing;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using BSHash.Manager;
+
+namespace BSHash
+{
+ public partial class LoginForm : Form
+ {
+ private TextBox txtUsername;
+ private TextBox txtPassword;
+ private CheckBox chkRememberCredentials;
+ private Button btnLogin;
+ private Button btnDatabaseSettings;
+ private Label lblTitle;
+ private Label lblUsername;
+ private Label lblPassword;
+ private Label lblStatus;
+ private ProgressBar progressBar;
+ private PictureBox pictureBoxLogo;
+ private Panel panelMain;
+
+ private Database database;
+
+ public LoginForm()
+ {
+ InitializeComponent();
+ LoadRememberedCredentials();
+ database = new Database();
+ }
+
+ private void InitializeComponent()
+ {
+ this.Size = new Size(500, 600);
+ this.Text = "HashKeeper Pro - Login";
+ this.StartPosition = FormStartPosition.CenterScreen;
+ this.FormBorderStyle = FormBorderStyle.FixedSingle;
+ this.MaximizeBox = false;
+ this.BackColor = Color.FromArgb(248, 249, 250);
+
+ // Main panel
+ panelMain = new Panel
+ {
+ Size = new Size(400, 500),
+ Location = new Point((this.Width - 400) / 2, (this.Height - 500) / 2),
+ BackColor = Color.White,
+ BorderStyle = BorderStyle.None
+ };
+
+ // Logo
+ pictureBoxLogo = new PictureBox
+ {
+ Size = new Size(64, 64),
+ Location = new Point((panelMain.Width - 64) / 2, 40),
+ BackColor = Color.FromArgb(59, 130, 246),
+ SizeMode = PictureBoxSizeMode.CenterImage
+ };
+
+ // Title
+ lblTitle = new Label
+ {
+ Text = "ACCEDI",
+ Font = new Font("Segoe UI", 24, FontStyle.Bold),
+ Location = new Point((panelMain.Width - 150) / 2, 130),
+ Size = new Size(150, 40),
+ TextAlign = ContentAlignment.MiddleCenter,
+ ForeColor = Color.FromArgb(31, 41, 55)
+ };
+
+ // Username label
+ lblUsername = new Label
+ {
+ Text = "Nome Utente",
+ Font = new Font("Segoe UI", 9),
+ Location = new Point(50, 200),
+ Size = new Size(100, 20),
+ ForeColor = Color.FromArgb(107, 114, 128)
+ };
+
+ // Username textbox
+ txtUsername = new TextBox
+ {
+ Location = new Point(50, 225),
+ Size = new Size(300, 35),
+ Font = new Font("Segoe UI", 11),
+ BorderStyle = BorderStyle.FixedSingle,
+ BackColor = Color.White
+ };
+
+ // Password label
+ lblPassword = new Label
+ {
+ Text = "Password",
+ Font = new Font("Segoe UI", 9),
+ Location = new Point(50, 270),
+ Size = new Size(100, 20),
+ ForeColor = Color.FromArgb(107, 114, 128)
+ };
+
+ // Password textbox
+ txtPassword = new TextBox
+ {
+ Location = new Point(50, 295),
+ Size = new Size(300, 35),
+ Font = new Font("Segoe UI", 11),
+ BorderStyle = BorderStyle.FixedSingle,
+ UseSystemPasswordChar = true,
+ BackColor = Color.White
+ };
+
+ // Remember credentials checkbox
+ chkRememberCredentials = new CheckBox
+ {
+ Text = "Ricorda Credenziali",
+ Location = new Point(50, 340),
+ Size = new Size(150, 20),
+ Font = new Font("Segoe UI", 9),
+ ForeColor = Color.FromArgb(107, 114, 128)
+ };
+
+ // Login button
+ btnLogin = new Button
+ {
+ Text = "Accedi",
+ Location = new Point(50, 380),
+ Size = new Size(300, 45),
+ Font = new Font("Segoe UI", 12, FontStyle.Bold),
+ BackColor = Color.FromArgb(59, 130, 246),
+ ForeColor = Color.White,
+ FlatStyle = FlatStyle.Flat,
+ Cursor = Cursors.Hand
+ };
+ btnLogin.FlatAppearance.BorderSize = 0;
+ btnLogin.Click += BtnLogin_Click;
+
+ // Status label
+ lblStatus = new Label
+ {
+ Location = new Point(50, 435),
+ Size = new Size(300, 20),
+ Font = new Font("Segoe UI", 9),
+ ForeColor = Color.FromArgb(107, 114, 128),
+ TextAlign = ContentAlignment.MiddleCenter
+ };
+
+ // Progress bar
+ progressBar = new ProgressBar
+ {
+ Location = new Point(50, 460),
+ Size = new Size(300, 5),
+ Style = ProgressBarStyle.Marquee,
+ Visible = false
+ };
+
+ // Database settings button
+ btnDatabaseSettings = new Button
+ {
+ Size = new Size(30, 30),
+ Location = new Point(this.Width - 50, this.Height - 50),
+ Text = "?",
+ Font = new Font("Segoe UI", 12),
+ BackColor = Color.Transparent,
+ FlatStyle = FlatStyle.Flat,
+ ForeColor = Color.FromArgb(107, 114, 128),
+ Cursor = Cursors.Hand
+ };
+ btnDatabaseSettings.FlatAppearance.BorderSize = 0;
+ btnDatabaseSettings.Click += BtnDatabaseSettings_Click;
+
+ // Add controls
+ panelMain.Controls.AddRange(new Control[]
+ {
+ pictureBoxLogo, lblTitle, lblUsername, txtUsername,
+ lblPassword, txtPassword, chkRememberCredentials,
+ btnLogin, lblStatus, progressBar
+ });
+
+ this.Controls.Add(panelMain);
+ this.Controls.Add(btnDatabaseSettings);
+
+ // Set tab order
+ txtUsername.TabIndex = 0;
+ txtPassword.TabIndex = 1;
+ chkRememberCredentials.TabIndex = 2;
+ btnLogin.TabIndex = 3;
+
+ // Set default button
+ this.AcceptButton = btnLogin;
+ }
+
+ private async void BtnLogin_Click(object sender, EventArgs e)
+ {
+ if (string.IsNullOrWhiteSpace(txtUsername.Text) || string.IsNullOrWhiteSpace(txtPassword.Text))
+ {
+ ShowStatus("Inserire nome utente e password.", Color.Red);
+ return;
+ }
+
+ SetControlsEnabled(false);
+ ShowStatus("Connessione al database...", Color.Blue);
+ progressBar.Visible = true;
+
+ try
+ {
+ // Test database connection
+ if (!await database.TestConnectionAsync())
+ {
+ ShowStatus("Errore di connessione al database. Verificare le impostazioni.", Color.Red);
+ return;
+ }
+
+ ShowStatus("Verifica struttura database...", Color.Blue);
+
+ // Ensure database schema
+ await database.EnsureDatabaseSchemaAsync();
+
+ ShowStatus("Autenticazione utente...", Color.Blue);
+
+ // Authenticate user
+ bool loginSuccess = await database.AuthenticateUserAsync(txtUsername.Text, txtPassword.Text);
+
+ if (loginSuccess)
+ {
+ // Save credentials if requested
+ if (chkRememberCredentials.Checked)
+ {
+ SaveCredentials();
+ }
+
+ // Log successful login
+ await database.LogEventAsync("Login", "Accesso effettuato con successo", Manager.LogType.INFO, txtUsername.Text);
+
+ ShowStatus("Login effettuato con successo!", Color.Green);
+
+ // Store current user
+ UserSession.CurrentUser = txtUsername.Text;
+
+ await Task.Delay(500); // Brief delay for user feedback
+ this.DialogResult = DialogResult.OK;
+ }
+ else
+ {
+ ShowStatus("Credenziali non valide.", Color.Red);
+ await database.LogEventAsync("Login", "Tentativo di accesso fallito", Manager.LogType.ERROR, txtUsername.Text);
+ }
+ }
+ catch (Exception ex)
+ {
+ ShowStatus($"Errore durante il login: {ex.Message}", Color.Red);
+ await database.LogEventAsync("Login", $"Errore durante il login: {ex.Message}", Manager.LogType.ERROR, txtUsername.Text);
+ }
+ finally
+ {
+ SetControlsEnabled(true);
+ progressBar.Visible = false;
+ }
+ }
+
+ private void BtnDatabaseSettings_Click(object sender, EventArgs e)
+ {
+ using (var settingsForm = new DatabaseSettingsForm())
+ {
+ settingsForm.ShowDialog();
+ }
+ }
+
+ private void SetControlsEnabled(bool enabled)
+ {
+ txtUsername.Enabled = enabled;
+ txtPassword.Enabled = enabled;
+ chkRememberCredentials.Enabled = enabled;
+ btnLogin.Enabled = enabled;
+ btnDatabaseSettings.Enabled = enabled;
+ }
+
+ private void ShowStatus(string message, Color color)
+ {
+ lblStatus.Text = message;
+ lblStatus.ForeColor = color;
+ }
+
+ private void LoadRememberedCredentials()
+ {
+ try
+ {
+ var credentials = CredentialManager.LoadCredentials();
+ if (credentials != null)
+ {
+ txtUsername.Text = credentials.Username;
+ txtPassword.Text = credentials.Password;
+ chkRememberCredentials.Checked = true;
+ }
+ }
+ catch
+ {
+ // Ignore errors loading credentials
+ }
+ }
+
+ private void SaveCredentials()
+ {
+ try
+ {
+ CredentialManager.SaveCredentials(txtUsername.Text, txtPassword.Text);
+ }
+ catch
+ {
+ // Ignore errors saving credentials
+ }
+ }
+ }
+
+ // Simple user session class
+ public static class UserSession
+ {
+ public static string CurrentUser { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/BSHash/BSHash/Forms/MainForm.cs b/BSHash/BSHash/Forms/MainForm.cs
new file mode 100644
index 0000000..3c19769
--- /dev/null
+++ b/BSHash/BSHash/Forms/MainForm.cs
@@ -0,0 +1,483 @@
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+using BSHash.Manager;
+
+namespace BSHash
+{
+ public partial class MainForm : Form
+ {
+ private Panel sidebarPanel;
+ private Panel contentPanel;
+ private Panel headerPanel;
+ private Label titleLabel;
+ private Button selectedNavButton;
+
+ // Navigation buttons
+ private Button btnHome;
+ private Button btnPaths;
+ private Button btnScanStatus;
+ private Button btnHistory;
+ private Button btnSettings;
+ private Button btnLog;
+ private Button btnLogout;
+
+ // Content panels
+ private Panel homePanel;
+ private Panel pathsPanel;
+ private Panel scanStatusPanel;
+ private Panel historyPanel;
+ private Panel settingsPanel;
+ private Panel logPanel;
+
+ private FileScanner fileScanner;
+ private Database database;
+ private ApiManager apiManager;
+
+ public MainForm()
+ {
+ InitializeComponent();
+ InitializeManagers();
+ ShowHomePanel();
+ }
+
+ private void InitializeComponent()
+ {
+ this.Size = new Size(1200, 800);
+ this.Text = "HashKeeper Pro";
+ this.StartPosition = FormStartPosition.CenterScreen;
+ this.WindowState = FormWindowState.Maximized;
+ this.BackColor = Color.FromArgb(248, 249, 250);
+
+ CreateSidebar();
+ CreateHeader();
+ CreateContentArea();
+ CreateContentPanels();
+ }
+
+ private void CreateSidebar()
+ {
+ sidebarPanel = new Panel
+ {
+ Dock = DockStyle.Left,
+ Width = 250,
+ BackColor = Color.FromArgb(31, 41, 55),
+ Padding = new Padding(0, 20, 0, 20)
+ };
+
+ // Logo area
+ var logoPanel = new Panel
+ {
+ Height = 80,
+ Dock = DockStyle.Top,
+ BackColor = Color.Transparent
+ };
+
+ var logoLabel = new Label
+ {
+ Text = "HashKeeper Pro",
+ Font = new Font("Segoe UI", 16, FontStyle.Bold),
+ ForeColor = Color.White,
+ TextAlign = ContentAlignment.MiddleCenter,
+ Dock = DockStyle.Fill
+ };
+
+ logoPanel.Controls.Add(logoLabel);
+ sidebarPanel.Controls.Add(logoPanel);
+
+ // Navigation buttons
+ CreateNavigationButtons();
+
+ this.Controls.Add(sidebarPanel);
+ }
+
+ private void CreateNavigationButtons()
+ {
+ var navPanel = new Panel
+ {
+ Dock = DockStyle.Fill,
+ BackColor = Color.Transparent,
+ Padding = new Padding(10, 20, 10, 10)
+ };
+
+ // Home
+ btnHome = CreateNavButton("?? Home", 0);
+ btnHome.Click += (s, e) => ShowHomePanel();
+
+ // Paths
+ btnPaths = CreateNavButton("?? Percorsi", 1);
+ btnPaths.Click += (s, e) => ShowPathsPanel();
+
+ // Scan Status
+ btnScanStatus = CreateNavButton("?? Stato Scansioni", 2);
+ btnScanStatus.Click += (s, e) => ShowScanStatusPanel();
+
+ // History
+ btnHistory = CreateNavButton("?? Cronologia", 3);
+ btnHistory.Click += (s, e) => ShowHistoryPanel();
+
+ // Settings
+ btnSettings = CreateNavButton("?? Impostazioni", 4);
+ btnSettings.Click += (s, e) => ShowSettingsPanel();
+
+ // Log
+ btnLog = CreateNavButton("?? Log", 5);
+ btnLog.Click += (s, e) => ShowLogPanel();
+
+ // Logout (at bottom)
+ btnLogout = CreateNavButton("?? Logout", 10);
+ btnLogout.Click += BtnLogout_Click;
+ btnLogout.Dock = DockStyle.Bottom;
+
+ navPanel.Controls.AddRange(new Control[] { btnHome, btnPaths, btnScanStatus, btnHistory, btnSettings, btnLog });
+ sidebarPanel.Controls.Add(navPanel);
+ sidebarPanel.Controls.Add(btnLogout);
+ }
+
+ private Button CreateNavButton(string text, int index)
+ {
+ var button = new Button
+ {
+ Text = text,
+ Height = 50,
+ Dock = DockStyle.Top,
+ FlatStyle = FlatStyle.Flat,
+ BackColor = Color.Transparent,
+ ForeColor = Color.FromArgb(209, 213, 219),
+ Font = new Font("Segoe UI", 10),
+ TextAlign = ContentAlignment.MiddleLeft,
+ Padding = new Padding(20, 0, 0, 0),
+ Margin = new Padding(0, 2, 0, 2),
+ Cursor = Cursors.Hand
+ };
+
+ button.FlatAppearance.BorderSize = 0;
+ button.FlatAppearance.MouseOverBackColor = Color.FromArgb(55, 65, 81);
+
+ return button;
+ }
+
+ private void CreateHeader()
+ {
+ headerPanel = new Panel
+ {
+ Dock = DockStyle.Top,
+ Height = 60,
+ BackColor = Color.White,
+ Padding = new Padding(20, 0, 20, 0)
+ };
+
+ titleLabel = new Label
+ {
+ Font = new Font("Segoe UI", 18, FontStyle.Bold),
+ ForeColor = Color.FromArgb(31, 41, 55),
+ BackColor = Color.Transparent,
+ Dock = DockStyle.Left,
+ AutoSize = true,
+ TextAlign = ContentAlignment.MiddleLeft
+ };
+
+ var userLabel = new Label
+ {
+ Text = $"Benvenuto, {UserSession.CurrentUser}",
+ Font = new Font("Segoe UI", 10),
+ ForeColor = Color.FromArgb(107, 114, 128),
+ Dock = DockStyle.Right,
+ AutoSize = true,
+ TextAlign = ContentAlignment.MiddleRight
+ };
+
+ headerPanel.Controls.Add(titleLabel);
+ headerPanel.Controls.Add(userLabel);
+ this.Controls.Add(headerPanel);
+ }
+
+ private void CreateContentArea()
+ {
+ contentPanel = new Panel
+ {
+ Dock = DockStyle.Fill,
+ BackColor = Color.FromArgb(248, 249, 250),
+ Padding = new Padding(20)
+ };
+
+ this.Controls.Add(contentPanel);
+ }
+
+ private void CreateContentPanels()
+ {
+ // Create all content panels but hide them initially
+ homePanel = CreateHomePanel();
+ pathsPanel = CreatePathsPanel();
+ scanStatusPanel = CreateScanStatusPanel();
+ historyPanel = CreateHistoryPanel();
+ settingsPanel = CreateSettingsPanel();
+ logPanel = CreateLogPanel();
+
+ contentPanel.Controls.AddRange(new Control[]
+ {
+ homePanel, pathsPanel, scanStatusPanel,
+ historyPanel, settingsPanel, logPanel
+ });
+
+ // Hide all panels initially
+ foreach (Control panel in contentPanel.Controls)
+ panel.Visible = false;
+ }
+
+ private Panel CreateHomePanel()
+ {
+ var panel = new Panel { Dock = DockStyle.Fill };
+
+ // Dashboard cards
+ var statsPanel = new FlowLayoutPanel
+ {
+ Dock = DockStyle.Top,
+ Height = 120,
+ FlowDirection = FlowDirection.LeftToRight,
+ WrapContents = false,
+ Padding = new Padding(0, 0, 0, 20)
+ };
+
+ // Total Hashes card
+ var totalHashesCard = CreateDashboardCard("Hash Totali", "0", Color.FromArgb(59, 130, 246));
+ var newHashesCard = CreateDashboardCard("Nuovi Hash", "0", Color.FromArgb(34, 197, 94));
+ var sentHashesCard = CreateDashboardCard("Hash Inviati", "0", Color.FromArgb(168, 85, 247));
+ var confirmedHashesCard = CreateDashboardCard("Hash Confermati", "0", Color.FromArgb(245, 158, 11));
+
+ statsPanel.Controls.AddRange(new Control[] { totalHashesCard, newHashesCard, sentHashesCard, confirmedHashesCard });
+
+ // Recent activity
+ var activityPanel = new Panel
+ {
+ Dock = DockStyle.Fill,
+ BackColor = Color.White,
+ Padding = new Padding(20)
+ };
+
+ var activityLabel = new Label
+ {
+ Text = "Attività Recente",
+ Font = new Font("Segoe UI", 14, FontStyle.Bold),
+ Dock = DockStyle.Top,
+ Height = 30
+ };
+
+ var activityList = new ListBox
+ {
+ Dock = DockStyle.Fill,
+ Font = new Font("Segoe UI", 10),
+ BorderStyle = BorderStyle.None
+ };
+
+ activityPanel.Controls.Add(activityLabel);
+ activityPanel.Controls.Add(activityList);
+
+ panel.Controls.Add(statsPanel);
+ panel.Controls.Add(activityPanel);
+
+ return panel;
+ }
+
+ private Panel CreateDashboardCard(string title, string value, Color color)
+ {
+ var card = new Panel
+ {
+ Size = new Size(200, 100),
+ BackColor = Color.White,
+ Margin = new Padding(0, 0, 20, 0)
+ };
+
+ var colorBar = new Panel
+ {
+ Height = 4,
+ Dock = DockStyle.Top,
+ BackColor = color
+ };
+
+ var titleLabel = new Label
+ {
+ Text = title,
+ Font = new Font("Segoe UI", 10),
+ ForeColor = Color.FromArgb(107, 114, 128),
+ Location = new Point(15, 15),
+ AutoSize = true
+ };
+
+ var valueLabel = new Label
+ {
+ Text = value,
+ Font = new Font("Segoe UI", 24, FontStyle.Bold),
+ ForeColor = Color.FromArgb(31, 41, 55),
+ Location = new Point(15, 40),
+ AutoSize = true
+ };
+
+ card.Controls.Add(colorBar);
+ card.Controls.Add(titleLabel);
+ card.Controls.Add(valueLabel);
+
+ return card;
+ }
+
+ private Panel CreatePathsPanel()
+ {
+ var panel = new Panel { Dock = DockStyle.Fill };
+
+ var label = new Label
+ {
+ Text = "Gestione Percorsi - In sviluppo",
+ Font = new Font("Segoe UI", 16),
+ Dock = DockStyle.Fill,
+ TextAlign = ContentAlignment.MiddleCenter
+ };
+
+ panel.Controls.Add(label);
+ return panel;
+ }
+
+ private Panel CreateScanStatusPanel()
+ {
+ var panel = new Panel { Dock = DockStyle.Fill };
+
+ var label = new Label
+ {
+ Text = "Stato Scansioni - In sviluppo",
+ Font = new Font("Segoe UI", 16),
+ Dock = DockStyle.Fill,
+ TextAlign = ContentAlignment.MiddleCenter
+ };
+
+ panel.Controls.Add(label);
+ return panel;
+ }
+
+ private Panel CreateHistoryPanel()
+ {
+ var panel = new Panel { Dock = DockStyle.Fill };
+
+ var label = new Label
+ {
+ Text = "Cronologia - In sviluppo",
+ Font = new Font("Segoe UI", 16),
+ Dock = DockStyle.Fill,
+ TextAlign = ContentAlignment.MiddleCenter
+ };
+
+ panel.Controls.Add(label);
+ return panel;
+ }
+
+ private Panel CreateSettingsPanel()
+ {
+ var panel = new Panel { Dock = DockStyle.Fill };
+
+ var label = new Label
+ {
+ Text = "Impostazioni - In sviluppo",
+ Font = new Font("Segoe UI", 16),
+ Dock = DockStyle.Fill,
+ TextAlign = ContentAlignment.MiddleCenter
+ };
+
+ panel.Controls.Add(label);
+ return panel;
+ }
+
+ private Panel CreateLogPanel()
+ {
+ var panel = new Panel { Dock = DockStyle.Fill };
+
+ var label = new Label
+ {
+ Text = "Log - In sviluppo",
+ Font = new Font("Segoe UI", 16),
+ Dock = DockStyle.Fill,
+ TextAlign = ContentAlignment.MiddleCenter
+ };
+
+ panel.Controls.Add(label);
+ return panel;
+ }
+
+ private void ShowPanel(Panel panelToShow, Button navButton, string title)
+ {
+ // Hide all panels
+ foreach (Control panel in contentPanel.Controls)
+ panel.Visible = false;
+
+ // Show selected panel
+ panelToShow.Visible = true;
+
+ // Update navigation button appearance
+ if (selectedNavButton != null)
+ {
+ selectedNavButton.BackColor = Color.Transparent;
+ selectedNavButton.ForeColor = Color.FromArgb(209, 213, 219);
+ }
+
+ selectedNavButton = navButton;
+ navButton.BackColor = Color.FromArgb(59, 130, 246);
+ navButton.ForeColor = Color.White;
+
+ // Update title
+ titleLabel.Text = title;
+ }
+
+ private void ShowHomePanel()
+ {
+ ShowPanel(homePanel, btnHome, "Dashboard");
+ }
+
+ private void ShowPathsPanel()
+ {
+ ShowPanel(pathsPanel, btnPaths, "Gestione Percorsi");
+ }
+
+ private void ShowScanStatusPanel()
+ {
+ ShowPanel(scanStatusPanel, btnScanStatus, "Stato Scansioni");
+ }
+
+ private void ShowHistoryPanel()
+ {
+ ShowPanel(historyPanel, btnHistory, "Cronologia");
+ }
+
+ private void ShowSettingsPanel()
+ {
+ ShowPanel(settingsPanel, btnSettings, "Impostazioni");
+ }
+
+ private void ShowLogPanel()
+ {
+ ShowPanel(logPanel, btnLog, "Log Sistema");
+ }
+
+ private void BtnLogout_Click(object sender, EventArgs e)
+ {
+ var result = MessageBox.Show("Sei sicuro di voler uscire?", "Conferma Logout",
+ MessageBoxButtons.YesNo, MessageBoxIcon.Question);
+
+ if (result == DialogResult.Yes)
+ {
+ UserSession.CurrentUser = null;
+ this.Close();
+ }
+ }
+
+ private void InitializeManagers()
+ {
+ database = new Database();
+ fileScanner = new FileScanner(database);
+ apiManager = new ApiManager(database);
+ }
+
+ protected override void OnFormClosing(FormClosingEventArgs e)
+ {
+ // Stop any running operations
+ fileScanner?.StopAllScans();
+ base.OnFormClosing(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/BSHash/BSHash/Logger.cs b/BSHash/BSHash/Logger.cs
deleted file mode 100644
index ea23d30..0000000
--- a/BSHash/BSHash/Logger.cs
+++ /dev/null
@@ -1,138 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows.Forms;
-using static System.Windows.Forms.VisualStyles.VisualStyleElement;
-
-namespace BSHash
-{
- public enum LogType
- {
- INFO,
- DEBUG,
- WARN,
- ERROR,
- FATAL,
- TEST
- }
-
- public enum LogStatus
- {
- ATTESA,
- PREPARAZIONE,
- ELABORAZIONE,
- FERMATA,
- COMPLETATO,
- ERRORE
- }
-
- public class Logger
- {
- private Database databaseHelper;
- private System.Windows.Forms.TextBox logTextBox;
-
- public Logger(System.Windows.Forms.TextBox logTextBox, Database databaseHelper)
- {
- this.logTextBox = logTextBox;
- this.databaseHelper = databaseHelper;
- }
-
- public void Log(string message, LogType type = LogType.INFO)
- {
- databaseHelper.InsertLog(message, type);
- }
-
- public void LogEsecuzioneExecute(LogStatus stato, long spazioscansionato, long scansionati, int errori, int warning)
- {
- StringBuilder log = new StringBuilder();
-
- log.Append("Stato procedura: " + LogStatusToString(stato) + Environment.NewLine);
- log.Append("Totale spazio scansionato: " + ConvertBytesToReadableSize(spazioscansionato) + Environment.NewLine);
- log.Append("Totale file scansionati: " + scansionati + Environment.NewLine);
- log.Append("Errori: " + errori + Environment.NewLine);
- log.Append("Warning: " + warning + Environment.NewLine);
-
- SetLogTextBox(log.ToString());
- }
-
- public void LogDispositivoFill(LogStatus stato, int creati, int salvati, long spaziototale, long spazioriempito, int errori, int warning)
- {
- StringBuilder log = new StringBuilder();
-
- log.Append("Stato procedura: " + LogStatusToString(stato) + Environment.NewLine);
- log.Append("Spazio totale da riempire: " + ConvertBytesToReadableSize(spaziototale) + Environment.NewLine);
- log.Append("Spazio occupato: " + ConvertBytesToReadableSize(spazioriempito) + Environment.NewLine);
- log.Append("Totale file generati: " + creati + Environment.NewLine);
- log.Append("Files salvati: " + salvati + Environment.NewLine);
- log.Append("Errori: " + errori + Environment.NewLine);
- log.Append("Warning: " + warning + Environment.NewLine);
-
- SetLogTextBox(log.ToString());
- }
-
- public void LogDispositivoCheck(LogStatus stato, int totale, int elaborati, int inseriti, int presenti, int errori, int warning)
- {
- StringBuilder log = new StringBuilder();
-
- log.Append("Stato procedura: " + LogStatusToString(stato) + Environment.NewLine);
- log.Append("Totale da scansionare: " + totale + Environment.NewLine);
- log.Append("Files scansionati: " + elaborati + Environment.NewLine);
- log.Append("Files aggiornati: " + presenti + Environment.NewLine);
- log.Append("Files inseriti: " + inseriti + Environment.NewLine);
- log.Append("Errori: " + errori + Environment.NewLine);
- log.Append("Warning: " + warning + Environment.NewLine);
-
- SetLogTextBox(log.ToString());
- }
-
- public string LogStatusToString(LogStatus status)
- {
- switch (status)
- {
- case LogStatus.ATTESA:
- return "In attesa di avvio";
- case LogStatus.PREPARAZIONE:
- return "Preparazione per l'elaborazione...";
- case LogStatus.ELABORAZIONE:
- return "In elaborazione...";
- case LogStatus.FERMATA:
- return "Stoppata dall'utente";
- case LogStatus.COMPLETATO:
- return "Completato";
- case LogStatus.ERRORE:
- return "Errore";
- default:
- return "In attesa di avvio";
- }
- }
-
- public void SetLogTextBox(string log)
- {
- if (logTextBox.InvokeRequired)
- {
- logTextBox.Invoke(new Action(() => logTextBox.Text = log + Environment.NewLine));
- }
- else
- {
- logTextBox.Text = log + Environment.NewLine;
- }
- }
-
- public static string ConvertBytesToReadableSize(long bytes)
- {
- string[] sizes = { "B", "KB", "MB", "GB", "TB" };
- double len = bytes;
- int order = 0;
-
- while (len >= 1024 && order < sizes.Length - 1)
- {
- order++;
- len = len / 1024;
- }
-
- return $"{len:0.##} {sizes[order]}";
- }
- }
-}
diff --git a/BSHash/BSHash/Main.Designer.cs b/BSHash/BSHash/Main.Designer.cs
deleted file mode 100644
index 95a9d0a..0000000
--- a/BSHash/BSHash/Main.Designer.cs
+++ /dev/null
@@ -1,507 +0,0 @@
-using System.Windows.Forms;
-
-namespace BSHash
-{
- partial class Main
- {
- private System.ComponentModel.IContainer components = null;
-
- protected override void Dispose(bool disposing)
- {
- if (disposing && (components != null))
- {
- components.Dispose();
- }
-
- base.Dispose(disposing);
- }
-
- private System.Windows.Forms.DataGridView dataGridViewLogRows;
- private System.Windows.Forms.Label labelImpostazioniPassword;
- private System.Windows.Forms.Label labelImpostazioniUser;
- private System.Windows.Forms.TextBox textBoxImpostazioniPassword;
- private System.Windows.Forms.TextBox textBoxImpostazioniUser;
- private System.Windows.Forms.Label labelImpostazioniServer;
- private System.Windows.Forms.TextBox textBoxImpostazioniServer;
- private ToolTip toolTipCheck;
- private System.Windows.Forms.Button buttonDispositivoSfoglia;
- private System.Windows.Forms.Label labelDispositivoPath;
- private System.Windows.Forms.TextBox textBoxDispositivoPath;
- private System.Windows.Forms.ProgressBar progressBarDispositivo;
- private System.Windows.Forms.Button buttonDispositivoStop;
- private System.Windows.Forms.TextBox textBoxDispositivoLog;
- private System.Windows.Forms.TextBox textBoxImpostazioniDatabase;
- private System.Windows.Forms.Label labelImpostazioniDatabase;
- private System.Windows.Forms.Button buttonImpostazioniSalva;
- private System.Windows.Forms.Button buttonExecuteStop;
- private System.Windows.Forms.Label labelImpostazioniPath;
- private System.Windows.Forms.TextBox textBoxImpostazioniPath;
- private System.Windows.Forms.Button buttonImpostazioniBrowse;
- private System.Windows.Forms.Label labelLogQuery;
- private System.Windows.Forms.TextBox textBoxLogQuery;
- private System.Windows.Forms.Button buttonLogQuery;
- private System.Windows.Forms.Label labelLogRecordNumber;
- private System.Windows.Forms.Label labelLogRecord;
- private System.Windows.Forms.Button buttonDispositivoStart;
- private System.Windows.Forms.RadioButton radioButtonDispositivoClear;
- private System.Windows.Forms.RadioButton radioButtonDispositivoCheck;
- private System.Windows.Forms.RadioButton radioButtonDispositivoFill;
- private System.Windows.Forms.GroupBox groupBoxDispositivoChoice;
-
- private void InitializeComponent()
- {
- this.components = new System.ComponentModel.Container();
- System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Main));
- this.tabHash = new System.Windows.Forms.TabControl();
- this.tabPageExecute = new System.Windows.Forms.TabPage();
- this.buttonExecuteStop = new System.Windows.Forms.Button();
- this.buttonExecuteStart = new System.Windows.Forms.Button();
- this.textBoxExecuteLog = new System.Windows.Forms.TextBox();
- this.tabPageDispositivo = new System.Windows.Forms.TabPage();
- this.groupBoxDispositivoChoice = new System.Windows.Forms.GroupBox();
- this.radioButtonDispositivoClear = new System.Windows.Forms.RadioButton();
- this.radioButtonDispositivoCheck = new System.Windows.Forms.RadioButton();
- this.radioButtonDispositivoFill = new System.Windows.Forms.RadioButton();
- this.buttonDispositivoStart = new System.Windows.Forms.Button();
- this.textBoxDispositivoLog = new System.Windows.Forms.TextBox();
- this.progressBarDispositivo = new System.Windows.Forms.ProgressBar();
- this.buttonDispositivoStop = new System.Windows.Forms.Button();
- this.buttonDispositivoSfoglia = new System.Windows.Forms.Button();
- this.labelDispositivoPath = new System.Windows.Forms.Label();
- this.textBoxDispositivoPath = new System.Windows.Forms.TextBox();
- this.tabPageLog = new System.Windows.Forms.TabPage();
- this.labelLogRecordNumber = new System.Windows.Forms.Label();
- this.labelLogRecord = new System.Windows.Forms.Label();
- this.labelLogQuery = new System.Windows.Forms.Label();
- this.textBoxLogQuery = new System.Windows.Forms.TextBox();
- this.buttonLogQuery = new System.Windows.Forms.Button();
- this.dataGridViewLogRows = new System.Windows.Forms.DataGridView();
- this.tabPageImpostazioni = new System.Windows.Forms.TabPage();
- this.buttonImpostazioniBrowse = new System.Windows.Forms.Button();
- this.labelImpostazioniPath = new System.Windows.Forms.Label();
- this.textBoxImpostazioniPath = new System.Windows.Forms.TextBox();
- this.buttonImpostazioniSalva = new System.Windows.Forms.Button();
- this.textBoxImpostazioniDatabase = new System.Windows.Forms.TextBox();
- this.labelImpostazioniDatabase = new System.Windows.Forms.Label();
- this.labelImpostazioniPassword = new System.Windows.Forms.Label();
- this.labelImpostazioniUser = new System.Windows.Forms.Label();
- this.textBoxImpostazioniPassword = new System.Windows.Forms.TextBox();
- this.textBoxImpostazioniUser = new System.Windows.Forms.TextBox();
- this.labelImpostazioniServer = new System.Windows.Forms.Label();
- this.textBoxImpostazioniServer = new System.Windows.Forms.TextBox();
- this.toolTipCheck = new System.Windows.Forms.ToolTip(this.components);
- this.tabHash.SuspendLayout();
- this.tabPageExecute.SuspendLayout();
- this.tabPageDispositivo.SuspendLayout();
- this.groupBoxDispositivoChoice.SuspendLayout();
- this.tabPageLog.SuspendLayout();
- ((System.ComponentModel.ISupportInitialize)(this.dataGridViewLogRows)).BeginInit();
- this.tabPageImpostazioni.SuspendLayout();
- this.SuspendLayout();
- //
- // tabHash
- //
- this.tabHash.Alignment = System.Windows.Forms.TabAlignment.Left;
- this.tabHash.Controls.Add(this.tabPageExecute);
- this.tabHash.Controls.Add(this.tabPageDispositivo);
- this.tabHash.Controls.Add(this.tabPageLog);
- this.tabHash.Controls.Add(this.tabPageImpostazioni);
- this.tabHash.Location = new System.Drawing.Point(12, 12);
- this.tabHash.Multiline = true;
- this.tabHash.Name = "tabHash";
- this.tabHash.SelectedIndex = 0;
- this.tabHash.Size = new System.Drawing.Size(675, 300);
- this.tabHash.TabIndex = 0;
- //
- // tabPageExecute
- //
- this.tabPageExecute.Controls.Add(this.buttonExecuteStop);
- this.tabPageExecute.Controls.Add(this.buttonExecuteStart);
- this.tabPageExecute.Controls.Add(this.textBoxExecuteLog);
- this.tabPageExecute.Location = new System.Drawing.Point(23, 4);
- this.tabPageExecute.Name = "tabPageExecute";
- this.tabPageExecute.Padding = new System.Windows.Forms.Padding(3);
- this.tabPageExecute.Size = new System.Drawing.Size(648, 292);
- this.tabPageExecute.TabIndex = 0;
- this.tabPageExecute.Text = "Esecuzione";
- this.tabPageExecute.UseVisualStyleBackColor = true;
- //
- // buttonExecuteStop
- //
- this.buttonExecuteStop.Enabled = false;
- this.buttonExecuteStop.Location = new System.Drawing.Point(313, 6);
- this.buttonExecuteStop.Name = "buttonExecuteStop";
- this.buttonExecuteStop.Size = new System.Drawing.Size(327, 23);
- this.buttonExecuteStop.TabIndex = 8;
- this.buttonExecuteStop.Text = "Stop";
- //
- // buttonExecuteStart
- //
- this.buttonExecuteStart.Location = new System.Drawing.Point(9, 6);
- this.buttonExecuteStart.Name = "buttonExecuteStart";
- this.buttonExecuteStart.Size = new System.Drawing.Size(298, 23);
- this.buttonExecuteStart.TabIndex = 4;
- this.buttonExecuteStart.Text = "Avvia";
- this.buttonExecuteStart.Click += new System.EventHandler(this.StartButton_Click);
- //
- // textBoxExecuteLog
- //
- this.textBoxExecuteLog.BackColor = System.Drawing.SystemColors.MenuText;
- this.textBoxExecuteLog.ForeColor = System.Drawing.SystemColors.Menu;
- this.textBoxExecuteLog.Location = new System.Drawing.Point(9, 35);
- this.textBoxExecuteLog.Multiline = true;
- this.textBoxExecuteLog.Name = "textBoxExecuteLog";
- this.textBoxExecuteLog.ScrollBars = System.Windows.Forms.ScrollBars.Horizontal;
- this.textBoxExecuteLog.Size = new System.Drawing.Size(631, 251);
- this.textBoxExecuteLog.TabIndex = 7;
- //
- // tabPageDispositivo
- //
- this.tabPageDispositivo.Controls.Add(this.groupBoxDispositivoChoice);
- this.tabPageDispositivo.Controls.Add(this.buttonDispositivoStart);
- this.tabPageDispositivo.Controls.Add(this.textBoxDispositivoLog);
- this.tabPageDispositivo.Controls.Add(this.progressBarDispositivo);
- this.tabPageDispositivo.Controls.Add(this.buttonDispositivoStop);
- this.tabPageDispositivo.Controls.Add(this.buttonDispositivoSfoglia);
- this.tabPageDispositivo.Controls.Add(this.labelDispositivoPath);
- this.tabPageDispositivo.Controls.Add(this.textBoxDispositivoPath);
- this.tabPageDispositivo.Location = new System.Drawing.Point(23, 4);
- this.tabPageDispositivo.Name = "tabPageDispositivo";
- this.tabPageDispositivo.Padding = new System.Windows.Forms.Padding(3);
- this.tabPageDispositivo.Size = new System.Drawing.Size(648, 292);
- this.tabPageDispositivo.TabIndex = 1;
- this.tabPageDispositivo.Text = "Dispositivo";
- this.tabPageDispositivo.UseVisualStyleBackColor = true;
- //
- // groupBoxDispositivoChoice
- //
- this.groupBoxDispositivoChoice.Controls.Add(this.radioButtonDispositivoClear);
- this.groupBoxDispositivoChoice.Controls.Add(this.radioButtonDispositivoCheck);
- this.groupBoxDispositivoChoice.Controls.Add(this.radioButtonDispositivoFill);
- this.groupBoxDispositivoChoice.Location = new System.Drawing.Point(9, 32);
- this.groupBoxDispositivoChoice.Name = "groupBoxDispositivoChoice";
- this.groupBoxDispositivoChoice.Size = new System.Drawing.Size(160, 82);
- this.groupBoxDispositivoChoice.TabIndex = 14;
- this.groupBoxDispositivoChoice.TabStop = false;
- this.groupBoxDispositivoChoice.Text = "Funzionalità ";
- //
- // radioButtonDispositivoClear
- //
- this.radioButtonDispositivoClear.AutoSize = true;
- this.radioButtonDispositivoClear.Location = new System.Drawing.Point(6, 59);
- this.radioButtonDispositivoClear.Name = "radioButtonDispositivoClear";
- this.radioButtonDispositivoClear.Size = new System.Drawing.Size(55, 17);
- this.radioButtonDispositivoClear.TabIndex = 12;
- this.radioButtonDispositivoClear.Text = "Pulisci";
- this.radioButtonDispositivoClear.UseVisualStyleBackColor = true;
- //
- // radioButtonDispositivoCheck
- //
- this.radioButtonDispositivoCheck.AutoSize = true;
- this.radioButtonDispositivoCheck.Checked = true;
- this.radioButtonDispositivoCheck.Location = new System.Drawing.Point(6, 39);
- this.radioButtonDispositivoCheck.Name = "radioButtonDispositivoCheck";
- this.radioButtonDispositivoCheck.Size = new System.Drawing.Size(66, 17);
- this.radioButtonDispositivoCheck.TabIndex = 11;
- this.radioButtonDispositivoCheck.TabStop = true;
- this.radioButtonDispositivoCheck.Text = "Controlla";
- this.toolTipCheck.SetToolTip(this.radioButtonDispositivoCheck, resources.GetString("radioButtonDispositivoCheck.ToolTip"));
- this.radioButtonDispositivoCheck.UseVisualStyleBackColor = true;
- //
- // radioButtonDispositivoFill
- //
- this.radioButtonDispositivoFill.AutoSize = true;
- this.radioButtonDispositivoFill.Location = new System.Drawing.Point(6, 19);
- this.radioButtonDispositivoFill.Name = "radioButtonDispositivoFill";
- this.radioButtonDispositivoFill.Size = new System.Drawing.Size(57, 17);
- this.radioButtonDispositivoFill.TabIndex = 10;
- this.radioButtonDispositivoFill.Text = "Riempi";
- this.radioButtonDispositivoFill.UseVisualStyleBackColor = true;
- //
- // buttonDispositivoStart
- //
- this.buttonDispositivoStart.Location = new System.Drawing.Point(175, 33);
- this.buttonDispositivoStart.Name = "buttonDispositivoStart";
- this.buttonDispositivoStart.Size = new System.Drawing.Size(467, 23);
- this.buttonDispositivoStart.TabIndex = 13;
- this.buttonDispositivoStart.Text = "Avvia";
- this.buttonDispositivoStart.UseVisualStyleBackColor = true;
- this.buttonDispositivoStart.Click += new System.EventHandler(this.buttonDispositivoStart_ClickAsync);
- //
- // textBoxDispositivoLog
- //
- this.textBoxDispositivoLog.BackColor = System.Drawing.SystemColors.MenuText;
- this.textBoxDispositivoLog.ForeColor = System.Drawing.SystemColors.Menu;
- this.textBoxDispositivoLog.Location = new System.Drawing.Point(9, 120);
- this.textBoxDispositivoLog.Multiline = true;
- this.textBoxDispositivoLog.Name = "textBoxDispositivoLog";
- this.textBoxDispositivoLog.ScrollBars = System.Windows.Forms.ScrollBars.Horizontal;
- this.textBoxDispositivoLog.Size = new System.Drawing.Size(633, 166);
- this.textBoxDispositivoLog.TabIndex = 8;
- //
- // progressBarDispositivo
- //
- this.progressBarDispositivo.Location = new System.Drawing.Point(175, 91);
- this.progressBarDispositivo.Name = "progressBarDispositivo";
- this.progressBarDispositivo.Size = new System.Drawing.Size(467, 23);
- this.progressBarDispositivo.TabIndex = 6;
- //
- // buttonDispositivoStop
- //
- this.buttonDispositivoStop.Enabled = false;
- this.buttonDispositivoStop.Location = new System.Drawing.Point(175, 62);
- this.buttonDispositivoStop.Name = "buttonDispositivoStop";
- this.buttonDispositivoStop.Size = new System.Drawing.Size(467, 23);
- this.buttonDispositivoStop.TabIndex = 5;
- this.buttonDispositivoStop.Text = "Stop";
- this.buttonDispositivoStop.UseVisualStyleBackColor = true;
- this.buttonDispositivoStop.Click += new System.EventHandler(this.buttonDispositivoStop_Click);
- //
- // buttonDispositivoSfoglia
- //
- this.buttonDispositivoSfoglia.Location = new System.Drawing.Point(567, 4);
- this.buttonDispositivoSfoglia.Name = "buttonDispositivoSfoglia";
- this.buttonDispositivoSfoglia.Size = new System.Drawing.Size(75, 23);
- this.buttonDispositivoSfoglia.TabIndex = 2;
- this.buttonDispositivoSfoglia.Text = "Sfoglia";
- this.buttonDispositivoSfoglia.UseVisualStyleBackColor = true;
- this.buttonDispositivoSfoglia.Click += new System.EventHandler(this.buttonDispositivoSfoglia_Click);
- //
- // labelDispositivoPath
- //
- this.labelDispositivoPath.AutoSize = true;
- this.labelDispositivoPath.Location = new System.Drawing.Point(6, 9);
- this.labelDispositivoPath.Name = "labelDispositivoPath";
- this.labelDispositivoPath.Size = new System.Drawing.Size(49, 13);
- this.labelDispositivoPath.TabIndex = 1;
- this.labelDispositivoPath.Text = "Percorso";
- //
- // textBoxDispositivoPath
- //
- this.textBoxDispositivoPath.Location = new System.Drawing.Point(61, 6);
- this.textBoxDispositivoPath.Name = "textBoxDispositivoPath";
- this.textBoxDispositivoPath.ReadOnly = true;
- this.textBoxDispositivoPath.Size = new System.Drawing.Size(500, 20);
- this.textBoxDispositivoPath.TabIndex = 0;
- //
- // tabPageLog
- //
- this.tabPageLog.Controls.Add(this.labelLogRecordNumber);
- this.tabPageLog.Controls.Add(this.labelLogRecord);
- this.tabPageLog.Controls.Add(this.labelLogQuery);
- this.tabPageLog.Controls.Add(this.textBoxLogQuery);
- this.tabPageLog.Controls.Add(this.buttonLogQuery);
- this.tabPageLog.Controls.Add(this.dataGridViewLogRows);
- this.tabPageLog.ImeMode = System.Windows.Forms.ImeMode.NoControl;
- this.tabPageLog.Location = new System.Drawing.Point(23, 4);
- this.tabPageLog.Name = "tabPageLog";
- this.tabPageLog.Padding = new System.Windows.Forms.Padding(3);
- this.tabPageLog.Size = new System.Drawing.Size(648, 292);
- this.tabPageLog.TabIndex = 1;
- this.tabPageLog.Text = "Log";
- this.tabPageLog.UseVisualStyleBackColor = true;
- //
- // labelLogRecordNumber
- //
- this.labelLogRecordNumber.AutoSize = true;
- this.labelLogRecordNumber.Location = new System.Drawing.Point(88, 276);
- this.labelLogRecordNumber.Name = "labelLogRecordNumber";
- this.labelLogRecordNumber.Size = new System.Drawing.Size(13, 13);
- this.labelLogRecordNumber.TabIndex = 9;
- this.labelLogRecordNumber.Text = "0";
- //
- // labelLogRecord
- //
- this.labelLogRecord.AutoSize = true;
- this.labelLogRecord.Location = new System.Drawing.Point(6, 276);
- this.labelLogRecord.Name = "labelLogRecord";
- this.labelLogRecord.Size = new System.Drawing.Size(76, 13);
- this.labelLogRecord.TabIndex = 8;
- this.labelLogRecord.Text = "Record estratti";
- //
- // labelLogQuery
- //
- this.labelLogQuery.AutoSize = true;
- this.labelLogQuery.Location = new System.Drawing.Point(6, 13);
- this.labelLogQuery.Name = "labelLogQuery";
- this.labelLogQuery.Size = new System.Drawing.Size(35, 13);
- this.labelLogQuery.TabIndex = 7;
- this.labelLogQuery.Text = "Query";
- //
- // textBoxLogQuery
- //
- this.textBoxLogQuery.Enabled = false;
- this.textBoxLogQuery.Location = new System.Drawing.Point(47, 10);
- this.textBoxLogQuery.Name = "textBoxLogQuery";
- this.textBoxLogQuery.ReadOnly = true;
- this.textBoxLogQuery.Size = new System.Drawing.Size(500, 20);
- this.textBoxLogQuery.TabIndex = 6;
- this.textBoxLogQuery.Text = "SELECT Date, Type, Message FROM Log ORDER BY Date DESC";
- //
- // buttonLogQuery
- //
- this.buttonLogQuery.Location = new System.Drawing.Point(553, 8);
- this.buttonLogQuery.Name = "buttonLogQuery";
- this.buttonLogQuery.Size = new System.Drawing.Size(89, 23);
- this.buttonLogQuery.TabIndex = 5;
- this.buttonLogQuery.Text = "Esegui";
- this.buttonLogQuery.UseVisualStyleBackColor = true;
- this.buttonLogQuery.Click += new System.EventHandler(this.buttonLogQuery_Click);
- //
- // dataGridViewLogRows
- //
- this.dataGridViewLogRows.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
- this.dataGridViewLogRows.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
- this.dataGridViewLogRows.Location = new System.Drawing.Point(6, 37);
- this.dataGridViewLogRows.Name = "dataGridViewLogRows";
- this.dataGridViewLogRows.ReadOnly = true;
- this.dataGridViewLogRows.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
- this.dataGridViewLogRows.Size = new System.Drawing.Size(636, 236);
- this.dataGridViewLogRows.TabIndex = 0;
- //
- // tabPageImpostazioni
- //
- this.tabPageImpostazioni.Controls.Add(this.buttonImpostazioniBrowse);
- this.tabPageImpostazioni.Controls.Add(this.labelImpostazioniPath);
- this.tabPageImpostazioni.Controls.Add(this.textBoxImpostazioniPath);
- this.tabPageImpostazioni.Controls.Add(this.buttonImpostazioniSalva);
- this.tabPageImpostazioni.Controls.Add(this.textBoxImpostazioniDatabase);
- this.tabPageImpostazioni.Controls.Add(this.labelImpostazioniDatabase);
- this.tabPageImpostazioni.Controls.Add(this.labelImpostazioniPassword);
- this.tabPageImpostazioni.Controls.Add(this.labelImpostazioniUser);
- this.tabPageImpostazioni.Controls.Add(this.textBoxImpostazioniPassword);
- this.tabPageImpostazioni.Controls.Add(this.textBoxImpostazioniUser);
- this.tabPageImpostazioni.Controls.Add(this.labelImpostazioniServer);
- this.tabPageImpostazioni.Controls.Add(this.textBoxImpostazioniServer);
- this.tabPageImpostazioni.Location = new System.Drawing.Point(23, 4);
- this.tabPageImpostazioni.Name = "tabPageImpostazioni";
- this.tabPageImpostazioni.Padding = new System.Windows.Forms.Padding(3);
- this.tabPageImpostazioni.Size = new System.Drawing.Size(648, 292);
- this.tabPageImpostazioni.TabIndex = 1;
- this.tabPageImpostazioni.Text = "Impostazioni";
- this.tabPageImpostazioni.UseVisualStyleBackColor = true;
- //
- // buttonImpostazioniBrowse
- //
- this.buttonImpostazioniBrowse.Location = new System.Drawing.Point(567, 109);
- this.buttonImpostazioniBrowse.Name = "buttonImpostazioniBrowse";
- this.buttonImpostazioniBrowse.Size = new System.Drawing.Size(75, 23);
- this.buttonImpostazioniBrowse.TabIndex = 11;
- this.buttonImpostazioniBrowse.Text = "Sfoglia";
- this.buttonImpostazioniBrowse.UseVisualStyleBackColor = true;
- this.buttonImpostazioniBrowse.Click += new System.EventHandler(this.buttonImpostazioniBrowse_Click);
- //
- // labelImpostazioniPath
- //
- this.labelImpostazioniPath.AutoSize = true;
- this.labelImpostazioniPath.Location = new System.Drawing.Point(6, 114);
- this.labelImpostazioniPath.Name = "labelImpostazioniPath";
- this.labelImpostazioniPath.Size = new System.Drawing.Size(49, 13);
- this.labelImpostazioniPath.TabIndex = 10;
- this.labelImpostazioniPath.Text = "Percorso";
- //
- // textBoxImpostazioniPath
- //
- this.textBoxImpostazioniPath.Location = new System.Drawing.Point(70, 111);
- this.textBoxImpostazioniPath.Name = "textBoxImpostazioniPath";
- this.textBoxImpostazioniPath.Size = new System.Drawing.Size(491, 20);
- this.textBoxImpostazioniPath.TabIndex = 9;
- //
- // buttonImpostazioniSalva
- //
- this.buttonImpostazioniSalva.Location = new System.Drawing.Point(567, 137);
- this.buttonImpostazioniSalva.Name = "buttonImpostazioniSalva";
- this.buttonImpostazioniSalva.Size = new System.Drawing.Size(75, 23);
- this.buttonImpostazioniSalva.TabIndex = 8;
- this.buttonImpostazioniSalva.Text = "Salva";
- this.buttonImpostazioniSalva.UseVisualStyleBackColor = true;
- this.buttonImpostazioniSalva.Click += new System.EventHandler(this.buttonImpostazioniSalva_Click);
- //
- // textBoxImpostazioniDatabase
- //
- this.textBoxImpostazioniDatabase.Location = new System.Drawing.Point(70, 85);
- this.textBoxImpostazioniDatabase.Name = "textBoxImpostazioniDatabase";
- this.textBoxImpostazioniDatabase.Size = new System.Drawing.Size(572, 20);
- this.textBoxImpostazioniDatabase.TabIndex = 7;
- //
- // labelImpostazioniDatabase
- //
- this.labelImpostazioniDatabase.AutoSize = true;
- this.labelImpostazioniDatabase.Location = new System.Drawing.Point(6, 88);
- this.labelImpostazioniDatabase.Name = "labelImpostazioniDatabase";
- this.labelImpostazioniDatabase.Size = new System.Drawing.Size(53, 13);
- this.labelImpostazioniDatabase.TabIndex = 6;
- this.labelImpostazioniDatabase.Text = "Database";
- //
- // labelImpostazioniPassword
- //
- this.labelImpostazioniPassword.AutoSize = true;
- this.labelImpostazioniPassword.Location = new System.Drawing.Point(6, 62);
- this.labelImpostazioniPassword.Name = "labelImpostazioniPassword";
- this.labelImpostazioniPassword.Size = new System.Drawing.Size(53, 13);
- this.labelImpostazioniPassword.TabIndex = 5;
- this.labelImpostazioniPassword.Text = "Password";
- //
- // labelImpostazioniUser
- //
- this.labelImpostazioniUser.AutoSize = true;
- this.labelImpostazioniUser.Location = new System.Drawing.Point(6, 36);
- this.labelImpostazioniUser.Name = "labelImpostazioniUser";
- this.labelImpostazioniUser.Size = new System.Drawing.Size(39, 13);
- this.labelImpostazioniUser.TabIndex = 4;
- this.labelImpostazioniUser.Text = "Utente";
- //
- // textBoxImpostazioniPassword
- //
- this.textBoxImpostazioniPassword.Location = new System.Drawing.Point(70, 59);
- this.textBoxImpostazioniPassword.Name = "textBoxImpostazioniPassword";
- this.textBoxImpostazioniPassword.Size = new System.Drawing.Size(572, 20);
- this.textBoxImpostazioniPassword.TabIndex = 3;
- //
- // textBoxImpostazioniUser
- //
- this.textBoxImpostazioniUser.Location = new System.Drawing.Point(70, 33);
- this.textBoxImpostazioniUser.Name = "textBoxImpostazioniUser";
- this.textBoxImpostazioniUser.Size = new System.Drawing.Size(572, 20);
- this.textBoxImpostazioniUser.TabIndex = 2;
- //
- // labelImpostazioniServer
- //
- this.labelImpostazioniServer.AutoSize = true;
- this.labelImpostazioniServer.Location = new System.Drawing.Point(6, 10);
- this.labelImpostazioniServer.Name = "labelImpostazioniServer";
- this.labelImpostazioniServer.Size = new System.Drawing.Size(38, 13);
- this.labelImpostazioniServer.TabIndex = 1;
- this.labelImpostazioniServer.Text = "Server";
- //
- // textBoxImpostazioniServer
- //
- this.textBoxImpostazioniServer.Location = new System.Drawing.Point(70, 7);
- this.textBoxImpostazioniServer.Name = "textBoxImpostazioniServer";
- this.textBoxImpostazioniServer.Size = new System.Drawing.Size(572, 20);
- this.textBoxImpostazioniServer.TabIndex = 0;
- //
- // Main
- //
- this.ClientSize = new System.Drawing.Size(698, 323);
- this.Controls.Add(this.tabHash);
- this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
- this.MaximizeBox = false;
- this.Name = "Main";
- this.Text = "BS Hash Management";
- this.tabHash.ResumeLayout(false);
- this.tabPageExecute.ResumeLayout(false);
- this.tabPageExecute.PerformLayout();
- this.tabPageDispositivo.ResumeLayout(false);
- this.tabPageDispositivo.PerformLayout();
- this.groupBoxDispositivoChoice.ResumeLayout(false);
- this.groupBoxDispositivoChoice.PerformLayout();
- this.tabPageLog.ResumeLayout(false);
- this.tabPageLog.PerformLayout();
- ((System.ComponentModel.ISupportInitialize)(this.dataGridViewLogRows)).EndInit();
- this.tabPageImpostazioni.ResumeLayout(false);
- this.tabPageImpostazioni.PerformLayout();
- this.ResumeLayout(false);
- }
- }
-}
diff --git a/BSHash/BSHash/Main.cs b/BSHash/BSHash/Main.cs
deleted file mode 100644
index 795a298..0000000
--- a/BSHash/BSHash/Main.cs
+++ /dev/null
@@ -1,330 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Data;
-using System.Data.SqlClient;
-using System.Drawing;
-using System.IO;
-using System.Linq;
-using System.Security.Cryptography;
-using System.Security.Policy;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Windows.Forms;
-
-namespace BSHash
-{
- public partial class Main : Form
- {
- //Grafica
- public Button buttonExecuteStart;
- public TextBox textBoxExecuteLog;
- public Database databaseHelper;
- public Calculator fileHashCalculator;
- public Storage storage;
- public TabControl tabHash;
- public TabPage tabPageExecute;
- public TabPage tabPageLog;
- public TabPage tabPageDispositivo;
- public TabPage tabPageImpostazioni;
- public Logger logger;
- public Logger loggerDispositivo;
-
- //cancellazione
- private CancellationTokenSource _cancellationTokenSource;
- // Nella classe Main.cs
-
-
- public Main()
- {
- InitializeComponent();
- LoadSettings();
-
- textBoxDispositivoPath.Text = Properties.Settings.Default.Path;
-
- databaseHelper = new Database();
- logger = new Logger(textBoxExecuteLog, databaseHelper);
- loggerDispositivo = new Logger(textBoxDispositivoLog, databaseHelper);
- fileHashCalculator = new Calculator(logger);
- storage = new Storage(loggerDispositivo);
- tabHash.SelectedIndexChanged += new EventHandler(tabControl_SelectedIndexChanged);
- }
-
- private async void StartButton_Click(object sender, EventArgs e)
- {
- // Inizializza il CancellationTokenSource
- _cancellationTokenSource = new CancellationTokenSource();
- CancellationToken cancellationToken = _cancellationTokenSource.Token;
-
- // Disabilita i controlli durante l'esecuzione
- buttonExecuteStart.Enabled = false;
- buttonExecuteStop.Enabled = true;
-
- long spazioscansionato = 0;
- long scansionati = 0;
- int errori = 0;
- int warning = 0;
-
- logger.LogEsecuzioneExecute(LogStatus.PREPARAZIONE, spazioscansionato, scansionati, errori, warning);
- logger.Log("Inizio procedura principale.", LogType.INFO);
-
- // Esegui il calcolo degli hash e l'inserimento nel database in un thread separato
- await Task.Run(async () =>
- {
- while (!cancellationToken.IsCancellationRequested)
- {
- logger.Log("Scansione database... ", LogType.INFO);
-
- DataTable hashes = databaseHelper.GetHashes();
-
- int totalFiles = hashes.Rows.Count;
- int processedFiles = 0;
-
- logger.Log("Trovati " + totalFiles.ToString() + " da scansionare.", LogType.INFO);
-
- foreach (DataRow row in hashes.Rows)
- {
- if (cancellationToken.IsCancellationRequested)
- {
- logger.Log("Procedura interrotta dall'utente.", LogType.WARN);
- break;
- }
-
- string filePath = row["Path"].ToString();
- string hash = row["Hash"].ToString();
-
- processedFiles++;
- scansionati++;
-
- logger.Log("Scansione file " + processedFiles.ToString() + " / " + totalFiles.ToString() + ". Percorso: " + filePath, LogType.INFO);
-
- if (!File.Exists(filePath))
- {
- logger.Log("Il file " + filePath + " non esiste.", LogType.ERROR);
- continue;
- }
-
- FileInfo fileInfo = new FileInfo(filePath);
- spazioscansionato += fileInfo.Length;
-
- logger.Log("Calcolo hash per il file " + filePath + ".", LogType.INFO);
-
- string calculatedHash = fileHashCalculator.CalculateHash(filePath);
-
- if (calculatedHash == null)
- {
- logger.Log("Non è stato possibile calcolare l'hash del file " + filePath, LogType.ERROR);
- continue;
- }
-
- if (calculatedHash != hash)
- {
- logger.Log("L'hash calcolato dal file (" + calculatedHash + ") è diverso da quell inserito nel database (" + hash + ")", LogType.ERROR);
- continue;
- }
-
- Network network = new Network(logger);
-
- var sendDataHashTask = network.SendDataHash(calculatedHash);
- if (await sendDataHashTask != Network.OK)
- {
- logger.Log("Errore nell'invio dell'hash " + calculatedHash, LogType.INFO);
- continue;
- }
-
- var getDataHashTask = network.GetDataHash(calculatedHash);
- if (await getDataHashTask != Network.OK)
- {
- logger.Log("Errore nella ricezione della risposta dell'hash " + calculatedHash, LogType.INFO);
- continue;
- }
-
- databaseHelper.InsertHistory(calculatedHash);
- logger.LogEsecuzioneExecute(LogStatus.ELABORAZIONE, spazioscansionato, scansionati, errori, warning);
- }
-
- logger.Log("Calcolati correttamente " + processedFiles.ToString() + " su " + totalFiles.ToString() + ".", LogType.INFO);
- }
- }, cancellationToken);
-
- logger.LogEsecuzioneExecute(LogStatus.FERMATA, spazioscansionato, scansionati, errori, warning);
- logger.Log("Procedura terminata.", LogType.INFO);
-
- // Riabilita i controlli dopo l'esecuzione
- buttonExecuteStart.Enabled = true;
- buttonExecuteStop.Enabled = false;
- }
-
- private void tabControl_SelectedIndexChanged(object sender, EventArgs e)
- {
- if (tabHash.SelectedTab == tabPageLog)
- {
- //LoadLogs();
- }
- }
-
- private void LoadLogs()
- {
- DataTable logs = databaseHelper.GetLogs(textBoxLogQuery.Text);
- dataGridViewLogRows.DataSource = logs;
- labelLogRecordNumber.Text = dataGridViewLogRows.RowCount.ToString();
- }
-
- private void buttonDispositivoSfoglia_Click(object sender, EventArgs e)
- {
- using (FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog())
- {
- if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
- {
- textBoxDispositivoPath.Text = folderBrowserDialog.SelectedPath;
- }
- }
- }
-
- private void LoadSettings()
- {
- textBoxImpostazioniServer.Text = Properties.Settings.Default.Server;
- textBoxImpostazioniUser.Text = Properties.Settings.Default.User;
- textBoxImpostazioniPassword.Text = Properties.Settings.Default.Password;
- textBoxImpostazioniDatabase.Text = Properties.Settings.Default.Database;
- textBoxImpostazioniPath.Text = Properties.Settings.Default.Path;
- }
-
- private void SaveSettings()
- {
- Properties.Settings.Default.Server = textBoxImpostazioniServer.Text;
- Properties.Settings.Default.User = textBoxImpostazioniUser.Text;
- Properties.Settings.Default.Password = textBoxImpostazioniPassword.Text;
- Properties.Settings.Default.Database = textBoxImpostazioniDatabase.Text;
- Properties.Settings.Default.Path = textBoxImpostazioniPath.Text;
- Properties.Settings.Default.Save();
- }
-
- protected override void OnFormClosing(FormClosingEventArgs e)
- {
- SaveSettings();
- base.OnFormClosing(e);
- }
-
- private void buttonImpostazioniSalva_Click(object sender, EventArgs e)
- {
- SaveSettings();
- }
-
- private void SetControlEnabled(bool enabled)
- {
- if (InvokeRequired)
- {
- Invoke(new Action(SetControlEnabled), enabled);
- }
- else
- {
- buttonDispositivoStart.Enabled = enabled;
- buttonDispositivoStop.Enabled = !enabled;
- }
- }
-
- private void buttonImpostazioniBrowse_Click(object sender, EventArgs e)
- {
- using (FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog())
- {
- if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
- {
- textBoxImpostazioniPath.Text = folderBrowserDialog.SelectedPath;
- }
- }
- }
-
- private void buttonLogQuery_Click(object sender, EventArgs e)
- {
- LoadLogs();
- }
-
- private async void buttonDispositivoStart_ClickAsync(object sender, EventArgs e)
- {
- if (radioButtonDispositivoCheck.Checked)
- {
- // Controlla se il percorso esiste
- if (!Directory.Exists(textBoxDispositivoPath.Text))
- {
- loggerDispositivo.Log("Errore: Il percorso specificato non esiste.", LogType.FATAL);
- return;
- }
-
- loggerDispositivo.Log("Caricamento informazioni per esecuzione...", LogType.INFO);
-
- // Disabilita i controlli prima dell'esecuzione e abilita il pulsante Stop
- SetControlEnabled(false);
- buttonDispositivoStop.Enabled = true;
-
- // Esegui il riempimento del percorso in un thread separato
- await Task.Run(() =>
- {
- // Avvio il riempimento del dispositivo
- storage.StartCheckFiles(textBoxDispositivoPath.Text, progressBarDispositivo, buttonDispositivoStart, buttonDispositivoStop);
- });
- }
-
- if(radioButtonDispositivoFill.Checked)
- {
- // Controlla se il percorso esiste
- if (!Directory.Exists(textBoxDispositivoPath.Text))
- {
- loggerDispositivo.Log("Errore: Il percorso specificato non esiste.", LogType.FATAL);
- return;
- }
-
- loggerDispositivo.Log("Caricamento informazioni per esecuzione...", LogType.INFO);
-
- // Disabilita i controlli prima dell'esecuzione e abilita il pulsante Stop
- SetControlEnabled(false);
- buttonDispositivoStop.Enabled = true;
-
- // Esegui il riempimento del percorso in un thread separato
- await Task.Run(() =>
- {
- // Avvio il riempimento del dispositivo
- storage.StartFillStorage(textBoxDispositivoPath.Text, progressBarDispositivo, buttonDispositivoStart, buttonDispositivoStop);
- });
- }
-
- if (radioButtonDispositivoClear.Checked)
- {
- // Controlla se il percorso esiste
- if (!Directory.Exists(textBoxDispositivoPath.Text))
- {
- loggerDispositivo.Log("Errore: Il percorso specificato non esiste.", LogType.FATAL);
- return;
- }
-
- // Disabilita i controlli prima dell'esecuzione e abilita il pulsante Stop
- SetControlEnabled(false);
- buttonDispositivoStop.Enabled = true;
-
- // Esegui la pulizia del percorso in un thread separato
- await Task.Run(() =>
- {
- // Avvio la pulizia del dispositivo in un thread separato
- storage.StartClearStorage(textBoxDispositivoPath.Text, progressBarDispositivo, buttonDispositivoStart, buttonDispositivoStop);
- });
- }
- }
-
- private void buttonDispositivoStop_Click(object sender, EventArgs e)
- {
- //Fermo l'attività avviata
- storage.StopFillStorage(progressBarDispositivo, buttonDispositivoStart, buttonDispositivoStop);
- //storage.StopCheckStorage(progressBarDispositivo, buttonDispositivoStart, buttonDispositivoStop);
- storage.StopClearStorage(progressBarDispositivo, buttonDispositivoStart, buttonDispositivoStop);
-
- // Riabilita i controlli dopo l'esecuzione
- SetControlEnabled(true);
- }
- private void buttonExecuteStop_Click(object sender, EventArgs e)
- {
- // Annulla l'operazione
- _cancellationTokenSource?.Cancel();
- }
- }
-}
diff --git a/BSHash/BSHash/Manager/ApiManager.cs b/BSHash/BSHash/Manager/ApiManager.cs
new file mode 100644
index 0000000..f33ad95
--- /dev/null
+++ b/BSHash/BSHash/Manager/ApiManager.cs
@@ -0,0 +1,267 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using System.Text.Json;
+using System.Threading;
+
+namespace BSHash
+{
+ public class ApiManager
+ {
+ private readonly HttpClient _httpClient;
+ private readonly Database _database;
+ private readonly Logger _logger;
+ private readonly string _apiEndpoint;
+ private readonly string _apiKey;
+ private readonly int _batchSize;
+ private Manager.Database database;
+
+ public ApiManager(Database database, Logger logger)
+ {
+ _database = database;
+ _logger = logger;
+ _httpClient = new HttpClient();
+
+ // Load settings from database
+ _apiEndpoint = _database.GetSetting("api_endpoint_url") ?? "https://api.hashkeeper.pro/submit";
+ _apiKey = _database.GetSetting("api_key") ?? "";
+ _batchSize = int.TryParse(_database.GetSetting("batch_size"), out int size) ? size : 100;
+
+ // Configure HTTP client
+ _httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {_apiKey}");
+ _httpClient.DefaultRequestHeaders.Add("User-Agent", "HashKeeper-Pro/1.0");
+ _httpClient.Timeout = TimeSpan.FromMinutes(5);
+ }
+
+ public ApiManager(Manager.Database database)
+ {
+ this.database = database;
+ }
+
+ public async Task SubmitPendingHashesAsync(CancellationToken cancellationToken = default)
+ {
+ var result = new ApiSubmissionResult
+ {
+ StartTime = DateTime.Now
+ };
+
+ try
+ {
+ // Check if API is enabled
+ var apiEnabled = bool.TryParse(_database.GetSetting("enable_api_sending"), out bool enabled) && enabled;
+ if (!apiEnabled)
+ {
+ result.Status = "Disabled";
+ result.Message = "API submission is disabled in settings";
+ return result;
+ }
+
+ if (string.IsNullOrEmpty(_apiKey))
+ {
+ result.Status = "Error";
+ result.Message = "API key not configured";
+ return result;
+ }
+
+ _logger.Log("Avvio invio hash all'API esterna", LogType.INFO);
+
+ // Get unsent hashes in batches
+ var unsentHashes = _database.GetUnsentHashes(_batchSize);
+ result.TotalHashes = unsentHashes.Rows.Count;
+
+ if (result.TotalHashes == 0)
+ {
+ result.Status = "Completed";
+ result.Message = "No hashes to send";
+ _logger.Log("Nessun hash da inviare", LogType.INFO);
+ return result;
+ }
+
+ _logger.Log($"Trovati {result.TotalHashes} hash da inviare", LogType.INFO);
+
+ var hashBatch = new List();
+
+ foreach (DataRow row in unsentHashes.Rows)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ result.Status = "Cancelled";
+ break;
+ }
+
+ var submission = new HashSubmission
+ {
+ Hash = row.Field("current_hash"),
+ FilePath = row.Field("file_path"),
+ FirstScanned = row.Field("first_scanned_date"),
+ LastScanned = row.Field("last_scanned_date"),
+ ClientId = Environment.MachineName
+ };
+
+ hashBatch.Add(submission);
+ }
+
+ // Submit batch to API
+ var submissionSuccess = await SubmitHashBatchAsync(hashBatch);
+
+ if (submissionSuccess)
+ {
+ // Mark hashes as sent
+ foreach (var submission in hashBatch)
+ {
+ _database.MarkHashAsSent(submission.Hash);
+ result.SuccessfulSubmissions++;
+ }
+
+ result.Status = "Completed";
+ result.Message = $"Successfully submitted {result.SuccessfulSubmissions} hashes";
+ _logger.Log($"Inviati con successo {result.SuccessfulSubmissions} hash", LogType.INFO);
+ }
+ else
+ {
+ result.Status = "Error";
+ result.Message = "Failed to submit hash batch";
+ result.FailedSubmissions = hashBatch.Count;
+ _logger.Log("Errore durante l'invio del batch di hash", LogType.ERROR);
+ }
+ }
+ catch (Exception ex)
+ {
+ result.Status = "Error";
+ result.Message = ex.Message;
+ _logger.Log($"Errore durante l'invio hash: {ex.Message}", LogType.ERROR);
+ }
+ finally
+ {
+ result.EndTime = DateTime.Now;
+ }
+
+ return result;
+ }
+
+ private async Task SubmitHashBatchAsync(List hashBatch)
+ {
+ try
+ {
+ var payload = new
+ {
+ hashes = hashBatch,
+ timestamp = DateTime.UtcNow,
+ client_version = "1.0.0"
+ };
+
+ var json = JsonSerializer.Serialize(payload, new JsonSerializerOptions
+ {
+ PropertyNamingPolicy = JsonNamingPolicy.CamelCase
+ });
+
+ var content = new StringContent(json, Encoding.UTF8, "application/json");
+
+ _logger.Log($"Invio batch di {hashBatch.Count} hash a {_apiEndpoint}", LogType.DEBUG);
+
+ var response = await _httpClient.PostAsync(_apiEndpoint, content);
+
+ if (response.IsSuccessStatusCode)
+ {
+ var responseContent = await response.Content.ReadAsStringAsync();
+ _logger.Log($"Risposta API: {response.StatusCode}", LogType.DEBUG);
+ return true;
+ }
+ else
+ {
+ var errorContent = await response.Content.ReadAsStringAsync();
+ _logger.Log($"Errore API: {response.StatusCode} - {errorContent}", LogType.ERROR);
+ return false;
+ }
+ }
+ catch (HttpRequestException ex)
+ {
+ _logger.Log($"Errore di rete durante l'invio: {ex.Message}", LogType.ERROR);
+ return false;
+ }
+ catch (TaskCanceledException ex)
+ {
+ _logger.Log($"Timeout durante l'invio: {ex.Message}", LogType.ERROR);
+ return false;
+ }
+ catch (Exception ex)
+ {
+ _logger.Log($"Errore imprevisto durante l'invio: {ex.Message}", LogType.ERROR);
+ return false;
+ }
+ }
+
+ public async Task CheckApiHealthAsync()
+ {
+ var result = new ApiHealthResult
+ {
+ CheckTime = DateTime.Now
+ };
+
+ try
+ {
+ var healthEndpoint = _apiEndpoint.Replace("/submit", "/health");
+ var response = await _httpClient.GetAsync(healthEndpoint);
+
+ result.IsHealthy = response.IsSuccessStatusCode;
+ result.StatusCode = (int)response.StatusCode;
+ result.ResponseTime = response.Headers.Date?.Subtract(DateTime.UtcNow) ?? TimeSpan.Zero;
+
+ if (result.IsHealthy)
+ {
+ var content = await response.Content.ReadAsStringAsync();
+ result.Message = "API is healthy";
+ }
+ else
+ {
+ result.Message = $"API returned status code: {response.StatusCode}";
+ }
+ }
+ catch (Exception ex)
+ {
+ result.IsHealthy = false;
+ result.Message = ex.Message;
+ }
+
+ return result;
+ }
+
+ public void Dispose()
+ {
+ _httpClient?.Dispose();
+ }
+ }
+
+ public class HashSubmission
+ {
+ public string Hash { get; set; }
+ public string FilePath { get; set; }
+ public DateTime FirstScanned { get; set; }
+ public DateTime LastScanned { get; set; }
+ public string ClientId { get; set; }
+ }
+
+ public class ApiSubmissionResult
+ {
+ public DateTime StartTime { get; set; }
+ public DateTime EndTime { get; set; }
+ public int TotalHashes { get; set; }
+ public int SuccessfulSubmissions { get; set; }
+ public int FailedSubmissions { get; set; }
+ public string Status { get; set; }
+ public string Message { get; set; }
+ public TimeSpan Duration => EndTime - StartTime;
+ }
+
+ public class ApiHealthResult
+ {
+ public DateTime CheckTime { get; set; }
+ public bool IsHealthy { get; set; }
+ public int StatusCode { get; set; }
+ public TimeSpan ResponseTime { get; set; }
+ public string Message { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/BSHash/BSHash/Manager/Calculator.cs b/BSHash/BSHash/Manager/Calculator.cs
new file mode 100644
index 0000000..ca1752c
--- /dev/null
+++ b/BSHash/BSHash/Manager/Calculator.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Security.Cryptography;
+using System.Windows.Forms;
+
+namespace BSHash
+{
+ public class Calculator
+ {
+ private Logger _logger;
+
+ public Calculator(Logger logger)
+ {
+ _logger = logger;
+ }
+
+ ///
+ /// Calcola l'hash SHA512 del file specificato.
+ ///
+ public string CalculateHashSHA512(string filePath)
+ {
+ try
+ {
+ using (SHA512 sha512 = SHA512.Create())
+ {
+ using (FileStream fileStream = File.OpenRead(filePath))
+ {
+ byte[] hashBytes = sha512.ComputeHash(fileStream);
+ string hash = BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant();
+
+ _logger.Log("Hash SHA512 " + hash + " calcolato per il file " + filePath.ToString(), LogType.INFO);
+
+ return hash;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.Log("Errore nella lettura o hash SHA512 del file " + filePath.ToString() + ".\nErrore: " + ex.Message.ToString(), LogType.ERROR);
+ return null;
+ }
+ }
+
+ ///
+ /// [DEPRECATO] Calcola l'hash SHA256 del file specificato.
+ ///
+ [Obsolete("Usa CalculateHashSHA512 per il calcolo dell'hash.")]
+ public string CalculateHashSHA256(string filePath)
+ {
+ try
+ {
+ using (SHA256 sha256 = SHA256.Create())
+ {
+ using (FileStream fileStream = File.OpenRead(filePath))
+ {
+ byte[] hashBytes = sha256.ComputeHash(fileStream);
+ string hash = BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant();
+
+ _logger.Log("Hash SHA256 " + hash + " calcolato per il file " + filePath.ToString(), LogType.INFO);
+
+ return hash;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.Log("Errore nella lettura o hash SHA256 del file " + filePath.ToString() + ".\nErrore: " + ex.Message.ToString(), LogType.ERROR);
+ return null;
+ }
+ }
+ }
+}
diff --git a/BSHash/BSHash/Manager/CredentialManager.cs b/BSHash/BSHash/Manager/CredentialManager.cs
new file mode 100644
index 0000000..59ea7aa
--- /dev/null
+++ b/BSHash/BSHash/Manager/CredentialManager.cs
@@ -0,0 +1,70 @@
+using System;
+using System.Security.Cryptography;
+using System.Text;
+using System.Text.Json;
+
+namespace BSHash
+{
+ public static class CredentialManager
+ {
+ public static void SaveCredentials(string username, string password)
+ {
+ try
+ {
+ var credentials = new UserCredentials { Username = username, Password = password };
+ var json = JsonSerializer.Serialize(credentials);
+ var encrypted = ProtectData(json);
+
+ Properties.Settings.Default.SavedCredentials = encrypted;
+ Properties.Settings.Default.Save();
+ }
+ catch (Exception ex)
+ {
+ throw new Exception($"Errore nel salvataggio delle credenziali: {ex.Message}");
+ }
+ }
+
+ public static UserCredentials LoadCredentials()
+ {
+ try
+ {
+ var encrypted = Properties.Settings.Default.SavedCredentials;
+ if (string.IsNullOrEmpty(encrypted))
+ return null;
+
+ var decrypted = UnprotectData(encrypted);
+ return JsonSerializer.Deserialize(decrypted);
+ }
+ catch
+ {
+ return null;
+ }
+ }
+
+ public static void ClearCredentials()
+ {
+ Properties.Settings.Default.SavedCredentials = string.Empty;
+ Properties.Settings.Default.Save();
+ }
+
+ private static string ProtectData(string data)
+ {
+ byte[] dataBytes = Encoding.UTF8.GetBytes(data);
+ byte[] protectedBytes = ProtectedData.Protect(dataBytes, null, DataProtectionScope.CurrentUser);
+ return Convert.ToBase64String(protectedBytes);
+ }
+
+ private static string UnprotectData(string protectedData)
+ {
+ byte[] protectedBytes = Convert.FromBase64String(protectedData);
+ byte[] dataBytes = ProtectedData.Unprotect(protectedBytes, null, DataProtectionScope.CurrentUser);
+ return Encoding.UTF8.GetString(dataBytes);
+ }
+ }
+
+ public class UserCredentials
+ {
+ public string Username { get; set; }
+ public string Password { get; set; }
+ }
+}
diff --git a/BSHash/BSHash/Manager/Database.cs b/BSHash/BSHash/Manager/Database.cs
new file mode 100644
index 0000000..3853b1a
--- /dev/null
+++ b/BSHash/BSHash/Manager/Database.cs
@@ -0,0 +1,689 @@
+using System;
+using System.Data;
+using System.Data.SqlClient;
+using System.Windows.Forms;
+using System.Threading.Tasks;
+using System.IO;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace BSHash.Manager
+{
+ public enum LogType
+ {
+ DEBUG = 0,
+ INFO = 1,
+ WARNING = 2,
+ ERROR = 3,
+ FATAL = 4
+ }
+
+ public class Database
+ {
+ private const string IdColumnName = "id";
+ private string _connectionString;
+
+ public Database()
+ {
+ BuildConnectionString();
+ }
+
+ private void BuildConnectionString()
+ {
+ var builder = new SqlConnectionStringBuilder
+ {
+ DataSource = Properties.Settings.Default.DatabaseServer,
+ InitialCatalog = Properties.Settings.Default.DatabaseName,
+ UserID = Properties.Settings.Default.DatabaseUser,
+ Password = Properties.Settings.Default.DatabasePassword,
+ ConnectTimeout = 60,
+ TrustServerCertificate = true
+ };
+
+ _connectionString = builder.ConnectionString;
+ }
+
+ public async Task TestConnectionAsync(string customConnectionString = null)
+ {
+ string connectionString = customConnectionString ?? _connectionString;
+ try
+ {
+ using (var connection = new SqlConnection(connectionString))
+ {
+ await connection.OpenAsync();
+ using (var command = new SqlCommand("SELECT 1", connection))
+ {
+ await command.ExecuteScalarAsync();
+ }
+ }
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ public async Task EnsureDatabaseSchemaAsync()
+ {
+ try
+ {
+ using (var connection = new SqlConnection(_connectionString))
+ {
+ await connection.OpenAsync();
+
+ // Create AppUsers table for authentication
+ await CreateAppUsersTableAsync(connection);
+
+ // Create core tables
+ await CreateCoreTablesAsync(connection);
+
+ // Insert default data
+ await InsertDefaultDataAsync(connection);
+ }
+ }
+ catch (Exception ex)
+ {
+ throw new Exception($"Error ensuring database schema: {ex.Message}", ex);
+ }
+ }
+
+ private async Task CreateAppUsersTableAsync(SqlConnection connection)
+ {
+ string createUsersTable = @"
+ IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='AppUsers' AND xtype='U')
+ CREATE TABLE [AppUsers] (
+ [id] INT IDENTITY(1,1) PRIMARY KEY,
+ [username] NVARCHAR(255) UNIQUE NOT NULL,
+ [password_hash] NVARCHAR(512) NOT NULL,
+ [password_salt] NVARCHAR(256) NOT NULL,
+ [created_date] DATETIME DEFAULT GETDATE(),
+ [last_login] DATETIME NULL,
+ [is_active] BIT DEFAULT 1
+ )";
+
+ using (var command = new SqlCommand(createUsersTable, connection))
+ {
+ await command.ExecuteNonQueryAsync();
+ }
+
+ // Create default admin user if none exists
+ string checkUsers = "SELECT COUNT(*) FROM AppUsers";
+ using (var command = new SqlCommand(checkUsers, connection))
+ {
+ int userCount = (int)await command.ExecuteScalarAsync();
+ if (userCount == 0)
+ {
+ await CreateUserAsync(connection, "admin", "admin123");
+ }
+ }
+ }
+
+ private async Task CreateCoreTablesAsync(SqlConnection connection)
+ {
+ // files_scanned table
+ string createFilesScanned = @"
+ IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='files_scanned' AND xtype='U')
+ CREATE TABLE [files_scanned] (
+ [id] INT IDENTITY(1,1) PRIMARY KEY,
+ [file_path] NVARCHAR(1024) UNIQUE NOT NULL,
+ [last_modified_date] DATETIME NULL,
+ [current_hash] VARCHAR(128) NOT NULL,
+ [first_scanned_date] DATETIME NOT NULL DEFAULT GETDATE(),
+ [last_scanned_date] DATETIME NOT NULL DEFAULT GETDATE(),
+ [is_sent_to_api] BIT DEFAULT 0,
+ [last_sent_date] DATETIME NULL,
+ [is_confirmed_by_api] BIT DEFAULT 0,
+ [last_confirmed_date] DATETIME NULL,
+ [is_deleted] BIT DEFAULT 0,
+ [deleted_date] DATETIME NULL,
+ [longevity_points_earned] INT DEFAULT 0
+ )";
+
+ // scan_history table
+ string createScanHistory = @"
+ IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='scan_history' AND xtype='U')
+ CREATE TABLE [scan_history] (
+ [id] INT IDENTITY(1,1) PRIMARY KEY,
+ [scan_date] DATETIME NOT NULL DEFAULT GETDATE(),
+ [end_date] DATETIME NULL,
+ [scanned_path_id] INT NULL,
+ [total_files_scanned] INT DEFAULT 0,
+ [new_files_found] INT DEFAULT 0,
+ [files_modified] INT DEFAULT 0,
+ [files_deleted] INT DEFAULT 0,
+ [hashes_sent_in_scan] INT DEFAULT 0,
+ [hashes_confirmed_in_scan] INT DEFAULT 0,
+ [status] NVARCHAR(50) DEFAULT 'In Progress'
+ )";
+
+ // configured_paths table
+ string createConfiguredPaths = @"
+ IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='configured_paths' AND xtype='U')
+ CREATE TABLE [configured_paths] (
+ [id] INT IDENTITY(1,1) PRIMARY KEY,
+ [path] NVARCHAR(MAX) NOT NULL,
+ [min_fill_limit_gb] INT DEFAULT 0,
+ [max_fill_limit_gb] INT DEFAULT 0,
+ [min_fill_limit_percent] INT DEFAULT 0,
+ [max_fill_limit_percent] INT DEFAULT 0,
+ [use_limits] BIT DEFAULT 0,
+ [is_active] BIT DEFAULT 1
+ )";
+
+ // program_settings table
+ string createProgramSettings = @"
+ IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='program_settings' AND xtype='U')
+ CREATE TABLE [program_settings] (
+ [id] INT IDENTITY(1,1) PRIMARY KEY,
+ [setting_name] NVARCHAR(255) UNIQUE NOT NULL,
+ [setting_value] NVARCHAR(MAX)
+ )";
+
+ // Enhanced log table
+ string createLog = @"
+ IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='log' AND xtype='U')
+ CREATE TABLE [log] (
+ [Entry] INT IDENTITY(1,1) PRIMARY KEY,
+ [Date] DATETIME DEFAULT GETDATE(),
+ [Message] NVARCHAR(MAX),
+ [Type] SMALLINT,
+ [username] NVARCHAR(255) NULL,
+ [related_path_id] INT NULL,
+ [event_category] NVARCHAR(50) NULL,
+ [details_json] NVARCHAR(MAX) NULL
+ )";
+
+ using (var command = new SqlCommand(createFilesScanned, connection))
+ await command.ExecuteNonQueryAsync();
+ using (var command = new SqlCommand(createScanHistory, connection))
+ await command.ExecuteNonQueryAsync();
+ using (var command = new SqlCommand(createConfiguredPaths, connection))
+ await command.ExecuteNonQueryAsync();
+ using (var command = new SqlCommand(createProgramSettings, connection))
+ await command.ExecuteNonQueryAsync();
+ using (var command = new SqlCommand(createLog, connection))
+ await command.ExecuteNonQueryAsync();
+ }
+
+ private async Task InsertDefaultDataAsync(SqlConnection connection)
+ {
+ // Default settings
+ var defaultSettings = new[]
+ {
+ ("scan_interval_minutes", "60"),
+ ("hash_algorithm", "SHA-256"),
+ ("api_endpoint_url", "https://api.hashkeeper.com/v1/hashes"),
+ ("api_key", ""),
+ ("enable_api_sending", "false"),
+ ("batch_size", "100"),
+ ("min_file_size_mb", "1"),
+ ("max_file_size_mb", "10"),
+ ("application_name", "HashKeeper Pro"),
+ ("enable_dark_mode", "false"),
+ ("auto_save_settings", "true")
+ };
+
+ foreach (var (name, value) in defaultSettings)
+ {
+ string checkSetting = "SELECT COUNT(*) FROM program_settings WHERE setting_name = @name";
+ using (var checkCommand = new SqlCommand(checkSetting, connection))
+ {
+ checkCommand.Parameters.AddWithValue("@name", name);
+ int count = (int)await checkCommand.ExecuteScalarAsync();
+
+ if (count == 0)
+ {
+ string insertSetting = "INSERT INTO program_settings (setting_name, setting_value) VALUES (@name, @value)";
+ using (var insertCommand = new SqlCommand(insertSetting, connection))
+ {
+ insertCommand.Parameters.AddWithValue("@name", name);
+ insertCommand.Parameters.AddWithValue("@value", value);
+ await insertCommand.ExecuteNonQueryAsync();
+ }
+ }
+ }
+ }
+ }
+
+ private async Task CreateUserAsync(SqlConnection connection, string username, string password)
+ {
+ var salt = GenerateSalt();
+ var hash = HashPassword(password, salt);
+
+ string insertUser = @"
+ INSERT INTO AppUsers (username, password_hash, password_salt)
+ VALUES (@username, @hash, @salt)";
+
+ using (var command = new SqlCommand(insertUser, connection))
+ {
+ command.Parameters.AddWithValue("@username", username);
+ command.Parameters.AddWithValue("@hash", hash);
+ command.Parameters.AddWithValue("@salt", salt);
+ await command.ExecuteNonQueryAsync();
+ }
+ }
+
+ public async Task AuthenticateUserAsync(string username, string password)
+ {
+ try
+ {
+ using (var connection = new SqlConnection(_connectionString))
+ {
+ await connection.OpenAsync();
+
+ string query = @"
+ SELECT password_hash, password_salt
+ FROM AppUsers
+ WHERE username = @username AND is_active = 1";
+
+ using (var command = new SqlCommand(query, connection))
+ {
+ command.Parameters.AddWithValue("@username", username);
+ using (var reader = await command.ExecuteReaderAsync())
+ {
+ if (await reader.ReadAsync())
+ {
+ string storedHash = reader["password_hash"].ToString();
+ string salt = reader["password_salt"].ToString();
+
+ string computedHash = HashPassword(password, salt);
+
+ if (storedHash == computedHash)
+ {
+ // Update last login
+ reader.Close();
+ string updateLogin = "UPDATE AppUsers SET last_login = GETDATE() WHERE username = @username";
+ using (var updateCommand = new SqlCommand(updateLogin, connection))
+ {
+ updateCommand.Parameters.AddWithValue("@username", username);
+ await updateCommand.ExecuteNonQueryAsync();
+ }
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ public async Task LogEventAsync(string eventCategory, string message, LogType logType, string username = null, int? relatedPathId = null, string detailsJson = null)
+ {
+ try
+ {
+ using (var connection = new SqlConnection(_connectionString))
+ {
+ await connection.OpenAsync();
+
+ string query = @"
+ INSERT INTO log (Message, Type, username, related_path_id, event_category, details_json)
+ VALUES (@message, @type, @username, @pathId, @category, @details)";
+
+ using (var command = new SqlCommand(query, connection))
+ {
+ command.Parameters.AddWithValue("@message", message);
+ command.Parameters.AddWithValue("@type", (int)logType);
+ command.Parameters.AddWithValue("@username", (object)username ?? DBNull.Value);
+ command.Parameters.AddWithValue("@pathId", (object)relatedPathId ?? DBNull.Value);
+ command.Parameters.AddWithValue("@category", (object)eventCategory ?? DBNull.Value);
+ command.Parameters.AddWithValue("@details", (object)detailsJson ?? DBNull.Value);
+
+ await command.ExecuteNonQueryAsync();
+ }
+ }
+ }
+ catch
+ {
+ // Silent fail for logging to prevent recursive errors
+ }
+ }
+
+ private string GenerateSalt()
+ {
+ byte[] saltBytes = new byte[32];
+ using (var rng = RandomNumberGenerator.Create())
+ {
+ rng.GetBytes(saltBytes);
+ }
+ return Convert.ToBase64String(saltBytes);
+ }
+
+ private string HashPassword(string password, string salt)
+ {
+ using (var pbkdf2 = new Rfc2898DeriveBytes(password, Convert.FromBase64String(salt), 10000))
+ {
+ byte[] hash = pbkdf2.GetBytes(64);
+ return Convert.ToBase64String(hash);
+ }
+ }
+
+ // New HashKeeper Pro methods
+ public async Task> GetUnsentHashesAsync(int batchSize = 100)
+ {
+ var files = new List();
+
+ using (var connection = new SqlConnection(_connectionString))
+ {
+ await connection.OpenAsync();
+
+ string query = @"
+ SELECT TOP (@batchSize) id, file_path, current_hash, first_scanned_date, last_scanned_date
+ FROM files_scanned
+ WHERE is_sent_to_api = 0 AND is_deleted = 0
+ ORDER BY first_scanned_date ASC";
+
+ using (var command = new SqlCommand(query, connection))
+ {
+ command.Parameters.AddWithValue("@batchSize", batchSize);
+ using (var reader = await command.ExecuteReaderAsync())
+ {
+ while (await reader.ReadAsync())
+ {
+ files.Add(new FileRecord
+ {
+ Id = reader.GetInt32(IdColumnName),
+ FilePath = reader.GetString("file_path"),
+ Hash = reader.GetString("current_hash"),
+ FirstScannedDate = reader.GetDateTime("first_scanned_date"),
+ LastScannedDate = reader.GetDateTime("last_scanned_date")
+ });
+ }
+ }
+ }
+ }
+
+ return files;
+ }
+
+ public async Task MarkHashesSentAsync(List hashes)
+ {
+ try
+ {
+ using (var connection = new SqlConnection(_connectionString))
+ {
+ await connection.OpenAsync();
+ using (var transaction = connection.BeginTransaction())
+ {
+ try
+ {
+ foreach (string hash in hashes)
+ {
+ string updateQuery = @"
+ UPDATE files_scanned
+ SET is_sent_to_api = 1, last_sent_date = GETDATE()
+ WHERE current_hash = @hash";
+
+ using (var command = new SqlCommand(updateQuery, connection, transaction))
+ {
+ command.Parameters.AddWithValue("@hash", hash);
+ await command.ExecuteNonQueryAsync();
+ }
+ }
+
+ transaction.Commit();
+ return true;
+ }
+ catch
+ {
+ transaction.Rollback();
+ return false;
+ }
+ }
+ }
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ public async Task MarkHashConfirmedAsync(string hash)
+ {
+ try
+ {
+ using (var connection = new SqlConnection(_connectionString))
+ {
+ await connection.OpenAsync();
+
+ string updateQuery = @"
+ UPDATE files_scanned
+ SET is_confirmed_by_api = 1, last_confirmed_date = GETDATE()
+ WHERE current_hash = @hash";
+
+ using (var command = new SqlCommand(updateQuery, connection))
+ {
+ command.Parameters.AddWithValue("@hash", hash);
+ await command.ExecuteNonQueryAsync();
+ }
+
+ return true;
+ }
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ public async Task GetDashboardStatsAsync()
+ {
+ var stats = new DashboardStats();
+
+ using (var connection = new SqlConnection(_connectionString))
+ {
+ await connection.OpenAsync();
+
+ // Total hashes
+ string totalQuery = "SELECT COUNT(*) FROM files_scanned WHERE is_deleted = 0";
+ using (var command = new SqlCommand(totalQuery, connection))
+ {
+ stats.TotalHashes = (int)await command.ExecuteScalarAsync();
+ }
+
+ // New hashes (last 24 hours)
+ string newQuery = @"
+ SELECT COUNT(*) FROM files_scanned
+ WHERE is_deleted = 0 AND first_scanned_date >= DATEADD(day, -1, GETDATE())";
+ using (var command = new SqlCommand(newQuery, connection))
+ {
+ stats.NewHashes = (int)await command.ExecuteScalarAsync();
+ }
+
+ // Sent hashes
+ string sentQuery = "SELECT COUNT(*) FROM files_scanned WHERE is_sent_to_api = 1 AND is_deleted = 0";
+ using (var command = new SqlCommand(sentQuery, connection))
+ {
+ stats.SentHashes = (int)await command.ExecuteScalarAsync();
+ }
+
+ // Confirmed hashes
+ string confirmedQuery = "SELECT COUNT(*) FROM files_scanned WHERE is_confirmed_by_api = 1 AND is_deleted = 0";
+ using (var command = new SqlCommand(confirmedQuery, connection))
+ {
+ stats.ConfirmedHashes = (int)await command.ExecuteScalarAsync();
+ }
+ }
+
+ return stats;
+ }
+
+ // Legacy compatibility methods
+ public DataTable GetHashes()
+ {
+ DataTable hashes = new DataTable();
+ using (var connection = new SqlConnection(_connectionString))
+ {
+ connection.Open();
+ string query = @"
+ SELECT file_path as Path, current_hash as Hash, last_modified_date as Updated
+ FROM files_scanned
+ WHERE is_deleted = 0";
+
+ using (var command = new SqlCommand(query, connection))
+ {
+ using (var adapter = new SqlDataAdapter(command))
+ {
+ adapter.Fill(hashes);
+ }
+ }
+ }
+ return hashes;
+ }
+
+ public bool HashExists(string hash)
+ {
+ using (var connection = new SqlConnection(_connectionString))
+ {
+ try
+ {
+ connection.Open();
+ string checkQuery = "SELECT COUNT(*) FROM files_scanned WHERE current_hash = @Hash AND is_deleted = 0";
+
+ using (var command = new SqlCommand(checkQuery, connection))
+ {
+ command.Parameters.AddWithValue("@Hash", hash.ToUpperInvariant());
+ int count = (int)command.ExecuteScalar();
+ return count > 0;
+ }
+ }
+ catch
+ {
+ return false;
+ }
+ }
+ }
+
+ public bool InsertHash(string path, string hash)
+ {
+ using (var connection = new SqlConnection(_connectionString))
+ {
+ connection.Open();
+ using (var transaction = connection.BeginTransaction())
+ {
+ try
+ {
+ DateTime lastModified = File.Exists(path) ? File.GetLastWriteTime(path) : DateTime.Now;
+
+ string insertQuery = @"
+ INSERT INTO files_scanned (file_path, current_hash, last_modified_date, first_scanned_date, last_scanned_date)
+ VALUES (@Path, @Hash, @LastModified, GETDATE(), GETDATE())";
+
+ using (var command = new SqlCommand(insertQuery, connection, transaction))
+ {
+ command.Parameters.AddWithValue("@Path", path);
+ command.Parameters.AddWithValue("@Hash", hash.ToUpperInvariant());
+ command.Parameters.AddWithValue("@LastModified", lastModified);
+ command.ExecuteNonQuery();
+ }
+ transaction.Commit();
+ return true;
+ }
+ catch
+ {
+ transaction.Rollback();
+ return false;
+ }
+ }
+ }
+ }
+
+ public bool UpdateHash(string path, string hash)
+ {
+ using (var connection = new SqlConnection(_connectionString))
+ {
+ connection.Open();
+ using (var transaction = connection.BeginTransaction())
+ {
+ try
+ {
+ DateTime lastModified = File.Exists(path) ? File.GetLastWriteTime(path) : DateTime.Now;
+
+ string updateQuery = @"
+ UPDATE files_scanned
+ SET file_path = @Path, last_modified_date = @LastModified, last_scanned_date = GETDATE(), is_sent_to_api = 0
+ WHERE current_hash = @Hash";
+
+ using (var command = new SqlCommand(updateQuery, connection, transaction))
+ {
+ command.Parameters.AddWithValue("@Path", path);
+ command.Parameters.AddWithValue("@Hash", hash.ToUpperInvariant());
+ command.Parameters.AddWithValue("@LastModified", lastModified);
+ command.ExecuteNonQuery();
+ }
+ transaction.Commit();
+ return true;
+ }
+ catch
+ {
+ transaction.Rollback();
+ return false;
+ }
+ }
+ }
+ }
+
+ public void InsertLog(string message, LogType type = LogType.INFO)
+ {
+ try
+ {
+ using (var connection = new SqlConnection(_connectionString))
+ {
+ connection.Open();
+ string query = "INSERT INTO log (Message, Type) VALUES (@Message, @Type)";
+ using (var command = new SqlCommand(query, connection))
+ {
+ command.Parameters.AddWithValue("@Message", message);
+ command.Parameters.AddWithValue("@Type", (int)type);
+ command.ExecuteNonQuery();
+ }
+ }
+ }
+ catch
+ {
+ // Silent fail for logging
+ }
+ }
+
+ public DataTable GetLogs(string query = null)
+ {
+ DataTable logs = new DataTable();
+ using (var connection = new SqlConnection(_connectionString))
+ {
+ connection.Open();
+ string sql = string.IsNullOrEmpty(query) ? "SELECT * FROM log ORDER BY Date DESC" : query;
+ using (var command = new SqlCommand(sql, connection))
+ {
+ using (var adapter = new SqlDataAdapter(command))
+ {
+ adapter.Fill(logs);
+ }
+ }
+ }
+ return logs;
+ }
+ }
+
+ public class FileRecord
+ {
+ public int Id { get; set; }
+ public string FilePath { get; set; }
+ public string Hash { get; set; }
+ public DateTime FirstScannedDate { get; set; }
+ public DateTime LastScannedDate { get; set; }
+ }
+
+ public class DashboardStats
+ {
+ public int TotalHashes { get; set; }
+ public int NewHashes { get; set; }
+ public int SentHashes { get; set; }
+ public int ConfirmedHashes { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/BSHash/BSHash/Manager/FileScanner.cs b/BSHash/BSHash/Manager/FileScanner.cs
new file mode 100644
index 0000000..73ab849
--- /dev/null
+++ b/BSHash/BSHash/Manager/FileScanner.cs
@@ -0,0 +1,426 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Security.Cryptography;
+using System.Text;
+using BSHash.Manager;
+
+namespace BSHash.Manager
+{
+ public class FileScanner
+ {
+ private readonly Database _database;
+ private readonly List _activeScanTokens;
+ private readonly object _lockObject = new object();
+
+ public event Action ProgressUpdated;
+ public event Action StatusUpdated;
+
+ public FileScanner(Database database)
+ {
+ _database = database;
+ _activeScanTokens = new List();
+ }
+
+ public async Task ScanPathAsync(string path, IProgress progress = null, CancellationToken cancellationToken = default)
+ {
+ var result = new ScanResult
+ {
+ ScanStartTime = DateTime.Now,
+ ScannedPath = path
+ };
+
+ try
+ {
+ if (!Directory.Exists(path))
+ {
+ result.Status = ScanStatus.Failed;
+ result.ErrorMessage = $"Directory does not exist: {path}";
+ return result;
+ }
+
+ StatusUpdated?.Invoke($"Starting scan of {path}");
+ await _database.LogEventAsync("Scan", $"Starting scan of path: {path}", LogType.INFO, UserSession.CurrentUser);
+
+ // Get all files in directory recursively
+ var files = GetAllFiles(path, cancellationToken);
+ result.TotalFiles = files.Count;
+
+ StatusUpdated?.Invoke($"Found {files.Count} files to process");
+
+ for (int i = 0; i < files.Count; i++)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ result.Status = ScanStatus.Cancelled;
+ break;
+ }
+
+ string filePath = files[i];
+
+ try
+ {
+ var fileResult = await ProcessFileAsync(filePath, cancellationToken);
+
+ if (fileResult.IsNew)
+ result.NewFiles++;
+ else if (fileResult.IsModified)
+ result.ModifiedFiles++;
+
+ result.ProcessedFiles++;
+
+ // Report progress
+ var progressReport = new ScanProgress
+ {
+ TotalFiles = result.TotalFiles,
+ ProcessedFiles = result.ProcessedFiles,
+ NewFiles = result.NewFiles,
+ ModifiedFiles = result.ModifiedFiles,
+ CurrentFile = filePath,
+ PercentComplete = (double)result.ProcessedFiles / result.TotalFiles * 100
+ };
+
+ progress?.Report(progressReport);
+ ProgressUpdated?.Invoke(progressReport);
+ }
+ catch (Exception ex)
+ {
+ result.ErrorFiles++;
+ await _database.LogEventAsync("Scan", $"Error processing file {filePath}: {ex.Message}", LogType.ERROR, UserSession.CurrentUser);
+ }
+ }
+
+ // Check for deleted files
+ await CheckForDeletedFilesAsync(path, result);
+
+ result.ScanEndTime = DateTime.Now;
+ result.Status = cancellationToken.IsCancellationRequested ? ScanStatus.Cancelled : ScanStatus.Completed;
+
+ StatusUpdated?.Invoke($"Scan completed. Processed {result.ProcessedFiles} files, {result.NewFiles} new, {result.ModifiedFiles} modified, {result.DeletedFiles} deleted");
+ await _database.LogEventAsync("Scan", $"Scan completed: {result.ProcessedFiles} files processed", LogType.INFO, UserSession.CurrentUser);
+
+ return result;
+ }
+ catch (Exception ex)
+ {
+ result.Status = ScanStatus.Failed;
+ result.ErrorMessage = ex.Message;
+ result.ScanEndTime = DateTime.Now;
+
+ await _database.LogEventAsync("Scan", $"Scan failed: {ex.Message}", LogType.ERROR, UserSession.CurrentUser);
+ return result;
+ }
+ }
+
+ private List GetAllFiles(string path, CancellationToken cancellationToken)
+ {
+ var files = new List();
+ var directories = new Queue();
+ directories.Enqueue(path);
+
+ while (directories.Count > 0 && !cancellationToken.IsCancellationRequested)
+ {
+ string currentDir = directories.Dequeue();
+
+ try
+ {
+ // Add files from current directory
+ string[] dirFiles = Directory.GetFiles(currentDir);
+ foreach (string file in dirFiles)
+ {
+ if (ShouldProcessFile(file))
+ {
+ files.Add(file);
+ }
+ }
+
+ // Add subdirectories to queue
+ string[] subDirs = Directory.GetDirectories(currentDir);
+ foreach (string subDir in subDirs)
+ {
+ if (ShouldProcessDirectory(subDir))
+ {
+ directories.Enqueue(subDir);
+ }
+ }
+ }
+ catch (UnauthorizedAccessException)
+ {
+ // Skip directories we can't access
+ continue;
+ }
+ catch (DirectoryNotFoundException)
+ {
+ // Skip directories that no longer exist
+ continue;
+ }
+ }
+
+ return files;
+ }
+
+ private bool ShouldProcessFile(string filePath)
+ {
+ try
+ {
+ var fileInfo = new FileInfo(filePath);
+
+ // Skip system files and hidden files
+ if (fileInfo.Attributes.HasFlag(FileAttributes.System) ||
+ fileInfo.Attributes.HasFlag(FileAttributes.Hidden))
+ return false;
+
+ // Skip very small files (less than 1KB)
+ if (fileInfo.Length < 1024)
+ return false;
+
+ // Skip temporary files
+ string extension = fileInfo.Extension.ToLower();
+ string[] skipExtensions = { ".tmp", ".temp", ".log", ".lock" };
+ if (Array.Exists(skipExtensions, ext => ext == extension))
+ return false;
+
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ private bool ShouldProcessDirectory(string dirPath)
+ {
+ string dirName = Path.GetFileName(dirPath).ToLower();
+
+ // Skip system directories
+ string[] skipDirs = {
+ "$recycle.bin", "system volume information", "temp",
+ "tmp", "cache", ".git", ".svn", "node_modules"
+ };
+
+ return !Array.Exists(skipDirs, skipDir => skipDir == dirName);
+ }
+
+ private async Task ProcessFileAsync(string filePath, CancellationToken cancellationToken)
+ {
+ var result = new FileProcessResult { FilePath = filePath };
+
+ try
+ {
+ // Calculate hash
+ string hash = await CalculateFileHashAsync(filePath, cancellationToken);
+ result.Hash = hash;
+
+ // Check if file exists in database
+ bool exists = _database.HashExists(hash);
+
+ if (!exists)
+ {
+ // New file
+ bool inserted = _database.InsertHash(filePath, hash);
+ result.IsNew = inserted;
+ }
+ else
+ {
+ // Existing file - check if path has changed
+ bool updated = _database.UpdateHash(filePath, hash);
+ result.IsModified = updated;
+ }
+
+ return result;
+ }
+ catch (Exception ex)
+ {
+ result.HasError = true;
+ result.ErrorMessage = ex.Message;
+ return result;
+ }
+ }
+
+ private async Task CalculateFileHashAsync(string filePath, CancellationToken cancellationToken)
+ {
+ using (var sha256 = SHA256.Create())
+ {
+ using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 8192, useAsync: true))
+ {
+ byte[] buffer = new byte[8192];
+ int bytesRead;
+
+ while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) > 0)
+ {
+ sha256.TransformBlock(buffer, 0, bytesRead, null, 0);
+ }
+
+ sha256.TransformFinalBlock(new byte[0], 0, 0);
+ byte[] hash = sha256.Hash;
+
+ StringBuilder sb = new StringBuilder();
+ foreach (byte b in hash)
+ {
+ sb.Append(b.ToString("x2"));
+ }
+
+ return sb.ToString().ToUpperInvariant();
+ }
+ }
+ }
+
+ private async Task CheckForDeletedFilesAsync(string scannedPath, ScanResult result)
+ {
+ try
+ {
+ // This would require tracking which files were scanned vs what's in the database
+ // For now, we'll implement a basic version that checks if files in the database still exist
+
+ var hashes = _database.GetHashes();
+ foreach (System.Data.DataRow row in hashes.Rows)
+ {
+ string filePath = row["Path"].ToString();
+
+ // Only check files that should be in the scanned path
+ if (filePath.StartsWith(scannedPath, StringComparison.OrdinalIgnoreCase))
+ {
+ if (!File.Exists(filePath))
+ {
+ // File has been deleted
+ // We would need to implement MarkFileAsDeleted in Database class
+ result.DeletedFiles++;
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ await _database.LogEventAsync("Scan", $"Error checking for deleted files: {ex.Message}", LogType.WARNING, UserSession.CurrentUser);
+ }
+ }
+
+ public async Task StartContinuousScanAsync(List paths, TimeSpan interval, CancellationToken cancellationToken)
+ {
+ await _database.LogEventAsync("Scanner", "Started continuous scanning", LogType.INFO, UserSession.CurrentUser);
+
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ foreach (string path in paths)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ break;
+
+ try
+ {
+ StatusUpdated?.Invoke($"Scanning {path}...");
+ await ScanPathAsync(path, null, cancellationToken);
+ }
+ catch (Exception ex)
+ {
+ await _database.LogEventAsync("Scanner", $"Error in continuous scan of {path}: {ex.Message}", LogType.ERROR, UserSession.CurrentUser);
+ }
+ }
+
+ // Wait for the specified interval
+ try
+ {
+ await Task.Delay(interval, cancellationToken);
+ }
+ catch (TaskCanceledException)
+ {
+ break;
+ }
+ }
+
+ await _database.LogEventAsync("Scanner", "Stopped continuous scanning", LogType.INFO, UserSession.CurrentUser);
+ }
+
+ public void StopAllScans()
+ {
+ lock (_lockObject)
+ {
+ foreach (var tokenSource in _activeScanTokens)
+ {
+ try
+ {
+ tokenSource.Cancel();
+ }
+ catch { }
+ }
+ _activeScanTokens.Clear();
+ }
+ }
+
+ public CancellationTokenSource StartScan(string path, IProgress progress = null)
+ {
+ var tokenSource = new CancellationTokenSource();
+
+ lock (_lockObject)
+ {
+ _activeScanTokens.Add(tokenSource);
+ }
+
+ Task.Run(async () =>
+ {
+ try
+ {
+ await ScanPathAsync(path, progress, tokenSource.Token);
+ }
+ finally
+ {
+ lock (_lockObject)
+ {
+ _activeScanTokens.Remove(tokenSource);
+ }
+ }
+ });
+
+ return tokenSource;
+ }
+ }
+
+ public class ScanResult
+ {
+ public DateTime ScanStartTime { get; set; }
+ public DateTime ScanEndTime { get; set; }
+ public string ScannedPath { get; set; }
+ public ScanStatus Status { get; set; }
+ public string ErrorMessage { get; set; }
+
+ public int TotalFiles { get; set; }
+ public int ProcessedFiles { get; set; }
+ public int NewFiles { get; set; }
+ public int ModifiedFiles { get; set; }
+ public int DeletedFiles { get; set; }
+ public int ErrorFiles { get; set; }
+
+ public TimeSpan Duration => ScanEndTime - ScanStartTime;
+ }
+
+ public class ScanProgress
+ {
+ public int TotalFiles { get; set; }
+ public int ProcessedFiles { get; set; }
+ public int NewFiles { get; set; }
+ public int ModifiedFiles { get; set; }
+ public string CurrentFile { get; set; }
+ public double PercentComplete { get; set; }
+ }
+
+ public class FileProcessResult
+ {
+ public string FilePath { get; set; }
+ public string Hash { get; set; }
+ public bool IsNew { get; set; }
+ public bool IsModified { get; set; }
+ public bool HasError { get; set; }
+ public string ErrorMessage { get; set; }
+ }
+
+ public enum ScanStatus
+ {
+ NotStarted,
+ Running,
+ Completed,
+ Cancelled,
+ Failed
+ }
+}
\ No newline at end of file
diff --git a/BSHash/BSHash/Manager/Logger.cs b/BSHash/BSHash/Manager/Logger.cs
new file mode 100644
index 0000000..6875061
--- /dev/null
+++ b/BSHash/BSHash/Manager/Logger.cs
@@ -0,0 +1,379 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using System.Text.Json;
+
+namespace BSHash
+{
+ public enum LogType
+ {
+ DEBUG = 0,
+ INFO = 1,
+ WARN = 2,
+ ERROR = 3,
+ FATAL = 4,
+ TEST = 5
+ }
+
+ public enum LogStatus
+ {
+ ATTESA,
+ PREPARAZIONE,
+ ELABORAZIONE,
+ FERMATA,
+ COMPLETATO,
+ ERRORE
+ }
+
+ public enum EventCategory
+ {
+ Login,
+ Scan,
+ API,
+ FileManagement,
+ Database,
+ System
+ }
+
+ public class Logger
+ {
+ private Database databaseHelper;
+ private System.Windows.Forms.TextBox logTextBox;
+ private string currentUsername;
+ private int? currentPathId;
+
+ public Logger(System.Windows.Forms.TextBox logTextBox, Database databaseHelper)
+ {
+ this.logTextBox = logTextBox;
+ this.databaseHelper = databaseHelper;
+ }
+
+ public void SetContext(string username, int? pathId = null)
+ {
+ currentUsername = username;
+ currentPathId = pathId;
+ }
+
+ public void Log(string message, LogType type = LogType.INFO)
+ {
+ LogDetailed(message, type, EventCategory.System, null);
+ }
+
+ public void LogDetailed(string message, LogType type = LogType.INFO, EventCategory category = EventCategory.System, object details = null)
+ {
+ try
+ {
+ string detailsJson = null;
+ if (details != null)
+ {
+ try
+ {
+ detailsJson = JsonSerializer.Serialize(details);
+ }
+ catch
+ {
+ detailsJson = details.ToString();
+ }
+ }
+
+ databaseHelper.InsertLogDetailed(message, type, currentUsername, currentPathId, category.ToString(), detailsJson);
+ }
+ catch (Exception ex)
+ {
+ // Fallback to basic logging if detailed logging fails
+ try
+ {
+ databaseHelper.InsertLog(message, type);
+ }
+ catch
+ {
+ // If all logging fails, at least try to write to debug output
+ System.Diagnostics.Debug.WriteLine($"[{type}] {message}: {ex.Message}");
+ }
+ }
+ }
+
+ public void LogLogin(string username, bool success, string details = null)
+ {
+ SetContext(username);
+
+ var loginDetails = new
+ {
+ success = success,
+ timestamp = DateTime.Now,
+ details = details,
+ machine = Environment.MachineName
+ };
+
+ LogDetailed(
+ success ? $"Login riuscito per utente: {username}" : $"Login fallito per utente: {username}",
+ success ? LogType.INFO : LogType.WARN,
+ EventCategory.Login,
+ loginDetails
+ );
+ }
+
+ public void LogScanStart(string path, int pathId, int totalFiles)
+ {
+ SetContext(currentUsername, pathId);
+
+ var scanDetails = new
+ {
+ scanned_path = path,
+ total_files = totalFiles,
+ start_time = DateTime.Now
+ };
+
+ LogDetailed(
+ $"Avvio scansione percorso: {path} ({totalFiles} file da processare)",
+ LogType.INFO,
+ EventCategory.Scan,
+ scanDetails
+ );
+ }
+
+ public void LogScanComplete(string path, int totalFiles, int newFiles, int modifiedFiles, int deletedFiles)
+ {
+ var scanDetails = new
+ {
+ scanned_path = path,
+ total_files = totalFiles,
+ new_files = newFiles,
+ modified_files = modifiedFiles,
+ deleted_files = deletedFiles,
+ end_time = DateTime.Now
+ };
+
+ LogDetailed(
+ $"Scansione completata: {path} - {totalFiles} file processati, {newFiles} nuovi, {modifiedFiles} modificati, {deletedFiles} eliminati",
+ LogType.INFO,
+ EventCategory.Scan,
+ scanDetails
+ );
+ }
+
+ public void LogFileProcessed(string filePath, string hash, bool isNew, bool isModified)
+ {
+ var fileDetails = new
+ {
+ file_path = filePath,
+ hash = hash,
+ is_new = isNew,
+ is_modified = isModified,
+ timestamp = DateTime.Now
+ };
+
+ LogDetailed(
+ $"File processato: {filePath} - Hash: {hash?.Substring(0, 8)}...",
+ LogType.DEBUG,
+ EventCategory.FileManagement,
+ fileDetails
+ );
+ }
+
+ public void LogApiSubmission(int hashCount, bool success, string apiResponse = null)
+ {
+ var apiDetails = new
+ {
+ hash_count = hashCount,
+ success = success,
+ api_response = apiResponse,
+ timestamp = DateTime.Now
+ };
+
+ LogDetailed(
+ success ? $"Invio API riuscito: {hashCount} hash inviati" : $"Invio API fallito: {hashCount} hash",
+ success ? LogType.INFO : LogType.ERROR,
+ EventCategory.API,
+ apiDetails
+ );
+ }
+
+ public void LogApiConfirmation(string hash, bool confirmed)
+ {
+ var confirmDetails = new
+ {
+ hash = hash,
+ confirmed = confirmed,
+ timestamp = DateTime.Now
+ };
+
+ LogDetailed(
+ confirmed ? $"Hash confermato: {hash?.Substring(0, 8)}..." : $"Hash rifiutato: {hash?.Substring(0, 8)}...",
+ confirmed ? LogType.INFO : LogType.WARN,
+ EventCategory.API,
+ confirmDetails
+ );
+ }
+
+ public void LogDatabaseOperation(string operation, bool success, string details = null)
+ {
+ var dbDetails = new
+ {
+ operation = operation,
+ success = success,
+ details = details,
+ timestamp = DateTime.Now
+ };
+
+ LogDetailed(
+ $"Operazione database: {operation} - {(success ? "Successo" : "Fallimento")}",
+ success ? LogType.INFO : LogType.ERROR,
+ EventCategory.Database,
+ dbDetails
+ );
+ }
+
+ public void LogEsecuzioneExecute(LogStatus stato, long spazioscansionato, long scansionati, int errori, int warning)
+ {
+ StringBuilder log = new StringBuilder();
+
+ log.Append("Stato procedura: " + LogStatusToString(stato) + Environment.NewLine);
+ log.Append("Totale spazio scansionato: " + ConvertBytesToReadableSize(spazioscansionato) + Environment.NewLine);
+ log.Append("Totale file scansionati: " + scansionati + Environment.NewLine);
+ log.Append("Errori: " + errori + Environment.NewLine);
+ log.Append("Warning: " + warning + Environment.NewLine);
+
+ SetLogTextBox(log.ToString());
+
+ // Also log to database
+ var executionDetails = new
+ {
+ status = stato.ToString(),
+ space_scanned = spazioscansionato,
+ files_scanned = scansionati,
+ errors = errori,
+ warnings = warning
+ };
+
+ LogDetailed(
+ $"Stato esecuzione: {LogStatusToString(stato)}",
+ LogType.INFO,
+ EventCategory.System,
+ executionDetails
+ );
+ }
+
+ public void LogDispositivoFill(LogStatus stato, int creati, int salvati, long spaziototale, long spazioriempito, int errori, int warning)
+ {
+ StringBuilder log = new StringBuilder();
+
+ log.Append("Stato procedura: " + LogStatusToString(stato) + Environment.NewLine);
+ log.Append("Spazio totale da riempire: " + ConvertBytesToReadableSize(spaziototale) + Environment.NewLine);
+ log.Append("Spazio occupato: " + ConvertBytesToReadableSize(spazioriempito) + Environment.NewLine);
+ log.Append("Totale file generati: " + creati + Environment.NewLine);
+ log.Append("Files salvati: " + salvati + Environment.NewLine);
+ log.Append("Errori: " + errori + Environment.NewLine);
+ log.Append("Warning: " + warning + Environment.NewLine);
+
+ SetLogTextBox(log.ToString());
+
+ // Also log to database
+ var fillDetails = new
+ {
+ status = stato.ToString(),
+ total_space = spaziototale,
+ filled_space = spazioriempito,
+ files_created = creati,
+ files_saved = salvati,
+ errors = errori,
+ warnings = warning
+ };
+
+ LogDetailed(
+ $"Riempimento dispositivo: {LogStatusToString(stato)}",
+ LogType.INFO,
+ EventCategory.FileManagement,
+ fillDetails
+ );
+ }
+
+ public void LogDispositivoCheck(LogStatus stato, int totale, int elaborati, int inseriti, int presenti, int errori, int warning)
+ {
+ StringBuilder log = new StringBuilder();
+
+ log.Append("Stato procedura: " + LogStatusToString(stato) + Environment.NewLine);
+ log.Append("Totale da scansionare: " + totale + Environment.NewLine);
+ log.Append("Files scansionati: " + elaborati + Environment.NewLine);
+ log.Append("Files aggiornati: " + presenti + Environment.NewLine);
+ log.Append("Files inseriti: " + inseriti + Environment.NewLine);
+ log.Append("Errori: " + errori + Environment.NewLine);
+ log.Append("Warning: " + warning + Environment.NewLine);
+
+ SetLogTextBox(log.ToString());
+
+ // Also log to database
+ var checkDetails = new
+ {
+ status = stato.ToString(),
+ total_files = totale,
+ processed_files = elaborati,
+ inserted_files = inseriti,
+ updated_files = presenti,
+ errors = errori,
+ warnings = warning
+ };
+
+ LogDetailed(
+ $"Controllo dispositivo: {LogStatusToString(stato)}",
+ LogType.INFO,
+ EventCategory.FileManagement,
+ checkDetails
+ );
+ }
+
+ public string LogStatusToString(LogStatus status)
+ {
+ switch (status)
+ {
+ case LogStatus.ATTESA:
+ return "In attesa di avvio";
+ case LogStatus.PREPARAZIONE:
+ return "Preparazione per l'elaborazione...";
+ case LogStatus.ELABORAZIONE:
+ return "In elaborazione...";
+ case LogStatus.FERMATA:
+ return "Stoppata dall'utente";
+ case LogStatus.COMPLETATO:
+ return "Completato";
+ case LogStatus.ERRORE:
+ return "Errore";
+ default:
+ return "In attesa di avvio";
+ }
+ }
+
+ public void SetLogTextBox(string log)
+ {
+ if (logTextBox != null)
+ {
+ if (logTextBox.InvokeRequired)
+ {
+ logTextBox.Invoke(new Action(() => logTextBox.Text = log + Environment.NewLine));
+ }
+ else
+ {
+ logTextBox.Text = log + Environment.NewLine;
+ }
+ }
+ }
+
+ public static string ConvertBytesToReadableSize(long bytes)
+ {
+ string[] sizes = { "B", "KB", "MB", "GB", "TB" };
+ double len = bytes;
+ int order = 0;
+
+ while (len >= 1024 && order < sizes.Length - 1)
+ {
+ order++;
+ len = len / 1024;
+ }
+
+ return $"{len:0.##} {sizes[order]}";
+ }
+ }
+}
diff --git a/BSHash/BSHash/Manager/Network.cs b/BSHash/BSHash/Manager/Network.cs
new file mode 100644
index 0000000..34aee4d
--- /dev/null
+++ b/BSHash/BSHash/Manager/Network.cs
@@ -0,0 +1,200 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace BSHash
+{
+ public class Network
+ {
+ private readonly HttpClient _httpClient;
+ private Logger _logger;
+ private ApiManager _apiManager;
+ private static readonly Random _random = new Random();
+
+ // Costanti per i possibili stati di risposta
+ public static string OK = "OK";
+ public static string TIMEOUT = "TIMEOUT";
+ public static string ERROR = "ERROR";
+
+ public Network(Logger logger)
+ {
+ _httpClient = new HttpClient();
+ _logger = logger;
+ }
+
+ public Network(Logger logger, Database database) : this(logger)
+ {
+ _apiManager = new ApiManager(database, logger);
+ }
+
+ public async Task SendDataHash(string hash)
+ {
+ try
+ {
+ _logger.Log("Invio dati hash...", LogType.INFO);
+
+ // If ApiManager is available, use it for real API calls
+ if (_apiManager != null)
+ {
+ var result = await _apiManager.SubmitPendingHashesAsync();
+ if (result.Status == "Completed" || result.Status == "Disabled")
+ {
+ _logger.Log($"Invio hash completato: {result.Message}", LogType.INFO);
+ return OK;
+ }
+ else
+ {
+ _logger.Log($"Errore invio hash: {result.Message}", LogType.ERROR);
+ return ERROR;
+ }
+ }
+
+ // Fallback to simulation for testing
+ /*
+ var content = new StringContent(data, Encoding.UTF8, "application/json");
+ HttpResponseMessage response = await _httpClient.PostAsync(url, content);
+
+ response.EnsureSuccessStatusCode();
+
+ string responseData = await response.Content.ReadAsStringAsync();
+ return responseData;
+ */
+
+ //Simula l'attesa di una risposta con un tempo randomico
+ //int delay = _random.Next(1, 5000); // da 1ms a 5s
+ int delay = _random.Next(100, 1000); // da 100ms a 1s per testing
+
+ _logger.Log("Dati inviati. Elaborazione...", LogType.INFO);
+
+ await Task.Delay(delay);
+
+ _logger.Log($"Tempo di chiamata: {delay}ms", LogType.INFO);
+
+ return OK;
+ }
+ catch (Exception ex)
+ {
+ // Logga o gestisci l'eccezione come necessario
+ _logger.Log("Errore della chiamata: " + ex.Message, LogType.ERROR);
+ return $"Error: {ex.Message}";
+ }
+ }
+
+ public async Task GetDataHash(string hash)
+ {
+ try
+ {
+ _logger.Log("Ricezione risposta hash...", LogType.INFO);
+
+ // If ApiManager is available, check API health
+ if (_apiManager != null)
+ {
+ var healthResult = await _apiManager.CheckApiHealthAsync();
+ if (healthResult.IsHealthy)
+ {
+ _logger.Log("API esterna raggiungibile e funzionante", LogType.INFO);
+ return OK;
+ }
+ else
+ {
+ _logger.Log($"API esterna non raggiungibile: {healthResult.Message}", LogType.WARN);
+ return ERROR;
+ }
+ }
+
+ // Fallback to simulation
+ /*
+ HttpResponseMessage response = await _httpClient.GetAsync(url);
+
+ response.EnsureSuccessStatusCode();
+
+ string responseData = await response.Content.ReadAsStringAsync();
+ return responseData;
+ */
+
+ // Simula l'attesa di una risposta con un tempo randomico
+ //int delay = _random.Next(1, 5000); // da 1ms a 5s
+ int delay = _random.Next(100, 800); // da 100ms a 800ms per testing
+
+ _logger.Log("Risposta ricevuta. Elaborazione...", LogType.INFO);
+
+ await Task.Delay(delay);
+
+ _logger.Log($"Tempo di risposta: {delay}ms", LogType.INFO);
+
+ return OK;
+ }
+ catch (Exception ex)
+ {
+ // Logga o gestisci l'eccezione come necessario
+ _logger.Log("Errore della chiamata: " + ex.Message, LogType.ERROR);
+ return $"Error: {ex.Message}";
+ }
+ }
+
+ // New method for HashKeeper Pro API integration
+ public async Task SubmitHashesAsync()
+ {
+ if (_apiManager == null)
+ {
+ _logger.Log("ApiManager non inizializzato", LogType.ERROR);
+ return ERROR;
+ }
+
+ try
+ {
+ var result = await _apiManager.SubmitPendingHashesAsync();
+
+ if (result.Status == "Completed")
+ {
+ _logger.Log($"Batch di hash inviato con successo: {result.SuccessfulSubmissions} hash inviati", LogType.INFO);
+ return OK;
+ }
+ else if (result.Status == "Disabled")
+ {
+ _logger.Log("Invio API disabilitato nelle impostazioni", LogType.INFO);
+ return OK;
+ }
+ else
+ {
+ _logger.Log($"Errore durante l'invio batch: {result.Message}", LogType.ERROR);
+ return ERROR;
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.Log($"Errore imprevisto durante l'invio hash: {ex.Message}", LogType.ERROR);
+ return ERROR;
+ }
+ }
+
+ public async Task TestApiConnectionAsync()
+ {
+ if (_apiManager == null)
+ return false;
+
+ try
+ {
+ var healthResult = await _apiManager.CheckApiHealthAsync();
+ _logger.Log($"Test connessione API: {(healthResult.IsHealthy ? "SUCCESSO" : "FALLITO")} - {healthResult.Message}",
+ healthResult.IsHealthy ? LogType.INFO : LogType.ERROR);
+ return healthResult.IsHealthy;
+ }
+ catch (Exception ex)
+ {
+ _logger.Log($"Errore test connessione API: {ex.Message}", LogType.ERROR);
+ return false;
+ }
+ }
+
+ public void Dispose()
+ {
+ _httpClient?.Dispose();
+ _apiManager?.Dispose();
+ }
+ }
+}
diff --git a/BSHash/BSHash/Storage.cs b/BSHash/BSHash/Manager/Storage.cs
similarity index 81%
rename from BSHash/BSHash/Storage.cs
rename to BSHash/BSHash/Manager/Storage.cs
index dc5fe50..ffc9d5b 100644
--- a/BSHash/BSHash/Storage.cs
+++ b/BSHash/BSHash/Manager/Storage.cs
@@ -223,14 +223,20 @@ namespace BSHash
{
try
{
- string fileName = Path.Combine(path, Guid.NewGuid() + ".bs");
- byte[] data = new byte[sectorSize];
+ // Generate filename with timestamp and GUID for uniqueness
+ string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
+ string fileName = Path.Combine(path, $"hashkeeper_{timestamp}_{Guid.NewGuid():N}.hkp");
+
+ // Create file with random content (1MB to 10MB range for optimal hash count)
+ int minSize = 1024 * 1024; // 1 MB
+ int maxSize = 10 * 1024 * 1024; // 10 MB
+ int fileSize = _random.Next(minSize, maxSize);
+
+ byte[] data = new byte[fileSize];
_random.NextBytes(data);
await WriteAllBytesAsync(fileName, data);
- _logger.Log($"Creato file {fileName}.", LogType.INFO);
-
-
+ _logger.Log($"Creato file {fileName} ({ConvertBytesToReadableSize(fileSize)})", LogType.INFO);
return data.Length;
}
@@ -241,6 +247,21 @@ namespace BSHash
}
}
+ private string ConvertBytesToReadableSize(long bytes)
+ {
+ string[] sizes = { "B", "KB", "MB", "GB", "TB" };
+ double len = bytes;
+ int order = 0;
+
+ while (len >= 1024 && order < sizes.Length - 1)
+ {
+ order++;
+ len = len / 1024;
+ }
+
+ return $"{len:0.##} {sizes[order]}";
+ }
+
private async Task WriteAllBytesAsync(string path, byte[] bytes)
{
using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, 4096, true))
@@ -251,12 +272,59 @@ namespace BSHash
private int GetSectorSize(string drive)
{
- // Assuming a default sector size of 1024 * 1024 * 128 bytes (128 MB)
- // Total 127.831.113.728 bytes
- // : 128 = 998.680.576
- // : 1024 = 975.274
- // : 1024 = 952
- return 1024 * 128;
+ // For HashKeeper Pro, use optimal file sizes between 1MB and 10MB
+ // This maximizes the number of unique hashes without overloading the filesystem
+
+ // Generate random size between 1MB and 10MB
+ int minSize = 1024 * 1024; // 1 MB
+ int maxSize = 10 * 1024 * 1024; // 10 MB
+
+ return _random.Next(minSize, maxSize);
+ }
+
+ // Funzione ricorsiva per ottenere tutti i file, saltando cartelle protette
+ private List GetAllFilesSafe(string rootPath, List excludeDirs, CancellationToken cancellationToken)
+ {
+ var files = new List();
+ try
+ {
+ foreach (var dir in Directory.GetDirectories(rootPath))
+ {
+ if (cancellationToken.IsCancellationRequested)
+ break;
+
+ string dirName = Path.GetFileName(dir).ToLowerInvariant();
+ if (excludeDirs.Contains(dirName))
+ continue;
+ try
+ {
+ files.AddRange(GetAllFilesSafe(dir, excludeDirs, cancellationToken));
+ }
+ catch (UnauthorizedAccessException ex)
+ {
+ _logger.Log($"Accesso negato alla cartella '{dir}': {ex.Message}", LogType.WARN);
+ }
+ catch (Exception ex)
+ {
+ _logger.Log($"Errore durante l'accesso alla cartella '{dir}': {ex.Message}", LogType.WARN);
+ }
+ }
+ foreach (var file in Directory.GetFiles(rootPath))
+ {
+ if (cancellationToken.IsCancellationRequested)
+ break;
+ files.Add(file);
+ }
+ }
+ catch (UnauthorizedAccessException ex)
+ {
+ _logger.Log($"Accesso negato alla cartella '{rootPath}': {ex.Message}", LogType.WARN);
+ }
+ catch (Exception ex)
+ {
+ _logger.Log($"Errore durante l'accesso alla cartella '{rootPath}': {ex.Message}", LogType.WARN);
+ }
+ return files;
}
public async Task CheckFilesAsync(string path, System.Windows.Forms.ProgressBar progressBar, CancellationToken cancellationToken, System.Windows.Forms.Button startButton, System.Windows.Forms.Button stopButton)
@@ -272,25 +340,27 @@ namespace BSHash
try
{
- _logger.Log("Ricavando la lista dei files supportati...", LogType.INFO); ;
+ _logger.Log("Ricavando la lista dei files supportati...", LogType.INFO);
- string[] files = Directory.GetFiles(path, "*", SearchOption.AllDirectories);
+ // Escludi cartelle di sistema/protette
+ var excludeDirs = new List { "system volume information", "$recycle.bin", "recycler", "lost+found", "found.000" };
+ var files = GetAllFilesSafe(path, excludeDirs, cancellationToken);
var hashSet = new HashSet();
var invalidFiles = new List();
var duplicateFiles = new List();
progressBar.Invoke((Action)(() =>
{
- progressBar.Maximum = files.Length;
+ progressBar.Maximum = files.Count;
progressBar.Value = 0;
}));
-
+
int processedFiles = 0;
int errori = 0;
int warning = 0;
int inseriti = 0;
int aggiornati = 0;
- int totalFiles = files.Length;
+ int totalFiles = files.Count;
_logger.Log($"Inizio controllo {totalFiles} files.", LogType.INFO);
@@ -319,8 +389,6 @@ namespace BSHash
hashSet.Add(hash);
}
-
-
_logger.Log("Verificando l'esistenza dell'hash...", LogType.INFO);
// Controlla se l'hash esiste già nel database
@@ -363,7 +431,6 @@ namespace BSHash
{
invalidFiles.Add(file);
_logger.Log($"Errore durante la verifica del file {file}: {ex.Message}", LogType.ERROR);
-
errori++;
}
diff --git a/BSHash/BSHash/Network.cs b/BSHash/BSHash/Network.cs
deleted file mode 100644
index c727a74..0000000
--- a/BSHash/BSHash/Network.cs
+++ /dev/null
@@ -1,99 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net.Http;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace BSHash
-{
- public class Network
- {
- private readonly HttpClient _httpClient;
- private Logger _logger;
- private static readonly Random _random = new Random();
-
- // Costanti per i possibili stati di risposta
- public static string OK = "OK";
- public static string TIMEOUT = "TIMEOUT";
- public static string ERROR = "ERROR";
-
- public Network(Logger logger)
- {
- _httpClient = new HttpClient();
- _logger = logger;
- }
-
- public async Task SendDataHash(string hash)
- {
- try
- {
- /*
- var content = new StringContent(data, Encoding.UTF8, "application/json");
- HttpResponseMessage response = await _httpClient.PostAsync(url, content);
-
- response.EnsureSuccessStatusCode();
-
- string responseData = await response.Content.ReadAsStringAsync();
- return responseData;
- */
-
- _logger.Log("Invio dati...", LogType.INFO);
-
- //Simula l'attesa di una risposta con un tempo randomico
- //int delay = _random.Next(1, 5000); // da 1ms a 5s
- int delay = 0; // per testare il timeout
-
- _logger.Log("Dati inviati. Elaborazione... ", LogType.INFO);
-
- Thread.Sleep(delay);
-
- _logger.Log("Tempo di chiamata: " + delay.ToString(), LogType.INFO);
-
- return OK;
- }
- catch (Exception ex)
- {
- // Logga o gestisci l'eccezione come necessario
- _logger.Log("Errore della chiamata: " + ex.Message, LogType.ERROR);
- return $"Error: {ex.Message}";
- }
- }
-
- public async Task GetDataHash(string hash)
- {
- try
- {
- /*
- HttpResponseMessage response = await _httpClient.GetAsync(url);
-
- response.EnsureSuccessStatusCode();
-
- string responseData = await response.Content.ReadAsStringAsync();
- return responseData;
- */
-
- _logger.Log("Ricezione risposta...", LogType.INFO);
-
- // Simula l'attesa di una risposta con un tempo randomico
- //int delay = _random.Next(1, 5000); // da 1ms a 5s
- int delay = 0; // per testare il timeout
-
- _logger.Log("Risposta ricevuta. Elaborazione... ", LogType.INFO);
-
- Thread.Sleep(delay);
-
- _logger.Log("Tempo di risposta: " + delay.ToString(), LogType.INFO);
-
- return OK;
- }
- catch (Exception ex)
- {
- // Logga o gestisci l'eccezione come necessario
- _logger.Log("Errore della chiamata: " + ex.Message, LogType.ERROR);
- return $"Error: {ex.Message}";
- }
- }
- }
-}
diff --git a/BSHash/BSHash/Program.cs b/BSHash/BSHash/Program.cs
index b14750b..d621902 100644
--- a/BSHash/BSHash/Program.cs
+++ b/BSHash/BSHash/Program.cs
@@ -1,19 +1,34 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
using System.Windows.Forms;
namespace BSHash
{
internal static class Program
{
+ ///
+ /// Punto di ingresso principale dell'applicazione HashKeeper Pro.
+ ///
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
- Application.Run(new Main());
+
+ // Show login form first
+ using (var loginForm = new LoginForm())
+ {
+ if (loginForm.ShowDialog() == DialogResult.OK)
+ {
+ // Login successful, show main dashboard
+ var mainForm = new MainForm();
+ Application.Run(mainForm);
+ }
+ else
+ {
+ // Login failed or cancelled, exit application
+ Application.Exit();
+ }
+ }
}
}
}
diff --git a/BSHash/BSHash/Properties/Settings.Designer.cs b/BSHash/BSHash/Properties/Settings.Designer.cs
index 2c00439..04de515 100644
--- a/BSHash/BSHash/Properties/Settings.Designer.cs
+++ b/BSHash/BSHash/Properties/Settings.Designer.cs
@@ -12,7 +12,7 @@ namespace BSHash.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.11.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.14.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
@@ -23,6 +23,234 @@ namespace BSHash.Properties {
}
}
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("")]
+ public string Password {
+ get {
+ return ((string)(this["Password"]));
+ }
+ set {
+ this["Password"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("localhost")]
+ public string DatabaseServer {
+ get {
+ return ((string)(this["DatabaseServer"]));
+ }
+ set {
+ this["DatabaseServer"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("HashKeeperPro")]
+ public string DatabaseName {
+ get {
+ return ((string)(this["DatabaseName"]));
+ }
+ set {
+ this["DatabaseName"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("sa")]
+ public string DatabaseUser {
+ get {
+ return ((string)(this["DatabaseUser"]));
+ }
+ set {
+ this["DatabaseUser"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("")]
+ public string DatabasePassword {
+ get {
+ return ((string)(this["DatabasePassword"]));
+ }
+ set {
+ this["DatabasePassword"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("1433")]
+ public int DatabasePort {
+ get {
+ return ((int)(this["DatabasePort"]));
+ }
+ set {
+ this["DatabasePort"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("SQL Server")]
+ public string DatabaseProvider {
+ get {
+ return ((string)(this["DatabaseProvider"]));
+ }
+ set {
+ this["DatabaseProvider"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("")]
+ public string SavedCredentials {
+ get {
+ return ((string)(this["SavedCredentials"]));
+ }
+ set {
+ this["SavedCredentials"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ public bool RememberCredentials {
+ get {
+ return ((bool)(this["RememberCredentials"]));
+ }
+ set {
+ this["RememberCredentials"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("60")]
+ public int ScanIntervalMinutes {
+ get {
+ return ((int)(this["ScanIntervalMinutes"]));
+ }
+ set {
+ this["ScanIntervalMinutes"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("https://api.hashkeeper.com/v1/hashes")]
+ public string ApiEndpointUrl {
+ get {
+ return ((string)(this["ApiEndpointUrl"]));
+ }
+ set {
+ this["ApiEndpointUrl"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("")]
+ public string ApiKey {
+ get {
+ return ((string)(this["ApiKey"]));
+ }
+ set {
+ this["ApiKey"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ public bool EnableApiSending {
+ get {
+ return ((bool)(this["EnableApiSending"]));
+ }
+ set {
+ this["EnableApiSending"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("100")]
+ public int BatchSize {
+ get {
+ return ((int)(this["BatchSize"]));
+ }
+ set {
+ this["BatchSize"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ public bool EnableDarkMode {
+ get {
+ return ((bool)(this["EnableDarkMode"]));
+ }
+ set {
+ this["EnableDarkMode"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
+ public bool AutoSaveSettings {
+ get {
+ return ((bool)(this["AutoSaveSettings"]));
+ }
+ set {
+ this["AutoSaveSettings"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("")]
+ public string DatabasePath {
+ get {
+ return ((string)(this["DatabasePath"]));
+ }
+ set {
+ this["DatabasePath"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ public bool RememberUsername {
+ get {
+ return ((bool)(this["RememberUsername"]));
+ }
+ set {
+ this["RememberUsername"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("")]
+ public string LastUsername {
+ get {
+ return ((string)(this["LastUsername"]));
+ }
+ set {
+ this["LastUsername"] = value;
+ }
+ }
+
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
@@ -47,18 +275,6 @@ namespace BSHash.Properties {
}
}
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("")]
- public string Password {
- get {
- return ((string)(this["Password"]));
- }
- set {
- this["Password"] = value;
- }
- }
-
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
diff --git a/BSHash/BSHash/Properties/Settings.settings b/BSHash/BSHash/Properties/Settings.settings
index d328b8d..5d09457 100644
--- a/BSHash/BSHash/Properties/Settings.settings
+++ b/BSHash/BSHash/Properties/Settings.settings
@@ -2,15 +2,69 @@
+
+
+
+
+ localhost
+
+
+ HashKeeperPro
+
+
+ sa
+
+
+
+
+
+ 1433
+
+
+ SQL Server
+
+
+
+
+
+ False
+
+
+ 60
+
+
+ https://api.hashkeeper.com/v1/hashes
+
+
+
+
+
+ False
+
+
+ 100
+
+
+ False
+
+
+ True
+
+
+
+
+
+ False
+
+
+
+
-
-
-
diff --git a/BSHash/BSHash/packages.config b/BSHash/BSHash/packages.config
new file mode 100644
index 0000000..cdf4833
--- /dev/null
+++ b/BSHash/BSHash/packages.config
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file