Не получается произвести обмен информацией через shared memory

Я пытаюсь создать сервис и клиент.Они должны обмениваться информацией через shared memory и синхронизироваться через мьютекс.Клиент отправляет сервису название файла и символ для замены пробелов. Сервис вполне неплохо запускается и работает, логи пишут что все успешно: " Служба останавливается. Событие остановки успешно создано. Отображаемая на память область успешно создана. Область памяти успешно отображена. Мьютекс успешно создан. Служба запускается."

Клиент же не может получить доступ к памяти:"Не удалось открыть отображаемую на память область."

Вот код сервиса:

#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <stdio.h>

#define SHARED_MEMORY_NAME TEXT("Global\\MySharedMemory") // Изменено на Global
#define LOG_FILE_PATH "C:\\Users\\vitek\\source\\repos\\Server\\x64\\Debug\\service_log.txt"
#define BUFFER_SIZE 256

SERVICE_STATUS_HANDLE g_ServiceStatusHandle = NULL;
SERVICE_STATUS g_ServiceStatus = { 0 };
HANDLE g_hStopEvent = NULL;
HANDLE g_hLogFile = NULL;
HANDLE g_hMutex = NULL;
char* g_pSharedMemory = NULL;
HANDLE g_hMapFile = NULL; // Глобальная переменная для дескриптора отображаемой области памяти

void WINAPI ServiceMain(DWORD argc, LPTSTR* argv);
void WINAPI ServiceCtrlHandler(DWORD CtrlCode);
void ReportServiceStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwCheckPoint, DWORD dwWaitHint);
void ServiceWorkerThread();
void LogEvent(const char* message);
void CreateSharedMemory();

char service[] = TEXT("MyService");

int main() {
SERVICE_TABLE_ENTRY ServiceTable[] = {
    { service, ServiceMain },
    { NULL, NULL }
};

if (StartServiceCtrlDispatcher(ServiceTable) == FALSE) {
    printf("StartServiceCtrlDispatcher failed (%d)\n", GetLastError());
}
return 0;
}

void LogEvent(const char* message) {
if (g_hLogFile == NULL) {
    g_hLogFile = CreateFile(LOG_FILE_PATH, FILE_APPEND_DATA, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (g_hLogFile == INVALID_HANDLE_VALUE) {
        return; // Не удалось открыть файл
    }
}

DWORD written;
SYSTEMTIME st;
GetSystemTime(&st);
char buffer[256];
sprintf(buffer, "[%04d-%02d-%02d %02d:%02d:%02d] %s\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, message);
WriteFile(g_hLogFile, buffer, strlen(buffer), &written, NULL);
}

void CreateSharedMemory() {
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL; // Используем стандартные права доступа
sa.bInheritHandle = FALSE;

g_hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE, 0, BUFFER_SIZE, SHARED_MEMORY_NAME);
if (g_hMapFile == NULL) {
    LogEvent("Не удалось создать отображаемую на память область.");
    return;
}
LogEvent("Отображаемая на память область успешно создана.");

g_pSharedMemory = (char*)MapViewOfFile(g_hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, BUFFER_SIZE);
if (g_pSharedMemory == NULL) {
    LogEvent("Не удалось отобразить область памяти.");
    CloseHandle(g_hMapFile);
    g_hMapFile = NULL; // Обнуляем дескриптор
    return;
}
LogEvent("Область памяти успешно отображена.");

// Инициализация общей памяти
memset(g_pSharedMemory, 0, BUFFER_SIZE);
}

void WINAPI ServiceMain(DWORD argc, LPTSTR* argv) {
g_ServiceStatusHandle = RegisterServiceCtrlHandler(TEXT("MyService"), ServiceCtrlHandler);
if (g_ServiceStatusHandle == 0) {
    LogEvent("Не удалось зарегистрировать обработчик управления службы.");
    return;
}

g_ServiceStatus.dwServiceType = SERVICE_WIN32;
g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
ReportServiceStatus(SERVICE_START_PENDING, NO_ERROR, 0, 3000);

g_hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (g_hStopEvent == NULL) {
    LogEvent("Не удалось создать событие остановки.");
    ReportServiceStatus(SERVICE_STOPPED, NO_ERROR, 0, 0);
    return;
}
LogEvent("Событие остановки успешно создано.");

// Создание общей памяти
CreateSharedMemory();

g_hMutex = CreateMutex(NULL, FALSE, TEXT("Global\\MyMutex")); // Изменено на Global
if (g_hMutex == NULL) {
    LogEvent("Не удалось создать мьютекс.");
    UnmapViewOfFile(g_pSharedMemory);
    g_pSharedMemory = NULL; // Обнуляем дескриптор
    CloseHandle(g_hMapFile); // Закрываем дескриптор отображаемой области памяти
    ReportServiceStatus(SERVICE_STOPPED, NO_ERROR, 0, 0);
    return;
}
LogEvent("Мьютекс успешно создан.");

LogEvent("Служба запускается.");
ReportServiceStatus(SERVICE_RUNNING, NO_ERROR, 0, 0);
ServiceWorkerThread();

LogEvent("Служба останавливается.");
ReportServiceStatus(SERVICE_STOPPED, NO_ERROR, 0, 0);

// Освобождение ресурсов
if (g_hLogFile != NULL) {
    CloseHandle(g_hLogFile);
}
if (g_pSharedMemory != NULL) {
    UnmapViewOfFile(g_pSharedMemory);
}
if (g_hMapFile != NULL) {
    CloseHandle(g_hMapFile); // Закрываем дескриптор отображаемой области памяти
}
CloseHandle(g_hMutex);
}

void WINAPI ServiceCtrlHandler(DWORD CtrlCode) {
switch (CtrlCode) {
case SERVICE_CONTROL_STOP:
    LogEvent("Служба останавливается.");
    ReportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0, 0);
    SetEvent(g_hStopEvent);
    break;
default:
    break;
}
}

void ReportServiceStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwCheckPoint, DWORD dwWaitHint) {
g_ServiceStatus.dwCurrentState = dwCurrentState;
g_ServiceStatus.dwWin32ExitCode = dwWin32ExitCode;
g_ServiceStatus.dwCheckPoint = dwCheckPoint;
g_ServiceStatus.dwWaitHint = dwWaitHint;

SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus);
}

void ServiceWorkerThread() {
while (WaitForSingleObject(g_hStopEvent, 0) != WAIT_OBJECT_0) {
    // Ожидание, пока клиент запишет данные в общую память
    WaitForSingleObject(g_hMutex, INFINITE);

    // Обработка данных
    for (int i = 0; i < BUFFER_SIZE; i++) {
        if (g_pSharedMemory[i] == ' ') {
            g_pSharedMemory[i] = '_'; // Замена пробелов на символ подчеркивания
        }
    }

    // Логирование обработанных данных
    LogEvent(g_pSharedMemory);

    ReleaseMutex(g_hMutex);
    Sleep(1000); // Имитация работы
}
}

вот код клиента:

#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <locale.h>
#include <stdlib.h>

#define SHARED_MEMORY_NAME TEXT("Global\\MySharedMemory") // Изменено на Global
#define LOG_FILE "client_log.txt"
#define BUFFER_SIZE 256

void LogEvent(const char* message);
BOOL IsServiceRunning(const char* serviceName);

int wmain(int argc, wchar_t** argv) {
HANDLE hMutex;
char* g_pSharedMemory;
HANDLE hMapFile;

// Проверка аргументов командной строки
if (argc != 3) {
    wprintf(L"Использование: имя_программы имя_входного_файла(на латинице) символ_который_нужно_заменить\n");
    LogEvent("Неверное количество аргументов командной строки.");
    return -1;
}

// Проверка состояния службы
if (!IsServiceRunning("MyService")) {
    wprintf(L"Служба не запущена. Обработка файла невозможна.\n");
    LogEvent("Служба не запущена. Обработка файла невозможна.");
    return -1;
}

// Открытие отображаемой на память области
hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, SHARED_MEMORY_NAME);
if (hMapFile == NULL) {
    DWORD error = GetLastError();
    wprintf(L"Не удалось открыть отображаемую на память область. Ошибка: %x\n", error);
    LogEvent("Не удалось открыть отображаемую на память область.");
    return -1;
}

g_pSharedMemory = (char*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, BUFFER_SIZE);
if (g_pSharedMemory == NULL) {
    DWORD error = GetLastError();
    wprintf(L"Не удалось отобразить область памяти. Ошибка: %x\n", error);
    LogEvent("Не удалось отобразить область памяти.");
    CloseHandle(hMapFile);
    return -1;
}

// Создание мьютекса
hMutex = OpenMutex(SYNCHRONIZE, FALSE, TEXT("Global\\MyMutex")); // Изменено на Global
if (hMutex == NULL) {
    DWORD error = GetLastError();
    wprintf(L"Не удалось открыть мьютекс. Ошибка: %x\n", error);
    LogEvent("Не удалось открыть мьютекс.");
    UnmapViewOfFile(g_pSharedMemory);
    CloseHandle(hMapFile);
    return -1;
}

// Преобразование имени входного файла из wchar_t в char
int len = wcslen(argv[1]) + 1; // +1 для нуль-терминатора
char* inputFilename = (char*)malloc(len);
if (inputFilename == NULL) {
    wprintf(L"Ошибка выделения памяти.\n");
    LogEvent("Ошибка выделения памяти для имени входного файла.");
    UnmapViewOfFile(g_pSharedMemory);
    CloseHandle(hMapFile);
    CloseHandle(hMutex);
    return -1;
}
wcstombs(inputFilename, argv[1], len); // Преобразование

// Открытие входного файла
FILE* inputFile = fopen(inputFilename, "r");
if (inputFile == NULL) {
    DWORD error = GetLastError();
    wprintf(L"Не удалось открыть входной файл. Ошибка: %x\n", error);
    LogEvent("Не удалось открыть входной файл.");
    LogEvent("Ошибка при открытии входного файла.");
    free(inputFilename);
    UnmapViewOfFile(g_pSharedMemory);
    CloseHandle(hMapFile);
    CloseHandle(hMutex);
    return -1;
}

// Чтение содержимого файла в общую память
fread(g_pSharedMemory, sizeof(char), BUFFER_SIZE, inputFile);
fclose(inputFile);

// Запись в общую память с использованием мьютекса
WaitForSingleObject(hMutex, INFINITE);

// Замена пробелов на указанный символ
char replaceChar = argv[2][0];
for (int i = 0; i < BUFFER_SIZE; i++) {
    if (g_pSharedMemory[i] == ' ') {
        g_pSharedMemory[i] = replaceChar; // Замена пробелов на указанный символ
    }
}

// Логирование события
char logMessage[256];
sprintf(logMessage, "Обработан файл: %s, заменен пробел на: %c", inputFilename,   replaceChar);
LogEvent(logMessage);

ReleaseMutex(hMutex);

// Освобождение ресурсов
free(inputFilename);
UnmapViewOfFile(g_pSharedMemory);
CloseHandle(hMapFile);
CloseHandle(hMutex);

return 0;
}

void LogEvent(const char* message) {
FILE* file = fopen(LOG_FILE, "a");
if (file) {
    fprintf(file, "%s\n", message);
    fclose(file);
}
else {
    // Вывод ошибки, если файл не может быть открыт
    printf("Ошибка открытия лог-файла: %s\n", message);
}
}

BOOL IsServiceRunning(const char* serviceName) {
SC_HANDLE schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (schSCManager == NULL) {
    LogEvent("Не удалось открыть диспетчер служб.");
    return FALSE;
}

SC_HANDLE schService = OpenService(schSCManager, serviceName, SERVICE_QUERY_STATUS);
if (schService == NULL) {
    CloseServiceHandle(schSCManager);
    LogEvent("Не удалось открыть службу.");
    return FALSE;
}

SERVICE_STATUS ss;
BOOL result = QueryServiceStatus(schService, &ss);
if (result) {
    result = (ss.dwCurrentState == SERVICE_RUNNING);
}

CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return result;
}

пытался запускать от имени администратора, ставить не global, а local мьютекс и память.


Ответы (0 шт):