|
|
/////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1996-2002 Microsoft Corporation
//
// Module Name:
// CASvc.cpp
//
// Description:
// Implementation of helper functions for accessing and controlling
// services.
//
// Maintained By:
// David Potter (davidp) December 23, 1996
//
// Revision History:
//
// Notes:
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <winsvc.h>
#include "resource.h"
#define _RESOURCE_H_
#include "CASvc.h"
#include "ConstDef.h"
#include "ExcOper.h"
#include "TraceTag.h"
#include "CluAdmin.h"
#include <FileMgmt.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
/////////////////////////////////////////////////////////////////////////////
// Global Variables
/////////////////////////////////////////////////////////////////////////////
#ifdef _DEBUG
CTraceTag g_tagService( _T("Service"), _T("SERVICE"), 0 ); #endif
/////////////////////////////////////////////////////////////////////////////
//++
//
// HOpenCluster
//
// Description:
// Open a cluster. If it fails, ask if the cluster service should be
// started.
//
// Arguments:
// pszClusterIn -- Name of cluster.
//
// Return Values:
// hCluster -- Cluster handle or NULL.
//
//--
/////////////////////////////////////////////////////////////////////////////
HCLUSTER HOpenCluster( IN LPCTSTR pszClusterIn ) { HCLUSTER hCluster = NULL; HRESULT hr; DWORD dwStatus; DWORD dwClusterState; LPTSTR pszRealCluster; TCHAR szRealClusterName[ MAX_PATH ]; CString strMsg; CFrameWnd * pframeMain;
ASSERT( pszClusterIn != NULL );
pframeMain = PframeMain(); ASSERT( pframeMain != NULL );
if ( _tcscmp( pszClusterIn, _T(".") ) == 0 ) { DWORD nSize = sizeof( szRealClusterName ) / sizeof( TCHAR ); pszRealCluster = NULL; GetComputerName( szRealClusterName, &nSize ); } // if: connecting to the local machine
else { pszRealCluster = (LPTSTR) pszClusterIn; hr = StringCchCopy( szRealClusterName, RTL_NUMBER_OF( szRealClusterName ), pszClusterIn ); if ( FAILED( hr ) ) { CNTException nte( hr, 0, NULL, NULL, FALSE /*bAutoDelete*/ ); nte.ReportError(); goto Cleanup; } } // else: not connecting to the local machine
// Display a message on the status bar.
{ CString strStatusBarText; strStatusBarText.FormatMessage( IDS_SB_OPENING_CONNECTION, szRealClusterName ); pframeMain->SetMessageText( strStatusBarText ); pframeMain->UpdateWindow(); } // Display a message on the status bar
// Encapsulate wait cursor class.
{ CWaitCursor wc;
Trace( g_tagService, _T("HOpenCluster() - Getting node cluster state on '%s'"), szRealClusterName );
// Get the cluster state of the node.
dwStatus = GetNodeClusterState( pszRealCluster, &dwClusterState ); if ( dwStatus != ERROR_SUCCESS ) { CNTException nte( dwStatus, IDS_CANNOT_START_CLUSTER_SERVICE, szRealClusterName, NULL, FALSE /*bAutoDelete*/ ); nte.ReportError( MB_OK | MB_ICONSTOP ); goto Cleanup; }
Trace( g_tagService, _T("HOpenCluster() - Node cluster state on '%s' is 0x%08.8x"), szRealClusterName, dwClusterState );
} // Encapsulate wait cursor class
// Check to see make sure that clustering is installed and configured
// on the specified node.
if ( ( dwClusterState == ClusterStateNotInstalled ) || ( dwClusterState == ClusterStateNotConfigured ) ) { strMsg.FormatMessage( IDS_CLUSTER_NOT_INSTALLED_OR_CONFIGURED, szRealClusterName ); AfxMessageBox( strMsg, MB_OK | MB_ICONSTOP ); goto Cleanup; } // if: clustering not installed or configured
// If the cluster service is not running, ask if it should be started.
if ( dwClusterState == ClusterStateNotRunning ) { ID id;
// Ask the user if the cluster service should be started.
strMsg.FormatMessage( IDS_START_CLUSTER_SERVICE, szRealClusterName ); id = AfxMessageBox( strMsg, MB_YESNO | MB_ICONEXCLAMATION ); if ( id == IDYES ) { // Display a message on the status bar.
{ CString strStatusBarText; strStatusBarText.FormatMessage( IDS_SB_STARTING_CLUSTER_SERVICE, szRealClusterName ); pframeMain->SetMessageText( strStatusBarText ); pframeMain->UpdateWindow(); } // Display a message on the status bar
// Encapsulate wait cursor class.
{ CWaitCursor wc;
// Start the service.
hr = HrStartService( CLUSTER_SERVICE_NAME, szRealClusterName ); if ( ! FAILED( hr ) && ( hr != S_FALSE ) ) { if ( hr == S_OK ) { // Wait a second. This is required to make sure that the
// cluster service is running and ready to receive RPC
// connections.
Sleep( 1000 ); } // if: user didn't cancel the start operation
} // if: service started successfully
else { CNTException nte( hr, IDS_CANNOT_START_CLUSTER_SERVICE, szRealClusterName, NULL, FALSE /*bAutoDelete*/ ); nte.ReportError(); goto Cleanup; } // else: failed to start the service
} // Encapsulate wait cursor class
} // if: user approved starting the service
} // if: cluster service not running
// Encapsulate wait cursor class.
{ CWaitCursor wc;
// Display a message on the status bar.
{ CString strStatusBarText; strStatusBarText.FormatMessage( IDS_SB_OPENING_CONNECTION, szRealClusterName ); pframeMain->SetMessageText( strStatusBarText ); pframeMain->UpdateWindow(); } // Display a message on the status bar
Trace( g_tagService, _T("HOpenCluster() - Opening the cluster on '%s'"), szRealClusterName );
// Open the cluster.
hCluster = OpenCluster( pszRealCluster ); if ( hCluster == NULL ) { CNTException nte( GetLastError(), IDS_OPEN_NODE_ERROR, szRealClusterName, NULL, FALSE /*bAutoDelete*/ );
dwStatus = nte.Sc(); nte.ReportError(); goto Cleanup; } // if: error opening the cluster
} // Encapsulate wait cursor class
Cleanup: // Reset the message on the status bar.
pframeMain->SetMessageText( AFX_IDS_IDLEMESSAGE ); pframeMain->UpdateWindow();
if ( dwStatus != ERROR_SUCCESS ) { SetLastError( dwStatus ); } // if: error occurred
return hCluster;
} //*** HOpenCluster()
/////////////////////////////////////////////////////////////////////////////
//++
//
// BCanServiceBeStarted
//
// Description:
// Find out if a service can be started on a specified node or not.
//
// Arguments:
// pszServiceNameIn -- Name of service.
// pszNodeIn -- Name of node.
//
// Return Values:
// TRUE -- Service can be started on the specified node.
// FALSE -- Service can not be started on the specified node.
//
//--
/////////////////////////////////////////////////////////////////////////////
BOOL BCanServiceBeStarted( LPCTSTR pszServiceNameIn, LPCTSTR pszNodeIn ) { BOOL bCanBeStarted = FALSE; DWORD dwStatus = ERROR_SUCCESS; SC_HANDLE hSCManager = NULL; SC_HANDLE hService = NULL; SERVICE_STATUS ssServiceStatus;
// Open the Service Control Manager.
hSCManager = OpenSCManager( pszNodeIn, NULL /*lpDatabaseName*/, GENERIC_READ ); if ( hSCManager == NULL ) { dwStatus = GetLastError(); Trace( g_tagService, _T("BCanServiceBeStarted() - Cannot access service control manager on node '%s'! Error: %u."), pszNodeIn, dwStatus ); goto Cleanup; } // if: error opening the Service Control Manager
// Open the service.
hService = OpenService( hSCManager, pszServiceNameIn, SERVICE_ALL_ACCESS ); if ( hService == NULL ) { dwStatus = GetLastError(); Trace( g_tagService, _T("BCanServiceBeStarted() - Cannot open service %s. Error: %u."), pszServiceNameIn, dwStatus ); if ( dwStatus != ERROR_SERVICE_DOES_NOT_EXIST ) { bCanBeStarted = TRUE; } // if: error not Service Does Not Exist
goto Cleanup; } // if: error opening the service
// Query the service status.
if ( QueryServiceStatus( hService, &ssServiceStatus ) ) { if ( ssServiceStatus.dwCurrentState == SERVICE_STOPPED ) { bCanBeStarted = TRUE; } // if: service is stopped
} // if: service status queried successfully
else { dwStatus = GetLastError(); } // if: error querying service status
Cleanup: if ( hService != NULL ) { CloseServiceHandle( hService ); }
if ( hSCManager != NULL ) { CloseServiceHandle( hSCManager ); }
SetLastError( dwStatus );
return bCanBeStarted;
} //*** BCanServiceBeStarted()
/////////////////////////////////////////////////////////////////////////////
//++
//
// BIsServiceInstalled
//
// Routine Description:
// Find out if a service is installed on a specified node or not.
//
// Arguments:
// pszServiceNameIn -- Name of service.
// pszNodeIn -- Name of node.
//
// Return Value:
// TRUE -- Service is running on the specified node.
// FALSE -- Service is not running on the specified node.
//
//--
/////////////////////////////////////////////////////////////////////////////
BOOL BIsServiceInstalled( LPCTSTR pszServiceNameIn, LPCTSTR pszNodeIn ) { BOOL bInstalled = FALSE; DWORD dwStatus = ERROR_SUCCESS; SC_HANDLE hSCManager = NULL; SC_HANDLE hService = NULL;
// Open the Service Control Manager.
hSCManager = OpenSCManager( pszNodeIn, NULL /*lpDatabaseName*/, GENERIC_READ ); if ( hSCManager == NULL ) { dwStatus = GetLastError(); Trace( g_tagService, _T("BIsServiceInstalled() - Cannot access service control manager on node '%s'! Error: %u."), pszNodeIn, dwStatus ); goto Cleanup; } // if: error opening the Service Control Manager
// Open the service.
hService = OpenService( hSCManager, pszServiceNameIn, SERVICE_ALL_ACCESS ); if ( hService == NULL ) { dwStatus = GetLastError(); Trace( g_tagService, _T("BIsServiceInstalled() - Cannot open service %s. Error: %u."), pszServiceNameIn, dwStatus ); if ( dwStatus != ERROR_SERVICE_DOES_NOT_EXIST ) { bInstalled = TRUE; } // if: error not Service Does Not Exist
} // if: error opening the service
else { bInstalled = TRUE; } // else: service opened successfully
Cleanup: if ( hService != NULL ) { CloseServiceHandle( hService ); }
if ( hSCManager != NULL ) { CloseServiceHandle( hSCManager ); }
SetLastError( dwStatus );
return bInstalled;
} //*** BIsServiceInstalled()
/////////////////////////////////////////////////////////////////////////////
//++
//
// BIsServiceRunning
//
// Description:
// Find out if a service is running on a specified node or not.
//
// Arguments:
// pszServiceNameIn -- Name of service.
// pszNodeIn -- Name of node.
//
// Return Values:
// TRUE -- Service is running on the specified node.
// FALSE -- Service is not running on the specified node.
//
//--
/////////////////////////////////////////////////////////////////////////////
BOOL BIsServiceRunning( LPCTSTR pszServiceNameIn, LPCTSTR pszNodeIn ) { BOOL bRunning = FALSE; DWORD dwStatus = ERROR_SUCCESS; SC_HANDLE hSCManager = NULL; SC_HANDLE hService = NULL; SERVICE_STATUS ssServiceStatus;
// Open the Service Control Manager.
hSCManager = OpenSCManager( pszNodeIn, NULL /*lpDatabaseName*/, GENERIC_READ ); if ( hSCManager == NULL ) { dwStatus = GetLastError(); Trace( g_tagService, _T("BIsServiceRunning() - Cannot access service control manager on node '%s'! Error: %u."), pszNodeIn, dwStatus ); goto Cleanup; } // if: error opening the Service Control Manager
// Open the service.
hService = OpenService( hSCManager, pszServiceNameIn, SERVICE_ALL_ACCESS ); if ( hService == NULL ) { dwStatus = GetLastError(); Trace( g_tagService, _T("BIsServiceRunning() - Cannot open service %s. Error: %u."), pszServiceNameIn, dwStatus ); goto Cleanup; } // if: error opening the service
// Query the service status.
if ( QueryServiceStatus( hService, &ssServiceStatus ) ) { if ( ssServiceStatus.dwCurrentState == SERVICE_RUNNING ) { bRunning = TRUE; } // if: service is running
} // if: service status queried successfully
Cleanup: if ( hService != NULL ) { CloseServiceHandle( hService ); }
if ( hSCManager != NULL ) { CloseServiceHandle( hSCManager ); }
SetLastError( dwStatus );
return bRunning;
} //*** BIsServiceRunning()
/////////////////////////////////////////////////////////////////////////////
//++
//
// HrStartService
//
// Description:
// Start a service on a specified node.
//
// Arguments:
// pszServiceNameIn -- Name of service.
// pszNodeIn -- Name of node.
//
// Return Values:
// S_OK -- Service started successfully.
// Any errors returned by SVCMGMT_IStartStopHelper::StartServiceHelper().
//
//--
/////////////////////////////////////////////////////////////////////////////
HRESULT HrStartService( LPCTSTR pszServiceNameIn, LPCTSTR pszNodeIn ) { HRESULT hr = S_OK; ISvcMgmtStartStopHelper * psmssh = NULL; BSTR bstrNode = NULL; BSTR bstrServiceName = NULL; CFrameWnd * pframeMain;
pframeMain = PframeMain(); ASSERT( pframeMain != NULL );
// Display a message on the status bar.
{ CString strStatusBarText; strStatusBarText.FormatMessage( IDS_SB_STARTING_SERVICE, pszServiceNameIn, pszNodeIn ); Trace( g_tagService, _T("HrStartService() - Starting the '%s' service on node '%s'."), pszServiceNameIn, pszNodeIn ); pframeMain->SetMessageText( strStatusBarText ); pframeMain->UpdateWindow(); } // Display a message on the status bar
// Make BSTRs for the arguments.
bstrNode = SysAllocString( pszNodeIn ); if ( bstrNode == NULL ) { hr = E_OUTOFMEMORY; goto Cleanup; } bstrServiceName = SysAllocString( pszServiceNameIn ); if ( bstrServiceName == NULL ) { hr = E_OUTOFMEMORY; goto Cleanup; }
// Create the service management object.
hr = CoCreateInstance( CLSID_SvcMgmt, NULL, CLSCTX_INPROC_SERVER, __uuidof( ISvcMgmtStartStopHelper ), reinterpret_cast< void ** >( &psmssh ) ); if ( FAILED( hr ) ) { Trace( g_tagService, _T("HrStartService() - Error creating IStartStopHelper interface. Error: %u."), hr ); goto Cleanup; }
// Start the service.
hr = psmssh->StartServiceHelper( AfxGetMainWnd()->m_hWnd, bstrNode, bstrServiceName, 0, NULL ); if ( FAILED( hr ) ) { Trace( g_tagService, _T("HrStartService() - Error from IStartStopHelper::StartServiceHelper() to start the '%s' service on node '%s'. Error: %u."), pszServiceNameIn, pszNodeIn, hr ); goto Cleanup; }
Cleanup: if ( bstrNode != NULL ) { SysFreeString( bstrNode ); } if ( bstrServiceName != NULL ) { SysFreeString( bstrServiceName ); } if ( psmssh != NULL ) { psmssh->Release(); }
// Reset the message on the status bar.
pframeMain->SetMessageText( AFX_IDS_IDLEMESSAGE ); pframeMain->UpdateWindow();
return hr;
} //*** HrStartService()
/////////////////////////////////////////////////////////////////////////////
//++
//
// HrStopService
//
// Description:
// Stop a service on a specified node.
//
// Arguments:
// pszServiceNameIn -- Name of service.
// pszNodeIn -- Name of node.
//
// Return Values:
// S_OK -- Service stopped successfully.
// Any errors returned by SVCMGMT_IStartStopHelper::ControlServiceHelper().
//
//--
/////////////////////////////////////////////////////////////////////////////
HRESULT HrStopService( LPCTSTR pszServiceNameIn, LPCTSTR pszNodeIn ) { HRESULT hr = S_OK; ISvcMgmtStartStopHelper * psmssh = NULL; BSTR bstrNode = NULL; BSTR bstrServiceName = NULL; CFrameWnd * pframeMain;
pframeMain = PframeMain(); ASSERT( pframeMain != NULL );
// Display a message on the status bar.
{ CString strStatusBarText; strStatusBarText.FormatMessage( IDS_SB_STOPPING_SERVICE, pszServiceNameIn, pszNodeIn ); Trace( g_tagService, _T("HrStopService() - Stopping the '%s' service on node '%s'."), pszServiceNameIn, pszNodeIn ); pframeMain->SetMessageText( strStatusBarText ); pframeMain->UpdateWindow(); } // Display a message on the status bar
// Make BSTRs for the arguments.
bstrNode = SysAllocString( pszNodeIn ); if ( bstrNode == NULL ) { hr = E_OUTOFMEMORY; goto Cleanup; } bstrServiceName = SysAllocString( pszServiceNameIn ); if ( bstrServiceName == NULL ) { hr = E_OUTOFMEMORY; goto Cleanup; }
// Create the service management object.
hr = CoCreateInstance( CLSID_SvcMgmt, NULL, CLSCTX_INPROC_SERVER, __uuidof( ISvcMgmtStartStopHelper ), reinterpret_cast< void ** >( &psmssh ) ); if ( FAILED( hr ) ) { Trace( g_tagService, _T("HrStopService() - Error creating IStartStopHelper interface. Error: %u."), hr ); goto Cleanup; }
// Start the service.
hr = psmssh->ControlServiceHelper( AfxGetMainWnd()->m_hWnd, bstrNode, bstrServiceName, SERVICE_CONTROL_STOP ); if ( FAILED( hr ) ) { Trace( g_tagService, _T("HrStopService() - Error from IStartStopHelper::ControlServiceHelper() to stop the '%s' service on node '%s'. Error: %u."), pszServiceNameIn, pszNodeIn, hr ); goto Cleanup; }
Cleanup: if ( bstrNode != NULL ) { SysFreeString( bstrNode ); } if ( bstrServiceName != NULL ) { SysFreeString( bstrServiceName ); } if ( psmssh != NULL ) { psmssh->Release(); }
// Reset the message on the status bar.
pframeMain->SetMessageText( AFX_IDS_IDLEMESSAGE ); pframeMain->UpdateWindow();
return hr;
} //*** HrStopService()
|