1:服务分两种:
- 符合Service Control Manager(SCM)接口规则的 服务应用程序
- 符合设备驱动协议的驱动服务 虽与Service application类似 但跟SCM没关系
2:服务在vista上有了如下重大改变:
- 延时自启动
- 故障检测和恢复
- 预关闭通知
- 限制网络访问
- 最小特权运行
- 服务隔离 (意思大概就是不需要高权限就可以访问文件系统或是注册表,只需要SID能访问这些特权系统)
- 服务状态改变通知
- Session 0 隔离(vista以前session 0 被第一个login关联, vista开始 session 0不运行用户进程, 第一个login从session 1开始)
3: 什么是SCM
- 服务控制管理模块做一件事:维护一个(已安装服务和驱动服务的)数据库并提供一套统一安全的方法去控制他们
4:什么样的程序才使用SCM提供的方法 (这个是重点 后面好多要理解的地方都是围绕她来展开的)
- 服务程序:包含一个或多个服务的可执行代码. 可以连接SCM并将状态发送给SCM
- 服务配置程序:需要查询或更新服务数据库的程序. 安装 卸载 查询 更新数据库. 包含了services和驱动services
- 服务控制程序:开启和控制services/驱动services的程序. 通过SCM来执行这些操作
5:SCM可提供的方法
- SCM随系统启动而启动 属于RPC服务 所以服务配置程序和服务控制程序可以被远程机器调用
- 维护数据库中已安装的服务
- 开启services/驱动services 随系统启动 或是根据需求启动
- 枚举已安装的services/驱动services
- 维护已运行服务(驱动服务)的状态信息
- 给已运行的服务传送一个控制请求
- 数据库的lock/unlock
6: 服务从哪儿启动
- SCM维护的服务数据库在注册表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services. 项值就是服务名
系统安装时会有一个最小的数据库拷贝. 这个db包含了系统引导时必须的几个入口(驱动服务和服务的) 随系统启动启动时 这些服务就启动了
7:数据库有哪些东西
- 服务类型
for services: 是独占的还是共享的. 独占:一个服务一个进程 共享:几个服务共享一个进程
for driver services:标识是内核服务还是文件系统驱动
- 启动方式
自动启动还是配置程序通过SCM启动 或是不启动
- 错误控制级别
指定服务启动失败的严重性 和启动程序的出错处理
- 可执行程序的有效路径
for services: xx.exe
for driver services: xx.sys
- 可选依赖信息
标识正确的启动顺序
for services: 依赖列表上的服务的信息 名称 启动顺序
for driver services: 依赖列表的信息
- for services 一个可选的账号密码
- fro driver services 一个可选的驱动对象名
是i/o系统用来加载设备驱动的
附加说明 数据库常被称为SCM数据库或是ServicesActive数据库
8:自启动包含了哪些部分
- 自启动服务所依赖的服务都是自启动的
- 自启动的顺序放
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control
这个项包含了每个服务包含了多少个组 每个组里每个服务顺序号
- 系统启动引导之后 会执行引导校验程序 然后在第一个用户登录之后报告引导的结果
我们可以提供服务的校验程序 并将引导的状态(结果)告诉SCM
- 系统成功引导之后 会拷贝一个数据库的副本 如果出现异常 可以用副本恢复
HKEY_LOCAL_MACHINE\SYSTEM\ControlSetXXX\Services 其中xxx保存在HKEY_LOCAL_MACHINE\System\Select\LastKnownGood
如果服务启动发生SERVICE_ERROR_CRITICAL错误 就会用LKG配置重新启动 如果还失败就报告启动失败 LKG:last-known-good
- 延时启动
在改变配置之后下次引导时生效
9:除了自启动还有其他方式启动吗
- 按需启动 可以通过服务控制面板 通过StartService()函数启动
10:SCM启动一个服务时 做了哪些操作
- 获取数据库中的账号信息
- 用账号登录
- 加载用户的配置信息
- 创建一个服务 置挂起状态
- 将登录令牌给进程
- 允许进程执行
11:什么是服务档案列表
db有服务的入口 SCM会为每一个启动的服务创建一个档案 每个档案又包含了如下信息:
- 服务名
- 服务类型
- 服务状态 (其中包含 类型 当前状态 可控制代码 退出码 等待提示)
- 依赖列表指针
12:服务中的部分LKG思想
除了db沿用LKG思想 对于有密码的的服务 会有两个密码拷贝 也是沿用LKG思想
13:怎么修改服务的状态
- 这些信息都保存在db中由SCM来维护 只能通过SCM来改动
for services: 服务程序发送状态给SCM来更新
for driver services:通过i/o系统来查询
14:SCM的句柄类型有哪些
- 数据库的句柄
- 一个服务的句柄
- 数据库lock的句柄
15:SCM管理对象是什么
- SCM维护着数据库 操作SCM管理对象就等同于操作数据库 管理对象包含了所有的服务对象
- 这个管理对象能做如下操作:
安装 卸载 打开 遍历 以及锁操作
- 服务对象的含义 一个已安装的服务
[编写一个服务程序涉及到哪些方面]
16:服务入口点是什么意思
一般服务是控制台程序(也可以是带图形化界面的程序 稍微处理一下就实现了) 入口点就是main函数
SCM启动一个服务时 会等待服务程序调用 StartServiceCtrlDispatcher() 对于独占和共享的 要分别做如下处理
独占:SERVICE_WIN32_OWN_PROCESS 在主线程中尽快调用StartServiceCtrlDispatcher 之后再初始化
共享:SERVICE_WIN32_SHARE_PROCESS 先执行公共初始化 再调用函数 再执行自己的初始化 (公共初始化和调用函数之间不能超过30s 否则需要用多线程处理)
17:StartServiceCtrlDispatcher的作用是什么
- StartServiceCtrlDispatcher函数会为进程中每个服务带来一个 SERVICE_TABLE_ENTRY 结构 望文生义 就是入口点表 这个表包含了入口点
- 如果函数执行成功了 那么这条线程会一直执行 直到档案中的状态信息被置为SERVICE_STOPPED状态 (回头看看11条)
这条线程和SCM交互是通过一个有名管道 而这条线程的作用就相当于一个控制分派器
18:调用StartServiceCtrlDispatcher()函数的线程可以做哪些事
这条线程就是一个分派器 可以做如下工作:
- 当一个新的服务启动时 创建一个新线程 调用入口点
- 调用处理函数来处理SCM的请求
19:服务的启动再讨论
当服务控制程序(可以跳到11条再看看)启动一个服务时
SCM会发送一个开始请求给分派器
分派器会创建一个新线程 并执行ServiceMain函数
20:这个ServiceMain函数做了哪些事
- 初始化全部全局变量
- 调用 RegisterServiceCtrlHandler函数来注册一个处理函数 返回值是一个服务状态句柄 通过这个句柄可以把服务状态通知给SCM (参看14条 这里用到的是服务句柄)
- 执行初始化 如果初始化的代码执行时间小于1s 那可以直接放在ServiceMain 如果时间大于1s 先用 SetServiceStatus 设置状态为SERVICE_START_PENDING 并设置wait hint
如果初始化时间大于了wait hint 就必须周期性调用SetServiceStatus. 特别注意:这是入口点被分派器调用 是阻塞的
如果卡死在这个地方 会照成其他服务无法启动 因为分派器一直在等待初始化返回SERVICE_RUNNING 提示:不要在一个单独的线程执行SetServiceStatus, 至少要保证初始化不被卡死
- 初始化完成后用SetServiceStatus 发送状态 SERVICE_RUNNING
- 执行服务中的任务(也就是我们的实际代码) 如果没有阻塞任务就返回 其中任何有可能改变服务状态的都需要调用 SetServiceStatus 来报告新的状态
- 如果初始化或者运行时出错了 而清理操作很漫长就需要调用SetServiceStatus设置SERVICE_STOP_PENDING
当清理完成了 等所有线程全结束了调用 SetServiceStatus 设置 SERVICE_STOPPED
设置SERVICE_STATUS 的两个成员dwServiceSpecificExitCode 和dwWin32ExitCode 来标识错误
- 符合Service Control Manager(SCM)接口规则的 服务应用程序
- 符合设备驱动协议的驱动服务 虽与Service application类似 但跟SCM没关系
2:服务在vista上有了如下重大改变:
- 延时自启动
- 故障检测和恢复
- 预关闭通知
- 限制网络访问
- 最小特权运行
- 服务隔离 (意思大概就是不需要高权限就可以访问文件系统或是注册表,只需要SID能访问这些特权系统)
- 服务状态改变通知
- Session 0 隔离(vista以前session 0 被第一个login关联, vista开始 session 0不运行用户进程, 第一个login从session 1开始)
3: 什么是SCM
- 服务控制管理模块做一件事:维护一个(已安装服务和驱动服务的)数据库并提供一套统一安全的方法去控制他们
4:什么样的程序才使用SCM提供的方法 (这个是重点 后面好多要理解的地方都是围绕她来展开的)
- 服务程序:包含一个或多个服务的可执行代码. 可以连接SCM并将状态发送给SCM
- 服务配置程序:需要查询或更新服务数据库的程序. 安装 卸载 查询 更新数据库. 包含了services和驱动services
- 服务控制程序:开启和控制services/驱动services的程序. 通过SCM来执行这些操作
5:SCM可提供的方法
- SCM随系统启动而启动 属于RPC服务 所以服务配置程序和服务控制程序可以被远程机器调用
- 维护数据库中已安装的服务
- 开启services/驱动services 随系统启动 或是根据需求启动
- 枚举已安装的services/驱动services
- 维护已运行服务(驱动服务)的状态信息
- 给已运行的服务传送一个控制请求
- 数据库的lock/unlock
6: 服务从哪儿启动
- SCM维护的服务数据库在注册表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services. 项值就是服务名
系统安装时会有一个最小的数据库拷贝. 这个db包含了系统引导时必须的几个入口(驱动服务和服务的) 随系统启动启动时 这些服务就启动了
7:数据库有哪些东西
- 服务类型
for services: 是独占的还是共享的. 独占:一个服务一个进程 共享:几个服务共享一个进程
for driver services:标识是内核服务还是文件系统驱动
- 启动方式
自动启动还是配置程序通过SCM启动 或是不启动
- 错误控制级别
指定服务启动失败的严重性 和启动程序的出错处理
- 可执行程序的有效路径
for services: xx.exe
for driver services: xx.sys
- 可选依赖信息
标识正确的启动顺序
for services: 依赖列表上的服务的信息 名称 启动顺序
for driver services: 依赖列表的信息
- for services 一个可选的账号密码
- fro driver services 一个可选的驱动对象名
是i/o系统用来加载设备驱动的
附加说明 数据库常被称为SCM数据库或是ServicesActive数据库
8:自启动包含了哪些部分
- 自启动服务所依赖的服务都是自启动的
- 自启动的顺序放
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control
这个项包含了每个服务包含了多少个组 每个组里每个服务顺序号
- 系统启动引导之后 会执行引导校验程序 然后在第一个用户登录之后报告引导的结果
我们可以提供服务的校验程序 并将引导的状态(结果)告诉SCM
- 系统成功引导之后 会拷贝一个数据库的副本 如果出现异常 可以用副本恢复
HKEY_LOCAL_MACHINE\SYSTEM\ControlSetXXX\Services 其中xxx保存在HKEY_LOCAL_MACHINE\System\Select\LastKnownGood
如果服务启动发生SERVICE_ERROR_CRITICAL错误 就会用LKG配置重新启动 如果还失败就报告启动失败 LKG:last-known-good
- 延时启动
在改变配置之后下次引导时生效
9:除了自启动还有其他方式启动吗
- 按需启动 可以通过服务控制面板 通过StartService()函数启动
10:SCM启动一个服务时 做了哪些操作
- 获取数据库中的账号信息
- 用账号登录
- 加载用户的配置信息
- 创建一个服务 置挂起状态
- 将登录令牌给进程
- 允许进程执行
11:什么是服务档案列表
db有服务的入口 SCM会为每一个启动的服务创建一个档案 每个档案又包含了如下信息:
- 服务名
- 服务类型
- 服务状态 (其中包含 类型 当前状态 可控制代码 退出码 等待提示)
- 依赖列表指针
12:服务中的部分LKG思想
除了db沿用LKG思想 对于有密码的的服务 会有两个密码拷贝 也是沿用LKG思想
13:怎么修改服务的状态
- 这些信息都保存在db中由SCM来维护 只能通过SCM来改动
for services: 服务程序发送状态给SCM来更新
for driver services:通过i/o系统来查询
14:SCM的句柄类型有哪些
- 数据库的句柄
- 一个服务的句柄
- 数据库lock的句柄
15:SCM管理对象是什么
- SCM维护着数据库 操作SCM管理对象就等同于操作数据库 管理对象包含了所有的服务对象
- 这个管理对象能做如下操作:
安装 卸载 打开 遍历 以及锁操作
- 服务对象的含义 一个已安装的服务
[编写一个服务程序涉及到哪些方面]
16:服务入口点是什么意思
一般服务是控制台程序(也可以是带图形化界面的程序 稍微处理一下就实现了) 入口点就是main函数
SCM启动一个服务时 会等待服务程序调用 StartServiceCtrlDispatcher() 对于独占和共享的 要分别做如下处理
独占:SERVICE_WIN32_OWN_PROCESS 在主线程中尽快调用StartServiceCtrlDispatcher 之后再初始化
共享:SERVICE_WIN32_SHARE_PROCESS 先执行公共初始化 再调用函数 再执行自己的初始化 (公共初始化和调用函数之间不能超过30s 否则需要用多线程处理)
17:StartServiceCtrlDispatcher的作用是什么
- StartServiceCtrlDispatcher函数会为进程中每个服务带来一个 SERVICE_TABLE_ENTRY 结构 望文生义 就是入口点表 这个表包含了入口点
- 如果函数执行成功了 那么这条线程会一直执行 直到档案中的状态信息被置为SERVICE_STOPPED状态 (回头看看11条)
这条线程和SCM交互是通过一个有名管道 而这条线程的作用就相当于一个控制分派器
18:调用StartServiceCtrlDispatcher()函数的线程可以做哪些事
这条线程就是一个分派器 可以做如下工作:
- 当一个新的服务启动时 创建一个新线程 调用入口点
- 调用处理函数来处理SCM的请求
19:服务的启动再讨论
当服务控制程序(可以跳到11条再看看)启动一个服务时
SCM会发送一个开始请求给分派器
分派器会创建一个新线程 并执行ServiceMain函数
20:这个ServiceMain函数做了哪些事
- 初始化全部全局变量
- 调用 RegisterServiceCtrlHandler函数来注册一个处理函数 返回值是一个服务状态句柄 通过这个句柄可以把服务状态通知给SCM (参看14条 这里用到的是服务句柄)
- 执行初始化 如果初始化的代码执行时间小于1s 那可以直接放在ServiceMain 如果时间大于1s 先用 SetServiceStatus 设置状态为SERVICE_START_PENDING 并设置wait hint
如果初始化时间大于了wait hint 就必须周期性调用SetServiceStatus. 特别注意:这是入口点被分派器调用 是阻塞的
如果卡死在这个地方 会照成其他服务无法启动 因为分派器一直在等待初始化返回SERVICE_RUNNING 提示:不要在一个单独的线程执行SetServiceStatus, 至少要保证初始化不被卡死
- 初始化完成后用SetServiceStatus 发送状态 SERVICE_RUNNING
- 执行服务中的任务(也就是我们的实际代码) 如果没有阻塞任务就返回 其中任何有可能改变服务状态的都需要调用 SetServiceStatus 来报告新的状态
- 如果初始化或者运行时出错了 而清理操作很漫长就需要调用SetServiceStatus设置SERVICE_STOP_PENDING
当清理完成了 等所有线程全结束了调用 SetServiceStatus 设置 SERVICE_STOPPED
设置SERVICE_STATUS 的两个成员dwServiceSpecificExitCode 和dwWin32ExitCode 来标识错误