бсит 2 done

master
serr 2024-12-01 23:12:04 +03:00
parent 3a3ba3debb
commit be34ebba76
2 changed files with 308 additions and 33 deletions

View File

@ -0,0 +1,229 @@
#define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING
#include <iostream>
#include <comdef.h>
#include <Wbemidl.h>
#include <Windows.h>
#include <filesystem>
#include <fstream>
#include <map>
#include <string>
#include <codecvt>
#pragma comment(lib, "wbemuuid.lib")
using namespace std;
namespace fs = filesystem;
// ULONGLONG GetFileSizeOrFolderSize(const std::wstring& path);
wstring replaceBackslashes(const wstring& input);
void folderTraversal(const wstring& path, IWbemServices* pSvc);
void checkFiles(const wstring& path, IWbemServices* pSvc, map<wstring, wstring>& fileMap);
void checkDirs(const wstring& path, IWbemServices* pSvc, map<wstring, wstring>& fileMap);
void checkObjects(const wstring& path, IWbemServices* pSvc,
const wstring& query, const wstring& objectType, map<wstring, wstring>& fileMap);
#define CHECK_SECONDS_INTERVAL 2
int main(int argc, char** argv) {
setlocale(LC_ALL, "");
HRESULT hres;
IWbemServices* pSvc = nullptr;
IWbemLocator* pLoc = nullptr;
// Initialize COM
hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres)) {
cout << "Failed to initialize COM library. "
<< "Error code = 0x" << hex << hres << endl;
return 1;
}
// Initialize COM Security
hres = CoInitializeSecurity(
NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL, EOAC_NONE, NULL);
if (FAILED(hres)) {
cout << "Failed to initialize security. "
<< "Error code = 0x" << hex << hres << endl;
CoUninitialize();
return 1;
}
// Create the IWbemLocator object
hres = CoCreateInstance(CLSID_WbemLocator, 0,
CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc);
if (FAILED(hres)) {
cout << "Failed to create IWbemLocator object. " << "Error code = 0x" << hex << hres << endl;
return 1;
}
// Connect to WMI
hres = pLoc->ConnectServer(
_bstr_t(L"ROOT\\CIMV2"),
NULL, NULL, 0, NULL,
0, 0, &pSvc);
if (FAILED(hres)) {
cout << "Could not connect. Error code = 0x" << hex << hres << endl;
pLoc->Release();
return 1;
}
wstring path = L"C:\\Users\\user\\Desktop\\WMI\\config.txt"; // Нужный путь для мониторинга
folderTraversal(path, pSvc);
pLoc->Release();
pSvc->Release();
CoUninitialize();
return 0;
}
wstring replaceBackslashes(const wstring& input) {
wstring output;
size_t pos = 0;
size_t found;
while ((found = input.find(L"\\", pos)) != wstring::npos) {
output.append(input, pos, found - pos); // Добавляем часть строки до найденного символа
output += L"\\\\"; // Добавляем заменяемую строку
pos = found + 1; // Продолжаем поиск с символа после найденного
}
output.append(input, pos, input.length() - pos); // Добавляем оставшуюся часть строки
return output;
}
// ПРИМЕР ЗАПРОСА
// SELECT * FROM CIM_Directory WHERE Drive = 'C:' AND Path = '\\Users\\user\\Desktop\\тестовая директория\\.vs\\'
// Говно, надо через MultiByteToWideChar, но лень
wstring utf8_to_wstring(const string& str) {
wstring_convert<codecvt_utf8<wchar_t>> converter;
return converter.from_bytes(str);
}
// сюда должен идти путь до конфига
void folderTraversal(const wstring& path, IWbemServices* pSvc) {
ifstream configFile(path); // Открываем файл конфигурации
if (!configFile.is_open()) {
wcerr << L"Не удалось открыть файл конфигурации: " << path << endl;
return;
}
// если хочу отслеживать файл, то надо сразу в карту его закинуть и не кидать в вектор,
// потому что этот вектор это вектор путей к директориям
map<wstring, wstring> prevFileMap; // Карта предыдущих файлов
vector<wstring> paths; // Вектор для хранения путей к папкам
string line;
// Чтение путей из файла
while (getline(configFile, line)) {
wstring wline = utf8_to_wstring(line);
// wcout << wline << endl;
paths.push_back(wline);
}
configFile.close(); // Закрываем файл
for (ULONGLONG i = 0; ; ++i) {
try {
map<wstring, wstring> currFileMap; // Карта текущих файлов
// Обработка файлов и директорий текущей директории
for (const auto& path : paths) {
checkFiles(path, pSvc, currFileMap);
checkDirs(path, pSvc, currFileMap);
}
if (i) { // чтобы не сработало для нулевого i (выведутся все файлы и папки при запуске)
// Сравнение карт
for (const auto& file : currFileMap) {
if (prevFileMap.find(file.first) == prevFileMap.end()) {
wcout << L"Новый файл: " << file.first << endl;
}
}
for (const auto& file : prevFileMap) {
if (currFileMap.find(file.first) == currFileMap.end()) {
wcout << L"Удаленный файл: " << file.first << endl;
}
}
}
prevFileMap = currFileMap; // Обновляем предыдущую карту
}
catch (const exception& e) {
wcerr << L"Общая ошибка: " << e.what() << endl;
break;
}
Sleep(CHECK_SECONDS_INTERVAL * 1000);
}
}
void checkFiles(const wstring& path, IWbemServices* pSvc, map<wstring, wstring>& fileMap) {
const wstring query = L"SELECT * FROM CIM_DataFile WHERE Drive = 'C:' AND Path = '" + path + L"'";
checkObjects(path, pSvc, query, L"F", fileMap);
}
void checkDirs(const wstring& path, IWbemServices* pSvc, map<wstring, wstring>& fileMap) {
const wstring query = L"SELECT * FROM CIM_Directory WHERE Drive = 'C:' AND Path = '" + path + L"'";
checkObjects(path, pSvc, query, L"D", fileMap);
}
void checkObjects(const wstring& path, IWbemServices* pSvc,
const wstring& query, const wstring& objectType, map<wstring, wstring>& fileMap) {
IEnumWbemClassObject* pEnumerator = nullptr;
HRESULT hres = pSvc->ExecQuery(
bstr_t("WQL"),
bstr_t(query.c_str()),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator
);
if (FAILED(hres)) {
cout << "ExecQuery failed. Error code = 0x" << hex << hres << endl;
return;
}
IWbemClassObject* pclsObj = nullptr;
ULONG uReturn = 0, count = 0;
while (pEnumerator) {
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if (0 == uReturn) {
break; // Нет больше объектов
}
// Получение имени объекта
VARIANT vtObjectName;
VariantInit(&vtObjectName); // Инициализируем VARIANT
if (SUCCEEDED(pclsObj->Get(L"Name", 0, &vtObjectName, 0, 0))) {
wstring fileName = vtObjectName.bstrVal;
fileMap[fileName] = L""; // Добавляем файл в карту
// wcout << "FILENAME: " << vtObjectName.bstrVal << " SIZE: " << GetFileSizeOrFolderSize(vtObjectName.bstrVal) << endl;
// Если это директория, рекурсивно проверяем её содержимое
if (objectType == L"D") {
wstring subDirPath = (wstring)vtObjectName.bstrVal + L"\\";
checkDirs(replaceBackslashes(subDirPath.substr(2)), pSvc, fileMap);
checkFiles(replaceBackslashes(subDirPath.substr(2)), pSvc, fileMap);
}
}
else {
wcerr << L"Failed to get the Name property." << endl;
}
VariantClear(&vtObjectName); // Очищаем VARIANT после использования
count++; // Увеличиваем счетчик объектов
// Освобождение объекта
pclsObj->Release();
}
pEnumerator->Release();
}

View File

@ -22,17 +22,18 @@ void consoleEncodingNormalize(void);
void zipDir(wchar_t* zipDirPath, void zipDir(wchar_t* zipDirPath,
wchar_t* zipDirArchive, wchar_t* zipDirArchive,
wchar_t* mask); wchar_t** masks);
void _zipDir(wchar_t* directory, void _zipDir(wchar_t* directory,
zip_t* zipArchive, zip_t* zipArchive,
wchar_t* baseDirectory, wchar_t* baseDirectory,
wchar_t* mask); wchar_t** masks);
int readConfig(const wchar_t* filename, int readConfig(const wchar_t* filename,
wchar_t* zipDirPath, wchar_t* zipDirPath,
wchar_t* zipDirArchive, wchar_t* zipDirArchive,
wchar_t* mask); wchar_t** masks);
// функции для работы сервиса // функции для работы сервиса
void ServiceMain(DWORD argc, LPTSTR* argv); void ServiceMain(DWORD argc, LPTSTR* argv);
@ -43,6 +44,15 @@ int removeService();
int startService(); int startService();
int initService(); int initService();
enum ERRORS {
ALLOC_COLS_ERR = -20,
ALLOC_ROWS_ERR,
CONF_READ_ERR
};
#define MMAX_ROWS 20 // максимальное кол-во масок
#define COLS MMAX_PATH
SERVICE_STATUS serviceStatus; SERVICE_STATUS serviceStatus;
SERVICE_STATUS_HANDLE hStatus; SERVICE_STATUS_HANDLE hStatus;
LPTSTR servicePath = Path; LPTSTR servicePath = Path;
@ -101,29 +111,46 @@ void ServiceMain(DWORD argc, LPTSTR* argv) {
SetServiceStatus(hStatus, &serviceStatus); SetServiceStatus(hStatus, &serviceStatus);
wchar_t zipDirPath[MMAX_PATH]; wchar_t zipDirPath[MMAX_PATH];
wchar_t zipDirArchive[MMAX_PATH]; wchar_t zipDirArchive[MMAX_PATH];
wchar_t mask[MMAX_PATH]; wchar_t** masks;
// аллокация памяти под маски
if ((masks = (wchar_t**)calloc(MMAX_ROWS, sizeof(wchar_t*))) != NULL) {
for (int i = 0; i < MMAX_ROWS; i++) {
if ((masks[i] = (wchar_t*)calloc(COLS, sizeof(wchar_t))) == NULL) {
exit(ALLOC_COLS_ERR);
}
}
}
else {
exit(ALLOC_ROWS_ERR);
}
if (readConfig(configFile, zipDirPath, zipDirArchive, masks) == 0) {
exit(CONF_READ_ERR);
}
readConfig(configFile, zipDirPath, zipDirArchive, mask);
addLogMessage(L"Содержимое config.txt по мнению чертовой программы:", 0);
addLogMessage(zipDirPath, 228); addLogMessage(zipDirPath, 228);
addLogMessage(zipDirArchive, 228); addLogMessage(zipDirArchive, 228);
addLogMessage(mask, 228);
while (serviceStatus.dwCurrentState == SERVICE_RUNNING) while (serviceStatus.dwCurrentState == SERVICE_RUNNING)
{ {
addLogMessage(L"Работает", 0); addLogMessage(L"Работает", 0);
zipDir(zipDirPath, zipDirArchive, mask); // zipDir(zipDirPath, zipDirArchive, masks); //
addLogMessage(L"Vishel iz zipDir", 228); addLogMessage(L"Vishel iz zipDir", 228);
Sleep(5000); Sleep(5000);
i++; i++;
} }
// mem clear
for (int i = 0; i < MMAX_ROWS; i++) {
free((void*)masks[i]);
}
free((void*)masks);
return; return;
} }
void getConfigData(FILE* file, wchar_t* p) { int getConfigData(FILE* file, wchar_t* p) {
addLogMessage(L"[ЧЕКПОИНТ] Я в getConfigData", 0); addLogMessage(L"[ЧЕКПОИНТ] Я в getConfigData", 0);
wchar_t buffer[MMAX_PATH] = { 0 }; wchar_t buffer[MMAX_PATH] = { 0 };
if (fgetws(buffer, MMAX_PATH, file) != NULL) { if (fgetws(buffer, MMAX_PATH, file) != NULL) {
@ -139,9 +166,11 @@ void getConfigData(FILE* file, wchar_t* p) {
p[len - 1] = L'\0'; p[len - 1] = L'\0';
} }
} }
return 1;
} }
else { else {
addLogMessage(L"[ОШИБКА] fgetws(buffer, MMAX_PATH, file) == NULL", 0); addLogMessage(L"[ОШИБКА] fgetws(buffer, MMAX_PATH, file) == NULL", 0);
return 0;
} }
} }
// //
@ -150,25 +179,26 @@ int readConfig(
const wchar_t* filename, const wchar_t* filename,
wchar_t* zipDirPath, wchar_t* zipDirPath,
wchar_t* zipDirArchive, wchar_t* zipDirArchive,
wchar_t* mask) { wchar_t** masks) {
FILE* file; FILE* file;
errno_t err = _wfopen_s(&file, filename, L"r, ccs=UTF-8"); // Используем кодировку UTF-8 чтобы русские слова корректно читать _wfopen_s(&file, filename, L"r, ccs=UTF-8"); // Используем кодировку UTF-8 чтобы русские слова корректно читать
if (file == NULL) { if (file == NULL) {
addLogMessage(L"Не открылся файл конфига:", err);
return 0; // Изменено на false return 0; // Изменено на false
} }
getConfigData(file, zipDirPath); getConfigData(file, zipDirPath);
getConfigData(file, zipDirArchive); getConfigData(file, zipDirArchive);
getConfigData(file, mask);
int i = -1;
while (getConfigData(file, masks[++i]) && (i < MMAX_ROWS)); // маски считываем пока они есть. построчно
fclose(file); fclose(file);
return 1; return 1;
} }
// //
// бэкап директории по пути к ней // бэкап директории по пути к ней
void zipDir(wchar_t* zipDirPath, wchar_t* zipDirArchive, wchar_t* mask) { void zipDir(wchar_t* zipDirPath, wchar_t* zipDirArchive, wchar_t** masks) {
// Создаем ZIP-архив // Создаем ZIP-архив
addLogMessage(L"zashel v zipDir", 228); addLogMessage(L"zashel v zipDir", 228);
char cArchivePath[MMAX_PATH] = { 0 }; char cArchivePath[MMAX_PATH] = { 0 };
@ -205,22 +235,26 @@ void zipDir(wchar_t* zipDirPath, wchar_t* zipDirArchive, wchar_t* mask) {
//_tprintf(TEXT("[ПОЛНЫЙ ПУТЬ К АРХИВУ] %s\n"), archivePath); //_tprintf(TEXT("[ПОЛНЫЙ ПУТЬ К АРХИВУ] %s\n"), archivePath);
WideCharToMultiByte(CP_UTF8, 0, archivePath, -1, cArchivePath, MMAX_PATH, NULL, NULL); WideCharToMultiByte(CP_UTF8, 0, archivePath, -1, cArchivePath, MMAX_PATH, NULL, NULL);
zip_t* zipArchive = zip_open(cArchivePath, ZIP_TRUNCATE | ZIP_CREATE, &err); // Проверка на существование архива
zip_t* zipArchive = zip_open(cArchivePath, ZIP_CREATE | ZIP_TRUNCATE, &err);
if (!zipArchive) { if (!zipArchive) {
zipArchive = zip_open(cArchivePath, ZIP_TRUNCATE, &err);
if (!zipArchive) {
//_tprintf(L"Не удалось открыть ZIP файл\n");
addLogMessage(L"ne udalos sozdat zipfile", 228); addLogMessage(L"ne udalos sozdat zipfile", 228);
//_tprintf(L"Не удалось создать ZIP файл\n");
return; return;
} }
}
addLogMessage(L"zipfile sozdan, zahodim v _zipDir", 228); addLogMessage(L"zipfile sozdan, zahodim v _zipDir", 228);
//_tprintf(L"ZIP файл был создан по пути: %s\n", archivePath); //_tprintf(L"ZIP файл был создан по пути: %s\n", archivePath);
_zipDir(zipDirPath, zipArchive, zipDirPath, mask); _zipDir(zipDirPath, zipArchive, zipDirPath, masks);
zip_close(zipArchive); zip_close(zipArchive);
} }
void _zipDir(wchar_t* directory, void _zipDir(wchar_t* directory,
zip_t* zipArchive, zip_t* zipArchive,
wchar_t* baseDirectory, wchar_t* baseDirectory,
wchar_t* mask) { wchar_t** masks) {
WIN32_FIND_DATA FindFileData; WIN32_FIND_DATA FindFileData;
HANDLE hFind; HANDLE hFind;
@ -254,12 +288,23 @@ void _zipDir(wchar_t* directory,
//_tprintf(TEXT("[ДИРЕКТОРИЯ] %s\n"), FindFileData.cFileName); //_tprintf(TEXT("[ДИРЕКТОРИЯ] %s\n"), FindFileData.cFileName);
// Рекурсивный вызов для поддиректории // Рекурсивный вызов для поддиректории
_zipDir(filePath, zipArchive, baseDirectory, mask); _zipDir(filePath, zipArchive, baseDirectory, masks);
} }
else { else {
//_tprintf(TEXT("[ФАЙЛ] %s\n"), FindFileData.cFileName); //_tprintf(TEXT("[ФАЙЛ] %s\n"), FindFileData.cFileName);
if (!isMatch(FindFileData.cFileName, mask)) continue; // проверка на совпадения по маскам
for (int i = 0; i < MMAX_ROWS; ++i) {
if (masks[i][0] && isMatch(FindFileData.cFileName, masks[i])) { // есть совпадение с i-й маской
break; // выходим из цикла во внешний код
}
// иначе если дальше нет масок
// (нулевый первый символ маски означает что там память, заполненная нулями)
else if (!masks[i][0]) {
goto CONTINUE; // continue для внешнего цикла do
}
// иначе смотрим след маску
}
char cfilePath[MMAX_PATH], cfileName[MMAX_PATH]; char cfilePath[MMAX_PATH], cfileName[MMAX_PATH];
@ -282,6 +327,7 @@ void _zipDir(wchar_t* directory,
} }
} }
} }
CONTINUE:;
} while (FindNextFile(hFind, &FindFileData) != 0); } while (FindNextFile(hFind, &FindFileData) != 0);
FindClose(hFind); FindClose(hFind);