UCHEBA/5 СЕМ/БСИТ/2 ЛАБА/WMI.cpp

229 lines
8.4 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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();
}