[Win32] SCManager 服务控制管理器API(1)

来源:互联网 发布:java常用算法手册下载 编辑:程序博客网 时间:2024/06/06 08:55
本博文由CSDN博主zuishikonghuan所作,版权归zuishikonghuan所有,转载请注明出处:http://blog.csdn.net/zuishikonghuan/article/details/47803033

前言:我之前写过一个“Win32服务开发四部曲“,如下:

[Win32] 服务程序开发(1)基本概念和服务程序的框架
[Win32] 服务程序开发(2)Session 0隔离(上)
[Win32] 服务程序开发(3)Session 0隔离(下)创建SYSTEM权限可交互进程
[Win32] 服务程序开发(4)自定义控制码与服务通信

我当时说,编写的服务程序可以使用SCManager API来安装,控制,下面我们来看看SCManager API的具体用法。

1。OpenSCManager 打开服务控制管理器
函数原型:

SC_HANDLE WINAPI OpenSCManager(  _In_opt_ LPCTSTR lpMachineName,  _In_opt_ LPCTSTR lpDatabaseName,  _In_     DWORD   dwDesiredAccess);
lpMachineName:置NULL
lpDatabaseName:服务控制管理器数据库,NULL表示默认数据库
dwDesiredAccess:访问权限

SC_MANAGER_ALL_ACCESS:包括 STANDARD_RIGHTS_REQUIRED,除了在此表中的所有访问权限之外。SC_MANAGER_CREATE_SERVICE:需要调用 CreateService 函数来创建一个服务。SC_MANAGER_CONNECT:需要连接到服务控制管理器。SC_MANAGER_ENUMERATE_SERVICE:需要调用 EnumServicesStatus 或 EnumServicesStatusEx 函数列出数据库中的服务。需要调用 NotifyServiceStatusChange 函数来接收当创建或删除任何服务时的通知。SC_MANAGER_LOCK:需要调用 LockServiceDatabase 函数来获取对数据库的锁定。SC_MANAGER_MODIFY_BOOT_CONFIG:需要调用 NotifyBootConfigStatus 函数。SC_MANAGER_QUERY_LOCK_STATUS:需要调用 QueryServiceLockStatus 函数来检索数据库的锁状态信息。

返回值:如果打开成功返回服务控制管理器的句柄,失败返回NULL

2。CloseServiceHandle 关闭服务控制管理器句柄或服务句柄
函数原型:

BOOL WINAPI CloseServiceHandle(  _In_ SC_HANDLE hSCObject);

hSCObject:要释放的服务控制管理器句柄或服务句柄

3。CreateService 创建服务
函数原型:

SC_HANDLE WINAPI CreateService(  _In_      SC_HANDLE hSCManager,  _In_      LPCTSTR   lpServiceName,  _In_opt_  LPCTSTR   lpDisplayName,  _In_      DWORD     dwDesiredAccess,  _In_      DWORD     dwServiceType,  _In_      DWORD     dwStartType,  _In_      DWORD     dwErrorControl,  _In_opt_  LPCTSTR   lpBinaryPathName,  _In_opt_  LPCTSTR   lpLoadOrderGroup,  _Out_opt_ LPDWORD   lpdwTagId,  _In_opt_  LPCTSTR   lpDependencies,  _In_opt_  LPCTSTR   lpServiceStartName,  _In_opt_  LPCTSTR   lpPassword);

hSCManager:服务控制管理器句柄。此句柄由 OpenSCManager 函数返回,并且必须具有 SC_MANAGER_CREATE_SERVICE 的访问权限。

lpServiceName:要安装的服务的名称。最大字符串长度为 256 个字符。服务控制管理器数据库保留字符的大小写,即服务名称区分大小写。正斜线 (/) 和反斜杠 (\) 不是有效的服务名称字符。

lpDisplayName:要由用户界面程序用于标识服务的显示名称。该字符串可以有最大长度为 256 个字符。

dwDesiredAccess:访问权限,要创建服务置SERVICE_ALL_ACCESS。

dwServiceType:服务类型。此参数可以是下列值之一:

SERVICE_ADAPTER:保留。SERVICE_FILE_SYSTEM_DRIVER:文件系统驱动程序服务。SERVICE_KERNEL_DRIVER:驱动程序服务。SERVICE_RECOGNIZER_DRIVER:保留。SERVICE_WIN32_OWN_PROCESS:在它自己的进程中运行的服务。SERVICE_WIN32_SHARE_PROCESS:与一个或多个其他服务共享一个进程的服务。如果您指定 SERVICE_WIN32_OWN_PROCESS 或 SERVICE_WIN32_SHARE_PROCESS,并且该服务运行在本地系统帐户的上下文中,您还可以指定以下值:SERVICE_INTERACTIVE_PROCESS:服务可以与桌面交互。

dwStartType:该服务启动选项。此参数可以是下列值之一:

SERVICE_AUTO_START:由服务控制管理器在系统启动时自动启动的服务。(自动)SERVICE_BOOT_START:由系统加载程序启动的设备驱动程序。此值是仅对驱动程序服务有效。SERVICE_DEMAND_START:当一个过程调用 StartService 函数由服务控制管理器启动的服务。(手动)SERVICE_DISABLED:无法启动服务。(禁用)SERVICE_SYSTEM_START:由 IoInitSystem 函数启动的设备驱动程序。此值是仅对驱动程序服务有效。

dwErrorControl:严重性错误,以及采取的行动,如果这项服务无法启动。此参数可以是下列值之一:

SERVICE_ERROR_CRITICAL:如果可能的话,启动程序在事件日志中记录错误。如果上次已知正确的配置正在启动,启动操作将失败。否则,与最后一次正确的配置重新启动系统。SERVICE_ERROR_IGNORE:启动程序忽略错误并继续启动操作。SERVICE_ERROR_NORMAL:启动程序记录错误事件日志但继续启动操作。SERVICE_ERROR_SEVERE:启动程序在事件日志中记录错误。如果上次已知的正确配置正被启动,启动操作将继续。否则,与上次已知的正确配置重新启动系统。

lpBinaryPathName:服务二进制文件的完全限定的路径。如果路径中包含空格,它必须被引用,例如,"d:\\my share\\myservice.exe"应该被指定为"\"d:\\my share\\myservice.exe\""。

lpLoadOrderGroup:加载顺序的组此服务是成员的名称。如果该服务不属于组,指定为 NULL 或空字符串。

lpdwTagId:指向接收是唯一在 lpLoadOrderGroup 参数中指定组中的一个标记值的变量的指针。如果您不更改现有标记,请指定 NULL。

lpDependencies:指向的 NULL 分隔名称的服务或加载顺序组系统必须启动此服务前双空终止数组的指针。如果该服务没有依赖项,指定为 NULL 或空字符串。

lpServiceStartName:服务应在其下运行的帐户的名称。如果此参数为 NULL,CreateService 将使用本地系统帐户。如果服务类型指定SERVICE_INTERACTIVE_PROCESS,该服务必须运行在本地系统帐户。

lpPassword:指定的帐户的密码。如果该帐户没有密码,或在本地、 网络服务或本地系统帐户运行该服务,请指定空字符串。

返回值:如果此函数成功,返回值是服务的句柄。如果函数失败,返回值为 NULL。

4。OpenService 打开服务

SC_HANDLE WINAPI OpenService(  _In_ SC_HANDLE hSCManager,  _In_ LPCTSTR   lpServiceName,  _In_ DWORD     dwDesiredAccess);

hSCManager:服务控制管理器句柄。此句柄由 OpenSCManager 函数返回。

lpServiceName:要打开的服务的名称。这是由指向函数的参数的 CreateService 时,创建服务对象指定的名称,不是显示名称。

dwDesiredAccess:打开权限

SERVICE_ALL_ACCESS:包括 STANDARD_RIGHTS_REQUIRED,除了在此表中的所有访问权限。SERVICE_CHANGE_CONFIG:需要调用 ChangeServiceConfig 或 ChangeServiceConfig2 函数来更改服务配置。因为这授予调用方有权修改系统运行的可执行文件,它应只授予管理员。SERVICE_ENUMERATE_DEPENDENTS:需要调用 EnumDependentServices 函数来枚举所有依赖于该服务的服务。SERVICE_INTERROGATE:需要调用ControlService函数来要求服务报告他的运行状态。SERVICE_PAUSE_CONTINUE:调用这个函数所需暂停或继续服务。SERVICE_QUERY_CONFIG:调用的 QueryServiceConfig 和 QueryServiceConfig2 的功能查询的服务配置。SERVICE_QUERY_STATUS:需要调用 QueryServiceStatus 或 QueryServiceStatusEx 的功能询问服务的状态。要调用 NotifyServiceStatusChange 函数来接收通知时服务的状态改变时需要此权限。SERVICE_START:需要调用 StartService 函数来启动该服务。SERVICE_STOP:调用 ControlService 函数停止服务。SERVICE_USER_DEFINED_CONTROL:调用 ControlService 函数来发送指定用户定义的控制代码。DELETE:需要删除服务

返回值:如果此函数成功,返回值是服务的句柄。如果函数失败,返回值为 NULL。

备注:若要使用 OpenService,除了 SC_MANAGER_CONNECT 之外不需要权限。

5。DeleteService 删除服务

BOOL WINAPI DeleteService(  _In_ SC_HANDLE hService);

hService:服务句柄,需要有DELETE权限。

返回值:如果此函数成功,返回值不为零。如果函数失败,返回值为零。

6。QueryServiceStatus 获取服务状态

BOOL WINAPI QueryServiceStatus(  _In_  SC_HANDLE        hService,  _Out_ LPSERVICE_STATUS lpServiceStatus);

hService:服务句柄,必须有SERVICE_QUERY_STATUS权限

lpServiceStatus:指向SERVICE_STATUS结构的指针,用于返回服务状态

SERVICE_STATUS结构:

typedef struct _SERVICE_STATUS {  DWORD dwServiceType;  DWORD dwCurrentState;  DWORD dwControlsAccepted;  DWORD dwWin32ExitCode;  DWORD dwServiceSpecificExitCode;  DWORD dwCheckPoint;  DWORD dwWaitHint;} SERVICE_STATUS, *LPSERVICE_STATUS;

dwCurrentState:服务状态

SERVICE_CONTINUE_PENDING:服务继续处于挂起状态。SERVICE_PAUSE_PENDING:服务暂停被挂起。SERVICE_PAUSED:服务已暂停。SERVICE_RUNNING:该服务正在运行。SERVICE_START_PENDING:服务正在启动。SERVICE_STOP_PENDING:服务正在停止。SERVICE_STOPPED:服务没有运行。

返回值:如果此函数成功,返回值不为零。如果函数失败,返回值为零。

7。StartService 启动服务
BOOL WINAPI StartService(  _In_     SC_HANDLE hService,  _In_     DWORD     dwNumServiceArgs,  _In_opt_ LPCTSTR   *lpServiceArgVectors);

hService:服务句柄,需要有SERVICE_START权限。

dwNumServiceArgs:LpServiceArgVectors 数组中的字符串的数目。如果 lpServiceArgVectors 为 NULL,则此参数可以是零。

lpServiceArgVectors:要作为参数传递给 ServiceMain 的字符串。如果没有参数,此参数可以为 NULL。否则为第一个参数 (lpServiceArgVectors[0]) 是服务的名称,其后任何附加参数。

返回值:如果此函数成功,返回值不为零。如果函数失败,返回值为零。

8。ControlService 发送控制码

BOOL WINAPI ControlService(  _In_  SC_HANDLE        hService,  _In_  DWORD            dwControl,  _Out_ LPSERVICE_STATUS lpServiceStatus);

hService:服务句柄

dwControl:控制码,

SERVICE_CONTROL_STOP:停止服务,服务句柄需要SERVICE_STOP权限

128-255:自定义控制码,服务句柄需要SERVICE_USER_DEFINED_CONTROL权限

。。。。其他不再一一列举,如果有需要请查MSDN

lpServiceStatus:指向接收最新的服务状态信息的 SERVICE_STATUS 结构的指针。SERVICE_STATUS 结构见上面

返回值:如果此函数成功,返回值不为零。如果函数失败,返回值为零。

实例源码:

参数说明和代码注释就不写了,如果看过上文理解下面的很轻松。

①创建一个服务:

BOOL WINAPI InstallService(LPCTSTR ServiceName,LPCTSTR DisplayName,LPCTSTR szPath,DWORD StartType,DWORD ErrorControl = SERVICE_ERROR_NORMAL,DWORD ServiceType = SERVICE_WIN32_OWN_PROCESS){SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);if (hSCManager != NULL){SC_HANDLE hService = CreateService(hSCManager, ServiceName, DisplayName, SERVICE_ALL_ACCESS, ServiceType, StartType, ErrorControl, szPath, NULL, NULL, NULL, NULL, TEXT(""));if (hService != NULL){CloseServiceHandle(hService);CloseServiceHandle(hSCManager);return TRUE;}CloseServiceHandle(hSCManager);return FALSE;}else return FALSE;}

②删除一个服务:

BOOL WINAPI DeleteService(LPCTSTR ServiceName){SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);if (hSCManager != NULL){SC_HANDLE hService = OpenService(hSCManager, ServiceName, DELETE);if (hService != NULL){if (DeleteService(hService)){CloseServiceHandle(hService);CloseServiceHandle(hSCManager);return TRUE;}CloseServiceHandle(hService);CloseServiceHandle(hSCManager);return FALSE;}CloseServiceHandle(hSCManager);return FALSE;}else return FALSE;}

未完待续:欲知如何枚举服务、修改服务信息、获取服务信息(描述、恢复模式等),且听下回分解。




0 0