Service Manager

//用于windows服务和NT式驱动程序的安装,卸载,运行,停止操作。
//SCM.cpp
///
 
#define OPER_INSTALL	0x1  //安装
#define OPER_START		0x2  //运行
#define OPER_STOP		0x3  //停止
#define OPER_UNINSTALL  0x4  //卸载
#define OPER_UNKNOWN	0x5

#define IDX_SERV_OPER 1  //argv[1]:operation-type
#define IDX_SERV_NAME 2  //argv[2]:service name
#define IDX_SERV_PATH 3  //argv[3]:service path

#include <windows.h>
#include <tchar.h>
#include <stdio.h>

SC_HANDLE hSCM;
SC_HANDLE hServ;

//提示错误信息
VOID ReportErr(int errCode)
{
	LPVOID lpMsgBuf;
	FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
				  NULL,
				  errCode,
				  MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
				  (LPTSTR)&lpMsgBuf,
				  0,
				  NULL);

	if(lpMsgBuf != NULL)
		printf("Err Info:\n%S\n", lpMsgBuf);
	else
		printf("can't format err message\n");
}

//创建服务
BOOL Create(LPTSTR lpszServiceName, LPTSTR lpszServicePath)
{
	hServ = CreateService(hSCM,
		lpszServiceName, 
		lpszServiceName,
		SERVICE_ALL_ACCESS,
		SERVICE_KERNEL_DRIVER,
		SERVICE_DEMAND_START,
		SERVICE_ERROR_IGNORE,
		lpszServicePath,
		NULL,NULL,NULL,NULL,NULL);
	if(hServ == NULL)
		return FALSE;
	return TRUE;
}

//停止所有依赖服务。
BOOL StopDependentServices(SC_HANDLE schServ)
{
	DWORD i, dwBytesNeeded, dwCount;
	LPENUM_SERVICE_STATUS lpDependencies = NULL;
	ENUM_SERVICE_STATUS ess;
	SERVICE_STATUS_PROCESS ssp;
	SC_HANDLE hDepServ;

	if(EnumDependentServices(schServ,
		SERVICE_ACTIVE,
		lpDependencies,
		0,
		&dwBytesNeeded,
		&dwCount))
	{return TRUE;} //没有依赖的服务
	else
	{
		if(GetLastError() != ERROR_MORE_DATA)
			return FALSE;
		lpDependencies = (LPENUM_SERVICE_STATUS)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwBytesNeeded);
		if(lpDependencies == NULL)
			return FALSE;
		__try
		{
			if(!EnumDependentServices(schServ,
									  SERVICE_ACTIVE,
									  lpDependencies,
								      0,
									  &dwBytesNeeded,
									  &dwCount))
			return FALSE;
			for(i=0; i<dwCount; i++)
			{
				ess = *(lpDependencies + i);
				hDepServ = OpenService(hSCM, ess.lpServiceName, SERVICE_STOP | SERVICE_QUERY_STATUS);
				if(hDepServ == NULL)
					return FALSE;
				__try
				{
					if ( !ControlService( hDepServ, 
                            SERVICE_CONTROL_STOP,
                            (LPSERVICE_STATUS) &ssp ) )
                    return FALSE;

                    // Wait for the service to stop.
                    while ( ssp.dwCurrentState != SERVICE_STOPPED ) 
                    {
                        Sleep( ssp.dwWaitHint );
                        if ( !QueryServiceStatusEx( 
                                hDepServ, 
                                SC_STATUS_PROCESS_INFO,
                                (LPBYTE)&ssp, 
                                sizeof(SERVICE_STATUS_PROCESS),
                                &dwBytesNeeded ) )
                        return FALSE;

                        if ( ssp.dwCurrentState == SERVICE_STOPPED )
                            break;
                    }

				}
				__finally
				{
					CloseServiceHandle(hDepServ);
				}

			}
		}
		__finally
		{
			HeapFree(GetProcessHeap(),0,lpDependencies);
		}
	}
	return TRUE;
}

//停止服务
BOOL Stop(SC_HANDLE schServ)
{
	SERVICE_STATUS_PROCESS ssp;
    DWORD dwBytesNeeded;

	if ( !QueryServiceStatusEx( schServ, 
							    SC_STATUS_PROCESS_INFO,
								(LPBYTE)&ssp, 
								sizeof(SERVICE_STATUS_PROCESS),
								&dwBytesNeeded ) 
		)
	{
		printf("Stop faild.");
		ReportErr(GetLastError());
		return FALSE;
	}
	//服务没有运行
	if ( ssp.dwCurrentState == SERVICE_STOPPED )
    {
        printf("Service is already stopped.\n");
        return TRUE;
    }
	//服务处于待决状态
	while ( ssp.dwCurrentState == SERVICE_STOP_PENDING ) 
    {
        Sleep( ssp.dwWaitHint );
        if ( !QueryServiceStatusEx( 
                 schServ, 
                 SC_STATUS_PROCESS_INFO,
                 (LPBYTE)&ssp, 
                 sizeof(SERVICE_STATUS_PROCESS),
                 &dwBytesNeeded ) )
        {
            printf("Stop faild.");
			ReportErr(GetLastError());
			return FALSE;
        }

        if ( ssp.dwCurrentState == SERVICE_STOPPED )
        {
            printf("Service stopped successfully.\n");
            return TRUE;
        }
    }
	//停止所有依赖的服务
	StopDependentServices(schServ);

	if ( !ControlService( schServ, 
						  SERVICE_CONTROL_STOP, 
						 (LPSERVICE_STATUS) &ssp )
		)
    {
		printf("Stop faild.");
		ReportErr(GetLastError());
		return FALSE;
    }

	while ( ssp.dwCurrentState != SERVICE_STOPPED ) 
    {
        Sleep( ssp.dwWaitHint );
        if ( !QueryServiceStatusEx( 
                 schServ, 
                 SC_STATUS_PROCESS_INFO,
                 (LPBYTE)&ssp, 
                 sizeof(SERVICE_STATUS_PROCESS),
                 &dwBytesNeeded ) )
        {
            printf("Stop faild.");
			ReportErr(GetLastError());
			return FALSE;
        }

        if ( ssp.dwCurrentState == SERVICE_STOPPED )
            break;
    }
	return TRUE;
}

//检查argv[3]传入的参数是否是有效文件路径
BOOL CheckFilePath(LPTSTR filePath)
{
	HANDLE hFile = CreateFile(filePath,
		FILE_ALL_ACCESS,
		0,
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL,
		NULL);
	if(hFile == INVALID_HANDLE_VALUE)
		return FALSE;
	CloseHandle(hFile);
	return TRUE;
}

//获得操作类型
int GetOperation(LPTSTR argv)
{
	size_t len = wcslen(argv);
	if( _wcsnicmp(argv, L"install", len) == 0) return OPER_INSTALL;
	if( _wcsnicmp(argv, L"start", len) == 0) return OPER_START;
	if( _wcsnicmp(argv, L"stop", len) == 0) return OPER_STOP;
	if( _wcsnicmp(argv, L"uninstall", len) == 0) return OPER_UNINSTALL;
	return OPER_UNKNOWN;
}

VOID Usage()
{
		printf("******************************************************\n");
		printf("Usage: scm operation driverName driverPath.\n");
		printf("语法:  scm 操作类型  服务名称   服务文件路径.\n\n");
		printf("operation: Specified the operation type.\n");
		printf("           The operation type is:\n");
		printf("               install\n");
		printf("               uninstall\n");
		printf("               start\n");
		printf("               stop\n");
		printf("driverName: The name of the driver to install.\n");
		printf("driverPath: The fully-qualified path to the driver binary file.\n");
		printf("******************************************************\n");
}

int _tmain(int argc, _TCHAR* argv[])
{
	hSCM = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
	if(hSCM == NULL)
	{
		printf("Open Service Control Manager faild.\n");
		ReportErr(GetLastError());
		return 0;
	}
	//
	int operation = OPER_UNKNOWN; 
	__try
	{
		// 处理Install
		if(argc == 4)
		{
			operation = GetOperation(argv[IDX_SERV_OPER]);
			if(operation == OPER_INSTALL)
			{
				if(!CheckFilePath(argv[IDX_SERV_PATH]))
				{
					printf("Install faild.The file path invalid.\n");
					ReportErr(GetLastError());
					__leave;
				}
				//
				if(!Create(argv[IDX_SERV_NAME], argv[IDX_SERV_PATH]))
				{
					printf("Install faild.\n");
					ReportErr(GetLastError());
					__leave;
				}
				printf("The service '%S' installed successfully\n", argv[IDX_SERV_NAME]);
				__leave;
			}
			operation = OPER_UNKNOWN;
		}

		//处理start,stop, uninstall
		if(argc == 3)
		{
			operation = GetOperation(argv[IDX_SERV_OPER]);
			if(operation != OPER_UNKNOWN)
			{
				hServ = OpenService(hSCM, argv[IDX_SERV_NAME],SERVICE_ALL_ACCESS);
				if(hServ == NULL)
				{
					printf("Open service faild.\n");
					ReportErr(GetLastError());
					__leave;
				}
				switch(operation)
				{
				case OPER_START:
					{
						if(!StartService(hServ,0,NULL))
						{
							printf("Start service faild.\n");
							ReportErr(GetLastError());
							__leave;
						}
						printf("The service '%S' start runing...\n", argv[IDX_SERV_NAME]);
					}
					break;
				case OPER_STOP:
					if(Stop(hServ))
						printf("The Service '%S' stopped successfully\n",argv[IDX_SERV_NAME]);
					break;
				case OPER_UNINSTALL:
					{
						Stop(hServ);
						if(!DeleteService(hServ))
						{
							printf("Delete service '%S' faild.\n", argv[IDX_SERV_NAME]);
							ReportErr(GetLastError());
							__leave;
						}
						printf("The service '%S' deleted successfully.\n", argv[IDX_SERV_NAME]);
					}
					break;
				default:
					operation = OPER_UNKNOWN;
				}
			}
		}
		//错误的参数或operation-type
		if(argc <2 || operation == OPER_UNKNOWN)
				Usage();
	}
	__finally
	{
		if(hSCM)
		CloseServiceHandle(hSCM);
		if(hServ)
		CloseServiceHandle(hServ);
	}
	return 0;
}


 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值