diff --git a/5 СЕМ/БСИТ/2 ЛАБА/WMI.cpp b/5 СЕМ/БСИТ/2 ЛАБА/WMI.cpp new file mode 100644 index 0000000..b6a21fc --- /dev/null +++ b/5 СЕМ/БСИТ/2 ЛАБА/WMI.cpp @@ -0,0 +1,229 @@ +#define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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& fileMap); +void checkDirs(const wstring& path, IWbemServices* pSvc, map& fileMap); +void checkObjects(const wstring& path, IWbemServices* pSvc, + const wstring& query, const wstring& objectType, map& 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> 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 prevFileMap; // Карта предыдущих файлов + vector 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 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& 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& 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& 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(); +} \ No newline at end of file diff --git a/5 СЕМ/БСИТ/2 ЛАБА/test_libzip_library.c b/5 СЕМ/БСИТ/2 ЛАБА/test_libzip_library.c index 5d8a361..48082a6 100644 --- a/5 СЕМ/БСИТ/2 ЛАБА/test_libzip_library.c +++ b/5 СЕМ/БСИТ/2 ЛАБА/test_libzip_library.c @@ -20,19 +20,20 @@ int isMatch(wchar_t* str, void consoleEncodingNormalize(void); -void zipDir(wchar_t* zipDirPath, - wchar_t* zipDirArchive, - wchar_t* mask); +void zipDir(wchar_t* zipDirPath, + wchar_t* zipDirArchive, + wchar_t** masks); void _zipDir(wchar_t* directory, - zip_t* zipArchive, - wchar_t* baseDirectory, - wchar_t* mask); + zip_t* zipArchive, + wchar_t* baseDirectory, + wchar_t** masks); + +int readConfig(const wchar_t* filename, + wchar_t* zipDirPath, + wchar_t* zipDirArchive, + wchar_t** masks); -int readConfig(const wchar_t* filename, - wchar_t* zipDirPath, - wchar_t* zipDirArchive, - wchar_t* mask); // функции для работы сервиса void ServiceMain(DWORD argc, LPTSTR* argv); @@ -43,6 +44,15 @@ int removeService(); int startService(); 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_HANDLE hStatus; LPTSTR servicePath = Path; @@ -101,29 +111,46 @@ void ServiceMain(DWORD argc, LPTSTR* argv) { SetServiceStatus(hStatus, &serviceStatus); wchar_t zipDirPath[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(zipDirArchive, 228); - addLogMessage(mask, 228); while (serviceStatus.dwCurrentState == SERVICE_RUNNING) { addLogMessage(L"Работает", 0); - zipDir(zipDirPath, zipDirArchive, mask); // + zipDir(zipDirPath, zipDirArchive, masks); // addLogMessage(L"Vishel iz zipDir", 228); Sleep(5000); i++; } + // mem clear + for (int i = 0; i < MMAX_ROWS; i++) { + free((void*)masks[i]); + } + free((void*)masks); return; } -void getConfigData(FILE* file, wchar_t* p) { +int getConfigData(FILE* file, wchar_t* p) { addLogMessage(L"[ЧЕКПОИНТ] Я в getConfigData", 0); - wchar_t buffer[MMAX_PATH] = { 0 }; if (fgetws(buffer, MMAX_PATH, file) != NULL) { @@ -139,36 +166,39 @@ void getConfigData(FILE* file, wchar_t* p) { p[len - 1] = L'\0'; } } + return 1; } else { addLogMessage(L"[ОШИБКА] fgetws(buffer, MMAX_PATH, file) == NULL", 0); + return 0; } } // // Функция для чтения конфигурационного файла int readConfig( - const wchar_t* filename, - wchar_t* zipDirPath, - wchar_t* zipDirArchive, - wchar_t* mask) { + const wchar_t* filename, + wchar_t* zipDirPath, + wchar_t* zipDirArchive, + wchar_t** masks) { 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) { - addLogMessage(L"Не открылся файл конфига:", err); return 0; // Изменено на false } getConfigData(file, zipDirPath); getConfigData(file, zipDirArchive); - getConfigData(file, mask); + + int i = -1; + while (getConfigData(file, masks[++i]) && (i < MMAX_ROWS)); // маски считываем пока они есть. построчно fclose(file); 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-архив addLogMessage(L"zashel v zipDir", 228); 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); 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) { - addLogMessage(L"ne udalos sozdat zipfile", 228); - //_tprintf(L"Не удалось создать ZIP файл\n"); - return; + zipArchive = zip_open(cArchivePath, ZIP_TRUNCATE, &err); + if (!zipArchive) { + //_tprintf(L"Не удалось открыть ZIP файл\n"); + addLogMessage(L"ne udalos sozdat zipfile", 228); + return; + } } addLogMessage(L"zipfile sozdan, zahodim v _zipDir", 228); //_tprintf(L"ZIP файл был создан по пути: %s\n", archivePath); - _zipDir(zipDirPath, zipArchive, zipDirPath, mask); + _zipDir(zipDirPath, zipArchive, zipDirPath, masks); zip_close(zipArchive); } void _zipDir(wchar_t* directory, zip_t* zipArchive, wchar_t* baseDirectory, - wchar_t* mask) { + wchar_t** masks) { WIN32_FIND_DATA FindFileData; HANDLE hFind; @@ -254,12 +288,23 @@ void _zipDir(wchar_t* directory, //_tprintf(TEXT("[ДИРЕКТОРИЯ] %s\n"), FindFileData.cFileName); // Рекурсивный вызов для поддиректории - _zipDir(filePath, zipArchive, baseDirectory, mask); + _zipDir(filePath, zipArchive, baseDirectory, masks); } else { //_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]; @@ -282,6 +327,7 @@ void _zipDir(wchar_t* directory, } } } + CONTINUE:; } while (FindNextFile(hFind, &FindFileData) != 0); FindClose(hFind);