Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

631 lines
15 KiB

//____________________________________________________________________________
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1995 - 1996.
//
// File: SchState.cxx
//
// Contents:
//
// Classes:
//
// Functions:
//
// History: 3/27/1996 RaviR Created
//
//____________________________________________________________________________
#include "..\pch\headers.hxx"
#pragma hdrstop
#include "dbg.h"
#include "macros.h"
#include "..\inc\common.hxx"
#include "..\inc\resource.h"
#include "..\inc\misc.hxx"
#include "resource.h"
#include "..\schedui\schedui.hxx"
#include <StrSafe.h>
#define MAX_MSGLEN 300
#define MAX_SCHED_START_WAIT 60 // seconds
//____________________________________________________________________________
//
// Function: GetSchSvcState
//
// Synopsis: returns the schedul service status
//
// Arguments: [dwState] -- IN
//
// Returns: HRESULT
//
// History: 3/29/1996 RaviR Created
//
//____________________________________________________________________________
HRESULT
GetSchSvcState(
DWORD &dwState)
{
SC_HANDLE hSchSvc = NULL;
HRESULT hr = S_OK;
do
{
hSchSvc = OpenScheduleService(SERVICE_QUERY_STATUS);
if (hSchSvc == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
DEBUG_OUT_LASTERROR;
break;
}
SERVICE_STATUS SvcStatus;
if (QueryServiceStatus(hSchSvc, &SvcStatus) == FALSE)
{
hr = HRESULT_FROM_WIN32(GetLastError());
DEBUG_OUT_LASTERROR;
break;
}
dwState = SvcStatus.dwCurrentState;
} while (0);
if (hSchSvc != NULL)
{
CloseServiceHandle(hSchSvc);
}
return hr;
}
//____________________________________________________________________________
//
// Function: StartScheduler
//
// Synopsis: Start the schedule service
//
// Returns: HRESULT
//
// History: 3/29/1996 RaviR Created
//
//____________________________________________________________________________
HRESULT
StartScheduler(void)
{
SC_HANDLE hSchSvc = NULL;
HRESULT hr = S_OK;
do
{
hSchSvc = OpenScheduleService(
SERVICE_CHANGE_CONFIG | SERVICE_START |
SERVICE_QUERY_STATUS);
if (hSchSvc == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
DEBUG_OUT_LASTERROR;
break;
}
SERVICE_STATUS SvcStatus;
if (QueryServiceStatus(hSchSvc, &SvcStatus) == FALSE)
{
hr = HRESULT_FROM_WIN32(GetLastError());
DEBUG_OUT_LASTERROR;
break;
}
if (SvcStatus.dwCurrentState == SERVICE_RUNNING)
{
// The service is already running.
break;
}
if (StartService(hSchSvc, 0, NULL) == FALSE)
{
hr = HRESULT_FROM_WIN32(GetLastError());
DEBUG_OUT_LASTERROR;
break;
}
} while (0);
if (hSchSvc != NULL)
{
CloseServiceHandle(hSchSvc);
}
return hr;
}
//____________________________________________________________________________
//
// Function: StopScheduler
//
// Synopsis: Stops the schedule service
//
// Returns: HRESULT
//
// History: 3/29/1996 RaviR Created
//
//____________________________________________________________________________
HRESULT
StopScheduler(void)
{
SC_HANDLE hSchSvc = NULL;
HRESULT hr = S_OK;
do
{
hSchSvc = OpenScheduleService(
SERVICE_CHANGE_CONFIG | SERVICE_STOP |
SERVICE_QUERY_STATUS);
if (hSchSvc == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
DEBUG_OUT_LASTERROR;
break;
}
SERVICE_STATUS SvcStatus;
if (QueryServiceStatus(hSchSvc, &SvcStatus) == FALSE)
{
hr = HRESULT_FROM_WIN32(GetLastError());
DEBUG_OUT_LASTERROR;
break;
}
if (SvcStatus.dwCurrentState == SERVICE_STOPPED)
{
// The service is already stopped.
break;
}
if (ControlService(hSchSvc, SERVICE_CONTROL_STOP, &SvcStatus) == FALSE)
{
hr = HRESULT_FROM_WIN32(GetLastError());
DEBUG_OUT_LASTERROR;
break;
}
} while (0);
if (hSchSvc != NULL)
{
CloseServiceHandle(hSchSvc);
}
return hr;
}
//____________________________________________________________________________
//
// Function: PauseScheduler
//
// Synopsis: If fPause==TRUE requests the schedule service to pauses,
// else to continue.
//
// Arguments: [fPause] -- IN
//
// Returns: HRESULT
//
// History: 3/29/1996 RaviR Created
//
//____________________________________________________________________________
HRESULT
PauseScheduler(
BOOL fPause)
{
SC_HANDLE hSchSvc = NULL;
HRESULT hr = S_OK;
do
{
hSchSvc = OpenScheduleService(
SERVICE_PAUSE_CONTINUE | SERVICE_QUERY_STATUS);
if (hSchSvc == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
DEBUG_OUT_LASTERROR;
break;
}
SERVICE_STATUS SvcStatus;
if (QueryServiceStatus(hSchSvc, &SvcStatus) == FALSE)
{
hr = HRESULT_FROM_WIN32(GetLastError());
DEBUG_OUT_LASTERROR;
break;
}
if (fPause == TRUE)
{
if ((SvcStatus.dwCurrentState == SERVICE_PAUSED) ||
(SvcStatus.dwCurrentState == SERVICE_PAUSE_PENDING))
{
// Nothing to do here.
break;
}
else if ((SvcStatus.dwCurrentState == SERVICE_STOPPED) ||
(SvcStatus.dwCurrentState == SERVICE_STOP_PENDING))
{
Win4Assert(0 && "Unexpected");
hr = E_UNEXPECTED;
CHECK_HRESULT(hr);
break;
}
else
{
if (ControlService(hSchSvc, SERVICE_CONTROL_PAUSE, &SvcStatus)
== FALSE)
{
hr = HRESULT_FROM_WIN32(GetLastError());
DEBUG_OUT_LASTERROR;
break;
}
}
}
else // continue
{
if ((SvcStatus.dwCurrentState == SERVICE_RUNNING) ||
(SvcStatus.dwCurrentState == SERVICE_CONTINUE_PENDING))
{
// Nothing to do here.
break;
}
else if ((SvcStatus.dwCurrentState == SERVICE_STOPPED) ||
(SvcStatus.dwCurrentState == SERVICE_STOP_PENDING))
{
Win4Assert(0 && "Unexpected");
hr = E_UNEXPECTED;
CHECK_HRESULT(hr);
break;
}
else
{
if (ControlService(hSchSvc, SERVICE_CONTROL_CONTINUE,
&SvcStatus)
== FALSE)
{
hr = HRESULT_FROM_WIN32(GetLastError());
DEBUG_OUT_LASTERROR;
break;
}
}
}
} while (0);
if (hSchSvc != NULL)
{
CloseServiceHandle(hSchSvc);
}
return hr;
}
//+--------------------------------------------------------------------------
//
// Function: UserCanChangeService
//
// Synopsis: Returns TRUE if the UI should allow the user to invoke
// service start, stop, pause/continue, or at account options.
//
// Returns: TRUE if focus is local machine and OS is win95 or it is NT
// and the user is an admin.
//
// History: 4-16-1997 DavidMun Created
//
//---------------------------------------------------------------------------
BOOL
UserCanChangeService(
LPCTSTR pszServerFocus)
{
if (pszServerFocus)
{
return FALSE;
}
//
// Determine if user is an admin. If not, some items under the
// advanced menu will be disabled.
// BUGBUG A more accurate way to do this would be to attempt to open
// the relevant registry keys and service handle.
//
return IsThreadCallerAnAdmin(NULL);
}
//+--------------------------------------------------------------------------
//
// Function: PromptForServiceStart
//
// Synopsis: If the service is not started or is paused, prompt the user
// to allow us to start/continue it.
//
// Returns: S_OK - service was already running, or was successfully
// started or continued.
// S_FALSE - user elected not to start/continue service
// E_* - error starting/continuing service
//
// History: 4-16-1997 DavidMun Created
//
//---------------------------------------------------------------------------
HRESULT
PromptForServiceStart(
HWND hwnd)
{
HRESULT hr = S_OK;
do
{
//
// Get the current service state
//
DWORD dwState = SERVICE_STOPPED;
hr = GetSchSvcState(dwState);
if (FAILED(hr))
{
dwState = SERVICE_STOPPED;
hr = S_OK; // reset
}
//
// Determine the required action
//
UINT uMsg = 0;
if (dwState == SERVICE_STOPPED ||
dwState == SERVICE_STOP_PENDING)
{
uMsg = IDS_START_SERVICE;
}
else if (dwState == SERVICE_PAUSED ||
dwState == SERVICE_PAUSE_PENDING)
{
uMsg = IDS_CONTINUE_SERVICE;
}
else if (dwState == SERVICE_START_PENDING)
{
uMsg = IDS_START_PENDING;
}
//
// If the service is running, there's nothing to do.
//
if (!uMsg)
{
hr = S_OK;
break;
}
if (uMsg == IDS_START_PENDING)
{
SchedUIMessageDialog(hwnd,
uMsg,
MB_SETFOREGROUND |
MB_TASKMODAL |
MB_ICONINFORMATION |
MB_OK,
NULL);
}
else
{
if (SchedUIMessageDialog(hwnd, uMsg,
MB_SETFOREGROUND |
MB_TASKMODAL |
MB_ICONQUESTION |
MB_YESNO,
NULL)
== IDNO)
{
hr = S_FALSE;
break;
}
}
CWaitCursor waitCursor;
if (uMsg == IDS_START_SERVICE)
{
hr = StartScheduler();
if (FAILED(hr))
{
SchedUIErrorDialog(hwnd, IERR_STARTSVC, (LPTSTR)NULL);
break;
}
// Give the schedule service time to start up.
Sleep(2000);
}
else if (uMsg == IDS_CONTINUE_SERVICE)
{
PauseScheduler(FALSE);
}
for (int count=0; count < 60; count++)
{
GetSchSvcState(dwState);
if (dwState == SERVICE_RUNNING)
{
break;
}
Sleep(1000); // Sleep for 1 seconds.
}
if (dwState != SERVICE_RUNNING)
{
//
// unable to start/continue the service.
//
SchedUIErrorDialog(hwnd,
(uMsg == IDS_START_SERVICE) ? IERR_STARTSVC
: IERR_CONTINUESVC,
(LPTSTR)NULL);
hr = E_FAIL;
break;
}
} while (0);
return hr;
}
//+--------------------------------------------------------------------------
//
// Function: QuietStartContinueService
//
// Synopsis: Start or continue the service without requiring user
// interaction.
//
// Returns: S_OK - service running
// E_FAIL - timeout or failure
//
// History: 5-19-1997 DavidMun Created
//
//---------------------------------------------------------------------------
HRESULT
QuietStartContinueService()
{
HRESULT hr = S_OK;
DWORD dwState = SERVICE_STOPPED;
do
{
hr = GetSchSvcState(dwState);
if (FAILED(hr))
{
dwState = SERVICE_STOPPED;
hr = S_OK; // reset
}
//
// If the service is running, there's nothing to do.
//
if (dwState == SERVICE_RUNNING)
{
break;
}
//
// If it's stopped, request a start. If it's paused, request
// continue.
//
CWaitCursor waitCursor;
switch (dwState)
{
case SERVICE_STOPPED:
case SERVICE_STOP_PENDING:
hr = StartScheduler();
break;
case SERVICE_PAUSED:
case SERVICE_PAUSE_PENDING:
hr = PauseScheduler(FALSE);
break;
}
if (FAILED(hr))
{
CHECK_HRESULT(hr);
break;
}
//
// Wait for its state to change to running
//
for (int count=0; count < MAX_SCHED_START_WAIT; count++)
{
GetSchSvcState(dwState);
if (dwState == SERVICE_RUNNING)
{
break;
}
Sleep(1000); // Sleep for 1 seconds.
}
if (dwState != SERVICE_RUNNING)
{
//
// unable to start/continue the service.
//
hr = E_FAIL;
CHECK_HRESULT(hr);
}
} while (0);
return hr;
}
//____________________________________________________________________________
//
// Function: OpenScheduleService
//
// Synopsis: Opens a handle to the "Schedule" service
//
// Arguments: [dwDesiredAccess] -- desired access
//
// Returns: Handle; if NULL, use GetLastError()
//
// History: 15-Nov-1996 AnirudhS Created
//
//____________________________________________________________________________
SC_HANDLE
OpenScheduleService(DWORD dwDesiredAccess)
{
SC_HANDLE hSC = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (hSC == NULL)
{
DEBUG_OUT_LASTERROR;
return NULL;
}
SC_HANDLE hSchSvc = OpenService(hSC, SCHED_SERVICE_NAME, dwDesiredAccess);
CloseServiceHandle(hSC);
if (hSchSvc == NULL)
{
DEBUG_OUT_LASTERROR;
}
return hSchSvc;
}