source: admin/Sources/Clients/ogAdmWinClient/sources/servicio.c @ de734df

918-git-images-111dconfigfileconfigure-oglivegit-imageslgromero-new-oglivemainmaint-cronmount-efivarfsmultivmmultivm-ogboot-installerogClonningEngineogboot-installer-jenkinsoglive-ipv6test-python-scriptsticket-301ticket-50ticket-50-oldticket-577ticket-585ticket-611ticket-612ticket-693ticket-700ubu24tplunification2use-local-agent-oglivevarios-instalacionwebconsole3
Last change on this file since de734df was 181c4de, checked in by ramon <ramongomez@…>, 13 years ago

#501: Cliente para sistemas Windows.

git-svn-id: https://opengnsys.es/svn/branches/version1.0@2982 a21b9725-9963-47de-94b9-378ad31fedc9

  • Property mode set to 100644
File size: 21.3 KB
Line 
1// ******************************************************************************************************************************************************************************
2// Aplicación HIDRA
3// Copyright 2003-2005 José Manuel Alonso. Todos los derechos reservados.
4// Fichero: servicio.c
5//      Descripción:
6//              Este proyecto implementa el servicio hidra en un ordenador con plataforma windows NT. Este fichero aporta las funciones para crear el servicio
7// ******************************************************************************************************************************************************************************
8//____________________________________________________________________________________________________________________________
9// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
10// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
11// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
12// PARTICULAR PURPOSE.
13//
14// Copyright (C) 1993-1997  Microsoft Corporation.  All Rights Reserved.
15//
16//  MODULE:   service.c
17//  PURPOSE:  Implements functions required by all services   windows.
18//
19//  FUNCTIONS:
20//    main(int argc, char **argv);
21//    service_ctrl(DWORD dwCtrlCode);
22//    service_main(DWORD dwArgc, LPTSTR *lpszArgv);
23//    CmdInstallService();
24//    CmdRemoveService();
25//    CmdDebugService(int argc, char **argv);
26//    ControlHandler ( DWORD dwCtrlType );
27//    GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize );
28//
29//  COMMENTS:
30//  AUTHOR: Craig Link - Microsoft Developer Support
31//____________________________________________________________________________________________________________________________
32#include "servicio.h"
33//____________________________________________________________________________________________________________________________
34// internal variables
35DWORD                   dwErr = 0;
36BOOL                    bDebug = FALSE;
37TCHAR                   szErr[256];
38
39// internal function prototypes
40VOID WINAPI service_ctrl(DWORD dwCtrlCode);
41VOID WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv);
42VOID CmdInstallService();
43VOID CmdRemoveService();
44VOID CmdDebugService(int argc, char **argv);
45BOOL WINAPI ControlHandler ( DWORD dwCtrlType );
46LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize );
47//____________________________________________________________________________________________________________________________
48//
49//  FUNCTION: tomarestoparametros
50//
51//      Descripción:
52//
53//              Toma los parametros de conexión de la linea de comando y los graba en el Registro
54//____________________________________________________________________________________________________________________________
55int tomarestoparametros(int argc, char **argv)
56{
57        int i,lon;
58        char servidorhidra[20];
59        char puerto[10];
60        char iplocal[20];
61
62        strcpy(servidorhidra,SERVIDOR_DEFAULT);
63        strcpy(puerto,PUERTO_DEFAULT);
64        strcpy(iplocal,IPLOCAL_DEFAULT);
65
66        for(i=2;i<argc;i++){
67                lon=strlen(argv[i]);
68        if ((argv[i][0]=='-')||(argv[i][0]=='/') && argv[i][2]==' ')        {
69            switch (tolower(argv[i][1])){
70                case 's':   // Ip del servidor hidra
71                                        //strcpy(servidorhidra,&argv[i][3]);
72                                        TOMAPARAMSTR(servidorhidra);
73                    break;
74                case 'p':   // Puerto
75                                        TOMAPARAMSTR(puerto);
76                    break;
77                case 'i':   // Ip local
78                                        TOMAPARAMSTR(iplocal);
79                    break;
80                default:
81                                        printf("\nSintaxis: -install\n\n");
82                                        printf(" -s IP del servidor\n -p puerto\n -i IP local\n");
83                                        return(FALSE);
84                    break;
85            }
86        }
87    }
88        if(strcmp(servidorhidra,SERVIDOR_DEFAULT)==0
89                || strcmp(puerto,PUERTO_DEFAULT)==0 
90                || strcmp(iplocal,IPLOCAL_DEFAULT)==0) {
91                printf("\nSintaxis: -install\n\n");
92                printf(" -s IP del servidor\n -p puerto\n -i IP local\n");
93                return(FALSE);
94        }
95
96        CHKREGISTRY(WriteRegistryString(HIVE,BASE,"servidoradm",servidorhidra));
97        CHKREGISTRY(WriteRegistryString(HIVE,BASE,"puerto",puerto));
98        CHKREGISTRY(WriteRegistryString(HIVE,BASE,"iplocal",iplocal));
99        return(TRUE);
100}
101//____________________________________________________________________________________________________________________________
102//
103//  FUNCTION: borraparametros
104//
105//      Descripción:
106//
107//              Elimina la clave y subclave donde están los parámetros de conexión
108//____________________________________________________________________________________________________________________________
109int borraparametros()
110{
111        RMVREGISTRY(DeleteRegistryKey(HIVE,BASE)); // Borra la subclave completa
112        RMVREGISTRY(DeleteRegistryKey(HIVE,BASEKEY)); // Borra la clave completa
113        return(TRUE);
114}
115//____________________________________________________________________________________________________________________________
116//
117//  FUNCTION: main
118//
119//  PURPOSE: entrypoint for service
120//
121//  PARAMETERS:
122//    argc - number of command line arguments
123//    argv - array of command line arguments
124//
125//  RETURN VALUE:
126//    none
127//
128//  COMMENTS:
129//    main() either performs the command line task, or
130//    call StartServiceCtrlDispatcher to register the
131//    main service thread.  When the this call returns,
132//    the service has stopped, so exit.
133//
134//____________________________________________________________________________________________________________________________
135void _CRTAPI1 main(int argc, char **argv)
136{
137    SERVICE_TABLE_ENTRY dispatchTable[] =
138    {
139        { TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)service_main },
140        { NULL, NULL }
141    };
142
143    if ( (argc > 1) &&
144         ((*argv[1] == '-') || (*argv[1] == '/')) )
145    {
146        if ( _stricmp( "install", argv[1]+1 ) == 0 )
147        {
148                        if (!tomarestoparametros(argc,argv))
149                                exit(1);
150            CmdInstallService();
151        }
152        else if ( _stricmp( "remove", argv[1]+1 ) == 0 )
153        {
154                        borraparametros();
155                        CmdRemoveService();
156        }
157        else if ( _stricmp( "debug", argv[1]+1 ) == 0 )
158        {
159            bDebug = TRUE;
160            CmdDebugService(argc, argv);
161        }
162        else
163        {
164            goto dispatch;
165        }
166        exit(0);
167    }
168    // if it doesn't match any of the above parameters
169    // the service control manager may be starting the service
170    // so we must call StartServiceCtrlDispatcher
171    dispatch:
172        // this is just to be friendly
173        printf( "%s -install          to install the service\n", SZAPPNAME );
174        printf( "%s -remove           to remove the service\n", SZAPPNAME );
175        printf( "%s -debug <params>   to run as a console app for debugging\n", SZAPPNAME );
176        printf( "\nStartServiceCtrlDispatcher being called.\n" );
177        printf( "This may take several seconds.  Please wait.\n" );
178
179        if (!StartServiceCtrlDispatcher(dispatchTable))
180            AddToMessageLog(TEXT("StartServiceCtrlDispatcher failed."));
181}
182//____________________________________________________________________________________________________________________________
183//  FUNCTION: service_main
184//
185//  PURPOSE: To perform actual initialization of the service
186//
187//  PARAMETERS:
188//    dwArgc   - number of command line arguments
189//    lpszArgv - array of command line arguments
190//
191//  RETURN VALUE:
192//    none
193//
194//  COMMENTS:
195//    This routine performs the service initialization and then calls
196//    the user defined ServiceStart() routine to perform majority
197//    of the work.
198//
199//____________________________________________________________________________________________________________________________
200void WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv)
201{
202    // register our service control handler:
203    //
204    sshStatusHandle = RegisterServiceCtrlHandler( TEXT(SZSERVICENAME), service_ctrl);
205
206    if (!sshStatusHandle)
207        goto cleanup;
208
209    // SERVICE_STATUS members that don't change in example
210    //
211    ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
212    ssStatus.dwServiceSpecificExitCode = 0;
213
214
215    // report the status to the service control manager.
216    //
217    if (!ReportStatusToSCMgr(
218        SERVICE_START_PENDING, // service state
219        NO_ERROR,              // exit code
220        3000))                 // wait hint
221        goto cleanup;
222
223    ServiceStart( dwArgc, lpszArgv );
224
225cleanup:
226
227    // try to report the stopped status to the service control manager.
228    //
229    if (sshStatusHandle)
230        (VOID)ReportStatusToSCMgr(
231                            SERVICE_STOPPED,
232                            dwErr,
233                            0);
234    return;
235}
236//____________________________________________________________________________________________________________________________
237//
238//  FUNCTION: service_ctrl
239//
240//  PURPOSE: This function is called by the SCM whenever
241//           ControlService() is called on this service.
242//
243//  PARAMETERS:
244//    dwCtrlCode - type of control requested
245//
246//  RETURN VALUE:
247//    none
248//
249//  COMMENTS:
250//
251//____________________________________________________________________________________________________________________________
252VOID WINAPI service_ctrl(DWORD dwCtrlCode)
253{
254    // Handle the requested control code.
255    //
256    switch(dwCtrlCode)
257    {
258        // Stop the service.
259        //
260        // SERVICE_STOP_PENDING should be reported before
261        // setting the Stop Event - hServerStopEvent - in
262        // ServiceStop().  This avoids a race condition
263        // which may result in a 1053 - The Service did not respond...
264        // error.
265        case SERVICE_CONTROL_STOP:
266            ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0);
267            ServiceStop();
268            return;
269
270        // Update the service status.
271        //
272        case SERVICE_CONTROL_INTERROGATE:
273            break;
274
275        // invalid control code
276        //
277        default:
278            break;
279
280    }
281    ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0);
282}
283//____________________________________________________________________________________________________________________________
284//
285//  FUNCTION: ReportStatusToSCMgr()
286//
287//  PURPOSE: Sets the current status of the service and
288//           reports it to the Service Control Manager
289//
290//  PARAMETERS:
291//    dwCurrentState - the state of the service
292//    dwWin32ExitCode - error code to report
293//    dwWaitHint - worst case estimate to next checkpoint
294//
295//  RETURN VALUE:
296//    TRUE  - success
297//    FALSE - failure
298//
299//  COMMENTS:
300//
301//____________________________________________________________________________________________________________________________
302BOOL ReportStatusToSCMgr(DWORD dwCurrentState,DWORD dwWin32ExitCode,DWORD dwWaitHint)
303{
304    static DWORD dwCheckPoint = 1;
305    BOOL fResult = TRUE;
306
307
308    if ( !bDebug ) // when debugging we don't report to the SCM
309    {
310        if (dwCurrentState == SERVICE_START_PENDING)
311            ssStatus.dwControlsAccepted = 0;
312        else
313            ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
314
315        ssStatus.dwCurrentState = dwCurrentState;
316        ssStatus.dwWin32ExitCode = dwWin32ExitCode;
317        ssStatus.dwWaitHint = dwWaitHint;
318
319        if ( ( dwCurrentState == SERVICE_RUNNING ) ||
320             ( dwCurrentState == SERVICE_STOPPED ) )
321            ssStatus.dwCheckPoint = 0;
322        else
323            ssStatus.dwCheckPoint = dwCheckPoint++;
324
325        // Report the status of the service to the service control manager.
326        //
327        if (!(fResult = SetServiceStatus( sshStatusHandle, &ssStatus))) {
328            AddToMessageLog(TEXT("SetServiceStatus"));
329        }
330    }
331    return fResult;
332}
333//____________________________________________________________________________________________________________________________
334//
335//  FUNCTION: AddToMessageLog(LPTSTR lpszMsg)
336//
337//  PURPOSE: Allows any thread to log an error message
338//
339//  PARAMETERS:
340//    lpszMsg - text for message
341//
342//  RETURN VALUE:
343//    none
344//
345//  COMMENTS:
346//
347//____________________________________________________________________________________________________________________________
348VOID AddToMessageLog(LPTSTR lpszMsg)
349{
350    TCHAR   szMsg[256];
351    HANDLE  hEventSource;
352    LPTSTR  lpszStrings[2];
353
354    if ( !bDebug )
355    {
356        dwErr = GetLastError();
357
358        // Use event logging to log the error.
359        //
360        hEventSource = RegisterEventSource(NULL, TEXT(SZSERVICENAME));
361
362        _stprintf(szMsg, TEXT("%s error: %d"), TEXT(SZSERVICENAME), dwErr);
363        lpszStrings[0] = szMsg;
364        lpszStrings[1] = lpszMsg;
365
366        if (hEventSource != NULL) {
367            ReportEvent(hEventSource, // handle of event source
368                EVENTLOG_ERROR_TYPE,  // event type
369                0,                    // event category
370                0,                    // event ID
371                NULL,                 // current user's SID
372                2,                    // strings in lpszStrings
373                0,                    // no bytes of raw data
374                lpszStrings,          // array of error strings
375                NULL);                // no raw data
376
377            (VOID) DeregisterEventSource(hEventSource);
378        }
379    }
380}
381//____________________________________________________________________________________________________________________________
382//
383//  The following code handles service installation and removal
384//
385//____________________________________________________________________________________________________________________________
386//
387//  FUNCTION: CmdInstallService()
388//
389//  PURPOSE: Installs the service
390//  PARAMETERS:
391//    none
392//
393//  RETURN VALUE:
394//    none
395//
396//  COMMENTS:
397//____________________________________________________________________________________________________________________________
398void CmdInstallService()
399{
400    SC_HANDLE   schService;
401    SC_HANDLE   schSCManager;
402
403    TCHAR szPath[512];
404
405    if ( GetModuleFileName( NULL, szPath, 512 ) == 0 )
406    {
407        _tprintf(TEXT("Unable to install %s - %s\n"), TEXT(SZSERVICEDISPLAYNAME), GetLastErrorText(szErr, 256));
408        return;
409    }
410    schSCManager = OpenSCManager(
411                        NULL,                   // machine (NULL == local)
412                        NULL,                   // database (NULL == default)
413                        SC_MANAGER_ALL_ACCESS   // access required
414                        );
415    if ( schSCManager )
416    {
417        schService = CreateService(
418            schSCManager,               // SCManager database
419            TEXT(SZSERVICENAME),        // name of service
420            TEXT(SZSERVICEDISPLAYNAME), // name to display
421            SERVICE_ALL_ACCESS,         // desired access
422            SERVICE_WIN32_OWN_PROCESS,  // service type
423            SERVICE_AUTO_START,       // start type
424            SERVICE_ERROR_NORMAL,       // error control type
425            szPath,                     // service's binary
426            NULL,                       // no load ordering group
427            NULL,                       // no tag identifier
428            TEXT(SZDEPENDENCIES),       // dependencies
429            NULL,                       // LocalSystem account
430            NULL);                      // no password
431
432        if ( schService )
433        {
434            _tprintf(TEXT("%s installed.\n"), TEXT(SZSERVICEDISPLAYNAME) );
435            CloseServiceHandle(schService);
436        }
437        else
438        {
439            _tprintf(TEXT("CreateService failed - %s\n"), GetLastErrorText(szErr, 256));
440        }
441
442        CloseServiceHandle(schSCManager);
443    }
444    else
445        _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
446}
447//____________________________________________________________________________________________________________________________
448//
449//  FUNCTION: CmdRemoveService()
450//
451//  PURPOSE: Stops and removes the service
452//
453//  PARAMETERS:
454//    none
455//
456//  RETURN VALUE:
457//    none
458//
459//  COMMENTS:
460//
461//____________________________________________________________________________________________________________________________
462void CmdRemoveService()
463{
464    SC_HANDLE   schService;
465    SC_HANDLE   schSCManager;
466
467    schSCManager = OpenSCManager(
468                        NULL,                   // machine (NULL == local)
469                        NULL,                   // database (NULL == default)
470                        SC_MANAGER_ALL_ACCESS   // access required
471                        );
472    if ( schSCManager )
473    {
474        schService = OpenService(schSCManager, TEXT(SZSERVICENAME), SERVICE_ALL_ACCESS);
475
476        if (schService)
477        {
478            // try to stop the service
479            if ( ControlService( schService, SERVICE_CONTROL_STOP, &ssStatus ) )
480            {
481                _tprintf(TEXT("Stopping %s."), TEXT(SZSERVICEDISPLAYNAME));
482                Sleep( 1000 );
483
484                while( QueryServiceStatus( schService, &ssStatus ) )
485                {
486                    if ( ssStatus.dwCurrentState == SERVICE_STOP_PENDING )
487                    {
488                        _tprintf(TEXT("."));
489                        Sleep( 1000 );
490                    }
491                    else
492                        break;
493                }
494
495                if ( ssStatus.dwCurrentState == SERVICE_STOPPED )
496                    _tprintf(TEXT("\n%s stopped.\n"), TEXT(SZSERVICEDISPLAYNAME) );
497                else
498                    _tprintf(TEXT("\n%s failed to stop.\n"), TEXT(SZSERVICEDISPLAYNAME) );
499
500            }
501
502            // now remove the service
503            if( DeleteService(schService) )
504                _tprintf(TEXT("%s removed.\n"), TEXT(SZSERVICEDISPLAYNAME) );
505            else
506                _tprintf(TEXT("DeleteService failed - %s\n"), GetLastErrorText(szErr,256));
507
508
509            CloseServiceHandle(schService);
510        }
511        else
512            _tprintf(TEXT("OpenService failed - %s\n"), GetLastErrorText(szErr,256));
513
514        CloseServiceHandle(schSCManager);
515    }
516    else
517        _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
518}
519//____________________________________________________________________________________________________________________________
520//
521//  The following code is for running the service as a console app
522//
523//
524//  FUNCTION: CmdDebugService(int argc, char ** argv)
525//
526//  PURPOSE: Runs the service as a console application
527//
528//  PARAMETERS:
529//    argc - number of command line arguments
530//    argv - array of command line arguments
531//
532//  RETURN VALUE:
533//    none
534//
535//  COMMENTS:
536//
537//____________________________________________________________________________________________________________________________
538void CmdDebugService(int argc, char ** argv)
539{
540    DWORD dwArgc;
541    LPTSTR *lpszArgv;
542
543#ifdef UNICODE
544    lpszArgv = CommandLineToArgvW(GetCommandLineW(), &(dwArgc) );
545#else
546    dwArgc   = (DWORD) argc;
547    lpszArgv = argv;
548#endif
549
550    _tprintf(TEXT("Debugging %s.\n"), TEXT(SZSERVICEDISPLAYNAME));
551
552    SetConsoleCtrlHandler( ControlHandler, TRUE );
553
554    ServiceStart( dwArgc, lpszArgv );
555}
556//____________________________________________________________________________________________________________________________
557//
558//  FUNCTION: ControlHandler ( DWORD dwCtrlType )
559//
560//  PURPOSE: Handled console control events
561//
562//  PARAMETERS:
563//    dwCtrlType - type of control event
564//
565//  RETURN VALUE:
566//    True - handled
567//    False - unhandled
568//
569//  COMMENTS:
570//
571//____________________________________________________________________________________________________________________________
572BOOL WINAPI ControlHandler ( DWORD dwCtrlType )
573{
574    switch( dwCtrlType )
575    {
576        case CTRL_BREAK_EVENT:  // use Ctrl+C or Ctrl+Break to simulate
577        case CTRL_C_EVENT:      // SERVICE_CONTROL_STOP in debug mode
578            _tprintf(TEXT("Stopping %s.\n"), TEXT(SZSERVICEDISPLAYNAME));
579            ServiceStop();
580            return TRUE;
581            break;
582
583    }
584    return FALSE;
585}
586//____________________________________________________________________________________________________________________________
587//
588//  FUNCTION: GetLastErrorText
589//
590//  PURPOSE: copies error message text to string
591//
592//  PARAMETERS:
593//    lpszBuf - destination buffer
594//    dwSize - size of buffer
595//
596//  RETURN VALUE:
597//    destination buffer
598//
599//  COMMENTS:
600//
601//____________________________________________________________________________________________________________________________
602LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize )
603{
604    DWORD dwRet;
605    LPTSTR lpszTemp = NULL;
606
607    dwRet = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ARGUMENT_ARRAY,
608                           NULL,
609                           GetLastError(),
610                           LANG_NEUTRAL,
611                           (LPTSTR)&lpszTemp,
612                           0,
613                           NULL );
614
615    // supplied buffer is not long enough
616    if ( !dwRet || ( (long)dwSize < (long)dwRet+14 ) )
617        lpszBuf[0] = TEXT('\0');
618    else
619    {
620        lpszTemp[lstrlen(lpszTemp)-2] = TEXT('\0');  //remove cr and newline character
621        _stprintf( lpszBuf, TEXT("%s (0x%x)"), lpszTemp, GetLastError() );
622    }
623
624    if ( lpszTemp )
625        LocalFree((HLOCAL) lpszTemp );
626
627    return lpszBuf;
628}
Note: See TracBrowser for help on using the repository browser.