diff --git a/src/client_backend/.vs/client_backend/FileContentIndex/f03805b6-9baf-42ce-861d-45898094a973.vsidx b/src/client_backend/.vs/client_backend/FileContentIndex/b776bd84-bdc5-432c-944c-f4a78ba936db.vsidx similarity index 99% rename from src/client_backend/.vs/client_backend/FileContentIndex/f03805b6-9baf-42ce-861d-45898094a973.vsidx rename to src/client_backend/.vs/client_backend/FileContentIndex/b776bd84-bdc5-432c-944c-f4a78ba936db.vsidx index 6c46d1e..efc04b9 100644 Binary files a/src/client_backend/.vs/client_backend/FileContentIndex/f03805b6-9baf-42ce-861d-45898094a973.vsidx and b/src/client_backend/.vs/client_backend/FileContentIndex/b776bd84-bdc5-432c-944c-f4a78ba936db.vsidx differ diff --git a/src/client_backend/.vs/client_backend/v17/.suo b/src/client_backend/.vs/client_backend/v17/.suo index 16e1b78..6a1458f 100644 Binary files a/src/client_backend/.vs/client_backend/v17/.suo and b/src/client_backend/.vs/client_backend/v17/.suo differ diff --git a/src/client_backend/.vs/client_backend/v17/Browse.VC.db b/src/client_backend/.vs/client_backend/v17/Browse.VC.db index f5b82d3..3388533 100644 Binary files a/src/client_backend/.vs/client_backend/v17/Browse.VC.db and b/src/client_backend/.vs/client_backend/v17/Browse.VC.db differ diff --git a/src/client_backend/check_dir.cpp b/src/client_backend/check_dir.cpp index 581cad1..ce418be 100644 --- a/src/client_backend/check_dir.cpp +++ b/src/client_backend/check_dir.cpp @@ -156,7 +156,7 @@ void process_changes(const FILE_NOTIFY_INFORMATION* pInfo) { filename_str = "c:\\" + filename_str; //scan the file and send it to virus_ctrl if it is a virus and then process it std::transform(filename_str.begin(), filename_str.end(), filename_str.begin(), ::tolower); - if (is_folder_excluded(filename_str.c_str()) or is_directory(filename_str.c_str())) { + if (!is_folder_included(filename_str.c_str()) or is_directory(filename_str.c_str()) or is_folder_excluded(filename_str.c_str())) { //dont scan excluded files or folders return; } diff --git a/src/client_backend/scan.cpp b/src/client_backend/scan.cpp index a0f4ec5..992840a 100644 --- a/src/client_backend/scan.cpp +++ b/src/client_backend/scan.cpp @@ -89,9 +89,11 @@ int search_hash(const std::string& dbname_, const std::string& hash_, const std: thread_local std::string filepath (filepath_); thread_local auto fileIter = fileHandles.find(dbname); - if (fileIter == fileHandles.end()) { + if (fileIter == fileHandles.end() and dbname_.find("c:.jdbf") == std::string::npos) { log(LOGLEVEL::ERR, "[search_hash()]: File mapping not initialized for ", dbname); return 2; + }else if (fileIter == fileHandles.end()) { + return 2; } // Use fileData for subsequent searches diff --git a/src/client_backend/scan.cpp~RF19f5c75.TMP b/src/client_backend/scan.cpp~RF19f5c75.TMP new file mode 100644 index 0000000..6015124 --- /dev/null +++ b/src/client_backend/scan.cpp~RF19f5c75.TMP @@ -0,0 +1,209 @@ +#include "scan.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "md5hash.h" +#include +#include "well_known.h" +#include "log.h" +#include "virus_ctrl.h" +#include "app_ctrl.h" +#ifndef SCAN_CPP +#define SCAN_CPP +std::unordered_map fileHandles; +std::unordered_map mappingHandles; +std::unordered_map fileData; + +int cnt = 0; +int num_threads=0; + +//load all the db files into memory +void initialize(const std::string& folderPath) { + for (char firstChar = '0'; firstChar <= 'f'; ++firstChar) { + for (char secondChar = '0'; secondChar <= 'f'; ++secondChar) { + // Ensure that the characters are valid hexadecimal digits + if (!std::isxdigit(firstChar) || !std::isxdigit(secondChar) or std::isupper(firstChar) or std::isupper(secondChar)) { + continue; + } + + // Create the filename based on the naming convention + std::string filename = folderPath +"\\" + firstChar + secondChar + ".jdbf"; + //printf("Loading %s\n", filename.c_str()); + + // Open the file + HANDLE hFile = CreateFile(filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) { + log(LOGLEVEL::ERR, "[initialize()]: Error opening database file: ", filename); + continue; // Move on to the next file if there's an error + } + + // Create the file mapping + HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); + if (hMapping == NULL) { + log(LOGLEVEL::ERR, "[initialize()]: Error creating database file mapping: ", filename); + CloseHandle(hFile); + continue; // Move on to the next file if there's an error + } + + // Map the file into memory + char* fileDataPtr = static_cast(MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0)); + if (fileDataPtr == NULL) { + log(LOGLEVEL::ERR, "[initialize()]: Error mapping database file: ", filename); + CloseHandle(hMapping); + CloseHandle(hFile); + continue; // Move on to the next file if there's an error + } + + // Store the handles in the global maps + fileHandles[filename] = hFile; + mappingHandles[filename] = hMapping; + fileData[filename] = fileDataPtr; + } + } +} + + +// Call this function when you are done using the file mappings +void cleanup() { + for (const auto& entry : fileHandles) { + UnmapViewOfFile(fileData[entry.first]); + CloseHandle(mappingHandles[entry.first]); + CloseHandle(entry.second); + } + + // Clear the global maps + fileHandles.clear(); + mappingHandles.clear(); + fileData.clear(); +} +//the latest and fastest version of searching a hash by now +int search_hash(const std::string& dbname_, const std::string& hash_, const std::string& filepath_) { + // Check if the file mapping is already open for the given filename + thread_local std::string dbname (dbname_); + thread_local std::string hash (hash_); + thread_local std::string filepath (filepath_); + + thread_local auto fileIter = fileHandles.find(dbname); + if (fileIter == fileHandles.end() or dbname_.find("c:.jdbf") != std::string::npos) { + log(LOGLEVEL::ERR, "[search_hash()]: File mapping not initialized for ", dbname); + return 2; + } + + // Use fileData for subsequent searches + thread_local DWORD fileSize = GetFileSize(fileHandles[dbname], NULL); + thread_local std::string fileContent(fileData[dbname], fileSize); + + // Search for the specific string in the file content + thread_local size_t foundPos = fileContent.find(hash); + if (foundPos != std::string::npos) { + log(LOGLEVEL::VIRUS, "[search_hash()]: Found virus: ", hash, " in file: ", filepath); + virus_ctrl_store(filepath.c_str(), hash.c_str(), hash.c_str()); + //afterwards do the processing with that file + virus_ctrl_process(hash.c_str()); + return 1; // Found + } + return 0; // Not found +} +bool file_exists(const std::string& filePath) { + DWORD fileAttributes = GetFileAttributes(filePath.c_str()); + + if (fileAttributes == INVALID_FILE_ATTRIBUTES) { + // The file does not exist or there was an error + return false; + } + + // Check if it's a regular file and not a directory + return (fileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0; +} + +//this is the main function to scan folders. it will then start multuiple threads based on the number of cores / settings +void scan_folder(const std::string& directory) { + std::string search_path = directory + "\\*.*"; + WIN32_FIND_DATA find_file_data; + HANDLE hFind = FindFirstFile(search_path.c_str(), &find_file_data); + + if (hFind == INVALID_HANDLE_VALUE) { + log(LOGLEVEL::ERR, "[scan_folder()]: Error opening directory: ", search_path.c_str() , " while scanning files inside folder."); + return; + } + + do { + if (strcmp(find_file_data.cFileName, ".") == 0 || strcmp(find_file_data.cFileName, "..") == 0) { + continue; // Skip the current and parent directories + } + + + const std::string full_path = directory + "\\" + find_file_data.cFileName; + if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + // If it's a directory, recurse into it + scan_folder(full_path); + } + else { + //action scanfile_t will start the trheads for scanning the hashes + //action_scanfile_t(full_path.c_str()); + + //do multithreading here + while (num_threads >= std::thread::hardware_concurrency()) { + Sleep(10); + } + num_threads++; + std::thread scan_thread(scan_file_t, full_path); + scan_thread.detach(); + + cnt++; + if (cnt % 100 == 0) { + printf("Processed %d files;\n", cnt); + //printf("Number of threads: %d\n", num_threads); + } + } + } while (FindNextFile(hFind, &find_file_data) != 0); + + FindClose(hFind); +} + + + +//for singlethreaded scans +void action_scanfile(const char*filepath) { + thread_init(); + char* db_path = new char[300]; + + //log(LOGLEVEL::INFO, "[action_scanfile_t()]: Scanning file: ", filepath); + if (strlen(filepath) == 0 or strcmp("", filepath) == 0 or file_exists(filepath) == false) { + thread_shutdown(); + return; //no filepath given or file not accessible + } + else { + char* hash = new char[300]; + hash[0] = '\0'; + strcpy_s(hash, 295, md5_file_t(filepath).c_str()); + sprintf_s(db_path, 295, "%s\\%c%c.jdbf", DB_DIR, hash[0], hash[1]); + search_hash(db_path, hash, filepath); + delete[] hash; + } + delete[] db_path; + thread_shutdown(); +} +void action_scanfolder(const char*folderpath) { + thread_init(); + cnt = 0; + thread_local std::string folderpath_ (folderpath); + scan_folder(folderpath_); + thread_shutdown(); +} + +void scan_file_t(const std::string& filepath_) { + thread_local const std::string filepath (filepath_); + thread_local char* db_path = new char[300]; + thread_local char* hash = new char[300]; + strcpy_s(hash,295 ,md5_file_t(filepath).c_str()); + sprintf_s(db_path, 295, "%s\\%c%c.jdbf", DB_DIR, hash[0], hash[1]); + search_hash(db_path, hash, filepath); + num_threads--; +} +#endif \ No newline at end of file diff --git a/src/client_backend/settings.cpp b/src/client_backend/settings.cpp index c710d0e..e5b46e6 100644 --- a/src/client_backend/settings.cpp +++ b/src/client_backend/settings.cpp @@ -7,7 +7,10 @@ int setting_virus_ctrl_virus_found_action = 0; char*setting_server_server_url = new char[300]; char exluded_folders[100][300]; int excluded_folders_size = 0; +char included_folders[100][300]; +int included_folders_size = 0; bool setting_rtp_folder_scan_status = 1; //0=off, 1=on +void load_included_folders(); void load_excluded_folders(); int load_settings() { FILE* fp; @@ -58,6 +61,7 @@ int load_settings() { delete[] settings_cmd; delete[] settings_arg; } + load_included_folders(); load_excluded_folders(); return 0; } @@ -82,6 +86,47 @@ int get_setting(const char* setting_name,char*out) { return -1; } +void load_included_folders() { + FILE* fp; + if (fopen_s(&fp, INCLUDED_FOLDERS, "r") != 0) { + log(LOGLEVEL::ERR, "[load_included_files()]: Could not open included folders file. ", INCLUDED_FOLDERS); + return; + } + else { + char* path = new char[300]; + while (!feof(fp)) { + //get the path of an excluded folder + path[0] = '\0'; + //the path is encapsulated with " + int cnt = 0; + int chr = 0; + chr = fgetc(fp); + if (chr == '\"') { + chr = 0; + while (cnt < 295 && chr != '\"') { + chr = fgetc(fp); //get a char + if (chr != '\"') + path[cnt] = chr; + path[cnt + 1] = '\0'; + cnt++; + } + //now add the path to the array + if (included_folders_size < 95) { + strcpy_s(included_folders[included_folders_size], 295, path); + included_folders_size++; + } + else { + log(LOGLEVEL::ERR, "[load_included_files()]: included folders array is full. Cannot add more folders."); + } + } + //else { we dont need to error out here. it is normal that it givs errors at the last lien of the file. but nothing bad happens, so errors arent needed + // log(LOGLEVEL::ERR, "[load_excluded_folders()]: Error while processing excluded folders database. Expected \" but got ", chr); + //} + } + fclose(fp); + delete[] path; + } +} void load_excluded_folders() { FILE* fp; if (fopen_s(&fp, EXCLUDED_FOLDERS, "r") != 0) { @@ -121,17 +166,25 @@ void load_excluded_folders() { } fclose(fp); delete[] path; - } + } } -bool is_folder_excluded(const char*path) { - for (int i = 0; i < excluded_folders_size; i++) { - if (strstr(path,exluded_folders[i]) != 0 and strcmp(exluded_folders[i],"")!=0 and strcmp(exluded_folders[i], " ") != 0 ) { +bool is_folder_included(const char*path) { + for (int i = 0; i < included_folders_size; i++) { + if (strstr(path,included_folders[i]) != 0 and strcmp(included_folders[i],"")!=0 and strcmp(included_folders[i], " ") != 0 ) { return true; } } return false; } -void print_exclusions() { +bool is_folder_excluded(const char* path) { + for (int i = 0; i < excluded_folders_size; i++) { + if (strstr(path, exluded_folders[i]) != 0 and strcmp(exluded_folders[i], "") != 0 and strcmp(exluded_folders[i], " ") != 0) { + return true; + } + } + return false; +} +void print_inclusuions() { for (int i = 0; i < excluded_folders_size; i++) { log(LOGLEVEL::INFO, "[print_exclusions()]: Excluded folder: ", exluded_folders[i]); } diff --git a/src/client_backend/settings.h b/src/client_backend/settings.h index d3f66be..76a3aa7 100644 --- a/src/client_backend/settings.h +++ b/src/client_backend/settings.h @@ -6,6 +6,7 @@ int get_setting(const char* setting_name); int get_setting(const char* setting_name,char*out); int load_settings(); +bool is_folder_included(const char* path); bool is_folder_excluded(const char* path); -void print_exclusions(); +void print_inclusions(); #endif \ No newline at end of file diff --git a/src/client_backend/well_known.h b/src/client_backend/well_known.h index 5638803..51d3507 100644 --- a/src/client_backend/well_known.h +++ b/src/client_backend/well_known.h @@ -34,5 +34,6 @@ #define PERIODIC_FOLDER_SCAN "C:\\Program Files\\cyberhex\\secure\\database\\folder\\periodic_folder_scan.txt" #define PERIODIC_FOLDER_SCAN_TEMP_DB "C:\\Program Files\\cyberhex\\secure\\database\\folder\\temp_db.txt" +#define INCLUDED_FOLDERS "C:\\Program Files\\cyberhex\\secure\\settings\\included_folders.txt" #define EXCLUDED_FOLDERS "C:\\Program Files\\cyberhex\\secure\\settings\\excluded_folders.txt" #endif // !WELL_KNOWN_H \ No newline at end of file diff --git a/src/client_backend/x64/Debug/client_backend.ilk b/src/client_backend/x64/Debug/client_backend.ilk index 4e440a7..a5bdfc3 100644 Binary files a/src/client_backend/x64/Debug/client_backend.ilk and b/src/client_backend/x64/Debug/client_backend.ilk differ diff --git a/src/client_backend/x64/Debug/client_backend.log b/src/client_backend/x64/Debug/client_backend.log index 648c73e..2ee27ad 100644 --- a/src/client_backend/x64/Debug/client_backend.log +++ b/src/client_backend/x64/Debug/client_backend.log @@ -1,2 +1,4 @@  Quellen werden auf Modulabhängigkeiten überprüft... + scan.cpp +C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\scan.cpp(153,32): warning C4018: ">=": Konflikt zwischen "signed" und "unsigned" client_backend.vcxproj -> C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\x64\Debug\client_backend.exe diff --git a/src/client_backend/x64/Debug/client_backend.pdb b/src/client_backend/x64/Debug/client_backend.pdb index c214a14..40f9c13 100644 Binary files a/src/client_backend/x64/Debug/client_backend.pdb and b/src/client_backend/x64/Debug/client_backend.pdb differ diff --git a/src/client_backend/x64/Debug/client_backend.tlog/CL.command.1.tlog b/src/client_backend/x64/Debug/client_backend.tlog/CL.command.1.tlog index 88284f4..4965484 100644 Binary files a/src/client_backend/x64/Debug/client_backend.tlog/CL.command.1.tlog and b/src/client_backend/x64/Debug/client_backend.tlog/CL.command.1.tlog differ diff --git a/src/client_backend/x64/Debug/client_backend.tlog/CL.read.1.tlog b/src/client_backend/x64/Debug/client_backend.tlog/CL.read.1.tlog index e5f9ef8..0b2ef22 100644 Binary files a/src/client_backend/x64/Debug/client_backend.tlog/CL.read.1.tlog and b/src/client_backend/x64/Debug/client_backend.tlog/CL.read.1.tlog differ diff --git a/src/client_backend/x64/Debug/client_backend.tlog/CL.write.1.tlog b/src/client_backend/x64/Debug/client_backend.tlog/CL.write.1.tlog index 66a4072..ce698ff 100644 Binary files a/src/client_backend/x64/Debug/client_backend.tlog/CL.write.1.tlog and b/src/client_backend/x64/Debug/client_backend.tlog/CL.write.1.tlog differ diff --git a/src/client_backend/x64/Debug/client_backend.tlog/client_backend.write.1u.tlog b/src/client_backend/x64/Debug/client_backend.tlog/client_backend.write.1u.tlog index 3d84f61..630abd5 100644 Binary files a/src/client_backend/x64/Debug/client_backend.tlog/client_backend.write.1u.tlog and b/src/client_backend/x64/Debug/client_backend.tlog/client_backend.write.1u.tlog differ diff --git a/src/client_backend/x64/Debug/client_backend.tlog/link.read.1.tlog b/src/client_backend/x64/Debug/client_backend.tlog/link.read.1.tlog index b7aea25..a8885b8 100644 Binary files a/src/client_backend/x64/Debug/client_backend.tlog/link.read.1.tlog and b/src/client_backend/x64/Debug/client_backend.tlog/link.read.1.tlog differ diff --git a/src/client_backend/x64/Debug/vc143.idb b/src/client_backend/x64/Debug/vc143.idb index de860c5..d25834d 100644 Binary files a/src/client_backend/x64/Debug/vc143.idb and b/src/client_backend/x64/Debug/vc143.idb differ diff --git a/src/client_backend/x64/Debug/vc143.pdb b/src/client_backend/x64/Debug/vc143.pdb index b406105..c3f0c76 100644 Binary files a/src/client_backend/x64/Debug/vc143.pdb and b/src/client_backend/x64/Debug/vc143.pdb differ diff --git a/src/ma_installer/.vs/ma_installer/v17/.suo b/src/ma_installer/.vs/ma_installer/v17/.suo index f6e9a8e..3a4da5b 100644 Binary files a/src/ma_installer/.vs/ma_installer/v17/.suo and b/src/ma_installer/.vs/ma_installer/v17/.suo differ diff --git a/src/ma_installer/.vs/ma_installer/v17/Browse.VC.db b/src/ma_installer/.vs/ma_installer/v17/Browse.VC.db index 592f868..2d55a24 100644 Binary files a/src/ma_installer/.vs/ma_installer/v17/Browse.VC.db and b/src/ma_installer/.vs/ma_installer/v17/Browse.VC.db differ diff --git a/src/ma_installer/.vs/ma_installer/v17/ipch/AutoPCH/d30ea52e71910fa3/MA_INSTALLER.ipch b/src/ma_installer/.vs/ma_installer/v17/ipch/AutoPCH/d30ea52e71910fa3/MA_INSTALLER.ipch index e7f17b1..8e9aad0 100644 Binary files a/src/ma_installer/.vs/ma_installer/v17/ipch/AutoPCH/d30ea52e71910fa3/MA_INSTALLER.ipch and b/src/ma_installer/.vs/ma_installer/v17/ipch/AutoPCH/d30ea52e71910fa3/MA_INSTALLER.ipch differ diff --git a/src/ma_installer/x64/Debug/ma_installer.ilk b/src/ma_installer/x64/Debug/ma_installer.ilk index 6dad637..1286dd3 100644 Binary files a/src/ma_installer/x64/Debug/ma_installer.ilk and b/src/ma_installer/x64/Debug/ma_installer.ilk differ diff --git a/src/ma_installer/x64/Debug/ma_installer.pdb b/src/ma_installer/x64/Debug/ma_installer.pdb index 0bb1a7f..42248cf 100644 Binary files a/src/ma_installer/x64/Debug/ma_installer.pdb and b/src/ma_installer/x64/Debug/ma_installer.pdb differ diff --git a/src/ma_installer/x64/Debug/ma_installer.tlog/link.read.1.tlog b/src/ma_installer/x64/Debug/ma_installer.tlog/link.read.1.tlog index 2c13e1a..f1ae0c8 100644 Binary files a/src/ma_installer/x64/Debug/ma_installer.tlog/link.read.1.tlog and b/src/ma_installer/x64/Debug/ma_installer.tlog/link.read.1.tlog differ diff --git a/src/ma_installer/x64/Debug/ma_installer.tlog/link.write.1.tlog b/src/ma_installer/x64/Debug/ma_installer.tlog/link.write.1.tlog index a78c0f7..a1d2cb1 100644 Binary files a/src/ma_installer/x64/Debug/ma_installer.tlog/link.write.1.tlog and b/src/ma_installer/x64/Debug/ma_installer.tlog/link.write.1.tlog differ diff --git a/src/ma_installer/x64/Debug/ma_installer.tlog/ma_installer.write.1u.tlog b/src/ma_installer/x64/Debug/ma_installer.tlog/ma_installer.write.1u.tlog index 7ee8794..1873951 100644 Binary files a/src/ma_installer/x64/Debug/ma_installer.tlog/ma_installer.write.1u.tlog and b/src/ma_installer/x64/Debug/ma_installer.tlog/ma_installer.write.1u.tlog differ diff --git a/src/ma_installer/x64/Debug/vc143.idb b/src/ma_installer/x64/Debug/vc143.idb index 2794eb4..614854a 100644 Binary files a/src/ma_installer/x64/Debug/vc143.idb and b/src/ma_installer/x64/Debug/vc143.idb differ diff --git a/src/ma_installer/x64/Debug/vc143.pdb b/src/ma_installer/x64/Debug/vc143.pdb index 7e9a7c3..3725073 100644 Binary files a/src/ma_installer/x64/Debug/vc143.pdb and b/src/ma_installer/x64/Debug/vc143.pdb differ diff --git a/src/server/cyberhex-code/system/secure_zone/php/client_settings.php b/src/server/cyberhex-code/system/secure_zone/php/client_settings.php index 8be2725..eaba58b 100644 --- a/src/server/cyberhex-code/system/secure_zone/php/client_settings.php +++ b/src/server/cyberhex-code/system/secure_zone/php/client_settings.php @@ -25,6 +25,31 @@ include "../../../config.php"; $setting_virus_ctrl_virus_found_action = "not configured yet"; $setting_server_server_url="not configured yet"; $setting_rtp_folder_scan_status=0; +function safe_settings(){ + $conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD,$DB_DATABASE); + if ($conn->connect_error) { + $success=0; + die("Connection failed: " . $conn->connect_error); + } + $value=htmlspecialchars($_GET["value"]); + //update what should be done if a virus is found + if($_GET["name"]=="setting_virus_ctrl_virus_found_action"){ + $stmt = $conn->prepare("INSERT INTO settings (value) VALUES (?) WHERE name = 'virus_ctrl:virus_found:action' DUPLICATE KEY UPDATE value = ? WHERE name = 'virus_ctrl:virus_found:action';"); + $stmt->bind_param("ss", $value,$value); + $stmt->execute(); + $stmt->close(); + $conn->close(); + } + //update rtp folder scanner + if($_GET["name"]=="setting_virus_ctrl_virus_found_action"){ + $stmt = $conn->prepare("INSERT INTO settings (value) VALUES (?) WHERE name = 'rtp_folder_scan:status';"); + $stmt->bind_param("ss", $value,$value); + $stmt->execute(); + $stmt->close(); + $conn->close(); + } + +} function load_settings(){ $conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE); if ($conn->connect_error) {