Files
apprepodbmgr/apprepodbmgr.Core/Workers/Database.cs

441 lines
16 KiB
C#
Raw Normal View History

//
// Author:
// Natalia Portillo claunia@claunia.com
//
// Copyright (c) 2017, © Claunia.com
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the distribution.
// * Neither the name of the [ORGANIZATION] nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
2017-12-30 00:32:21 +00:00
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
2017-06-13 18:21:12 +01:00
using System.Threading;
namespace apprepodbmgr.Core
{
public static partial class Workers
{
public static void GetAllApps()
{
try
{
2017-12-30 00:32:21 +00:00
#if DEBUG
2017-05-19 03:24:34 +01:00
stopwatch.Restart();
2017-12-30 00:32:21 +00:00
#endif
dbCore.DbOps.GetAllApps(out List<DbEntry> apps);
2017-12-30 00:32:21 +00:00
#if DEBUG
2017-05-19 03:24:34 +01:00
stopwatch.Stop();
Console.WriteLine("Core.GetAllApps(): Took {0} seconds to get apps from database",
2017-12-30 00:32:21 +00:00
stopwatch.Elapsed.TotalSeconds);
#endif
if(AddApp != null)
{
2017-12-30 00:32:21 +00:00
#if DEBUG
2017-05-19 03:24:34 +01:00
stopwatch.Restart();
2017-12-30 00:32:21 +00:00
#endif
int counter = 0;
// TODO: Check file name and existence
foreach(DbEntry app in apps)
{
UpdateProgress?.Invoke("Populating apps table", $"{app.Developer} {app.Product}", counter,
apps.Count);
AddApp?.Invoke(app);
counter++;
}
2017-12-30 00:32:21 +00:00
#if DEBUG
2017-05-19 03:24:34 +01:00
stopwatch.Stop();
Console.WriteLine("Core.GetAllApps(): Took {0} seconds to add apps to the GUI",
2017-12-30 00:32:21 +00:00
stopwatch.Elapsed.TotalSeconds);
#endif
}
2017-12-30 00:32:21 +00:00
Finished?.Invoke();
}
2017-12-30 00:32:21 +00:00
catch(ThreadAbortException) { }
catch(Exception ex)
{
2017-12-30 00:32:21 +00:00
if(Debugger.IsAttached) throw;
Failed?.Invoke($"Exception {ex.Message}\n{ex.InnerException}");
#if DEBUG
2017-06-13 18:21:12 +01:00
Console.WriteLine("Exception {0}\n{1}", ex.Message, ex.InnerException);
2017-12-30 00:32:21 +00:00
#endif
}
}
public static void CheckDbForFiles()
{
try
{
long counter = 0;
2017-12-30 00:32:21 +00:00
#if DEBUG
2017-05-19 03:24:34 +01:00
stopwatch.Restart();
2017-12-30 00:32:21 +00:00
#endif
Dictionary<string, DbAppFile> knownFiles = new Dictionary<string, DbAppFile>();
2017-08-16 00:14:08 +01:00
bool unknownFile = false;
foreach(KeyValuePair<string, DbAppFile> kvp in Context.Hashes)
{
2017-08-16 00:14:08 +01:00
// Empty file with size zero
if(kvp.Value.Sha256 == "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
{
AddFileForApp(kvp.Key, kvp.Value.Sha256, true, kvp.Value.Crack);
2017-08-16 00:14:08 +01:00
counter++;
continue;
}
2017-12-30 00:32:21 +00:00
UpdateProgress?.Invoke(null, "Checking files in database", counter, Context.Hashes.Count);
AddFileForApp?.Invoke(kvp.Key, kvp.Value.Sha256, dbCore.DbOps.ExistsFile(kvp.Value.Sha256),
2017-12-30 00:32:21 +00:00
kvp.Value.Crack);
2017-12-30 00:32:21 +00:00
if(dbCore.DbOps.ExistsFile(kvp.Value.Sha256))
2017-08-16 00:14:08 +01:00
{
counter++;
knownFiles.Add(kvp.Key, kvp.Value);
}
2017-12-30 00:32:21 +00:00
else unknownFile = true;
}
2017-12-30 00:32:21 +00:00
#if DEBUG
2017-05-19 03:24:34 +01:00
stopwatch.Stop();
2017-12-30 00:32:21 +00:00
Console.WriteLine("Core.CheckDbForFiles(): Took {0} seconds to checks for file knowledge in the DB",
stopwatch.Elapsed.TotalSeconds);
2017-05-19 03:24:34 +01:00
stopwatch.Restart();
2017-12-30 00:32:21 +00:00
#endif
2017-08-16 00:14:08 +01:00
if(knownFiles.Count == 0 || unknownFile)
{
2017-12-30 00:32:21 +00:00
Finished?.Invoke();
2017-08-16 00:14:08 +01:00
return;
}
UpdateProgress?.Invoke(null, "Retrieving apps from database", counter, Context.Hashes.Count);
dbCore.DbOps.GetAllApps(out List<DbEntry> apps);
2017-12-30 00:32:21 +00:00
#if DEBUG
2017-05-19 03:24:34 +01:00
stopwatch.Stop();
Console.WriteLine("Core.CheckDbForFiles(): Took {0} seconds get all apps from DB",
2017-12-30 00:32:21 +00:00
stopwatch.Elapsed.TotalSeconds);
#endif
if(apps != null && apps.Count > 0)
{
DbEntry[] appsArray = new DbEntry[apps.Count];
apps.CopyTo(appsArray);
long appCounter = 0;
2017-12-30 00:32:21 +00:00
#if DEBUG
2017-05-19 03:24:34 +01:00
stopwatch.Restart();
2017-12-30 00:32:21 +00:00
#endif
2017-08-16 00:14:08 +01:00
foreach(DbEntry app in appsArray)
{
UpdateProgress?.Invoke(null, $"Check application id {app.Id}", appCounter, appsArray.Length);
counter = 0;
foreach(KeyValuePair<string, DbAppFile> kvp in knownFiles)
{
2017-12-30 00:32:21 +00:00
UpdateProgress2?.Invoke(null, $"Checking for file {kvp.Value.Path}", counter,
knownFiles.Count);
if(!dbCore.DbOps.ExistsFileInApp(kvp.Value.Sha256, app.Id))
{
if(apps.Contains(app)) apps.Remove(app);
// If one file is missing, the rest don't matter
break;
}
counter++;
}
if(apps.Count == 0) break; // No apps left
}
2017-12-30 00:32:21 +00:00
#if DEBUG
2017-05-19 03:24:34 +01:00
stopwatch.Stop();
Console.WriteLine("Core.CheckDbForFiles(): Took {0} seconds correlate all files with all known applications",
2017-12-30 00:32:21 +00:00
stopwatch.Elapsed.TotalSeconds);
#endif
}
if(AddApp != null)
foreach(DbEntry app in apps)
AddApp?.Invoke(app);
2017-12-30 00:32:21 +00:00
Finished?.Invoke();
}
2017-12-30 00:32:21 +00:00
catch(ThreadAbortException) { }
catch(Exception ex)
{
2017-12-30 00:32:21 +00:00
if(Debugger.IsAttached) throw;
Failed?.Invoke($"Exception {ex.Message}\n{ex.InnerException}");
#if DEBUG
2017-06-13 18:21:12 +01:00
Console.WriteLine("Exception {0}\n{1}", ex.Message, ex.InnerException);
2017-12-30 00:32:21 +00:00
#endif
}
}
public static void AddFilesToDb()
{
try
{
long counter = 0;
2017-12-30 00:32:21 +00:00
#if DEBUG
2017-05-19 03:24:34 +01:00
stopwatch.Restart();
2017-12-30 00:32:21 +00:00
#endif
foreach(KeyValuePair<string, DbAppFile> kvp in Context.Hashes)
{
2017-12-30 00:32:21 +00:00
UpdateProgress?.Invoke(null, "Adding files to database", counter, Context.Hashes.Count);
2017-12-30 00:32:21 +00:00
if(!dbCore.DbOps.ExistsFile(kvp.Value.Sha256))
{
2017-12-30 00:32:21 +00:00
DbFile file = new DbFile
{
2017-12-30 00:32:21 +00:00
Sha256 = kvp.Value.Sha256,
ClamTime = null,
Crack = kvp.Value.Crack,
Length = kvp.Value.Length,
Virus = null,
HasVirus = null,
VirusTotalTime = null
};
2017-12-30 00:32:21 +00:00
dbCore.DbOps.AddFile(file);
2017-12-30 00:32:21 +00:00
AddFile?.Invoke(file);
}
counter++;
}
2017-12-30 00:32:21 +00:00
#if DEBUG
2017-05-19 03:24:34 +01:00
stopwatch.Stop();
2017-12-30 00:32:21 +00:00
Console.WriteLine("Core.AddFilesToDb(): Took {0} seconds to add all files to the database",
stopwatch.Elapsed.TotalSeconds);
#endif
UpdateProgress?.Invoke(null, "Adding application information", counter, Context.Hashes.Count);
dbCore.DbOps.AddApp(Context.DbInfo, out Context.DbInfo.Id);
UpdateProgress?.Invoke(null, "Creating application table", counter, Context.Hashes.Count);
dbCore.DbOps.CreateTableForApp(Context.DbInfo.Id);
2017-12-30 00:32:21 +00:00
#if DEBUG
2017-05-19 03:24:34 +01:00
stopwatch.Restart();
2017-12-30 00:32:21 +00:00
#endif
counter = 0;
foreach(KeyValuePair<string, DbAppFile> kvp in Context.Hashes)
{
UpdateProgress?.Invoke(null, "Adding files to application in database", counter, Context.Hashes.Count);
dbCore.DbOps.AddFileToApp(kvp.Value, Context.DbInfo.Id);
counter++;
}
2017-12-30 00:32:21 +00:00
#if DEBUG
2017-05-19 03:24:34 +01:00
stopwatch.Stop();
Console.WriteLine("Core.AddFilesToDb(): Took {0} seconds to add all files to the application in the database",
2017-12-30 00:32:21 +00:00
stopwatch.Elapsed.TotalSeconds);
2017-05-19 03:24:34 +01:00
stopwatch.Restart();
2017-12-30 00:32:21 +00:00
#endif
counter = 0;
2017-12-30 00:32:21 +00:00
foreach(KeyValuePair<string, DbFolder> kvp in Context.FoldersDict)
{
UpdateProgress?.Invoke(null, "Adding folders to application in database", counter,
2017-12-30 00:32:21 +00:00
Context.FoldersDict.Count);
dbCore.DbOps.AddFolderToApp(kvp.Value, Context.DbInfo.Id);
counter++;
}
2017-12-30 00:32:21 +00:00
#if DEBUG
2017-05-19 03:24:34 +01:00
stopwatch.Stop();
2017-12-30 00:32:21 +00:00
Console.WriteLine("Core.AddFilesToDb(): Took {0} seconds to add all folders to the database",
stopwatch.Elapsed.TotalSeconds);
stopwatch.Restart();
2017-12-30 00:32:21 +00:00
#endif
counter = 0;
2017-12-30 00:32:21 +00:00
if(Context.SymlinksDict.Count > 0) dbCore.DbOps.CreateSymlinkTableForOs(Context.DbInfo.Id);
foreach(KeyValuePair<string, string> kvp in Context.SymlinksDict)
{
UpdateProgress?.Invoke(null, "Adding symbolic links to application in database", counter,
2017-12-30 00:32:21 +00:00
Context.SymlinksDict.Count);
dbCore.DbOps.AddSymlinkToApp(kvp.Key, kvp.Value, Context.DbInfo.Id);
counter++;
}
2017-12-30 00:32:21 +00:00
#if DEBUG
stopwatch.Stop();
2017-12-30 00:32:21 +00:00
Console.WriteLine("Core.AddFilesToDb(): Took {0} seconds to add all symbolic links to the database",
stopwatch.Elapsed.TotalSeconds);
#endif
2017-12-30 00:32:21 +00:00
Finished?.Invoke();
}
2017-12-30 00:32:21 +00:00
catch(ThreadAbortException) { }
catch(Exception ex)
{
2017-12-30 00:32:21 +00:00
if(Debugger.IsAttached) throw;
Failed?.Invoke($"Exception {ex.Message}\n{ex.InnerException}");
#if DEBUG
2017-06-13 18:21:12 +01:00
Console.WriteLine("Exception {0}\n{1}", ex.Message, ex.InnerException);
2017-12-30 00:32:21 +00:00
#endif
}
}
public static void InitDB()
{
CloseDB();
dbCore = null;
try
{
if(string.IsNullOrEmpty(Settings.Current.DatabasePath))
{
2017-12-30 00:32:21 +00:00
Failed?.Invoke("No database file specified");
return;
}
dbCore = new SQLite();
if(File.Exists(Settings.Current.DatabasePath))
{
2017-12-30 00:32:21 +00:00
if(!dbCore.OpenDb(Settings.Current.DatabasePath, null, null, null))
{
2017-12-30 00:32:21 +00:00
Failed?.Invoke("Could not open database, correct file selected?");
dbCore = null;
return;
}
}
else
{
2017-12-30 00:32:21 +00:00
if(!dbCore.CreateDb(Settings.Current.DatabasePath, null, null, null))
{
2017-12-30 00:32:21 +00:00
Failed?.Invoke("Could not create database, correct file selected?");
dbCore = null;
return;
}
2017-12-30 00:32:21 +00:00
if(!dbCore.OpenDb(Settings.Current.DatabasePath, null, null, null))
{
2017-12-30 00:32:21 +00:00
Failed?.Invoke("Could not open database, correct file selected?");
dbCore = null;
return;
}
}
2017-12-30 00:32:21 +00:00
Finished?.Invoke();
}
2017-12-30 00:32:21 +00:00
catch(ThreadAbortException) { }
catch(Exception ex)
{
2017-12-30 00:32:21 +00:00
if(Debugger.IsAttached) throw;
Failed?.Invoke($"Exception {ex.Message}\n{ex.InnerException}");
#if DEBUG
2017-06-13 18:21:12 +01:00
Console.WriteLine("Exception {0}\n{1}", ex.Message, ex.InnerException);
2017-12-30 00:32:21 +00:00
#endif
}
}
public static void CloseDB()
{
2017-12-30 00:32:21 +00:00
dbCore?.CloseDb();
}
public static void RemoveApp(long id, string mdid)
{
2017-12-30 00:32:21 +00:00
if(id == 0 || string.IsNullOrWhiteSpace(mdid)) return;
dbCore.DbOps.RemoveApp(id);
}
public static void GetFilesFromDb()
{
try
{
2017-12-30 00:32:21 +00:00
ulong count = dbCore.DbOps.GetFilesCount();
const ulong PAGE = 2500;
ulong offset = 0;
2017-12-30 00:32:21 +00:00
#if DEBUG
2017-05-19 03:24:34 +01:00
stopwatch.Restart();
2017-12-30 00:32:21 +00:00
#endif
while(dbCore.DbOps.GetFiles(out List<DbFile> files, offset, PAGE))
{
2017-12-30 00:32:21 +00:00
if(files.Count == 0) break;
2017-12-30 00:32:21 +00:00
UpdateProgress?.Invoke(null, $"Loaded file {offset} of {count}", (long)offset, (long)count);
2017-12-30 00:32:21 +00:00
AddFiles?.Invoke(files);
2017-12-30 00:32:21 +00:00
offset += PAGE;
}
2017-12-30 00:32:21 +00:00
#if DEBUG
2017-05-19 03:24:34 +01:00
stopwatch.Stop();
2017-12-30 00:32:21 +00:00
Console.WriteLine("Core.GetFilesFromDb(): Took {0} seconds to get all files from the database",
stopwatch.Elapsed.TotalSeconds);
#endif
2017-12-30 00:32:21 +00:00
Finished?.Invoke();
}
2017-12-30 00:32:21 +00:00
catch(ThreadAbortException) { }
catch(Exception ex)
{
2017-12-30 00:32:21 +00:00
if(Debugger.IsAttached) throw;
Failed?.Invoke($"Exception {ex.Message}\n{ex.InnerException}");
#if DEBUG
2017-06-13 18:21:12 +01:00
Console.WriteLine("Exception {0}\n{1}", ex.Message, ex.InnerException);
2017-12-30 00:32:21 +00:00
#endif
}
}
public static void ToggleCrack(string hash, bool crack)
{
try
{
2017-12-30 00:32:21 +00:00
dbCore.DbOps.ToggleCrack(hash, crack);
2017-12-30 00:32:21 +00:00
Finished?.Invoke();
}
2017-12-30 00:32:21 +00:00
catch(ThreadAbortException) { }
catch(Exception ex)
{
2017-12-30 00:32:21 +00:00
if(Debugger.IsAttached) throw;
Failed?.Invoke($"Exception {ex.Message}\n{ex.InnerException}");
#if DEBUG
2017-06-13 18:21:12 +01:00
Console.WriteLine("Exception {0}\n{1}", ex.Message, ex.InnerException);
2017-12-30 00:32:21 +00:00
#endif
}
}
2017-05-18 22:23:49 +01:00
2017-12-30 00:32:21 +00:00
public static DbFile GetDBFile(string hash)
2017-05-18 22:23:49 +01:00
{
2017-12-30 00:32:21 +00:00
return dbCore.DbOps.GetFile(hash);
2017-05-18 22:23:49 +01:00
}
}
2017-12-30 00:32:21 +00:00
}