1. Требуются разработчики и тестеры для проекта codebyOS. Требования для участия в проекте: Знание принципов работы ОС на базе Linux; Знание Bash; Крайне желательное знание CPP, Python, Lua; Навыки системного администрирования. Подробнее ...

    Скрыть объявление

Сервис И Месседжы

Тема в разделе "MS Visual C++", создана пользователем bearpaw, 26 сен 2013.

  1. bearpaw

    bearpaw Member

    Репутация:
    0
    Регистрация:
    15 окт 2010
    Сообщения:
    8
    Симпатии:
    0
    Доброго времени суток, уважаемые форумчане!

    Занимаюсь созданием сервиса для Windows, который должен отлавливать один единственный месседж от ОС - WM_TIMECHANGE и писать это в лог-файл (в дальнейшем - писать на syslog-сервер).
    Заготовка сервиса создана, уже умеет запускатся/останавливатся.
    Единственное что - никак не могу сообразить как обрабатывать сообщения, не имея при этом окна.

    Быть может, кто-либо подскажет как сие реализовать? Желательно, куском кода или пошаговым описанием процесса. Короче, как для человека, изрядно подзабывшего Cpp... :)

    <div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">Выглядит заготовка так :</div></div><div class="sp-body"><div class="sp-content">
    Код:
    #include <stdio.h>
    #include "stdafx.h"
    #include <Windows.h>
    #include <time.h>
    #include <iomanip>
    
    DWORD WINAPI HandlerEx(DWORD control, DWORD eventType, void *eventData, void *context);
    void ReportErrorStatus(DWORD errorCode);
    void ReportProgressStatus(DWORD state, DWORD checkPoint, DWORD waitHint);
    void ReportStatus(DWORD state);
    void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);
    void addLogMessage(const TCHAR* t, ...);
    
    int StartService();
    int RemoveService();
    void InstallService();
    
    LPTSTR svcName; 
    LPTSTR svcPath;
    
    time_t curTime;
    
    SERVICE_STATUS_HANDLE g_ServiceStatusHandle; 
    HANDLE g_StopEvent;
    DWORD g_CurrentState = 0;
    bool g_SystemShutdown = false;
    
    int _tmain(int argc, wchar_t* argv[]) 
    {
    time(&curTime);
    
    svcName = LPTSTR(L"TimeWatcher");
    svcPath = LPTSTR(argv[0]);
    
    TCHAR buf[64] = {0};
    wsprintf(buf, L"Trying to %s service\n", argv[argc - 1]);
    addLogMessage(buf);
    
    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();
    } 
    else if (wcscmp(argv[argc-1], _T("service")) == 0) 
    {
    
    SERVICE_TABLE_ENTRY serviceTable[] = {
    { _T(""), &ServiceMain },
    { NULL, NULL }
    };
    if (StartServiceCtrlDispatcher(serviceTable))
    return 0;
    else if (GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
    return -1; // Program not started as a service.
    else
    return -2; // Other error.
    }
    return 0;
    }
    
    // Main function to be executed as entire service code.
    void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
    {
    g_ServiceStatusHandle = RegisterServiceCtrlHandlerEx(svcName, &HandlerEx, NULL);
    
    time(&curTime);
    
    ReportStatus(SERVICE_START_PENDING);
    g_StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    
    ReportStatus(SERVICE_RUNNING);
    
    while (WaitForSingleObject(g_StopEvent, 3000) != WAIT_OBJECT_0)
    {
    // add something here
    }
    
    ReportStatus(SERVICE_STOP_PENDING);
    addLogMessage(TEXT("Service shutdown! \n"));
    
    CloseHandle(g_StopEvent);
    ReportStatus(SERVICE_STOPPED);
    }
    
    void ReportStatus(DWORD state)
    {
    g_CurrentState = state;
    SERVICE_STATUS serviceStatus = {
    SERVICE_WIN32_OWN_PROCESS,
    g_CurrentState,
    state == SERVICE_START_PENDING ? 0 : SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN,
    NO_ERROR,
    0,
    0,
    0,
    };
    SetServiceStatus(g_ServiceStatusHandle, &serviceStatus);
    }
    
    void ReportProgressStatus(DWORD state, DWORD checkPoint, DWORD waitHint)
    {
    g_CurrentState = state;
    SERVICE_STATUS serviceStatus = {
    SERVICE_WIN32_OWN_PROCESS,
    g_CurrentState,
    state == SERVICE_START_PENDING ? 0 : SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN,
    NO_ERROR,
    0,
    checkPoint,
    waitHint,
    };
    SetServiceStatus(g_ServiceStatusHandle, &serviceStatus);
    }
    
    void ReportErrorStatus(DWORD errorCode)
    {
    g_CurrentState = SERVICE_STOPPED;
    SERVICE_STATUS serviceStatus = {
    SERVICE_WIN32_OWN_PROCESS,
    g_CurrentState,
    0,
    ERROR_SERVICE_SPECIFIC_ERROR,
    errorCode,
    0,
    0,
    };
    SetServiceStatus(g_ServiceStatusHandle, &serviceStatus);
    }
    
    // Handler for service control events.
    DWORD WINAPI HandlerEx(DWORD control, DWORD eventType, void *eventData, void *context)
    {
    switch (control)
    {
    // System is shutting down.
    case SERVICE_CONTROL_SHUTDOWN:
    g_SystemShutdown = true;
    // continue...
    // Service is being stopped.
    case SERVICE_CONTROL_STOP:
    ReportStatus(SERVICE_STOP_PENDING);
    SetEvent(g_StopEvent);
    break;
    // Ignoring all other events, but we must always report service status.
    default:
    ReportStatus(g_CurrentState);
    break;
    }
    return NO_ERROR;
    }
    
    
    void InstallService()
    {
    SC_HANDLE schSCManager;
    SC_HANDLE schService;
    TCHAR szPath[MAX_PATH + 9];
    TCHAR tCantInst[] = L"Cannot install service (%d)";
    
    if (!GetModuleFileName(NULL, szPath, MAX_PATH))
    {
    addLogMessage(tCantInst);
    return;
    }
    wcscat_s(szPath,MAX_PATH+9,L" service");
    
    schSCManager = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
    if (!schSCManager)
    {
    addLogMessage(tCantInst);
    return;
    }
    
    schService=CreateService(schSCManager, svcName, svcName,
    SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START,
    SERVICE_ERROR_NORMAL, szPath, 0, 0, 0, 0, 0);
    if (!schService)
    {
    addLogMessage(tCantInst);
    CloseServiceHandle(schSCManager);
    return;
    }
    CloseServiceHandle(schService);
    CloseServiceHandle(schSCManager);
    time(&curTime);
    addLogMessage(L"Service Installed!\n");
    }
    
    int RemoveService() 
    {
    SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (!hSCManager) 
    {
    addLogMessage(TEXT("Error: Can't open Service Control Manager\n"));
    return -1;
    }
    SC_HANDLE hService = OpenService(hSCManager, svcName, SERVICE_STOP | DELETE);
    if (!hService) 
    {
    addLogMessage(TEXT("Error: Can't remove service\n"));
    CloseServiceHandle(hSCManager);
    return -1;
    }
    
    DeleteService(hService);
    CloseServiceHandle(hService);
    CloseServiceHandle(hSCManager);
    addLogMessage(TEXT("Success remove service!\n"));
    return 0;
    }
    
    int StartService() 
    {
    SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
    SC_HANDLE hService = OpenService(hSCManager, svcName, SERVICE_START);
    if (!StartService(hService, 0, NULL)) 
    {
    CloseServiceHandle(hSCManager);
    addLogMessage(TEXT("Error: Can't start service\n"));
    return -1;
    }
    
    CloseServiceHandle(hService);
    CloseServiceHandle(hSCManager);
    return 0;
    }
    
    
    void getServicePath(TCHAR *path)
    {
    HKEY hKey = 0;
    TCHAR buf[260] = {0};
    DWORD dwBufSize = sizeof(buf);
    
    TCHAR subkey[260];
    wsprintf(subkey, L"SYSTEM\\CurrentControlSet\\services\\%s", svcName);
    
    if (RegOpenKey(HKEY_LOCAL_MACHINE, subkey, &hKey) == ERROR_SUCCESS)
    {
    int i = 0;
    if (RegQueryValueEx(hKey, TEXT("ImagePath"), NULL, NULL, (LPBYTE)buf, &dwBufSize) == ERROR_SUCCESS)
    {
    //wcsncpy(path, buf, dwBufSize);
    _wsplitpath(buf, NULL, path, NULL, NULL);
    }
    RegCloseKey(hKey);
    }
    }
    
    
    WCHAR* timeStamp(WCHAR* txt)
    {
    WCHAR* rc;
    WCHAR timestamp[16];
    time_t rawtime = time(0);
    tm *now = localtime(&rawtime);
    
    if (rawtime != -1) 
    {
    wcsftime(timestamp, 16, __TEXT("%d_%m_%y.log"), gmtime(&curTime));
    rc = wcscat(txt, timestamp);
    }
    return(rc);
    }
    
    void addLogMessage(const TCHAR* t,...)
    {
    TCHAR format[MAX_PATH] = {0};
    TCHAR fname[MAX_PATH] = {0};
    getServicePath(format);
    timeStamp(fname);
    wcsncat(format, L"tw_", MAX_PATH);
    wcsncat(format, fname, MAX_PATH);
    
    TCHAR tmstp[MAX_PATH] = {0};
    timeStamp(tmstp);
    
    HANDLE h = ::CreateFile(format, GENERIC_WRITE, 0, 0, OPEN_ALWAYS, 0, 0);
    if (INVALID_HANDLE_VALUE != h)
    {
    unsigned long w = 0;
    va_list val;
    TCHAR f[0x1000];
    int l;
    
    va_start(val, t);
    wsprintf(f, L"%w - ", tmstp);
    l = _vsntprintf_s(f, sizeof(f)/sizeof(f[0]), _TRUNCATE, t, val);
    va_end(val);
    if (0 == SetFilePointer(h, 0, 0, FILE_END))
    {
    if (sizeof(short) == sizeof(TCHAR))
    {
    unsigned short unicode = 0xFeFF;
    WriteFile(h, (void*)&unicode, 2, &w, 0);
    }
    }
    WriteFile(h, (void*)f, l*sizeof(TCHAR), &w, 0);
    CloseHandle(h);
    }
    }
     
Загрузка...
Похожие Темы - Сервис Месседжы
  1. Code Market
    Ответов:
    0
    Просмотров:
    9
  2. Code Market
    Ответов:
    0
    Просмотров:
    12
  3. WebWare Team
    Ответов:
    0
    Просмотров:
    672
  4. TLab
    Ответов:
    0
    Просмотров:
    104
  5. olegiva
    Ответов:
    0
    Просмотров:
    131

Поделиться этой страницей