

// SILENT INSTALLER FOR THE OSIRIS DAEMONS.

#include "stdafx.h"

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <tchar.h>
#include <fcntl.h>
#include <io.h>

/* windows service paramaters.                   */
/* name of the executable, service, display name */
/* and the dependency list.                      */


#define SERVICE_DEPENDENCIES     ""

TCHAR	error_message[256];
SERVICE_STATUS          status;

void install_windows_service( const char *name, const char *display_name,
                              char *path );

void uninstall_windows_service( const char *name );


int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
    /* if we were only given a name, we uninstall only. */

    if( __argc == 2 )
    {
        uninstall_windows_service( __argv[1] );
        return 0;
    }

    /* now install and start. */

	install_windows_service( __argv[1], __argv[2], __argv[3] );

    

	return 0;
}

/******************************************************************************
**
**    Function: GetLastErrorText
**
**    Purpose:  copies error message text to string.
**
******************************************************************************/

LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize )
{
    DWORD dwRet;
    LPTSTR lpszTemp = NULL;

    dwRet = FormatMessage( ( FORMAT_MESSAGE_ALLOCATE_BUFFER |
                             FORMAT_MESSAGE_FROM_SYSTEM |
                             FORMAT_MESSAGE_ARGUMENT_ARRAY ),
                           NULL,
                           GetLastError(),
                           LANG_NEUTRAL,
                           (LPTSTR)&lpszTemp,
                           0,
                           NULL );

    if( !dwRet || ( (long)dwSize < (long)dwRet+14 ) )
    {
        lpszBuf[0] = TEXT('\0');
    }

    else
    {
        // remove cr and newline character.

        lpszTemp[lstrlen(lpszTemp)-2] = TEXT('\0');
        _stprintf( lpszBuf, TEXT("%s (0x%x)"), lpszTemp, GetLastError() );
    }

    if( lpszTemp )
    {
        LocalFree( (HLOCAL)lpszTemp );
    }

    return lpszBuf;
}

/******************************************************************************
**
**    Function: install_windows_service
**
**    Purpose:  install this daemon as a service on the local machine.
**
******************************************************************************/

void install_windows_service( const char *name, const char *display_name, char *path )
{
    SC_HANDLE   schService;
    SC_HANDLE   schSCManager;
    DWORD err_code;

    TCHAR szPath[512];

	strcpy( szPath, path );
    schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

    if( schSCManager )
    {
        schService = CreateService(
                schSCManager,
                TEXT(name),
                TEXT(display_name),
                SERVICE_ALL_ACCESS | SERVICE_INTERACTIVE_PROCESS,
                SERVICE_WIN32_OWN_PROCESS,
                SERVICE_AUTO_START,
                SERVICE_ERROR_NORMAL,
                szPath,
                NULL,                       /* no load ordering group */
                NULL,                       /* no tag identifier */
                TEXT(SERVICE_DEPENDENCIES),
                NULL,                       /* localSystem account */
                NULL);                      /* no password */

        if( schService )
        {
            fprintf( stderr, "%s installed.\n", TEXT(display_name) );

            if( ( StartService( schService, 0, NULL ) ) == 0 )
            {
                err_code = GetLastError();
                fprintf( stderr, TEXT("error code  = %lx\n"), err_code );
            }

            fprintf( stderr, "%s started.\n", TEXT(display_name ) );
            CloseServiceHandle( schService );
        }

        else
        {
            fprintf( stderr, "CreateService failed - %s\n",
                     GetLastErrorText( error_message, 256 ) );
        }

        CloseServiceHandle( schSCManager );
    }

    else
    {
        fprintf( stderr, "OpenSCManager failed - %s\n",
                 GetLastErrorText( error_message, 256 ) );
    }
}

void uninstall_windows_service( const char *name )
{
    SC_HANDLE   schService;
    SC_HANDLE   schSCManager;

    schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

    if( schSCManager )
    {
        schService = OpenService( schSCManager,
                                  TEXT(name),
                                  SERVICE_ALL_ACCESS );

        /* first stop the service. */

        if( schService )
        {
            if( ControlService( schService, SERVICE_CONTROL_STOP, &status ) )
            {
                Sleep( 1000 );

                while( QueryServiceStatus( schService, &status ) )
                {
                    if( status.dwCurrentState == SERVICE_STOP_PENDING )
                    {
                        Sleep( 1000 );
                    }

                    else
                    {
                        break;
                    }
                }

                if( status.dwCurrentState == SERVICE_STOPPED )
                {
                }

                else
                {
                }
            }

            /* now remove the service */

            if( DeleteService( schService ) )
            {
            }

            else
            {
            }

            CloseServiceHandle( schService );
        }

        CloseServiceHandle(schSCManager);
    }
}
