WY.lslrt
驱动牛犊
驱动牛犊
  • 注册日期2004-07-30
  • 最后登录2009-10-27
  • 粉丝0
  • 关注0
  • 积分116分
  • 威望15点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
阅读:1588回复:7

我的有问题switch代码,请大家给我说说为什么会蓝屏

楼主#
更多 发布于:2004-10-20 13:42
switch(WY_CtrCode)
{
case IO_REFERENCE_EVENT:
    WY_Evt = (HANDLE)WY_irpStack->Parameters.DeviceIoControl.Type3InputBuffer;//获得号句柄
    WY_status = ObReferenceObjectByHandle(WY_Evt,
                                          GENERIC_ALL,
                                          NULL,
                                          KernelMode,
                                          &WY_GbEvt,
                                          &WY_OBJ_HandleInfo);//转化为核心信号量句柄
    if(WY_status != STATUS_SUCCESS){
    WY_DBGPRN("ObReferenceObjectByHandle Faild");
    WY_DBGPRNEX("Error Code = %d",WY_status);
    }
    WY_DBGPRN("ObReferenceObjectByHandle Sucessful");
    break;
case IO_DEREFERENCE_EVENT:
   if(WY_GbEvt)
      ObDereferenceObject(WY_GbEvt);//移除信号量
   WY_DBGPRN("ObDereferenceObject Successful");
   break;
case IO_SET_EVENT:
   KeSetEvent(WY_GbEvt,0,FALSE);
   WY_DBGPRN("KeSetEvent Successful");
   break;
case IO_CLEAR_EVENT:
   KeClearEvent(WY_GbEvt);
   WY_DBGPRN("KeClearEvent Successful");
   break;
case IO_QUERY_EVENT_STATE:
   WY_DBGPRN("KeReadStateEvent");
   WY_OutBuf = (LONG *)WY_Irp->UserBuffer;//获得应用层缓冲区地址
   *WY_OutBuf = KeReadStateEvent(WY_GbEvt);
   
   
   WY_Irp->IoStatus.Status = STATUS_SUCCESS;
   WY_Irp->IoStatus.Information = sizeof(LONG);
   IoCompleteRequest(WY_Irp,IO_NO_INCREMENT);
   WY_DBGPRN("KeReadStateEvent Successful");
   return WY_status;//一但改成break就出问题
 
case IO_GET_USER_ADDRESS:
   WY_DBGPRN("Converting SysAddr to UserAddr");
   try
   {
    WY_UserVirtualAddress = MmMapLockedPages(WY_MDL,UserMode);//转化核心地址到用户态
    *((PVOID *)(WY_Irp->AssociatedIrp.SystemBuffer)) = WY_UserVirtualAddress;
                     
    WY_Irp->IoStatus.Status = STATUS_SUCCESS;
    WY_Irp->IoStatus.Information = sizeof(PVOID);
   }
   except(EXCEPTION_EXECUTE_HANDLER){}
   WY_DBGPRN("Convert Successful!");
   
   break;
       default:
           break;
}
---传说中的分割线--------
WY.lslrt
驱动牛犊
驱动牛犊
  • 注册日期2004-07-30
  • 最后登录2009-10-27
  • 粉丝0
  • 关注0
  • 积分116分
  • 威望15点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-10-20 13:44
case IO_QUERY_EVENT_STATE:
最后的return 改为break;时应用层一传递Irp就会蓝屏
为什么啊
---传说中的分割线--------
streamvian
驱动牛犊
驱动牛犊
  • 注册日期2002-11-15
  • 最后登录2013-08-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望10点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-10-20 15:47
代码不全,问题不一定是出在这里的,可能是switch
后面的代码,因为return 之后就直接堆栈返回了,switch
后面的代码执行不到了.
往事不要再提................................
WY.lslrt
驱动牛犊
驱动牛犊
  • 注册日期2004-07-30
  • 最后登录2009-10-27
  • 粉丝0
  • 关注0
  • 积分116分
  • 威望15点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-10-20 15:56
别的都测试过,没问题。应用层是这样进行IRP的
DWORD WY_dwReturn;
ULONG WY_dwState;
if(WY_hDev){
//获得信号量状态
DeviceIoControl(WY_hDev,IO_QUERY_EVENT_STATE,NULL,0,(LPVOID)&WY_dwState,sizeof(WY_dwState),&WY_dwReturn,NULL);
}

以下该驱动的完整代码
#include <ntddk.h>
#include "MinDriver.h"

PVOID WY_GbEvt = NULL;                             //全局信号量
PVOID WY_SysVirtualAddress,WY_UserVirtualAddress;  //共享内存核心地址,用户地址
PMDL  WY_MDL;                                      //MDL
NTSTATUS DriverEntry(IN PDRIVER_OBJECT   WY_DriverObject, IN PUNICODE_STRING  WY_RegistryPath)
{
        NTSTATUS WY_status = STATUS_SUCCESS;
        UNICODE_STRING  WY_DEV_Name;               //设备名
        UNICODE_STRING  WY_SymbolicName;           //连接名
WY_DBGPRN("Hello 王艳");
WY_DBGPRN("MinDriver Beta");
WY_DBGPRN("WY_Driver Entry Loading ...");
WY_DriverObject->DriverUnload = PacketUnload;         //卸栽函数
WY_DriverObject->MajorFunction[IRP_MJ_CREATE]         = MinDrv_Create;//定义Dispatch例程响应CreateFile
WY_DriverObject->MajorFunction[IRP_MJ_CLOSE]          = MinDrv_Close;//定义Dispatch例程响应CloseHandle
WY_DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MinDrv_IoControl;//定义Dispatch例程响应DeviceIoControl
RtlInitUnicodeString(&WY_DEV_Name,MIN_DRIVER_DEV_NAME);       //注册设备
RtlInitUnicodeString(&WY_SymbolicName,MIN_DRIVER_WIN32_DEV_NAME);//注册设备
WY_status = IoCreateDevice(WY_DriverObject,
                       sizeof(MIN_DRIVER_EXT),
                       &WY_DEV_Name,
                       FILE_DEVICE_UNKNOWN,
                       0,
                       TRUE,
                       &WY_DriverObject->DeviceObject);
        if(WY_status != STATUS_SUCCESS){
         WY_DBGPRN("IoCreateDevice Failed");
         WY_DBGPRNEX("Error Code = %d",WY_status);
        }
        WY_status = IoCreateSymbolicLink(&WY_SymbolicName,&WY_DEV_Name);//创建设备连接,共应用层通讯
        if(WY_status != STATUS_SUCCESS){
         WY_DBGPRN("IoCreateSymbolicLink Failed");
         WY_DBGPRNEX("Error Code = %d",WY_status);
        }
       WY_SysVirtualAddress = ExAllocatePool(NonPagedPool,1024);//申请非分页缓冲池
       WY_MDL = IoAllocateMdl(WY_SysVirtualAddress,1024,FALSE,FALSE,NULL);//建立MDL
       MmBuildMdlForNonPagedPool(WY_MDL);//为非分页缓冲池建立MDL
                    
return WY_status;

}

VOID PacketUnload(IN PDRIVER_OBJECT WY_DriverObject)
{
PDEVICE_OBJECT    WY_DeviceObject;
PDEVICE_OBJECT    WY_OldDeviceObject;
WY_DBGPRN("WY_Driver unLoading ...");
WY_DeviceObject = WY_DriverObject->DeviceObject;
while(WY_DeviceObject != NULL){//删除建立的设备
WY_OldDeviceObject = WY_DeviceObject;
WY_DeviceObject = WY_DeviceObject->NextDevice;
IoDeleteDevice(WY_OldDeviceObject);
}
WY_DBGPRN("王艳 GoodBye");
}

NTSTATUS MinDrv_Create(IN PDEVICE_OBJECT WY_DEV_Object, IN PIRP WY_Irp)//Dispatch例程
{
NTSTATUS WY_status = STATUS_SUCCESS;
WY_DBGPRN("Create Device--New");

WY_Irp->IoStatus.Status = STATUS_SUCCESS;//返回成功
WY_Irp->IoStatus.Information = 0;
IoCompleteRequest(WY_Irp,IO_NO_INCREMENT);//完成例程

return WY_status;
}

NTSTATUS MinDrv_Close(IN PDEVICE_OBJECT WY_DEV_Object, IN PIRP WY_Irp)//Dispatch例程
{
NTSTATUS WY_status = STATUS_SUCCESS;
WY_DBGPRN("Close Device");

WY_Irp->IoStatus.Status = STATUS_SUCCESS;
WY_Irp->IoStatus.Information = 0;
IoCompleteRequest(WY_Irp,IO_NO_INCREMENT);

return WY_status;

}

NTSTATUS MinDrv_IoControl(IN PDEVICE_OBJECT WY_DEV_Object, IN PIRP WY_Irp)//Dispatch例程
{
NTSTATUS                   WY_status = STATUS_SUCCESS;
ULONG                      WY_CtrCode;//控制代码
PIO_STACK_LOCATION         WY_irpStack;//IRP堆栈
HANDLE                     WY_Evt;//信号量
OBJECT_HANDLE_INFORMATION  WY_OBJ_HandleInfo;
LONG                      *WY_OutBuf;//应用层缓冲区

WY_irpStack = IoGetCurrentIrpStackLocation(WY_Irp);//获得当前IRP堆栈
WY_CtrCode  = WY_irpStack->Parameters.DeviceIoControl.IoControlCode;//获得控制代码

switch(WY_CtrCode)
{
case IO_REFERENCE_EVENT:
    WY_Evt = (HANDLE)WY_irpStack->Parameters.DeviceIoControl.Type3InputBuffer;//获得号句柄
    WY_status = ObReferenceObjectByHandle(WY_Evt,
                                          GENERIC_ALL,
                                          NULL,
                                          KernelMode,
                                          &WY_GbEvt,
                                          &WY_OBJ_HandleInfo);//转化为核心信号量句柄
    if(WY_status != STATUS_SUCCESS){
    WY_DBGPRN("ObReferenceObjectByHandle Faild");
    WY_DBGPRNEX("Error Code = %d",WY_status);
    }
    WY_DBGPRN("ObReferenceObjectByHandle Sucessful");
    break;
case IO_DEREFERENCE_EVENT:
   if(WY_GbEvt)
      ObDereferenceObject(WY_GbEvt);//移除信号量
   WY_DBGPRN("ObDereferenceObject Successful");
   break;
case IO_SET_EVENT:
   KeSetEvent(WY_GbEvt,0,FALSE);
   WY_DBGPRN("KeSetEvent Successful");
   break;
case IO_CLEAR_EVENT:
   KeClearEvent(WY_GbEvt);
   WY_DBGPRN("KeClearEvent Successful");
   break;
case IO_QUERY_EVENT_STATE:
   WY_DBGPRN("KeReadStateEvent");
   WY_OutBuf = (LONG *)WY_Irp->UserBuffer;//获得应用层缓冲区地址
   *WY_OutBuf = KeReadStateEvent(WY_GbEvt);
   
   
   WY_Irp->IoStatus.Status = STATUS_SUCCESS;
   WY_Irp->IoStatus.Information = sizeof(LONG);
   IoCompleteRequest(WY_Irp,IO_NO_INCREMENT);
   WY_DBGPRN("KeReadStateEvent Successful");
   return WY_status;
 
case IO_GET_USER_ADDRESS:
   WY_DBGPRN("Converting SysAddr to UserAddr");
   try
   {
    WY_UserVirtualAddress = MmMapLockedPages(WY_MDL,UserMode);//转化核心地址到用户态
    *((PVOID *)(WY_Irp->AssociatedIrp.SystemBuffer)) = WY_UserVirtualAddress;
                     
    WY_Irp->IoStatus.Status = STATUS_SUCCESS;
    WY_Irp->IoStatus.Information = sizeof(PVOID);
   }
   except(EXCEPTION_EXECUTE_HANDLER){}
   WY_DBGPRN("Convert Successful!");
   
   break;
       default:
           break;
}
        WY_Irp->IoStatus.Status = STATUS_SUCCESS;
WY_Irp->IoStatus.Information = 0;
IoCompleteRequest(WY_Irp,IO_NO_INCREMENT);
     
return WY_status;

}
---传说中的分割线--------
streamvian
驱动牛犊
驱动牛犊
  • 注册日期2002-11-15
  • 最后登录2013-08-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望10点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-10-20 16:36
老总,
看看你代码的最后了,
WY_Irp->IoStatus.Status = STATUS_SUCCESS;
WY_Irp->IoStatus.Information = 0;
IoCompleteRequest(WY_Irp,IO_NO_INCREMENT);
这里的WY_Irp->IoStatus.Information怎么能等于0呢,
肯定的是sizeof(ULONG)了。
往事不要再提................................
WY.lslrt
驱动牛犊
驱动牛犊
  • 注册日期2004-07-30
  • 最后登录2009-10-27
  • 粉丝0
  • 关注0
  • 积分116分
  • 威望15点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-10-20 19:55
那我的前两个例程中的WY_Irp->IoStatus.Information = 0;
怎么不会出错呢? :(
---传说中的分割线--------
aasa2
驱动中牛
驱动中牛
  • 注册日期2004-04-01
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分525分
  • 威望339点
  • 贡献值0点
  • 好评度106点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-10-22 09:44
WY.lslrt 女孩?
information取值看irp是成功还是失败。
一般irp完成失败,information为0;
成功的传输数据,设成传输的字节量。如果设成0,会造成资源丢失。
技术交流:aasa2@21cn.com QQ群:10863699
WY.lslrt
驱动牛犊
驱动牛犊
  • 注册日期2004-07-30
  • 最后登录2009-10-27
  • 粉丝0
  • 关注0
  • 积分116分
  • 威望15点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-10-22 12:34
哦。谢谢,不过分我已经给过了,不知道还能不能在给。
不过我很疑问,我怎么会是女孩呢?我的名字很女性化吗?
---传说中的分割线--------
游客

返回顶部