Introduction
Hello fellow CPians,
Back again with new application .I think, you wanna know that what exactly this application is doing. This application can enumerate all window services, provide support for Starting, Stopping and Restarting, provide support for switching the Startup Type between Automatic, Manual And Disable, changing the path of Services and last but not the least and most dangerous one Uninstalling the Service.
"I Request, Please handle this Option with Care (UnInstalling One), if this action is executed once, there is no chance of rollback or you know how to install that particular service".
Background
Now let's take a look at what MSDN says about services ---
�A service application conforms to the interface rules of the Service Control Manager (SCM). It can be started automatically at system boot, by a user through the Services control panel applet, or by an application that uses the service functions, Services Start Running.
A driver service conforms to the device driver protocols. It is similar to a service application, but it does not interact with the SCM. For simplicity, the term service refers to a service application in this overview. "
This is the list of all the APIs I have used to Enumerate, Control, Edit and Delete service.
A Little Description About These APIs
-
SC_HANDLE OpenSCManager
(
LPCTSTR lpMachineName,
LPCTSTR lpDatabaseName,
DWORD dwDesiredAccess
);
A little description about OpenSCManager
This API is used to open the database of service on local computer. Yeah, you can open it to use the service database on remote computer (but that required proper network authorization). You need to open the service manager to perform each service related task.
-
SC_HANDLE OpenService
(
SC_HANDLE hSCManager,
LPCTSTR lpServiceName,
DWORD dwDesiredAccess
);
A little description about OpenService
This API is used to open particular service from service database. This API is used after a successful call of OpenSCManager
API.
-
BOOL EnumServicesStatus
(
SC_HANDLE hSCManager,
DWORD dwServiceType,
DWORD dwServiceState,
LPENUM_SERVICE_STATUS lpServices,
DWORD cbBufSize,
LPDWORD pcbBytesNeeded,
LPDWORD lpServicesReturned,
LPDWORD lpResumeHandle
);
A little description about EnumServiceStatus
As the name indicates, this API is used to enumerate the services depending upon function call specifications:
- Second parameter - which type of service you want to enumerate.
- Third parameter - what type of service is returned, i.e. running or stopped services.
- Fourth parameter - buffer of
ENUM_SERVICE_STATUS
( which will bring back all the Services).
- Fifth parameter - will hold total buffer size of fourth parameter
- Sixth parameter - contain total byte of memory needed to retrieve all the service with necessary details (i.e.
ENUM_SERVICE_STATUS
)
- Seventh parameter - contains number of services returned after successful call of above API.
- Eighth parameter - is returned with resume handle if the buffer is not enough to hold the all the services present in system.
-
BOOL QueryServiceConfig
(
SC_HANDLE hService,
LPQUERY_SERVICE_CONFIG lpServiceConfig,
DWORD cbBufSize,
LPDWORD pcbBytesNeeded
);
A little description about QueryServieConfig
This API query current status of service, where the first parameter is handle obtained from OpenService
and the second parameter is structure, which will return with information.
-
BOOL StartService
(
SC_HANDLE hService,
DWORD dwNumServiceArgs,
LPCTSTR* lpServiceArgVectors
);
A little description about StartService
As the name suggests that it will Start service whose handle is going to pass in the first parameter, second parameter inputs the number of arguments for service to be passed in parameter three and third parameter is an array of string argument for service.
-
BOOL ControlService
(
SC_HANDLE hService,
DWORD dwControl,
LPSERVICE_STATUS lpServiceStatus
);
A little description about ControlService
As the name suggests that it will Control service whose handle is going to pass in the First Parameter, Second Parameter specifies the requested control code, most common are SERVICE_CONTROL_STOP
, SERVICE_CONTROL_PAUSE
, SERVICE_CONTROL_CONTINUE
and third Parameter returns current status structure of service.
-
BOOL DeleteService
(
SC_HANDLE hService
);
A little description about DeleteService
As the name suggests that it will Delete service whose handle is going to be passed in the First Parameter.
-
BOOL ChangeServiceConfig
(
SC_HANDLE hService
DWORD dwServiceType,
DWORD dwStartType,
DWORD dwErrorControl,
LPCTSTR lpBinaryPathName,
LPCTSTR lpLoadOrderGroup,
LPDWORD lpdwTagId,
LPCTSTR lpDependencies,
LPCTSTR lpServiceStartName,
LPCTSTR lpPassword,
LPCTSTR lpDisplayName
);
A little description about ChangeServiceConfig
As name indicates, this API is used to Change the service Configuration. I am going to discuss commonly used parameter of this API.
- First Parameter - Indicates the handle of service.
- Second parameter - If you want to change service type.
- Third parameter - For changing startup type.
- Fifth Parameter - For changing binary path of executable.
- Ninth parameter - Indicates in which user, you want to run the service.
- Tenth parameter - Password of account specified in ninth paragraph.
- Eleventh Parameter - Used to change the display name of the service.
Using the code
I will Explain Everything now, with the help of code snippet.
Here is list of possible common functions that can be performed from above APIs.
I know more combinations possible, but I am stating those only which is going to provide with MFS Service Manager TM :D
- For obtaining the main
ScManager
handle.
SC_HANDLE ScManager;
ScManager=::OpenSCManager(NULL,NULL,SC_MANAGER_ENUMERATE_SERVICE|GENERIC_READ);
if(ScManager==NULL)
{
MessageBox("Error Opening Service Mgr");
return;
}
- For obtaining particular service handle.
SC_HANDLE ScService;
if((ScService=::OpenService(
ScManager,"any service Name",SERVICE_ALL_ACCESS))==NULL)
{
::CloseHandle(ScManager);
MessageBox("Problem in opening service");
}
- For enumerating the service.
ENUM_SERVICE_STATUS EnService[512];
DWORD cbBufSize=512*sizeof(ENUM_SERVICE_STATUS);
DWORD lpServicesReturned;
DWORD pcbBytesNeeded;
DWORD lpResumeHandle
DWORD lpResumeHandle=0;
if(::EnumServicesStatus(
ScManager,
SERVICE_WIN32,
SERVICE_STATE_ALL,
EnService,
cbBufSize,
&pcbBytesNeeded,
&lpServicesReturned,
&lpResumeHandle
)= =0)
{
MessageBox("Error Querrying Service Mgr");
return;
}
- Checking state of service.
for(int i=0;i< INT ( LPSERVICESRETURNED);i++)
{
MessageBox(EnService[i].lpServiceName,"service Name");
MessageBox(EnService[i].lpDisplayName,"Display Name");
switch(EnService[i].ServiceStatus.dwCurrentState)
{
case SERVICE_PAUSED:
case SERVICE_RUNNING:
case SERVICE_STOPPED:
case SERVICE_START_PENDING:
case SERVICE_STOP_PENDING :
default:
}
- For starting the service.
if(::StartService(ScService,0,NULL)==0)
{
Variable MessageBox("Error Starting Service");
return;
}
- & 7. For pausing and stopping service.
if(::ControlService(ScService,SERVICE_CONTROL_STOP,&stt)==0)
{
MessageBox("Error: Unable to Stop Service");
return;
}
- Updating the path of service.
LPQUERY_SERVICE_CONFIG lpqscBuf;
DWORD dwBytesNeeded;
lpqscBuf = (LPQUERY_SERVICE_CONFIG) LocalAlloc( LPTR,4096);
if (lpqscBuf == NULL)
{
MessageBox("Memory Allocation error");
return;
}
if (!QueryServiceConfig(
ScService,
lpqscBuf,
4096,
&dwBytesNeeded)
)
{
MessageBox("Error in querying Services");
return;
}
MessageBox(lpqscBuf->lpBinaryPathName ,"Current Binary path");
if(::ChangeServiceConfig(
ScService,
SERVICE_NO_CHANGE,
SERVICE_NO_CHANGE,
SERVICE_NO_CHANGE,
NEW PATH,
NULL,NULL,NULL,NULL,NULL,NULL))
{
MessageBox("Service PathChanged",
"MFS SERVICEMGR",MB_OK|MB_ICONINFORMATION);
}
else
{
MessageBox("Error In ChangingPath","MFS SERVICE MGR",MB_OK|MB_ICONSTOP);
}
- For deleting the service.
if(::DeleteService(ScService)==0)
{
MessageBox("Error Deleting Service");
return;
}
else
{
MessageBox("Service Marked For Deletion\nDeleted After Computer Restart");
}
History
Special Thanks
- My Parents
- My friend Amit Mehta
- Mr. Suhredayan for demanding newer version of this application.
- The Code Project for providing platform for emerging Programmers.