228 lines
8.4 KiB
C++
228 lines
8.4 KiB
C++
|
#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;
|
|||
|
|
|||
|
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();
|
|||
|
}
|