#include "StdAfx.h"
#include "Service.h"

CService::CService(void)
{
	lpFilePath = NULL;
	lpServiceName = NULL;
	lpDisplayName = NULL;

	dwStartType = 0;

	hService = NULL;
	
	init = false;
	loaded = false;
	started = false;
}

CService::CService(LPTSTR _lpFilePath,LPTSTR _lpServiceName,LPTSTR _lpDisplayName,DWORD _dwStartType)
{
	printf("++CService::CService \n");
	lpFilePath = _lpFilePath;
	lpServiceName = _lpServiceName;
	lpDisplayName = _lpDisplayName;

	dwStartType = _dwStartType;

	hService = NULL;
	
	init = true;
	loaded = false;
	started = false;
	printf("--CService::CService \n");
}

CService::~CService(void)
{
	printf("++CService::~CService \n");
	
	lpFilePath = NULL;
	lpServiceName = NULL;
	lpDisplayName = NULL;

	dwStartType = 0;

	hService = NULL;
	
	init = false;
	loaded = false;
	started = false;
	printf("--CService::~CService \n");
}

SC_HANDLE CService::InitSvc(LPTSTR _lpFilePath,LPTSTR _lpServiceName,LPTSTR _lpDisplayName,DWORD _dwStartType)
{
	SC_HANDLE hSCManager;

	printf("++CService::InitSvc \n");
	if (IsInit())
		return SVC_OK;		
	
	
	lpFilePath = _lpFilePath;
	lpServiceName = _lpServiceName;
	lpDisplayName = _lpDisplayName;

	dwStartType = _dwStartType;

	hService = NULL;

	init = true;
	loaded = false;
	started = false;

	hSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_CREATE_SERVICE);

	printf("--CService::InitSvc \n");
	return hSCManager;
}


DWORD CService::CreateSvc(SC_HANDLE hSCManager)
{
	DWORD       err;

	printf("++CService::CreateSvc \n");
	if (!IsInit())
		return SVC_NOT_INIT;
	
	if (IsLoaded())
		return SVC_OK;

	if (hSCManager == NULL)
		return SVC_ERROR_SCMANAGER;
	printf("++CService::CreateSvc : CreateService\n");
	printf("hSCManager = 0x%x, lpServiceName = %s, lpDisplayName = %s, lpFilePath = %s\n",hSCManager,lpServiceName,lpDisplayName,lpFilePath);
	hService = CreateService(hSCManager,lpServiceName,lpDisplayName,
							 SERVICE_ALL_ACCESS,    
							 SERVICE_KERNEL_DRIVER, 
							 SERVICE_DEMAND_START,  
							 SERVICE_ERROR_NORMAL,  
							 lpFilePath,	          
							 NULL,                  
							 NULL,                  
							 NULL,                 
							 NULL,                  
							 NULL);
	printf("--CService::CreateSvc : CreateService\n");

	if (hService == NULL){
		err = GetLastError();

        if (err == ERROR_SERVICE_EXISTS) {
			printf("CService::CreateSvc : ERROR_SERVICE_EXISTS\n");

            //
            // Ignore this error.
            //
			loaded = true;
            return SVC_OK;
		}
		else {
			printf("CreateService failed!  Error = %d \n", err );

            //
            // Indicate an error.
            //
            return  SVC_ERROR_CREATE;
		}
	}
		
	loaded = true;


	printf("--CService::CreateSvc \n");
	return SVC_OK;	
}

DWORD CService::StartSvc(SC_HANDLE hSCManager)
{
	printf("++CService::StartSvc \n");
	DWORD	last_error;
	if (!IsLoaded()){
		printf("SVC_NOT_CREATE\n");
		return SVC_NOT_CREATE;
	}

	if (IsStarted()){
		printf("SVC_OK\n");
		return SVC_OK;
	}

	if (hSCManager == NULL){
		printf("SVC_ERROR_SCMANAGER\n");
		return SVC_ERROR_SCMANAGER;
	}

	printf("++CService::StartSvc : OpenService \n");
	hService = OpenService(hSCManager, lpServiceName, SERVICE_ALL_ACCESS);
	printf("--CService::StartSvc : OpenService \n");
		
	if (hService == NULL) {
		CloseServiceHandle(hSCManager);
		return SVC_ERROR_OPEN;
	}

	printf("++CService::StartSvc : StartService \n");
	if (!StartService(hService,0,NULL)){
		printf("StartService(hService,0,NULL)== NULL\n");
		CloseServiceHandle(hSCManager);
		CloseServiceHandle(hService);

		last_error = GetLastError();
		if(last_error==ERROR_ACCESS_DENIED){
			printf("ERROR_ACCESS_DENIED\n");
		}

		if(last_error==ERROR_INVALID_HANDLE){
			printf("ERROR_INVALID_HANDLE\n");
		}

		if(last_error==ERROR_PATH_NOT_FOUND){
			printf("ERROR_PATH_NOT_FOUND\n");
		}

		if(last_error==ERROR_SERVICE_ALREADY_RUNNING){
			printf("ERROR_SERVICE_ALREADY_RUNNING\n");
		}

		if(last_error==ERROR_SERVICE_DATABASE_LOCKED){
			printf("ERROR_SERVICE_DATABASE_LOCKED\n");
		}

		if(last_error==ERROR_SERVICE_DEPENDENCY_DELETED){
			printf("ERROR_SERVICE_DEPENDENCY_DELETED\n");
		}

		if(last_error==ERROR_SERVICE_DEPENDENCY_FAIL){
			printf("ERROR_SERVICE_DEPENDENCY_FAIL\n");
		}

		if(last_error==ERROR_SERVICE_DISABLED){
			printf("ERROR_SERVICE_DISABLED\n");
		}

		
		if(last_error==ERROR_SERVICE_LOGON_FAILED){
			printf("ERROR_SERVICE_LOGON_FAILED\n");
		}

		if(last_error==ERROR_SERVICE_MARKED_FOR_DELETE){
			printf("ERROR_SERVICE_MARKED_FOR_DELETE\n");
		}

		if(last_error==ERROR_SERVICE_NO_THREAD){
			printf("ERROR_SERVICE_NO_THREAD\n");
		}

			if(last_error==ERROR_SERVICE_REQUEST_TIMEOUT){
			printf("ERROR_SERVICE_REQUEST_TIMEOUT\n");
		}

		return SVC_ERROR_START;
	}
	printf("--CService::StartSvc : StartService \n");

	
	started = true;

	printf("--CService::StartSvc \n");

	return SVC_OK;
}

DWORD CService::StopSvc(SC_HANDLE hSCManager)
{
	SERVICE_STATUS ss;

	printf("++CService::StopSvc \n");
	if (!IsStarted())
		return SVC_OK;

	if (hSCManager == NULL){
		printf("hSCManager == NULL\n");
		return SVC_ERROR_SCMANAGER;
	}

	printf("++CService::StopSvc : OpenService\n");
	hService = OpenService(hSCManager, lpServiceName, SERVICE_ALL_ACCESS);
	printf("--CService::StopSvc : OpenService\n");
		
	if (hService == NULL) {
		printf("hService == NULL\n");
		CloseServiceHandle(hSCManager);
		return SVC_ERROR_OPEN;
	}

	printf("++CService::StopSvc : ControlService\n");
	if (ControlService(hService,SERVICE_CONTROL_STOP,&ss) == NULL){
		CloseServiceHandle(hSCManager);
		CloseServiceHandle(hService);
		printf("SVC_ERROR_STOP\n");
		return SVC_ERROR_STOP;
	
	}
	printf("--CService::StopSvc : ControlService\n");
	
	started = false;

	CloseServiceHandle(hService);
	printf("--CService::StopSvc \n");
	return SVC_OK;
}

DWORD CService::UnloadSvc(SC_HANDLE hSCManager)
{
	printf("++CService::UnloadSvc \n");
	if (!IsLoaded())
		return SVC_OK;

	if (IsStarted()){
		printf("++CService::OpenSCManager : StopSvc\n");
		if (StopSvc(hSCManager) != SVC_OK){
			return SVC_ERROR_UNLOAD;
		}
		printf("--CService::OpenSCManager : StopSvc\n");
	}

	if (hSCManager == NULL)
		return SVC_ERROR_SCMANAGER;

	printf("++CService::OpenSCManager : OpenService\n");
	hService = OpenService(hSCManager, lpServiceName, SERVICE_ALL_ACCESS);
	printf("--CService::OpenSCManager : OpenService\n");
		
	if (hService == NULL) {
		CloseServiceHandle(hSCManager);
		return SVC_ERROR_OPEN;
	}

	printf("++CService::OpenSCManager : DeleteService\n");
	DeleteService(hService);
	printf("--CService::OpenSCManager : DeleteService\n");

	if(hService){
		CloseServiceHandle(hService);
	}
	CloseServiceHandle(hSCManager);
	
	loaded = false;

	printf("--CService::UnloadSvc \n");
	return SVC_OK;
}

BOOL CService::IsInit(void)
{
	return init;
}

BOOL CService::IsLoaded(void)
{
	return loaded;
}

BOOL CService::IsStarted(void)
{
	return started;
}