Удалить 5 СЕМ/БСИТ/2 ЛАБА/test_libzip_library.c

master
serr 2024-12-07 17:17:10 +03:00
parent be34ebba76
commit 86ff8bc787
1 changed files with 0 additions and 529 deletions

View File

@ -1,529 +0,0 @@
#include <Windows.h>
#include <stdio.h>
#include <tchar.h>
#include <locale.h>
#include <zip.h>
#define MMAX_PATH MAX_PATH
// название сервиса
#define serviceName _T("aaaa_ARCHIVER")
// путь к конфигу
#define configFile _T("C:/Users/user/Desktop/LIBZIP_ARCHIEVER_SERVICE/config.txt")
// путь к файлу с логами
#define logfileName _T("C:/Users/user/Desktop/LIBZIP_ARCHIEVER_SERVICE/log.txt")
// путь к исполняемому файлу
#define Path _T("C:/Users/user/Desktop/LIBZIP_ARCHIEVER_SERVICE/x64/Debug/test_libzip_library.exe")
// функции для архивирования
int isMatch(wchar_t* str,
wchar_t* pattern);
void consoleEncodingNormalize(void);
void zipDir(wchar_t* zipDirPath,
wchar_t* zipDirArchive,
wchar_t** masks);
void _zipDir(wchar_t* directory,
zip_t* zipArchive,
wchar_t* baseDirectory,
wchar_t** masks);
int readConfig(const wchar_t* filename,
wchar_t* zipDirPath,
wchar_t* zipDirArchive,
wchar_t** masks);
// функции для работы сервиса
void ServiceMain(DWORD argc, LPTSTR* argv);
void ControlHandler(DWORD request);
int addLogMessage(wchar_t* str, int code);
int installService();
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;
HANDLE hServiceEvent;
int _tmain(int argc, _TCHAR* argv[]) {
consoleEncodingNormalize();
if (argc - 1 == 0) {
SERVICE_TABLE_ENTRY ServiceTable[] =
{
{(LPWSTR)serviceName, (LPSERVICE_MAIN_FUNCTION)ServiceMain},
{NULL, NULL}
};
if (!StartServiceCtrlDispatcher(ServiceTable)) {
addLogMessage(L"Error: StartServiceCtrlDispatcher", GetLastError());
}
}
else if (wcscmp(argv[argc - 1], _T("stop")) == 0) { // осталось
stopService();
}
else if (wcscmp(argv[argc - 1], _T("install")) == 0) {
installService();
}
else if (wcscmp(argv[argc - 1], _T("remove")) == 0) {
removeService();
}
else if (wcscmp(argv[argc - 1], _T("start")) == 0) {
startService();
}
}
void ServiceMain(DWORD argc, LPTSTR* argv) {
addLogMessage(L"\nЯ в ServiceMain", 1);
int error;
int i = 0;
serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
serviceStatus.dwCurrentState = SERVICE_START_PENDING;
serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
serviceStatus.dwWin32ExitCode = 0;
serviceStatus.dwServiceSpecificExitCode = 0;
serviceStatus.dwCheckPoint = 0;
serviceStatus.dwWaitHint = 0;
hStatus = RegisterServiceCtrlHandler(serviceName, (LPHANDLER_FUNCTION)ControlHandler);
if (hStatus == (SERVICE_STATUS_HANDLE)0) {
return;
}
error = initService();
if (error) {
serviceStatus.dwCurrentState = SERVICE_STOPPED;
serviceStatus.dwWin32ExitCode = -1;
SetServiceStatus(hStatus, &serviceStatus);
return;
}
serviceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(hStatus, &serviceStatus);
wchar_t zipDirPath[MMAX_PATH];
wchar_t zipDirArchive[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);
}
addLogMessage(zipDirPath, 228);
addLogMessage(zipDirArchive, 228);
while (serviceStatus.dwCurrentState == SERVICE_RUNNING)
{
addLogMessage(L"Работает", 0);
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;
}
int getConfigData(FILE* file, wchar_t* p) {
addLogMessage(L"[ЧЕКПОИНТ] Я в getConfigData", 0);
wchar_t buffer[MMAX_PATH] = { 0 };
if (fgetws(buffer, MMAX_PATH, file) != NULL) {
addLogMessage(L"[ЧЕКПОИНТ] getConfigData", 0);
addLogMessage(buffer, 0);
addLogMessage(L"\n", 0);
wchar_t* t = wcschr(buffer, L' ');
if (t) {
wcscpy_s(p, MMAX_PATH, t + 1);
size_t len = wcslen(p);
if (len > 0 && p[len - 1] == L'\n') {
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** masks) {
FILE* file;
_wfopen_s(&file, filename, L"r, ccs=UTF-8"); // Используем кодировку UTF-8 чтобы русские слова корректно читать
if (file == NULL) {
return 0; // Изменено на false
}
getConfigData(file, zipDirPath);
getConfigData(file, zipDirArchive);
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** masks) {
// Создаем ZIP-архив
addLogMessage(L"zashel v zipDir", 228);
char cArchivePath[MMAX_PATH] = { 0 };
wchar_t archivePath[MMAX_PATH] = { 0 };
// формирование полного пути к архиву
addLogMessage(L"Перед формированием пути", 228);
errno_t err;
addLogMessage(zipDirArchive, 1);
err = wcsncpy_s(archivePath, MMAX_PATH, zipDirArchive, wcslen(zipDirArchive));
if (err != 0) {
// Обработка ошибки
addLogMessage(L"wcsncpy_s error:", err);
return; // или exit(1);
}
err = wcscat_s(archivePath, MMAX_PATH, wcsrchr(zipDirPath, TEXT('/')));
if (err != 0) {
// Обработка ошибки
addLogMessage(L"wcscat_s error:", err);
return; // или exit(1);
}
err = wcscat_s(archivePath, MMAX_PATH, L".zip");
if (err != 0) {
// Обработка ошибки
addLogMessage(L"wcscat_s error:", err);
return; // или exit(1);
}
addLogMessage(L"sformiroval put", 228);
//_tprintf(TEXT("[ПОЛНЫЙ ПУТЬ К АРХИВУ] %s\n"), archivePath);
WideCharToMultiByte(CP_UTF8, 0, archivePath, -1, cArchivePath, MMAX_PATH, NULL, NULL);
// Проверка на существование архива
zip_t* zipArchive = zip_open(cArchivePath, ZIP_CREATE | ZIP_TRUNCATE, &err);
if (!zipArchive) {
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, masks);
zip_close(zipArchive);
}
void _zipDir(wchar_t* directory,
zip_t* zipArchive,
wchar_t* baseDirectory,
wchar_t** masks) {
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
// Формируем строку для поиска файлов и директорий
wchar_t searchPath[MMAX_PATH] = { 0 };
//_snwprintf_s(searchPath, MMAX_PATH, TEXT("%s/*.*"), directory);
wcscat_s(searchPath, MMAX_PATH, directory);
wcscat_s(searchPath, MMAX_PATH, L"/*.*");
//_tprintf(L"searchPath = %s\n", searchPath);
hFind = FindFirstFile(searchPath, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE) {
//printf("FindFirstFile вернулось с ошибкой: (%d)\n", GetLastError());
return;
}
else {
do {
// Игнорируем папки "." и ".."
if (_tcscmp(FindFileData.cFileName, TEXT(".")) != 0 &&
_tcscmp(FindFileData.cFileName, TEXT("..")) != 0)
{
wchar_t filePath[MMAX_PATH] = { 0 };
//_snwprintf_s(filePath, MMAX_PATH, TEXT("%s/%s"), directory, FindFileData.cFileName);
wcscat_s(filePath, MMAX_PATH, directory);
wcscat_s(filePath, MMAX_PATH, L"/");
wcscat_s(filePath, MMAX_PATH, FindFileData.cFileName);
if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
//_tprintf(TEXT("[ДИРЕКТОРИЯ] %s\n"), FindFileData.cFileName);
// Рекурсивный вызов для поддиректории
_zipDir(filePath, zipArchive, baseDirectory, masks);
}
else {
//_tprintf(TEXT("[ФАЙЛ] %s\n"), FindFileData.cFileName);
// проверка на совпадения по маскам
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];
// Преобразую юникодный путь в обычный байтовый, т.к. libzip`ные ф-ии требуют char*
WideCharToMultiByte(CP_UTF8, 0, filePath, -1, cfilePath, MMAX_PATH, NULL, NULL);
// Получаем относительный путь для сохранения структуры директории в архиве
wchar_t relativePath[MMAX_PATH];
_snwprintf_s(relativePath, MMAX_PATH, TEXT("%s"), filePath + wcslen(baseDirectory) + 1);
WideCharToMultiByte(CP_UTF8, 0, relativePath, -1, cfileName, MMAX_PATH, NULL, NULL);
// Добавляем файл в архив
zip_source_t* source = zip_source_file(zipArchive, cfilePath, 0, 0);
if (source == NULL || zip_file_add(zipArchive, cfileName, source, ZIP_FL_OVERWRITE) < 0) {
//printf("Ошибка добавления файла %ls в архив: %s\n", filePath, zip_strerror(zipArchive));
if (source) {
zip_source_free(source);
}
}
}
}
CONTINUE:;
} while (FindNextFile(hFind, &FindFileData) != 0);
FindClose(hFind);
}
}
void consoleEncodingNormalize(void) {
// ОС вернет свою кодировку и она будет установлена для консоли
setlocale(LC_ALL, "ru_RU.UTF-8");
}
int isMatch(wchar_t* str, wchar_t* pattern) {
const wchar_t* s = str;
const wchar_t* p = pattern;
const wchar_t* star = NULL;
const wchar_t* ss = NULL;
while (*s) {
if (*p == '?' || *p == *s) {
// Символ совпадает или паттерн - ?
s++;
p++;
}
else if (*p == '*') {
// Найден * в паттерне
star = p++;
ss = s;
}
else if (star) {
// Предыдущий * совпадает с одним символом
p = star + 1;
s = ++ss;
}
else {
return 0;
}
}
// Проверка оставшихся символов в паттерне
while (*p == '*') {
p++;
}
return *p == '\0';
}
//
int installService() {
SC_HANDLE hSCManager = OpenSCManager(NULL, NULL,
SC_MANAGER_CREATE_SERVICE);
if (!hSCManager) {
addLogMessage(L"Error: Can't open Service Control Manager", GetLastError());
return -1;
}
SC_HANDLE hService = CreateService(
hSCManager,
serviceName,
serviceName,
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
servicePath,
NULL, NULL, NULL, NULL, NULL
);
if (!hService) {
int err = GetLastError();
switch (err) {
case ERROR_ACCESS_DENIED:
addLogMessage(L"Error: ERROR_ACCESS_DENIED", err);
break;
case ERROR_CIRCULAR_DEPENDENCY:
addLogMessage(L"Error: ERROR_CIRCULAR_DEPENDENCY", err);
break;
case ERROR_DUPLICATE_SERVICE_NAME:
addLogMessage(L"Error: ERROR_DUPLICATE_SERVICE_NAME", err);
break;
case ERROR_INVALID_HANDLE:
addLogMessage(L"Error: ERROR_INVALID_HANDLE", err);
break;
case ERROR_INVALID_NAME:
addLogMessage(L"Error: ERROR_INVALID_NAME", err);
break;
case ERROR_INVALID_PARAMETER:
addLogMessage(L"Error: ERROR_INVALID_PARAMETER", err);
break;
case ERROR_INVALID_SERVICE_ACCOUNT:
addLogMessage(L"Error: ERROR_INVALID_SERVICE_ACCOUNT", err);
break;
case ERROR_SERVICE_EXISTS:
addLogMessage(L"Error: ERROR_SERVICE_EXISTS", err);
break;
default:
addLogMessage(L"Error: Undefined", err);
}
CloseServiceHandle(hSCManager);
return -1;
}
CloseServiceHandle(hService);
CloseServiceHandle(hSCManager);
addLogMessage(L"Success install service!", 0);
return 0;
}
int removeService() {
SC_HANDLE hSCManager = OpenSCManager(NULL, NULL,
SC_MANAGER_ALL_ACCESS);
if (!hSCManager) {
addLogMessage(L"Error: Can't open Service Control Manager", GetLastError());
return -1;
}
SC_HANDLE hService = OpenService(hSCManager, serviceName,
SERVICE_STOP | DELETE);
if (!hService) {
addLogMessage(L"Error: Can't remove service", GetLastError());
CloseServiceHandle(hSCManager);
return -1;
}
DeleteService(hService);
CloseServiceHandle(hService);
CloseServiceHandle(hSCManager);
addLogMessage(L"Success remove service!", 0);
return 0;
}
int startService() {
SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
SC_HANDLE hService = OpenService(hSCManager, serviceName, SERVICE_START);
if (!StartService(hService, 0, NULL)) {
CloseServiceHandle(hSCManager);
addLogMessage(L"Error: Can't start service", GetLastError());
return -1;
}
CloseServiceHandle(hService);
CloseServiceHandle(hSCManager);
return 0;
}
int stopService() {
SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
SC_HANDLE hService = OpenService(hSCManager, serviceName, SERVICE_STOP);
SERVICE_STATUS ss;
if (!ControlService(hService, SERVICE_CONTROL_STOP, &ss))
{
CloseServiceHandle(hSCManager);
addLogMessage(L"Невозможно остановить сервис", 0);
return -1;
}
addLogMessage(L"Сервис успешно остановлен", 0);
CloseServiceHandle(hService);
CloseServiceHandle(hSCManager);
return 0;
}
int initService() {
int result = addLogMessage(L"Service started!", 0);
return result;
}
void ControlHandler(DWORD request) {
switch (request)
{
case SERVICE_CONTROL_STOP:
addLogMessage(L"Stopped.", 0);
serviceStatus.dwWin32ExitCode = 0;
serviceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hStatus, &serviceStatus);
return;
case SERVICE_CONTROL_SHUTDOWN:
addLogMessage(L"Shutdown.", 0);
serviceStatus.dwWin32ExitCode = 0;
serviceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hStatus, &serviceStatus);
return;
default:
break;
}
SetServiceStatus(hStatus, &serviceStatus);
return;
}
// только на английском сообщения сюда передавать
int addLogMessage(wchar_t* str, int code) {
errno_t err;
FILE* log;
// Открываем файл для добавления (append) с кодировкой UTF-8
if ((err = _wfopen_s(&log, logfileName, L"a, ccs=UTF-8")) != 0) {
return -1; // Ошибка при открытии файла
}
if (log == NULL) return -1;
// Записываем сообщение в лог
fwprintf(log, L"[code: %d] %s\n", code, str); // Используем fwprintf для записи wstring
fclose(log);
return 0; // Успешное выполнение
}