首页
社区
课程
招聘
[旧帖] [求助]调用ControlService就蓝屏怎么办 0.00雪花
发表于: 2011-11-21 17:51 2334

[旧帖] [求助]调用ControlService就蓝屏怎么办 0.00雪花

2011-11-21 17:51
2334
我写了个驱动程序,在卸载例程中,只要一运行到ControlService函数这里就蓝屏,这是什么原因?
代码如下:
//卸载驱动程序  
BOOL UnloadNTDriver( char * szSvrName )  
{
        BOOL bRet = FALSE;
        SC_HANDLE hServiceMgr=NULL;//SCM管理器的句柄
        SC_HANDLE hServiceDDK=NULL;//NT驱动程序的服务句柄
        SERVICE_STATUS SvrSta;
        //打开SCM管理器
        hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );  
        if( hServiceMgr == NULL )  
        {
                //带开SCM管理器失败
                printf( "OpenSCManager() Faild %d ! \n", GetLastError() );  
                bRet = FALSE;
                goto BeforeLeave;
        }  
        else  
        {
                //带开SCM管理器失败成功
                printf( "OpenSCManager() ok ! \n" );  
        }
        //打开驱动所对应的服务
        hServiceDDK = OpenService( hServiceMgr, szSvrName, SERVICE_ALL_ACCESS );
        if( hServiceDDK == NULL )  
        {
                //打开驱动所对应的服务失败
                printf( "OpenService() Faild %d ! \n", GetLastError() );  
                bRet = FALSE;
                goto BeforeLeave;
        }  
        else  
        {  
                printf( "OpenService() ok ! \n" );
        }
        //停止驱动程序,如果停止失败,只有重新启动才能,再动态加载。  
        if( !ControlService( hServiceDDK, SERVICE_CONTROL_STOP , &SvrSta ) )  
        {  
                printf( "ControlService() Faild %d !\n", GetLastError() );  
        }  
        else  
        {
                //打开驱动所对应的失败
                printf( "ControlService() ok !\n" );  
        }
        //动态卸载驱动程序。  
        if( !DeleteService( hServiceDDK ) )  
        {
                //卸载失败
                printf( "DeleteSrevice() Faild %d !\n", GetLastError() );  
        }  
        else  
        {  
                //卸载成功
                printf( "DelServer:eleteSrevice() ok !\n" );  
        }
        bRet = TRUE;
BeforeLeave:
//离开前关闭打开的句柄
        if(hServiceDDK)
        {
                CloseServiceHandle(hServiceDDK);
        }
        if(hServiceMgr)
        {
                CloseServiceHandle(hServiceMgr);
        }
        return bRet;       
}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (10)
雪    币: 55
活跃值: (75)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
2
你只贴这个,是看不出问题的,关键代码还是在你的卸载例程中,所以你好好调试一下的你驱动中的卸载函数吧!
2011-11-21 18:02
0
雪    币: 29
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
你整个代码是没有什么问题的.不知道你问题出在哪里的??
2011-11-21 18:50
0
雪    币: 20
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
我贴出来的代码就是整个卸载例程的代码,这个代码我调试了,就是一运行ControlService这个函数就蓝屏,我是运行在win7下的,编译器是VC6
2011-11-21 18:58
0
雪    币: 55
活跃值: (75)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
5
你贴出来的是应用层的代码,我说的是驱动代码。
2011-11-22 09:38
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
人家要你贴出驱动的卸载例程代码。
应用层的代码绝大部分情况下是没法让系统蓝屏的,一般只能让自身进程崩溃。如果应用层的一个操作导致系统蓝屏了,那么基本可以认定,这个操作在内核的部分代码有问题。你的ControlService就是停止驱动,他本身没啥问题,但是这个操作会导致IO管理器调用驱动的Unload例程,如果你的驱动Unload例程有问题,那就可能会蓝屏。

所以蓝屏要贴出驱动代码!!!
2011-11-22 09:46
0
雪    币: 20
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
#include "whl.h"

/************************************************************************
* 函数名称:DriverEntry
* 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象
* 参数列表:
      pDriverObject:从I/O管理器中传进来的驱动对象
      pRegistryPath:驱动程序在注册表的中的路径
* 返回 值:返回初始化驱动状态
*************************************************************************/
#pragma INITCODE
extern "C" NTSTATUS DriverEntry (
                        IN PDRIVER_OBJECT pDriverObject,
                        IN PUNICODE_STRING pRegistryPath        )
{
        NTSTATUS status;
        KdPrint(("Enter DriverEntry\n"));

        //注册其他驱动调用函数入口
        pDriverObject->DriverUnload = HelloDDKUnload;
        pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutine;
        pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutine;
        pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine;
        pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKDispatchRoutine;
       
        //创建驱动设备对象
        status = CreateDevice(pDriverObject);

        KdPrint(("Leave DriverEntry\n"));
        return status;
}

/************************************************************************
* 函数名称:CreateDevice
* 功能描述:初始化设备对象
* 参数列表:
      pDriverObject:从I/O管理器中传进来的驱动对象
* 返回 值:返回初始化状态
*************************************************************************/
#pragma INITCODE
NTSTATUS CreateDevice (
                IN PDRIVER_OBJECT        pDriverObject)
{
        NTSTATUS status;
        PDEVICE_OBJECT pDevObj;
        PDEVICE_EXTENSION pDevExt;
       
        //创建设备名称
        UNICODE_STRING devName;
        RtlInitUnicodeString(&devName,L"\\Device\\WHLDevice");
       
        //创建设备
        status = IoCreateDevice( pDriverObject,
                                                sizeof(DEVICE_EXTENSION),
                                                &(UNICODE_STRING)devName,
                                                FILE_DEVICE_UNKNOWN,
                                                0, TRUE,
                                                &pDevObj );
        if (!NT_SUCCESS(status))
                return status;

        pDevObj->Flags |= DO_BUFFERED_IO;
        pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
        pDevExt->pDevice = pDevObj;
        pDevExt->ustrDeviceName = devName;
        //创建符号链接
        UNICODE_STRING symLinkName;
        RtlInitUnicodeString(&symLinkName,L"\\??\\WHLDDK");
        pDevExt->ustrSymLinkName = symLinkName;
        status = IoCreateSymbolicLink( &symLinkName,&devName );
        if (!NT_SUCCESS(status))
        {
                IoDeleteDevice( pDevObj );
                return status;
        }
        return STATUS_SUCCESS;
}

/************************************************************************
* 函数名称:HelloDDKUnload
* 功能描述:负责驱动程序的卸载操作
* 参数列表:
      pDriverObject:驱动对象
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject)
{
        PDEVICE_OBJECT        pNextObj;
        KdPrint(("Enter DriverUnload\n"));
        pNextObj = pDriverObject->DeviceObject;
        while (pNextObj != NULL)
        {
                PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
                        pNextObj->DeviceExtension;

                //删除符号链接
                UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;
                IoDeleteSymbolicLink(&pLinkName);
                pNextObj = pNextObj->NextDevice;
                IoDeleteDevice( pDevExt->pDevice );
        }
        KdPrint(("Leave DriverUnload\n"));
}

/************************************************************************
* 函数名称:HelloDDKDispatchRoutine
* 功能描述:对读IRP进行处理
* 参数列表:
      pDevObj:功能设备对象
      pIrp:从IO请求包
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,
                                                                 IN PIRP pIrp)
{
        KdPrint(("Enter HelloDDKDispatchRoutine\n"));
        NTSTATUS status = STATUS_SUCCESS;
        // 完成IRP
        pIrp->IoStatus.Status = status;
        pIrp->IoStatus.Information = 0;        // bytes xfered
        IoCompleteRequest( pIrp, IO_NO_INCREMENT );
        KdPrint(("Leave HelloDDKDispatchRoutine\n"));
        return status;
}
2011-11-22 10:13
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
这个问题我一个朋友也碰到过,是张帆驱动详解里的代码,由于你的代码没给全,我没法调试确切原因,我朋友那个蓝屏是因为CreateDevice函数上面的#pragma INITCODE导致的,改成#pragma PAGEDCODE就好了,#pragma INITCODE标识下面的代码是初始化用的代码,一旦驱动初始化完毕,这些空间就可能被收回了,你在unload例程里使用的符号名和设备名就是在CreateDevice里初始化的,但是这两个变量是全局变量,是否受INITCODE的影响,我也不清楚,还请牛人们说明下情况,让我们这些菜鸟也学学。
2011-11-22 13:30
0
雪    币: 55
活跃值: (75)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
9
VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT pNextObj;
KdPrint(("Enter DriverUnload\n"));
pNextObj = pDriverObject->DeviceObject;
while (pNextObj != NULL)
{
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
pNextObj->DeviceExtension;

//删除符号链接
UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;
IoDeleteSymbolicLink(&pLinkName);
pNextObj = pNextObj->NextDevice;
IoDeleteDevice( pDevExt->pDevice );
}
KdPrint(("Leave DriverUnload\n"));
}


上面这段代码中,你需要注意的那几个指针,最好的方式是用windbg跟一下,不要说windbg+vmware 调试驱动你不会。如果不会,那么先把这个学会哈,这个比写代码更基础。
2011-11-23 11:41
0
雪    币: 316
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
学习驱动开发也遇到这个问题。和楼主一样,用的驱动源码也是同一本书提供的源码。真的好奇怪。
2020-1-17 17:18
0
雪    币: 316
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
11
ITSailor 这个问题我一个朋友也碰到过,是张帆驱动详解里的代码,由于你的代码没给全,我没法调试确切原因,我朋友那个蓝屏是因为CreateDevice函数上面的#pragma INITCODE导致的,改成#prag ...
8楼正解。
最后于 2020-1-19 14:53 被KBoss编辑 ,原因:
2020-1-19 14:53
0
游客
登录 | 注册 方可回帖
返回
//