Даже не знаю, как и объяснить. Вообщем мне нужно сделать одну программку в виде винсервиса. Как я понял, нужно два exe файла, чтобы один устанавливал второй сервисом. А как сделать так, чтобы всё это было в одном файле? Или можно записать содержимое файла-сервиса в память лоадеру, чтобы он потом записывал сначала этот сервис на диск и лишь потом запускал? Тогда как это сделать поправильнее как-нибудь? Если тут было уже такое, не серчайте, а дайте ссылку. Надеюсь я понятно изложил суть
Ну я раньше делал так,тока не для сервисов...Вобщем в программе лоадере в секции данных оставляешь пустое место такого размера как сервис,он будет использоваться как буфер...потом создаешь третью программу которая записывает твой сервис в этот буфер в программу лоадер...В лоадере вызываешь функции CreateFile создаешь файл,и записываешь в него данные из буфера,далее юзаешь функции для запуска сервиса из лоадера...
А зачем третья программа? Если сразу записать сервис в буфер лоадера? Только я чёт не очень понимаю как именно это сделать всё? всё равно размер лоадера не имеет значения, так как после установки сервиса его можно удалить.
Ребят.. вы чет намудрили не слабо (% theMUX поэкспериментируй, установку и сам сервис совместить можно..
Это как? Ведь процедура установки должна уже иметь готовый exe файл сервиса. А если сначала написать сервис, то как потом установить его из того же файла? Т.е. argv[0] будет пытаться установить сам себя? И как это работает? А если вынести всю процедуру установки сервиса в отдельный поток, который и установит сам argv[0]? Но тогда в коде сервиса придётся делать лишнюю проверку на текущее состояние сервиса, так как он будет каждый раз после запуска пытаться установится заново... как-то так: InstallService(); main() { CheckServiceStatus() if (нет) InstallServiceThread(blabla, InstallService, blabla) Ну и дальше собсно код самого сервиса } Я правильно понял?
если бы мона было устанавливать сервисы из сервисов то скорее всего тогда отпадали лоадеры для них...
дааа.. все просто ведь.. вначале проверяем запустились как сервис или нет. можно например пути сравнить. если как обычное приложение -- тогда устанавливаемся, копируем файл куда надо.. запускаем как сервис. до функции RegisterServiceCtrlHandler (или как её там (% ) можно выполнить любой код
Ага, вроде понятно. А какой функцией в окошках можно получить путь к файлу? Я имею ввиду не main(int argc, char **argv), а каким нибудь другим способом?
Код (Text): #include <cstdio> #include <windows.h> #pragma comment (lib, "advapi32.lib") #define SERVICENAME "AAAAAAAAAA" SC_HANDLE hSCM, hService; int ManaError() { printf ("NOT ENOUGH MANA - %s", GetLastError()); return 0; } //Поток установки сервиса DWORD WINAPI InstallServiceThread() { //Получить путь к файлу char filename[1024]; GetModuleFileName(NULL, filename, sizeof(filename)); printf("Thread loaded successful, filepath is: %s", filename); hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); if (hSCM == NULL) { ManaError(); } 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); if (hService == NULL) { printf("not enough mana for create service\n"); CloseServiceHandle(hSCM); return 0; } //теперь старт сервиса hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (hSCM == NULL) { printf("error by getting handle when service try to start\n"); CloseServiceHandle(hSCM); CloseServiceHandle(hService); return 0; } hService = OpenService(hSCM, SERVICENAME, SERVICE_ALL_ACCESS); if (hService == NULL) { printf("error by getting access to service\n"); CloseServiceHandle(hSCM); CloseServiceHandle(hService); return 0; } //start if(!StartService(hService, 0, NULL)) { printf("error at service start\n"); CloseServiceHandle(hSCM); CloseServiceHandle(hService); return 0; } printf("Service is started!"); CloseServiceHandle(hSCM); CloseServiceHandle(hService); return 0; } int main(int argc, char **argv) { HANDLE hThread; DWORD IDThread; //garbage code char *suka="пока что всё работает\n"; CharToOem(suka, suka); printf("%s",suka); //garbage code end // сцуко яйца отсидел hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (hSCM == NULL) { ManaError(); } hService = OpenService(hSCM, SERVICENAME, SERVICE_ALL_ACCESS); printf("workeng...\n"); if (hService == NULL) { printf("workeng!!!\n"); hThread = CreateThread(NULL, 0, NULL, InstallServiceThread, 0, &IDThread); if(hThread == NULL) ManaError(); printf("thread...\n"); WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); } return 0; } чёт не понятно, поток вроде стартует, но оттуда никаких новостей нету... Это конечно ещё не законченный вариант, но почему поток не выполняется?
Тут вообщем всё нормально уже, но сервис всё равно по каким-то причинам не хочет работать, код: Код (Text): #include <stdio.h> #include <windows.h> #pragma comment (lib, "advapi32.lib") #define SERVICENAME "AAAAAAAAAA" SC_HANDLE hSCM, hService; SERVICE_STATUS service_status; SERVICE_STATUS_HANDLE hServiceStatus; HANDLE hThread; DWORD IDThread; VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv); VOID WINAPI ServiceCtrlHandler(DWORD dwControl); void ManaError() { printf ("NOT ENOUGH MANA - %x", GetLastError()); ExitProcess(0); } //Поток установки сервиса DWORD WINAPI InstallServiceThread() { MessageBoxA(0,"Thread is working","omg",MB_ICONINFORMATION); //Получить путь к файлу char filename[1024]; GetModuleFileName(NULL, filename, sizeof(filename)); printf("Thread loaded successful, filepath is: %s", filename); hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); if (hSCM == NULL) { ManaError(); } 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); if (hService == NULL) { printf("not enough mana for create service\n"); CloseServiceHandle(hSCM); return 0; } //теперь старт сервиса hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (hSCM == NULL) { printf("error by getting handle when service try to start\n"); CloseServiceHandle(hSCM); CloseServiceHandle(hService); return 0; } hService = OpenService(hSCM, SERVICENAME, SERVICE_ALL_ACCESS); if (hService == NULL) { printf("error by getting access to service\n"); CloseServiceHandle(hSCM); CloseServiceHandle(hService); return 0; } //start if(!StartService(hService, 0, NULL)) { printf("error by service start\n"); CloseServiceHandle(hSCM); CloseServiceHandle(hService); return 0; } CloseServiceHandle(hSCM); CloseServiceHandle(hService); return 0; } int main(int argc, char **argv) { // сцуко яйца отсидел //так как уже main, то надо теперь проверять состояние сервиса, чтобы сервис не пытался каждый раз инсталлить себя hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (hSCM == NULL) { ManaError(); } hService = OpenService(hSCM, SERVICENAME, SERVICE_ALL_ACCESS); printf("Loading...\n"); if (hService == NULL) { printf("Installing service...\n"); hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)InstallServiceThread, NULL, 0, &IDThread); if(hThread == NULL) ManaError(); WaitForSingleObject(hThread, INFINITE); TerminateThread(hThread,0); printf("\nService is installed and work (maybe even successful)...\n"); CloseHandle(hThread); ExitProcess(0); } //Service code SERVICE_TABLE_ENTRY service_table[] = { {SERVICENAME, ServiceMain}, { NULL, NULL } }; if (!StartServiceCtrlDispatcher(service_table)) { ManaError(); } return 0; } /////////////////////////////////////////////////////////////////////////////// VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) { hServiceStatus = RegisterServiceCtrlHandler(SERVICENAME, ServiceCtrlHandler); if (!hServiceStatus) { ManaError(); } //инит структуры состояния сервиса service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; service_status.dwCurrentState = SERVICE_START_PENDING; service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; service_status.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR; service_status.dwServiceSpecificExitCode = 0; service_status.dwCheckPoint = 0; service_status.dwWaitHint = 5000; // set SERV_START_PENDING if (!SetServiceStatus(hServiceStatus, &service_status)) { ManaError(); } //set RUNNING service_status.dwCurrentState = SERVICE_RUNNING; service_status.dwWin32ExitCode = NO_ERROR; if (!SetServiceStatus(hServiceStatus, &service_status)) { ManaError(); } // рабочий цикл сервиса while (service_status.dwCurrentState == SERVICE_RUNNING) { // тут собсно и будет код while(true) { Sleep(2500); } } } VOID WINAPI ServiceCtrlHandler(DWORD dwControl) { switch(dwControl) { case SERVICE_CONTROL_STOP: service_status.dwCurrentState = SERVICE_STOPPED; SetServiceStatus(hServiceStatus, &service_status); break; case SERVICE_CONTROL_SHUTDOWN: service_status.dwCurrentState = SERVICE_STOPPED; SetServiceStatus(hServiceStatus, &service_status); break; default: SetServiceStatus(hServiceStatus, &service_status); break; } }
не хотел создавать новую тему.. вопрос тоже по установке сервиса. Значится начал разбираться с сервисами, появился вопрос. Вот есть сервисы выполняющиеся в svhost.exe, как мне сделать такой же сервис? как я понял такой сервис должен быть в виде длл, экспортировать 2 функции ServiceMain и SvchostPushServiceGlobals(с этой я еще не разобрался толком, так что пока не знаю для чего она..). А какие еще требования есть? Подскажите пожалуйста.
А разве виндоус средствами нельзя? sc.exe - регистрирует сервис, хотя для этого наверное должен быть адекватный бинарь? Я вот тоже мечтаю чтоб консоль запускалась как-то типа SYSTEM, чтоб её вырубить нельзя было? Чтоб над десктопом висела. (в нулевом кольце привилегий ))) )
Я вот так устанавливаю CloneCD Код (Text): format PE GUI 5.0 include '%fasm%\win32a.inc' section '.code' code readable executable invoke ShellExecute,0,0,sc,CDIO,0,0 invoke ShellExecute,0,0,sc,CDFL,0,0 invoke ExitProcess,0 sc db 'sc.exe',0 CDIO db 'create ElbyCDIO binPath= System32\Drivers\ElbyCDIO.sys type= kernel start= system error= normal DisplayName= "ElbyCDIO Driver"',0 CDFL db 'create ElbyCDFL binPath= System32\Drivers\ElbyCDFL.sys type= kernel start= demand error= normal DisplayName= "ElbyCDFL"',0 data import library kernel32,'KERNEL32.DLL',shell32,'SHELL32.DLL' import kernel32,ExitProcess,'ExitProcess' import shell32,ShellExecute,'ShellExecuteA' end data Похоже что работает, но одна проблемма в том что перезагрузка нужна... а ведь сам CloneCD после своего инсталла без перезагрузки работатет, как интересно он это делает?