Windows Service App in C++
This is C++ code for minimal windows service including functionarities of installation and uninstallation.
svc.cpp
#include "SvcApp.h"
#include <assert.h>
#include <stdarg.h>
#define SERVICE_NAME "ScvApp"
#define DEBUG_BUFF_SIZE (1024)
#define SERVICE_CONTROL_EXEC 128
SERVICE_TABLE_ENTRY ServiceTable[] = {
{ (LPSTR)SERVICE_NAME, ServiceMain },
{ NULL, NULL }
};
BOOL g_bRun = TRUE;
BOOL g_bService = TRUE;
SERVICE_STATUS_HANDLE g_hServiceStatus = NULL;
int main() {
LPWSTR buf = NULL;
int dst_size = 0;
int rc = 0;
rc = MultiByteToWideChar(CP_ACP, 0, GetCommandLine(), -1, NULL, 0);
if (rc == 0) {
return NULL;
}
dst_size = rc + 1;
buf = (LPWSTR) malloc(sizeof(WCHAR) * dst_size);
if (buf == NULL) {
return NULL;
}
rc = MultiByteToWideChar(CP_ACP, 0, GetCommandLine(), -1, buf, dst_size);
if (rc == 0) {
free(buf);
return NULL;
}
buf[rc] = L'\0';
int nArgc = 0;
WCHAR** lppArgv = CommandLineToArgvW( buf, &nArgc );
if(lppArgv == NULL){
free(buf);
return -1;
}
for(int i = 0;i < nArgc; i++){
WCHAR* arg = *(lppArgv + i);
if(!arg){
return -1;
}
if(wcscmp(arg, L"Install") == 0){
InstallService();
MessageBox(NULL,"instlation finished","Debug",MB_OK);
return 0;
} else if(wcscmp(arg, L"Uninstall") == 0){
UninstallService();
MessageBox(NULL,"uninstlation finished","Debug",MB_OK);
return 0;
}
}
StartServiceCtrlDispatcher (ServiceTable);
return 0;
}
DWORD WINAPI HandlerEx (
DWORD dwControl,
DWORD dwEventType,
LPVOID lpEventData,
LPVOID lpContext ) {
SERVICE_STATUS ss;
BOOL bRet;
// Initialize Variables for Service Control
ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ss.dwWin32ExitCode = NO_ERROR;
ss.dwServiceSpecificExitCode = 0;
ss.dwCheckPoint = 1;
ss.dwWaitHint = 3000;
ss.dwControlsAccepted = SERVICE_ACCEPT_STOP;
switch(dwControl) {
case SERVICE_CONTROL_STOP:
// Set STOP_PENDING status.
ss.dwCurrentState = SERVICE_STOP_PENDING;
bRet = SetServiceStatus (g_hServiceStatus, &ss);
if (!bRet) {
break;
}
// SERVICE SPECIFIC STOPPING CODE HERE.
// ...
// ...
g_bService = FALSE;
Sleep (3 * 1000);
// Set STOPPED status.
ss.dwCurrentState = SERVICE_STOPPED;
ss.dwCheckPoint = 0;
ss.dwWaitHint = 0;
bRet = SetServiceStatus (g_hServiceStatus, &ss);
if (!bRet) {
break;
}
break;
case SERVICE_CONTROL_PAUSE:
// Set PAUSE_PENDING status.
ss.dwCurrentState = SERVICE_PAUSE_PENDING;
bRet = SetServiceStatus (g_hServiceStatus, &ss);
if (!bRet) {
break;
}
// APPLICATION SPECIFIC PAUSE_PENDING CODE HERE.
g_bRun = FALSE;
// Set SERVICE_PAUSED status.
ss.dwCurrentState = SERVICE_PAUSED;
ss.dwCheckPoint = 0;
ss.dwWaitHint = 0;
ss.dwControlsAccepted |= SERVICE_ACCEPT_PAUSE_CONTINUE;
bRet = SetServiceStatus (g_hServiceStatus, &ss);
if (!bRet) {
break;
}
break;
case SERVICE_CONTROL_CONTINUE:
// Set PAUSE_PENDING status.
ss.dwCurrentState = SERVICE_START_PENDING;
bRet = SetServiceStatus (g_hServiceStatus, &ss);
if (!bRet) {
break;
}
// APPLICATION SPECIFIC START_PENDING CODE HERE.
g_bRun = TRUE;
// Set RUNNING status.
ss.dwCurrentState = SERVICE_RUNNING;
ss.dwCheckPoint = 0;
ss.dwWaitHint = 0;
ss.dwControlsAccepted |= SERVICE_ACCEPT_PAUSE_CONTINUE;
bRet = SetServiceStatus (g_hServiceStatus, &ss);
if (!bRet) {
break;
}
break;
default:
return ERROR_CALL_NOT_IMPLEMENTED;
}
return NO_ERROR;
}
VOID WINAPI ServiceMain(DWORD dwArgc, PTSTR* pszArgv) {
BOOL bRet;
SERVICE_STATUS ss;
// Initialize Variables for Service Control
ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ss.dwWin32ExitCode = NO_ERROR;
ss.dwServiceSpecificExitCode = 0;
ss.dwCheckPoint = 1;
ss.dwWaitHint = 1000;
ss.dwControlsAccepted = SERVICE_ACCEPT_STOP;
// Register Service Control Handler
g_hServiceStatus =
RegisterServiceCtrlHandlerEx (SERVICE_NAME, HandlerEx, NULL);
if(0 == g_hServiceStatus) {
return;
}
// Entering Starting Service.
ss.dwCurrentState = SERVICE_START_PENDING;
bRet = SetServiceStatus (g_hServiceStatus, &ss);
if (!bRet) {
return;
}
// APPLICATION SPECIFIC INITIALIZATION CODE
// Finish Initializing.
ss.dwCurrentState = SERVICE_RUNNING;
ss.dwCheckPoint = 0;
ss.dwWaitHint = 0;
ss.dwControlsAccepted =
SERVICE_ACCEPT_PAUSE_CONTINUE |
SERVICE_ACCEPT_STOP;
bRet = SetServiceStatus (g_hServiceStatus, &ss);
if (!bRet) {
return;
}
//
// Service Main Code.
//
MSG msg = {0};
while(g_bService) {
if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)){
if(!GetMessage(&msg, NULL, 0 ,0 )){
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Sleep(1 * 1000);
}
}
bool InstallService()
{
SC_HANDLE hSCM = NULL;
SC_HANDLE hService = NULL;
TCHAR szBinaryPathName[MAX_PATH];
SERVICE_DESCRIPTION sd;
bool bRet = FALSE;
hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
if (hSCM == NULL) {
goto EXIT;
}
//Get Path
GetModuleFileName(NULL,
szBinaryPathName,
sizeof(szBinaryPathName)/sizeof(szBinaryPathName[0]));
//Register My Service
hService = CreateService(hSCM,
"SvcApp",
"SvcApp",
SERVICE_CHANGE_CONFIG,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START,
SERVICE_ERROR_IGNORE,
szBinaryPathName,
NULL,
NULL,
NULL,
NULL,
NULL);
if (hService == NULL) {
goto EXIT;
}
sd.lpDescription = (LPSTR)"This is SvcApp."; //Description
ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &sd);
bRet = true;
EXIT:
//Crean up
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
return bRet;
}
bool UninstallService()
{
SC_HANDLE hSCM = NULL;
SC_HANDLE hService = NULL;
bool bRet = FALSE;
hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (hSCM == NULL) {
goto EXIT;
}
//Calling Delete Service Function
hService = OpenService(hSCM, SERVICE_NAME, DELETE);
if (hService == NULL) {
goto EXIT;
}
//Delete My Service
if (DeleteService(hService) == FALSE) {
goto EXIT;
}
bRet = true;
EXIT:
//Crean up
CloseServiceHandle(hSCM);
CloseServiceHandle(hService);
return bRet;
}
Profile
I have technical job experience in enbedded software development and server side infrastructure/application engineering.
I'm interested in programming and computer security.
Objective
To write down my technical knowledge in the place where I can access from anywhere.
To share my program source code.
To train my writing skill.
New entries