Сервисы в windows

Тема в разделе "WASM.BEGINNERS", создана пользователем theMUX, 8 мар 2009.

  1. theMUX

    theMUX New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2009
    Сообщения:
    28
    Даже не знаю, как и объяснить. Вообщем мне нужно сделать одну программку в виде винсервиса. Как я понял, нужно два exe файла, чтобы один устанавливал второй сервисом. А как сделать так, чтобы всё это было в одном файле?
    Или можно записать содержимое файла-сервиса в память лоадеру, чтобы он потом записывал сначала этот сервис на диск и лишь потом запускал? Тогда как это сделать поправильнее как-нибудь?
    Если тут было уже такое, не серчайте, а дайте ссылку.
    Надеюсь я понятно изложил суть
     
  2. mupsy

    mupsy New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2008
    Сообщения:
    55
    Ну я раньше делал так,тока не для сервисов...Вобщем в программе лоадере в секции данных оставляешь пустое место такого размера как сервис,он будет использоваться как буфер...потом создаешь третью программу которая записывает твой сервис в этот буфер в программу лоадер...В лоадере вызываешь функции CreateFile создаешь файл,и записываешь в него данные из буфера,далее юзаешь функции для запуска сервиса из лоадера...
     
  3. theMUX

    theMUX New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2009
    Сообщения:
    28
    А зачем третья программа? Если сразу записать сервис в буфер лоадера? Только я чёт не очень понимаю как именно это сделать всё? всё равно размер лоадера не имеет значения, так как после установки сервиса его можно удалить.
     
  4. _Sl4yer

    _Sl4yer New Member

    Публикаций:
    0
    Регистрация:
    2 мар 2009
    Сообщения:
    55
    Ребят.. вы чет намудрили не слабо (% theMUX поэкспериментируй, установку и сам сервис совместить можно..
     
  5. theMUX

    theMUX New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2009
    Сообщения:
    28
    Это как? Ведь процедура установки должна уже иметь готовый exe файл сервиса. А если сначала написать сервис, то как потом установить его из того же файла? Т.е. argv[0] будет пытаться установить сам себя? И как это работает?
    А если вынести всю процедуру установки сервиса в отдельный поток, который и установит сам argv[0]? Но тогда в коде сервиса придётся делать лишнюю проверку на текущее состояние сервиса, так как он будет каждый раз после запуска пытаться установится заново...


    как-то так:
    InstallService();
    main()
    {
    CheckServiceStatus()
    if (нет) InstallServiceThread(blabla, InstallService, blabla)
    Ну и дальше собсно код самого сервиса
    }

    Я правильно понял?
     
  6. mupsy

    mupsy New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2008
    Сообщения:
    55
    если бы мона было устанавливать сервисы из сервисов то скорее всего тогда отпадали лоадеры для них...
     
  7. theMUX

    theMUX New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2009
    Сообщения:
    28
    ну а чем плох мой алгоритм? По-моему всё норм.
     
  8. mupsy

    mupsy New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2008
    Сообщения:
    55
    Ну если норм тогда все хорошо...
     
  9. _Sl4yer

    _Sl4yer New Member

    Публикаций:
    0
    Регистрация:
    2 мар 2009
    Сообщения:
    55
    дааа.. все просто ведь..
    вначале проверяем запустились как сервис или нет. можно например пути сравнить.
    если как обычное приложение -- тогда устанавливаемся, копируем файл куда надо.. запускаем как сервис.
    до функции RegisterServiceCtrlHandler (или как её там (% ) можно выполнить любой код
     
  10. theMUX

    theMUX New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2009
    Сообщения:
    28
    Ага, вроде понятно. А какой функцией в окошках можно получить путь к файлу? Я имею ввиду не main(int argc, char **argv), а каким нибудь другим способом?
     
  11. Partner

    Partner Павел

    Публикаций:
    0
    Регистрация:
    28 фев 2008
    Сообщения:
    917
    Адрес:
    Los Angeles
    Программа сама без проблем может установить себя как сервис.
     
  12. theMUX

    theMUX New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2009
    Сообщения:
    28
    Да это уже ясно, смотри пост номер 10
     
  13. _Sl4yer

    _Sl4yer New Member

    Публикаций:
    0
    Регистрация:
    2 мар 2009
    Сообщения:
    55
    первое что приходит на ум -- GetModuleFileName
     
  14. _int2e_

    _int2e_ New Member

    Публикаций:
    0
    Регистрация:
    1 мар 2009
    Сообщения:
    124
    А второе - GetCommandLineW
     
  15. theMUX

    theMUX New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2009
    Сообщения:
    28
    Код (Text):
    1. #include <cstdio>
    2. #include <windows.h>
    3.  
    4.  
    5. #pragma comment (lib, "advapi32.lib")
    6.  
    7. #define SERVICENAME "AAAAAAAAAA"
    8.     SC_HANDLE hSCM, hService;
    9.    
    10.     int ManaError()
    11.     {
    12.         printf ("NOT ENOUGH MANA - %s", GetLastError());
    13.         return 0;
    14.     }
    15.     //Поток установки сервиса
    16.     DWORD WINAPI InstallServiceThread()
    17.     {
    18.         //Получить путь к файлу
    19.         char filename[1024];
    20.         GetModuleFileName(NULL, filename, sizeof(filename));
    21.         printf("Thread loaded successful, filepath is: %s", filename);
    22.        
    23.         hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
    24.         if (hSCM == NULL)
    25.         {
    26.         ManaError();
    27.         }
    28.         hService = CreateService(hSCM, SERVICENAME, "armageddon service", SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START,SERVICE_ERROR_NORMAL, filename, NULL, NULL, NULL, NULL, NULL);
    29.         if (hService == NULL)
    30.         {
    31.             printf("not enough mana for create service\n");
    32.             CloseServiceHandle(hSCM);
    33.             return 0;
    34.         }
    35.         //теперь старт сервиса
    36.         hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
    37.         if (hSCM == NULL)
    38.         {
    39.             printf("error by getting handle when service try to start\n");
    40.             CloseServiceHandle(hSCM);
    41.             CloseServiceHandle(hService);
    42.             return 0;
    43.         }
    44.         hService = OpenService(hSCM, SERVICENAME, SERVICE_ALL_ACCESS);
    45.         if (hService == NULL)
    46.         {
    47.             printf("error by getting access to service\n");
    48.             CloseServiceHandle(hSCM);
    49.             CloseServiceHandle(hService);
    50.             return 0;
    51.         }
    52.         //start
    53.         if(!StartService(hService, 0, NULL))
    54.         {
    55.             printf("error at service start\n");
    56.             CloseServiceHandle(hSCM);
    57.             CloseServiceHandle(hService);
    58.             return 0;
    59.         }
    60.         printf("Service is started!");
    61.         CloseServiceHandle(hSCM);
    62.         CloseServiceHandle(hService);
    63.         return 0;
    64.     }
    65.        
    66.     int main(int argc, char **argv)
    67.     {
    68.         HANDLE hThread;
    69.         DWORD IDThread;
    70.        
    71.         //garbage code
    72.         char *suka="пока что всё работает\n";
    73.         CharToOem(suka, suka);
    74.         printf("%s",suka);
    75.         //garbage code end
    76.         // сцуко яйца отсидел
    77.         hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
    78.         if (hSCM == NULL)
    79.         {
    80.         ManaError();
    81.         }
    82.        
    83.         hService = OpenService(hSCM, SERVICENAME, SERVICE_ALL_ACCESS);
    84.         printf("workeng...\n");
    85.         if (hService == NULL)
    86.         {
    87.             printf("workeng!!!\n");
    88.             hThread = CreateThread(NULL, 0, NULL, InstallServiceThread, 0, &IDThread);
    89.             if(hThread == NULL) ManaError();
    90.             printf("thread...\n");
    91.             WaitForSingleObject(hThread, INFINITE);
    92.             CloseHandle(hThread);          
    93.         }  
    94.        
    95.        
    96.         return 0;
    97.     }
    чёт не понятно, поток вроде стартует, но оттуда никаких новостей нету... Это конечно ещё не законченный вариант, но почему поток не выполняется?
     
  16. theMUX

    theMUX New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2009
    Сообщения:
    28
    Тут вообщем всё нормально уже, но сервис всё равно по каким-то причинам не хочет работать, код:
    Код (Text):
    1. #include <stdio.h>
    2. #include <windows.h>
    3. #pragma comment (lib, "advapi32.lib")
    4. #define SERVICENAME "AAAAAAAAAA"
    5.    
    6.     SC_HANDLE hSCM, hService;
    7.     SERVICE_STATUS    service_status;
    8.     SERVICE_STATUS_HANDLE  hServiceStatus;
    9.     HANDLE hThread;
    10.     DWORD IDThread;
    11.    
    12.     VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv);
    13.     VOID WINAPI ServiceCtrlHandler(DWORD dwControl);
    14.    
    15. void ManaError()
    16.     {
    17.         printf ("NOT ENOUGH MANA - %x", GetLastError());
    18.         ExitProcess(0);
    19.     }  
    20.     //Поток установки сервиса
    21.     DWORD WINAPI InstallServiceThread()
    22.     {
    23.         MessageBoxA(0,"Thread is working","omg",MB_ICONINFORMATION);
    24.         //Получить путь к файлу
    25.         char filename[1024];
    26.         GetModuleFileName(NULL, filename, sizeof(filename));
    27.         printf("Thread loaded successful, filepath is: %s", filename);
    28.        
    29.         hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
    30.         if (hSCM == NULL)
    31.         {
    32.         ManaError();
    33.         }
    34.         hService = CreateService(hSCM, SERVICENAME, "armageddon service", SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START,SERVICE_ERROR_NORMAL, filename, NULL, NULL, NULL, NULL, NULL);
    35.         if (hService == NULL)
    36.         {
    37.             printf("not enough mana for create service\n");
    38.             CloseServiceHandle(hSCM);
    39.             return 0;
    40.         }
    41.         //теперь старт сервиса
    42.         hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
    43.         if (hSCM == NULL)
    44.         {
    45.             printf("error by getting handle when service try to start\n");
    46.             CloseServiceHandle(hSCM);
    47.             CloseServiceHandle(hService);
    48.             return 0;
    49.         }
    50.         hService = OpenService(hSCM, SERVICENAME, SERVICE_ALL_ACCESS);
    51.         if (hService == NULL)
    52.         {
    53.             printf("error by getting access to service\n");
    54.             CloseServiceHandle(hSCM);
    55.             CloseServiceHandle(hService);
    56.             return 0;
    57.         }
    58.         //start
    59.         if(!StartService(hService, 0, NULL))
    60.         {
    61.             printf("error by service start\n");
    62.             CloseServiceHandle(hSCM);
    63.             CloseServiceHandle(hService);
    64.             return 0;
    65.         }
    66.         CloseServiceHandle(hSCM);
    67.         CloseServiceHandle(hService);
    68.         return 0;
    69.     }
    70.        
    71.     int main(int argc, char **argv)
    72.     {
    73.  
    74.         // сцуко яйца отсидел
    75.         //так как уже main, то надо теперь проверять состояние сервиса, чтобы сервис не пытался каждый раз инсталлить себя
    76.         hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
    77.         if (hSCM == NULL)
    78.         {
    79.         ManaError();
    80.         }
    81.        
    82.         hService = OpenService(hSCM, SERVICENAME, SERVICE_ALL_ACCESS);
    83.         printf("Loading...\n");
    84.         if (hService == NULL)
    85.         {
    86.                         printf("Installing service...\n");
    87.                         hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)InstallServiceThread, NULL, 0, &IDThread);
    88.                         if(hThread == NULL) ManaError();
    89.                         WaitForSingleObject(hThread, INFINITE);
    90.                         TerminateThread(hThread,0);
    91.                         printf("\nService is installed and work (maybe even successful)...\n");
    92.                         CloseHandle(hThread);
    93.                         ExitProcess(0);
    94.         }
    95.        
    96.         //Service code
    97.         SERVICE_TABLE_ENTRY  service_table[] =
    98.         {
    99.         {SERVICENAME, ServiceMain},  
    100.         { NULL, NULL }                
    101.         };
    102.         if (!StartServiceCtrlDispatcher(service_table))
    103.           {
    104.             ManaError();
    105.           }
    106.         return 0;
    107.     }
    108.    
    109.     ///////////////////////////////////////////////////////////////////////////////
    110.     VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
    111. {
    112.  
    113.   hServiceStatus = RegisterServiceCtrlHandler(SERVICENAME, ServiceCtrlHandler);
    114.   if (!hServiceStatus)
    115.   {
    116.       ManaError();
    117.   }
    118.  
    119.   //инит структуры состояния сервиса
    120.   service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    121.   service_status.dwCurrentState = SERVICE_START_PENDING;
    122.   service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
    123.   service_status.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
    124.   service_status.dwServiceSpecificExitCode = 0;
    125.   service_status.dwCheckPoint = 0;
    126.   service_status.dwWaitHint = 5000;
    127.  
    128.   // set SERV_START_PENDING
    129.   if (!SetServiceStatus(hServiceStatus, &service_status))
    130.   {
    131.       ManaError();
    132.   }
    133.   //set RUNNING
    134.   service_status.dwCurrentState = SERVICE_RUNNING;
    135.   service_status.dwWin32ExitCode = NO_ERROR;
    136.  
    137.   if (!SetServiceStatus(hServiceStatus, &service_status))
    138.   {
    139.       ManaError();
    140.   }
    141.  
    142.   // рабочий цикл сервиса
    143.   while (service_status.dwCurrentState == SERVICE_RUNNING)
    144.   {
    145.     // тут собсно и будет код
    146.         while(true)
    147.         {
    148.         Sleep(2500);
    149.         }
    150.   }
    151. }
    152.  
    153. VOID WINAPI ServiceCtrlHandler(DWORD dwControl)
    154. {
    155.   switch(dwControl)
    156.   {
    157.   case SERVICE_CONTROL_STOP:    
    158.     service_status.dwCurrentState = SERVICE_STOPPED;
    159.     SetServiceStatus(hServiceStatus, &service_status);
    160.     break;
    161.    
    162.   case SERVICE_CONTROL_SHUTDOWN:
    163.     service_status.dwCurrentState = SERVICE_STOPPED;
    164.     SetServiceStatus(hServiceStatus, &service_status);
    165.     break;
    166.   default:
    167.     SetServiceStatus(hServiceStatus, &service_status);
    168.     break;
    169.   }
    170. }
     
  17. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    Пусть наша программа будет лоадером, а сам сервис - будет упакованным овелеем в конце файла.
     
  18. _Sl4yer

    _Sl4yer New Member

    Публикаций:
    0
    Регистрация:
    2 мар 2009
    Сообщения:
    55
    не хотел создавать новую тему.. вопрос тоже по установке сервиса.
    Значится начал разбираться с сервисами, появился вопрос. Вот есть сервисы выполняющиеся в svhost.exe, как мне сделать такой же сервис? как я понял такой сервис должен быть в виде длл, экспортировать 2 функции ServiceMain и SvchostPushServiceGlobals(с этой я еще не разобрался толком, так что пока не знаю для чего она..). А какие еще требования есть? Подскажите пожалуйста.
     
  19. Semiono

    Semiono Member

    Публикаций:
    0
    Регистрация:
    27 ноя 2005
    Сообщения:
    793
    А разве виндоус средствами нельзя? sc.exe - регистрирует сервис, хотя для этого наверное должен быть адекватный бинарь?
    Я вот тоже мечтаю чтоб консоль запускалась как-то типа SYSTEM, чтоб её вырубить нельзя было?
    Чтоб над десктопом висела.
    (в нулевом кольце привилегий ))) )
     
  20. Semiono

    Semiono Member

    Публикаций:
    0
    Регистрация:
    27 ноя 2005
    Сообщения:
    793
    Я вот так устанавливаю CloneCD
    Код (Text):
    1. format PE GUI 5.0
    2. include '%fasm%\win32a.inc'
    3.  
    4. section '.code' code readable executable
    5.  
    6. invoke ShellExecute,0,0,sc,CDIO,0,0
    7. invoke ShellExecute,0,0,sc,CDFL,0,0
    8. invoke  ExitProcess,0
    9.  
    10. sc db 'sc.exe',0
    11. CDIO db 'create ElbyCDIO binPath= System32\Drivers\ElbyCDIO.sys type= kernel start= system error= normal DisplayName= "ElbyCDIO Driver"',0
    12. CDFL db 'create ElbyCDFL binPath= System32\Drivers\ElbyCDFL.sys type= kernel start= demand error= normal DisplayName= "ElbyCDFL"',0
    13.  
    14. data import
    15.  
    16. library kernel32,'KERNEL32.DLL',shell32,'SHELL32.DLL'
    17. import kernel32,ExitProcess,'ExitProcess'
    18. import shell32,ShellExecute,'ShellExecuteA'
    19.  
    20. end data
    Похоже что работает, но одна проблемма в том что перезагрузка нужна...
    а ведь сам CloneCD после своего инсталла без перезагрузки работатет, как интересно он это делает?
    :)