/*++ Copyright (c) 1996 Microsoft Corporation Module Name: service.c Abstract: This file provides access to the service control manager for starting, stopping, adding, and removing services. Environment: WIN32 User Mode Author: Wesley Witt (wesw) 17-Feb-1996 --*/ #include "wizard.h" #pragma hdrstop BOOL InstallFaxService( BOOL UseLocalSystem, BOOL DemandStart, LPTSTR AccountName, LPTSTR Password ) /*++ Routine Description: Service installation function. This function just calls the service controller to install the FAX service. It is required that the FAX service run in the context of a user so that the service can access MAPI, files on disk, the network, etc. Arguments: UseLocalSystem - Don't use the accountname/password, use LocalSystem Username - User name where the service runs. Password - Password for the user name. Return Value: Return code. Return zero for success, all other values indicate errors. --*/ { SC_HANDLE hSvcMgr; SC_HANDLE hService; SERVICE_STATUS Status; DWORD ErrorCode; hSvcMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if (!hSvcMgr) { DebugPrint(( TEXT("could not open service manager: error code = %u"), GetLastError() )); return FALSE; } hService = OpenService( hSvcMgr, FAX_SERVICE_NAME, SERVICE_ALL_ACCESS ); if (hService) { // // the service exists, lets be sure that it is stopped // ControlService( hService, SERVICE_CONTROL_STOP, &Status ); DeleteService( hService ); CloseServiceHandle( hService ); } if (!UseLocalSystem) { ErrorCode = SetServiceSecurity( AccountName ); if (ErrorCode) { DebugPrint(( TEXT("Could not grant access rights to [%s] : error code = 0x%08x"), AccountName, ErrorCode )); SetLastError( ERROR_SERVICE_LOGON_FAILED ); return FALSE; } } hService = CreateService( hSvcMgr, FAX_SERVICE_NAME, FAX_SERVICE_DISPLAY_NAME, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, DemandStart ? SERVICE_DEMAND_START : SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, FAX_SERVICE_IMAGE_NAME, NULL, NULL, FAX_SERVICE_DEPENDENCY, UseLocalSystem ? NULL : AccountName, UseLocalSystem ? NULL : Password ); if (!hService) { DebugPrint(( TEXT("Could not create fax service: error code = %u"), GetLastError() )); return FALSE; } CloseServiceHandle( hService ); CloseServiceHandle( hSvcMgr ); return TRUE; } DWORD StartTheService( LPTSTR ServiceName ) { DWORD rVal = 0; SC_HANDLE hSvcMgr = NULL; SC_HANDLE hService = NULL; SERVICE_STATUS Status; DWORD OldCheckPoint = 0; DWORD i = 0; hSvcMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if (!hSvcMgr) { rVal = GetLastError(); DebugPrint(( TEXT("could not open service manager: error code = %u"), rVal )); goto exit; } hService = OpenService( hSvcMgr, ServiceName, SERVICE_ALL_ACCESS ); if (!hService) { rVal = GetLastError(); DebugPrint(( TEXT("could not open the %s service: error code = %u"), ServiceName, rVal )); goto exit; } // // the service exists, lets start it // if (!StartService( hService, 0, NULL )) { rVal = GetLastError(); DebugPrint(( TEXT("could not start the %s service: error code = %u"), ServiceName, rVal )); goto exit; } if (!QueryServiceStatus( hService, &Status )) { rVal = GetLastError(); DebugPrint(( TEXT("could not query status for the %s service: error code = %u"), ServiceName, rVal )); goto exit; } #if 0 while (Status.dwCurrentState != SERVICE_RUNNING) { OldCheckPoint = Status.dwCheckPoint; Sleep( Status.dwWaitHint ); if (!QueryServiceStatus( hService, &Status )) { break; } if (OldCheckPoint >= Status.dwCheckPoint) { break; } } #endif while (Status.dwCurrentState != SERVICE_RUNNING) { Sleep( 1000 ); if (!QueryServiceStatus( hService, &Status )) { break; } i += 1; if (i > 60) { break; } } if (Status.dwCurrentState != SERVICE_RUNNING) { rVal = GetLastError(); DebugPrint(( TEXT("could not start the %s service: error code = %u"), ServiceName, rVal )); goto exit; } rVal = ERROR_SUCCESS; exit: CloseServiceHandle( hService ); CloseServiceHandle( hSvcMgr ); return rVal; } DWORD MyStartService( LPTSTR ServiceName ) { DWORD rVal = 0; SC_HANDLE hSvcMgr = NULL; SC_HANDLE hService = NULL; LPENUM_SERVICE_STATUS EnumServiceStatus = NULL; hSvcMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if (!hSvcMgr) { rVal = GetLastError(); DebugPrint(( TEXT("could not open service manager: error code = %u"), rVal )); goto exit; } hService = OpenService( hSvcMgr, ServiceName, SERVICE_ALL_ACCESS ); if (!hService) { rVal = GetLastError(); DebugPrint(( TEXT("could not open the %s service: error code = %u"), ServiceName, rVal )); goto exit; } rVal = StartTheService( ServiceName ); exit: CloseServiceHandle( hService ); CloseServiceHandle( hSvcMgr ); return rVal; } BOOL StopTheService( LPTSTR ServiceName ) { DWORD rVal = 0; SC_HANDLE hSvcMgr; SC_HANDLE hService; SERVICE_STATUS Status; DWORD OldCheckPoint; hSvcMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if (!hSvcMgr) { DebugPrint(( TEXT("could not open service manager: error code = %u"), GetLastError() )); goto exit; } hService = OpenService( hSvcMgr, ServiceName, SERVICE_ALL_ACCESS ); if (!hService) { DebugPrint(( TEXT("could not open the %s service: error code = %u"), ServiceName, GetLastError() )); goto exit; } // // the service exists, lets stop it // ControlService( hService, SERVICE_CONTROL_STOP, &Status ); if (!QueryServiceStatus( hService, &Status )) { DebugPrint(( TEXT("could not query status for the %s service: error code = %u"), ServiceName, GetLastError() )); goto exit; } while (Status.dwCurrentState == SERVICE_RUNNING) { OldCheckPoint = Status.dwCheckPoint; Sleep( Status.dwWaitHint ); if (!QueryServiceStatus( hService, &Status )) { break; } if (OldCheckPoint >= Status.dwCheckPoint) { break; } } if (Status.dwCurrentState == SERVICE_RUNNING) { DebugPrint(( TEXT("could not stop the %s service: error code = %u"), ServiceName, GetLastError() )); goto exit; } rVal = TRUE; exit: CloseServiceHandle( hService ); CloseServiceHandle( hSvcMgr ); return rVal; } BOOL MyStopService( LPTSTR ServiceName ) { DWORD rVal = 0; SC_HANDLE hSvcMgr; SC_HANDLE hService; LPENUM_SERVICE_STATUS EnumServiceStatus = NULL; DWORD BytesNeeded; DWORD ServiceCount; DWORD i; hSvcMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if (!hSvcMgr) { DebugPrint(( TEXT("could not open service manager: error code = %u"), GetLastError() )); goto exit; } hService = OpenService( hSvcMgr, ServiceName, SERVICE_ALL_ACCESS ); if (!hService) { DebugPrint(( TEXT("could not open the %s service: error code = %u"), ServiceName, GetLastError() )); goto exit; } if (!EnumDependentServices( hService, SERVICE_ACTIVE, NULL, 0, &BytesNeeded, &ServiceCount )) { if (GetLastError() != ERROR_MORE_DATA) { DebugPrint(( TEXT("could not enumerate dependent services, ec=%d"), GetLastError() )); goto exit; } EnumServiceStatus = (LPENUM_SERVICE_STATUS) MemAlloc( BytesNeeded ); if (!EnumServiceStatus) { DebugPrint(( TEXT("could not allocate memory for EnumDependentServices()") )); goto exit; } } if (!EnumDependentServices( hService, SERVICE_ACTIVE, EnumServiceStatus, BytesNeeded, &BytesNeeded, &ServiceCount )) { DebugPrint(( TEXT("could not enumerate dependent services, ec=%d"), GetLastError() )); goto exit; } if (ServiceCount) { for (i=0; iAccountName, // pointer to account name of service SecurityInfo->Password, // pointer to password for service account NULL // pointer to display name )) { DebugPrint(( TEXT("could not open change service configuration, ec=%d"), GetLastError() )); goto exit; } rVal = TRUE; exit: CloseServiceHandle( hService ); CloseServiceHandle( hSvcMgr ); return rVal; } BOOL MyDeleteService( LPTSTR ServiceName ) { SC_HANDLE hSvcMgr; SC_HANDLE hService; SERVICE_STATUS Status; hSvcMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if (!hSvcMgr) { return FALSE; } hService = OpenService( hSvcMgr, ServiceName, SERVICE_ALL_ACCESS ); if (hService) { // // the service exists, lets be sure that it is stopped // ControlService( hService, SERVICE_CONTROL_STOP, &Status ); DeleteService( hService ); CloseServiceHandle( hService ); } CloseServiceHandle( hSvcMgr ); return TRUE; } BOOL DeleteFaxService( VOID ) { return MyDeleteService( FAX_SERVICE_NAME ); } BOOL SetFaxServiceAutoStart( VOID ) { return SetServiceStart( FAX_SERVICE_NAME, SERVICE_AUTO_START ); }