这两天写了一个驱动安装的例子,又写了一个Hook NtquerySystemInformation函数来隐藏进程的驱动,可没想到在安装的时候出错了。 虽然知道安装程序出错的可能性不大,但是为了放心还是又重新详细研究了一遍安装程序的一些函数。 首先就是第一个。 OpenSCManager 这个函数打开指定计算机上的service control manager database。其中参数lpMachineName指定计算机名,若为空则指定为本机。LpDatabaseName为指定要打开的service control manager database名, 默认为空。dwDesiredAccess指定操作的权限, 可以为下面取值之一: ----SC_MANAGER_ALL_ACCESS //所有权限 ----SC_MANAGER_CONNECT//允许连接到service control manager database ----SC_MANAGER_CREATE_SERVICE //允许创建服务对象并把它加入database ----SC_MANAGER_ENUMERATE_SERVICE //允许枚举database 中的Service ---- SC_MANAGER_LOCK //允许锁住database ---- SC_MANAGER_QUERY_LOCK_STATUS//允许查询database的封锁信息 ---- 函数执行成功则返回一个指向service control manager database的句柄,失败则返回NULL。注意:WINNT通过一个名为service control manager database的数据库来管理所有的Service,因此对Service的任何操作都应打开此数据库。 而我的代码是: hSCManager=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS) 也就是打开本机的SCManager,检查结果,并没有出错。 那么检查第二项,CreateService。CreateService函数的原型如下: SC_HANDLE CreateService(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPCTSTR lpDisplayName, DWORD dwDesiredAccess, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCTSTR lpBinaryPathName, LPCTSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCTSTR lpDependencies, LPCTSTR lpServiceStartName, LPCTSTR lpPassword) CreatService函数顾名思义产生一个新的SERVICE。其中参数hSCManager为指向service control manager database 的句柄,由OpenSCManager返回。LpServiceName为SERVICE的名字,lpDisplayName为Service显示用名,dwDesiredAccess是访问权限。wServiceType指明SERVICE类型。dwStartType为Service启动方式,本来应该采用自启动,即dwStartType等于SERVICE_AUTO_START。不过为了方便在命令行下一个一个函数的调试,我先设成了SERVICE_DEMAND_START,这应该是不会产生错误的。 dwErrorControl说明当Service在启动中出错时采取什么动作。LpBinaryPathName指明Service本体程序的路径名。剩下的五个参数一般可设为NULL。如函数调用成功则返回这个新Service的句柄,失败则返回NULL。与此函数对应的是DeleteService( hService),它删除指定的Service。 然后对照我自己的代码: schService = CreateService( hSCManager, ServiceName, ServiceName, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, ServiceExe, NULL, NULL, NULL, NULL, NULL ); 也没发现什么错误。 接下来第三项,OpenService。函数原型: SC_HANDLE OpenService(SC_HANDLE hSCManager, LPCTSTR lpServiceName, DWORD dwDesiredAccess ) OpenService函数打开指定的Service。其中参数hSCManager为指向service control manager database 的句柄,由OpenSCManager返回。LpServiceName为Service的名字,dwDesiredAccess是访问权限,SDK Help里面都有这些具体的值. 函数调用成功则返回打开的Service句柄,失败则返回NULL。 这个函数比较简单,我的三个参数也没错,hSCManager是OpenSCManager函数返回的句柄,访问权限也设的最高了。 schService= OpenService(hSCManager,ServiceName,SERVICE_ALL_ACCESS); 上面三个函数我在Debug下调试得到的返回值也都是正确的,也就是说创建、打开服务都是没问题的。问题出现在下面这个函数身上了。 第四项,StartService。用来启动服务。这个函数的原型: BOOL StartService( SC_HANDLE hService, DWORD dwNumServiceArgs,LPCTSTR *lpServiceArgVectors ) StartService函数启动指定的Service。其中参数hService为指向Service的句柄,由OpenService返回。dwNumServiceAr为启动服务所需的参数的个数。lpszServiceArgs 为 启 动 服务所需的参数。函数执行成功返回True, 失败返回False。 我的代码: nRet = StartService(schService, 0, NULL) schService是OpenService函数返回的句柄没错,也就是说我的语句没错,但是调试时返回的nRet值却一直为0。怀疑是自己的驱动写的有问题了,从网上当了一个helloworld的简单代码编译了一个hello.sys,调试结果nRet=1,这就说明安装程序的确没有问题,问题出在驱动程序上。 问题找到了,证明了我一开始的感觉是正确的。虽然浪费了时间,但既然检查到这里了,就把最后一个函数也检查一下好了,权当再学习一遍。 第五项是用来停止服务的ControlService函数。原型为: BOOL ControlService(SC_HANDLE hService DWORD dwControl,LPSERVICE_STATUS lpServiceStatus ) Service程序没有专门的停止函数,而是用ControlService函数来控制Service的暂停、继续、停止等操作。第一个参数hService是OpenService函数返回的句柄,参数dwControl指定发出的控制命令,可以为以下几个值: SERVICE_CONTROL_STOP //停止Service SERVICE_CONTROL_PAUSE //暂停Service SERVICE_CONTROL_CONTINUE //继续Service SERVICE_CONTROL_INTERROGATE //查询Service的状态 SERVICE_CONTROL_SHUTDOWN //让ControlService调用失效 参数lpServiceStatus是一个指向SERVICE_STATUS的指针。SERVICE_STATUS是一个比较重要的结构,它包含了Service的各种信息,如当前状态、可接受何种控制命令等等。 看来是我的驱动程序有问题了,着手研究去了。。。。。。
了解更多驱动信息请到: http://www.qudong360.com