X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fcontrol%2Fntservice.c;h=4d52d14a84521928d7f30d6162925fc460c3f2c1;hb=6411526fe052a033300e73045b07c0aaee089e88;hp=7f00d01e81f53409f45140c6165bcb5b4823ddd3;hpb=11a86fba8228b97deb9845beb159a3468a5e9064;p=vlc diff --git a/modules/control/ntservice.c b/modules/control/ntservice.c old mode 100755 new mode 100644 index 7f00d01e81..4d52d14a84 --- a/modules/control/ntservice.c +++ b/modules/control/ntservice.c @@ -1,10 +1,10 @@ /***************************************************************************** * ntservice.c: Windows NT/2K/XP service interface ***************************************************************************** - * Copyright (C) 2001 VideoLAN - * $Id: ntservice.c,v 1.3 2003/11/15 10:38:01 ipkiss Exp $ + * Copyright (C) 2004 the VideoLAN team + * $Id$ * - * Authors: Gildas Bazin + * Authors: Gildas Bazin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,15 +18,18 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** * Preamble *****************************************************************************/ -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include -#include +#include #define VLCSERVICENAME "VLC media player" @@ -36,31 +39,40 @@ static int Activate( vlc_object_t * ); static void Close ( vlc_object_t * ); -#define INSTALL_TEXT N_( "Install NT/2K/XP service" ) +#define INSTALL_TEXT N_( "Install Windows Service" ) #define INSTALL_LONGTEXT N_( \ - "If enabled the interface will install the service and exit." ) -#define UNINSTALL_TEXT N_( "Uninstall NT/2K/XP service" ) + "Install the Service and exit." ) +#define UNINSTALL_TEXT N_( "Uninstall Windows Service" ) #define UNINSTALL_LONGTEXT N_( \ - "If enabled the interface will uninstall the service and exit." ) -#define NAME_TEXT N_( "Display name of the service" ) + "Uninstall the Service and exit." ) +#define NAME_TEXT N_( "Display name of the Service" ) #define NAME_LONGTEXT N_( \ - "This allows you to change the display name of the service." ) + "Change the display name of the Service." ) +#define OPTIONS_TEXT N_("Configuration options") +#define OPTIONS_LONGTEXT N_( \ + "Configuration options that will be " \ + "used by the Service (eg. --foo=bar --no-foobar). It should be specified "\ + "at install time so the Service is properly configured.") #define EXTRAINTF_TEXT N_("Extra interface modules") #define EXTRAINTF_LONGTEXT N_( \ - "This option allows you to select additional interfaces spawned by the " \ - "service. It should be specified at install time so the service is " \ + "Additional interfaces spawned by the " \ + "Service. It should be specified at install time so the Service is " \ "properly configured. Use a comma separated list of interface modules. " \ - "(common values are: logger,sap,rc,http)") + "(common values are: logger, sap, rc, http)") vlc_module_begin(); - set_description( _("Windows NT/2K/XP service interface") ); - add_category_hint( N_("NT service"), NULL, VLC_TRUE ); + set_shortname( _("NT Service")); + set_description( _("Windows Service interface") ); + set_category( CAT_INTERFACE ); + set_subcategory( SUBCAT_INTERFACE_CONTROL ); add_bool( "ntservice-install", 0, NULL, INSTALL_TEXT, INSTALL_LONGTEXT, VLC_TRUE ); add_bool( "ntservice-uninstall", 0, NULL, UNINSTALL_TEXT, UNINSTALL_LONGTEXT, VLC_TRUE ); add_string ( "ntservice-name", VLCSERVICENAME, NULL, NAME_TEXT, NAME_LONGTEXT, VLC_TRUE ); + add_string ( "ntservice-options", NULL, NULL, + OPTIONS_TEXT, OPTIONS_LONGTEXT, VLC_TRUE ); add_string ( "ntservice-extraintf", NULL, NULL, EXTRAINTF_TEXT, EXTRAINTF_LONGTEXT, VLC_TRUE ); @@ -113,6 +125,7 @@ void Close( vlc_object_t *p_this ) *****************************************************************************/ static void Run( intf_thread_t *p_intf ) { + intf_thread_t *p_extraintf; SERVICE_TABLE_ENTRY dispatchTable[] = { { VLCSERVICENAME, &ServiceDispatch }, @@ -139,13 +152,22 @@ static void Run( intf_thread_t *p_intf ) if( StartServiceCtrlDispatcher( dispatchTable ) == 0 ) { - msg_Err( p_intf, "StartServiceCtrlDispatcher failed" ); + msg_Err( p_intf, "StartServiceCtrlDispatcher failed" ); /* str review */ } free( p_intf->p_sys->psz_service ); + /* Stop and destroy the interfaces we spawned */ + while( (p_extraintf = vlc_object_find(p_intf, VLC_OBJECT_INTF, FIND_CHILD))) + { + intf_StopThread( p_extraintf ); + vlc_object_detach( p_extraintf ); + vlc_object_release( p_extraintf ); + intf_Destroy( p_extraintf ); + } + /* Make sure we exit (In case other interfaces have been spawned) */ - p_intf->p_vlc->b_die = VLC_TRUE; + vlc_object_kill( p_intf->p_libvlc ); } /***************************************************************************** @@ -154,11 +176,12 @@ static void Run( intf_thread_t *p_intf ) static int NTServiceInstall( intf_thread_t *p_intf ) { intf_sys_t *p_sys = p_intf->p_sys; - char psz_path[MAX_PATH], psz_pathtmp[MAX_PATH], *psz_extraintf; + char psz_path[10*MAX_PATH], psz_pathtmp[MAX_PATH], *psz_extra; SC_HANDLE handle = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if( handle == NULL ) { - msg_Err( p_intf, "Could not connect to SCM database" ); + msg_Err( p_intf, + "could not connect to Services Control Manager database" ); return VLC_EGENERIC; } @@ -167,13 +190,21 @@ static int NTServiceInstall( intf_thread_t *p_intf ) GetModuleFileName( NULL, psz_pathtmp, MAX_PATH ); sprintf( psz_path, "\"%s\" -I "MODULE_STRING, psz_pathtmp ); - psz_extraintf = config_GetPsz( p_intf, "ntservice-extraintf" ); - if( psz_extraintf && *psz_extraintf ) + psz_extra = config_GetPsz( p_intf, "ntservice-extraintf" ); + if( psz_extra && *psz_extra ) { strcat( psz_path, " --ntservice-extraintf " ); - strcat( psz_path, psz_extraintf ); + strcat( psz_path, psz_extra ); } - if( psz_extraintf ) free( psz_extraintf ); + free( psz_extra ); + + psz_extra = config_GetPsz( p_intf, "ntservice-options" ); + if( psz_extra && *psz_extra ) + { + strcat( psz_path, " " ); + strcat( psz_path, psz_extra ); + } + free( psz_extra ); SC_HANDLE service = CreateService( handle, p_sys->psz_service, p_sys->psz_service, @@ -185,20 +216,20 @@ static int NTServiceInstall( intf_thread_t *p_intf ) { if( GetLastError() != ERROR_SERVICE_EXISTS ) { - msg_Err( p_intf, "Could not create new service: \"%s\" (%s)", + msg_Err( p_intf, "could not create new service: \"%s\" (%s)", p_sys->psz_service ,psz_path ); CloseServiceHandle( handle ); return VLC_EGENERIC; } else { - msg_Warn( p_intf, "Service \"%s\" already exists", + msg_Warn( p_intf, "service \"%s\" already exists", p_sys->psz_service ); } } else { - msg_Warn( p_intf, "Service successfuly created" ); + msg_Warn( p_intf, "service successfuly created" ); } if( service ) CloseServiceHandle( service ); @@ -214,7 +245,8 @@ static int NTServiceUninstall( intf_thread_t *p_intf ) SC_HANDLE handle = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if( handle == NULL ) { - msg_Err( p_intf, "Could not connect to SCM database" ); + msg_Err( p_intf, + "could not connect to Services Control Manager database" ); return VLC_EGENERIC; } @@ -222,7 +254,7 @@ static int NTServiceUninstall( intf_thread_t *p_intf ) SC_HANDLE service = OpenService( handle, p_sys->psz_service, DELETE ); if( service == NULL ) { - msg_Err( p_intf, "Could not open service" ); + msg_Err( p_intf, "could not open service" ); CloseServiceHandle( handle ); return VLC_EGENERIC; } @@ -230,12 +262,12 @@ static int NTServiceUninstall( intf_thread_t *p_intf ) /* Remove the service */ if( !DeleteService( service ) ) { - msg_Err( p_intf, "Could not delete service \"%s\"", + msg_Err( p_intf, "could not delete service \"%s\"", p_sys->psz_service ); } else { - msg_Dbg( p_intf, "Service deleted successfuly" ); + msg_Dbg( p_intf, "service deleted successfuly" ); } CloseServiceHandle( service ); @@ -260,7 +292,7 @@ static void WINAPI ServiceDispatch( DWORD numArgs, char **args ) RegisterServiceCtrlHandler( p_sys->psz_service, &ServiceCtrlHandler ); if( p_sys->hStatus == (SERVICE_STATUS_HANDLE)0 ) { - msg_Err( p_intf, "Failed to register service control handler" ); + msg_Err( p_intf, "failed to register service control handler" ); return; } @@ -286,7 +318,7 @@ static void WINAPI ServiceDispatch( DWORD numArgs, char **args ) sprintf( psz_temp, "%s,none", psz_module ); /* Try to create the interface */ - p_new_intf = intf_Create( p_intf, psz_temp ); + p_new_intf = intf_Create( p_intf, psz_temp, 0, NULL ); if( p_new_intf == NULL ) { msg_Err( p_intf, "interface \"%s\" initialization failed", @@ -296,7 +328,6 @@ static void WINAPI ServiceDispatch( DWORD numArgs, char **args ) } /* Try to run the interface */ - p_new_intf->b_block = VLC_FALSE; if( intf_RunThread( p_new_intf ) ) { vlc_object_detach( p_new_intf ); @@ -307,10 +338,7 @@ static void WINAPI ServiceDispatch( DWORD numArgs, char **args ) free( psz_temp ); } } - if( psz_modules ) - { - free( psz_modules ); - } + free( psz_modules ); /* Initialization complete - report running status */ p_sys->status.dwCurrentState = SERVICE_RUNNING;