|
|
/*
File service.c
Handles requests to deal with the remote access service as neccessary for the dialup-server ui.
Paul Mayfield, 11/3/97 */
#include "rassrv.h"
// Data used for the dialup server
typedef struct _SERVICE_DATA { HANDLE hSC; HANDLE hService; SERVICE_STATUS Status; } SERVICE_DATA;
// This is the string that holds the name of the remote access service
static WCHAR pszRemoteAccess[] = L"remoteaccess"; static WCHAR pszRasman[] = L"rasman"; static WCHAR pszServer[] = L"lanmanserver";
// Opens a named dialup service object
//
DWORD DialupOpenNamedService( IN WCHAR* pszService, OUT HANDLE * phDialup) { SERVICE_DATA * pServData; BOOL bOk = FALSE; DWORD dwErr = NO_ERROR;
// Validate parameters
if (!phDialup) { return ERROR_INVALID_PARAMETER; }
// Create the data structure
if ((pServData = RassrvAlloc(sizeof(SERVICE_DATA), TRUE)) == NULL) { return ERROR_NOT_ENOUGH_MEMORY; }
do { // Open the service manager
pServData->hSC = OpenSCManager( NULL, SERVICES_ACTIVE_DATABASE, GENERIC_EXECUTE); if (! pServData->hSC) { dwErr = GetLastError(); break; }
// Open the dialup service
pServData->hService = OpenServiceW( pServData->hSC, pszService, SERVICE_START | SERVICE_STOP | SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS); if (! pServData->hService) { dwErr = GetLastError(); break; }
// Assign the handle
*phDialup = (HANDLE)pServData; bOk = TRUE; } while (FALSE); // Cleanup
{ if (! bOk) { if (pServData->hService) { CloseServiceHandle(pServData->hService); } if (pServData->hSC) { CloseServiceHandle(pServData->hSC); } RassrvFree(pServData); *phDialup = NULL; } }
return NO_ERROR; }
// Opens a reference to the server service object
DWORD SvcOpenServer(HANDLE * phDialup) { return DialupOpenNamedService(pszServer, phDialup); }
// Opens a reference to the rasman service object
DWORD SvcOpenRasman(HANDLE * phDialup) { return DialupOpenNamedService(pszRasman, phDialup); }
// Creates/destroys instances of the dialup server service object
DWORD SvcOpenRemoteAccess(HANDLE * phDialup) { return DialupOpenNamedService(pszRemoteAccess, phDialup); }
// Close up the references to the dialup service object
DWORD SvcClose(HANDLE hDialup) { SERVICE_DATA * pServData = (SERVICE_DATA *)hDialup; if (! pServData) return ERROR_INVALID_PARAMETER;
if (pServData->hService) CloseServiceHandle(pServData->hService); if (pServData->hSC) CloseServiceHandle(pServData->hSC);
RassrvFree(pServData);
return NO_ERROR; }
// Gets the status of a dialup server service object.
DWORD SvcIsStarted (HANDLE hDialup, PBOOL pbStarted) { SERVICE_DATA * pServData = (SERVICE_DATA *)hDialup; BOOL bOk;
// Verify parameters
if (!pServData || !pbStarted) return ERROR_INVALID_PARAMETER;
// Get the status
bOk = QueryServiceStatus (pServData->hService, &pServData->Status); if (! bOk) return GetLastError();
// Return the status
*pbStarted = (BOOL)(pServData->Status.dwCurrentState == SERVICE_RUNNING);
return NO_ERROR; }
// Gets the status of a dialup server service object.
DWORD SvcIsStopped (HANDLE hDialup, PBOOL pbStopped) { SERVICE_DATA * pServData = (SERVICE_DATA *)hDialup; BOOL bOk;
// Verify parameters
if (!pServData || !pbStopped) return ERROR_INVALID_PARAMETER;
// Get the status
bOk = QueryServiceStatus (pServData->hService, &pServData->Status); if (! bOk) return GetLastError();
// Return the status
*pbStopped = (BOOL)(pServData->Status.dwCurrentState == SERVICE_STOPPED);
return NO_ERROR; }
// Gets the status of a dialup server service object.
DWORD SvcIsPaused (HANDLE hDialup, PBOOL pbPaused) { SERVICE_DATA * pServData = (SERVICE_DATA *)hDialup; BOOL bOk;
// Verify parameters
if (!pServData || !pbPaused) return ERROR_INVALID_PARAMETER;
// Get the status
bOk = QueryServiceStatus (pServData->hService, &pServData->Status); if (! bOk) return GetLastError();
// Return the status
*pbPaused = (BOOL)(pServData->Status.dwCurrentState == SERVICE_PAUSED);
return NO_ERROR; }
//
// Returns whether the given state is a pending state
//
BOOL DialupIsPendingState (DWORD dwState) { return (BOOL) ((dwState == SERVICE_START_PENDING) || (dwState == SERVICE_STOP_PENDING) || (dwState == SERVICE_CONTINUE_PENDING) || (dwState == SERVICE_PAUSE_PENDING) ); }
// Gets the status of a dialup server service object.
DWORD SvcIsPending (HANDLE hDialup, PBOOL pbPending) { SERVICE_DATA * pServData = (SERVICE_DATA *)hDialup; BOOL bOk;
// Verify parameters
if (!pServData || !pbPending) return ERROR_INVALID_PARAMETER;
// Get the status
bOk = QueryServiceStatus (pServData->hService, &pServData->Status); if (! bOk) return GetLastError();
// Return the status
*pbPending = DialupIsPendingState (pServData->Status.dwCurrentState);
return NO_ERROR; }
// Start and stop the service. Both functions block until the service
// completes startup/stop or until dwTimeout (in seconds) expires.
DWORD SvcStart(HANDLE hDialup, DWORD dwTimeout) { SERVICE_DATA * pServData = (SERVICE_DATA *)hDialup; DWORD dwErr, dwState; BOOL bStarted, bOk;
// See if we're already started
if ((dwErr = SvcIsStarted(hDialup, &bStarted)) != NO_ERROR) return dwErr; if (bStarted) return NO_ERROR;
// Put the service in a state that so that
// it is trying to start. (continue if paused,
// start if stopped)
dwState = pServData->Status.dwCurrentState; switch (dwState) { case SERVICE_STOPPED: bOk = StartService(pServData->hService, 0, NULL); if (! bOk) return GetLastError(); break; case SERVICE_PAUSED: bOk = ControlService(pServData->hService, SERVICE_CONTROL_CONTINUE, &(pServData->Status)); if (! bOk) return GetLastError(); break; }
// Wait for the service to change states or for the timeout to
// expire.
while (dwTimeout != 0) { // Wait for something to happen
Sleep(1000); dwTimeout--;
// Get the status of the service
bOk = QueryServiceStatus (pServData->hService, &(pServData->Status)); if (! bOk) return GetLastError();
// See if the state changed
if (dwState != pServData->Status.dwCurrentState) { // If the service changed to a pending state, continue
if (DialupIsPendingState (pServData->Status.dwCurrentState)) dwState = pServData->Status.dwCurrentState;
// Otherwise, we're either stopped or running
else break; } }
// Return a timeout error if appropriate
if (dwTimeout == 0) return ERROR_TIMEOUT;
// If the service is now running, then everything
if (pServData->Status.dwCurrentState == SERVICE_RUNNING) return NO_ERROR;
// Otherwise, return the fact that we were'nt able to
// get to a running state
if (pServData->Status.dwWin32ExitCode != NO_ERROR) return pServData->Status.dwWin32ExitCode;
return ERROR_CAN_NOT_COMPLETE; }
// Stops the service.
DWORD SvcStop(HANDLE hDialup, DWORD dwTimeout) { SERVICE_DATA * pServData = (SERVICE_DATA *)hDialup; DWORD dwErr, dwState; BOOL bStopped, bOk;
// See if we're already stopped
if ((dwErr = SvcIsStopped(hDialup, &bStopped)) != NO_ERROR) return dwErr; if (bStopped) return NO_ERROR;
// Stop the service
dwState = pServData->Status.dwCurrentState; bOk = ControlService(pServData->hService, SERVICE_CONTROL_STOP, &pServData->Status); if (! bOk) return GetLastError();
// Wait for the service to change states or for the timeout to
// expire.
while (dwTimeout != 0) { // Wait for something to happen
Sleep(1000); dwTimeout--;
// Get the status of the service
bOk = QueryServiceStatus (pServData->hService, &(pServData->Status)); if (! bOk) return GetLastError();
// See if the state changed
if (dwState != pServData->Status.dwCurrentState) { // If the service changed to a pending state, continue
if (DialupIsPendingState (pServData->Status.dwCurrentState)) dwState = pServData->Status.dwCurrentState;
// Otherwise, we're either stopped or running
else break; } }
// Report a timeout
if (dwTimeout == 0) return ERROR_TIMEOUT;
// If the service is now stopped, then everything is great
if (pServData->Status.dwCurrentState == SERVICE_STOPPED) return NO_ERROR;
// Otherwise report that we're unable to stop the service
return ERROR_CAN_NOT_COMPLETE; }
// Marks the dialup service as autostart
DWORD SvcMarkAutoStart(HANDLE hDialup) { SERVICE_DATA * pServData = (SERVICE_DATA *)hDialup; BOOL bOk;
// Validate the parameters
if (! pServData) return ERROR_INVALID_PARAMETER;
// Stop the service
bOk = ChangeServiceConfig(pServData->hService, SERVICE_NO_CHANGE, SERVICE_AUTO_START, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (! bOk) return GetLastError();
return NO_ERROR; }
// Marks the service as disabled.
DWORD SvcMarkDisabled(HANDLE hDialup) { SERVICE_DATA * pServData = (SERVICE_DATA *)hDialup; BOOL bOk;
// Validate the parameters
if (! pServData) return ERROR_INVALID_PARAMETER;
// Stop the service
bOk = ChangeServiceConfig(pServData->hService, SERVICE_NO_CHANGE, SERVICE_DISABLED, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (! bOk) return GetLastError();
return NO_ERROR; }
|