基于visual c++之windows核心编程代码分析(35)实践NT服务的框架

NT指的是计算机操作系统的核心,有NT4.0/server2000/xp/server2003/vista/2008.是微软NT系列NT服务器网络是计算机网络中服务器是NT型主机。

一个NT服务有三部分构成:
1:Service Control Manager(SCM) 每个WIN NT/2K都有一个SCM,他存在于Service.exe中.
2:服务本身一个服务拥有能从SCM受到信号和命令所必需的特殊代码,并能够在处理后将他的状态返回SCM.
3:Service Control Dispatcher(SCP) 他是一个拥有用户截面,允许用户开始,暂停,继续,并且控制已经安装在计算机上作为服务运行的WIN32

下面我们来见实践NT服务的框架,编写一个完整的NT服务。

#include <stdio.h>
#include <windows.h>
SERVICE_STATUS m_ServiceStatus;
SERVICE_STATUS_HANDLE m_ServiceStatusHandle;
BOOL bRunning=true;
void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);//服务主函数
void WINAPI ServiceCtrlHandler(DWORD Opcode);//服务控制函数
void WINAPI CmdStart(void);//要启动的程序函数
BOOL InstallService();   //安装服务的函数
BOOL DeleteService();    //删除服务的函数

int main(int argc, char* argv[])
{
	printf("\twindows based service demo\n");
	printf("\tgxisone@hotmail.com\n");
    if(argc!=3)
	{
		printf("usage: %s -install[remove]",argv[0]);
		return 0;
	}
		if(strcmp(argv[1],"-install")==0)                    /// install
		{
			if(InstallService())
				printf("\n\nService Installed Sucessfully\n");
			else
				printf("\n\nError Installing Service\n");
		}
	else if(strcmp(argv[1],"-remove")==0)    // remove
		{
			if(DeleteService())
				printf("\n\nService remove sucessfully\n");
			else
				printf("\n\nError removing Service\n");
		} 
		else
		{
			printf("\nusage: %s -install[remove]\n",argv[0]);
			return 0;
		}
//在进入点函数里面要完成ServiceMain的初始化,
//准确点说是初始化一个SERVICE_TABLE_ENTRY结构数组,
//这个结构记录了这个服务程序里面所包含的所有服务的名称
//和服务的进入点函数
SERVICE_TABLE_ENTRY 
DispatchTable[]={{"WindowsMgr",ServiceMain},{NULL,NULL}};
//最后的NULL指明数组的结束
	  StartServiceCtrlDispatcher(DispatchTable); 
		return 0;
}

void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
{
	m_ServiceStatus.dwServiceType = SERVICE_WIN32;
	m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING; 
	m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
	m_ServiceStatus.dwWin32ExitCode = 0; 
	m_ServiceStatus.dwServiceSpecificExitCode = 0; 
	m_ServiceStatus.dwCheckPoint = 0; 
	m_ServiceStatus.dwWaitHint = 0;
	m_ServiceStatusHandle = RegisterServiceCtrlHandler("WindowsMgr",ServiceCtrlHandler);
	if (m_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)return; 
	m_ServiceStatus.dwCurrentState = SERVICE_RUNNING; //设置服务状态
	m_ServiceStatus.dwCheckPoint = 0; 
	m_ServiceStatus.dwWaitHint = 0; 
//SERVICE_STATUS结构含有七个成员,它们反映服务的现行状态。
//所有这些成员必须在这个结构被传递到SetServiceStatus之前正确的设置
SetServiceStatus (m_ServiceStatusHandle, &m_ServiceStatus);
 	bRunning=true;
	//*
    CmdStart(); //启动我们的服务程序
	//*
	return; 
}
void WINAPI ServiceCtrlHandler(DWORD Opcode)//服务控制函数
{
	switch(Opcode) 
	{ 
	case SERVICE_CONTROL_PAUSE:    // we accept the command to pause it
		m_ServiceStatus.dwCurrentState = SERVICE_PAUSED; 
		break; 
	case SERVICE_CONTROL_CONTINUE:  // we got the command to continue
		m_ServiceStatus.dwCurrentState = SERVICE_RUNNING; 
		break; 
	case SERVICE_CONTROL_STOP:   // we got the command to stop this service
		m_ServiceStatus.dwWin32ExitCode = 0; 
		m_ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
		m_ServiceStatus.dwCheckPoint = 0; 
		m_ServiceStatus.dwWaitHint = 0; 
		SetServiceStatus (m_ServiceStatusHandle,&m_ServiceStatus);
		bRunning=false;
		break;
	case SERVICE_CONTROL_INTERROGATE: // 
		break; 
	} 
	return; 
}
BOOL InstallService()   //安装服务函数
{
	char strDir[1024];
	SC_HANDLE schSCManager,schService;
	GetCurrentDirectory(1024,strDir);
	GetModuleFileName(NULL,strDir,sizeof(strDir));

	char chSysPath[1024];
	GetSystemDirectory(chSysPath,sizeof(chSysPath));

	strcat(chSysPath,"\\WindowsMgr.exe");
if(!CopyFile(strDir,chSysPath,FALSE))printf("Copy file OK\n");                    // 把我们的服务程序复制到系统根目录

	strcpy(strDir,chSysPath);
schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); 
	if (schSCManager == NULL) 
	{
		printf("open scmanger failed,maybe you do not have the privilage to do this\n");
		return false;
	}

	LPCTSTR lpszBinaryPathName=strDir;
	
	schService = CreateService(schSCManager,"WindowsMgr","Windows Manger Control", //将服务的信息添加到SCM的数据库
		SERVICE_ALL_ACCESS, // desired access 
		SERVICE_WIN32_OWN_PROCESS, // service type 
		SERVICE_AUTO_START, // start type 
		SERVICE_ERROR_NORMAL, // error control type 
		lpszBinaryPathName, // service's binary 
		NULL, // no load ordering group 
		NULL, // no tag identifier 
		NULL, // no dependencies 
		NULL, // LocalSystem account 
		NULL); // no password 

		if (schService == NULL) 
	{
		printf("faint,we failed just because we invoke createservices failed\n");
		return false; 
	}
	CloseServiceHandle(schService); 
	return true;
}
BOOL DeleteService()
{
	SC_HANDLE schSCManager;
	SC_HANDLE hService;
	schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);

    char chSysPath[1024];
	GetSystemDirectory(chSysPath,sizeof(chSysPath));
    strcat(chSysPath,"\\WindowsMgr.exe");

	if (schSCManager == NULL) 
	{
		printf("faint,open scmanger failed\n");
		return false; 
	}
	hService=OpenService(schSCManager,"WindowsMgr",SERVICE_ALL_ACCESS);
	if (hService == NULL) 
	{
		printf("faint,open services failt\n");
		return false;
	}
    if(DeleteFile(chSysPath)==0)
		{
			printf("Dell file Failure !\n");               
			return false;
		}
	else printf("Delete file OK!\n");
	if(DeleteService(hService)==0)
		return false;
    
	if(CloseServiceHandle(hService)==0)
		return false;
	else
		return true;
}

void WINAPI CmdStart(void)
{
//--------------------------------
//把你的要做成服务启动的程序代码添加到这里
//那么你的代码就可以作为NT服务启动了
//--------------------------------
}


 

原文地址:https://www.cnblogs.com/new0801/p/6177796.html