lovehunterboy
驱动小牛
驱动小牛
  • 注册日期2008-05-29
  • 最后登录2010-04-16
  • 粉丝2
  • 关注0
  • 积分67分
  • 威望463点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:4823回复:6

关于IoQueueWorkItem的问题,我真的很努力了!

楼主#
更多 发布于:2008-08-22 13:26
大虾们帮帮我呀,在REGMON中,把我把以前过期的IExInitializeWorkItem、ExQueueWorkItem两个函数用oAllocateWorkItem、IoQueueWorkItem、IoFreeWorkItem替换了,可是怎么也不能把缓存的内容写到日志文件。我在网上搜了两天没什么结果。
我不知道为什么不直接高调用函数而要把他加入到工作项列队中来等待系统工作线程调用。到底那些情况下不能直接调用函数,要像类似IoQueueWorkItem经处理来调用?
大虾们能不能给我祥细讲讲这方面的东西,或者那有这方面的文章。
yuanyuan
驱动大牛
驱动大牛
  • 注册日期2003-01-15
  • 最后登录2010-08-04
  • 粉丝0
  • 关注0
  • 积分1025分
  • 威望300点
  • 贡献值0点
  • 好评度232点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2008-08-22 14:53
贴点代码上来,帮你分析一下啊
lovehunterboy
驱动小牛
驱动小牛
  • 注册日期2008-05-29
  • 最后登录2010-04-16
  • 粉丝2
  • 关注0
  • 积分67分
  • 威望463点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2008-08-22 15:15
就是在本网站下载的regmon,只是有两个函数过期了,我把他换了,好像就不行了!
原来的是这样:
void RegmonNewStore( void )
{
    PSTORE_BUF prev = Store, newstore;
    WORK_QUEUE_ITEM  workItem;

    //
    // If we're boot logging, write the current store out to disk
    //
    if( BootLogging ) {

        ExInitializeWorkItem( &workItem, RegmonWriteBootLog, Store );//这个DDK说过期了
        ExQueueWorkItem( &workItem, CriticalWorkQueue );//这个也是
        KeWaitForSingleObject( &LoggingEvent, Executive, KernelMode, FALSE, NULL );
    }

    //
    // If we have maxed out or haven't accessed the current store
    // just return
    //
    if( MaxStore == NumStore ) {
        Store->Len = 0;
        return;
    }

    //
    // See if we can re-use a store
    //
    if( !Store->Len ) {

        return;
    }

    //
    // Move to the next buffer and allocate another one
    //
    newstore = ExAllocatePool( PagedPool, sizeof(*Store) );
    if( newstore ) {

        Store   = newstore;
        Store->Len  = 0;
        Store->Next = prev;
        NumStore++;

    } else {

        Store->Len = 0;

    }
}
lovehunterboy
驱动小牛
驱动小牛
  • 注册日期2008-05-29
  • 最后登录2010-04-16
  • 粉丝2
  • 关注0
  • 积分67分
  • 威望463点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2008-08-22 15:23
我改过以后,另外因为改的子函数需要传递一个PDEVICE_OBJECT,我定义了个全局的变量WORKITEM_DeviceObject,在RegmonDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )里调用这个函数时,把DeviceObject赋给WORKITEM_DeviceObject
void RegmonNewStore( void )//先把store写到文件,在判断是否到最大、或是否为空,然后分配一个新的空间,把新的换在前面
{
    PSTORE_BUF prev = Store, newstore;
    PIO_WORKITEM  workItem;

    //
    // If we're boot logging, write the current store out to disk。已经启动,写当前的store
    //
    if( BootLogging ) {

        workItem = IoAllocateWorkItem( WORKITEM_DeviceObject);//函数过期已改,DeviceObject还不知道在那定义好呢?????????
        IoQueueWorkItem( workItem, (PIO_WORKITEM_ROUTINE)RegmonWriteBootLog, DelayedWorkQueue, Store );//函数过期已改        
        IoFreeWorkItem( workItem );//函数已过期等我已修改***********************
        KeWaitForSingleObject( &LoggingEvent, Executive, KernelMode, FALSE, NULL );//等RegmonWriteBootLog发来信号,目的是为了保证写到日志文件后或日志文件关闭后才更新
    }

    //
    // If we have maxed out or haven't accessed the current store
    // just return
    //
    if( MaxStore == NumStore ) {//是否达到最大
        Store->Len = 0;
        return;
    }

    //
    // See if we can re-use a store
    //
    if( !Store->Len ) {//len等于0返回

        return;
    }

    //
    // Move to the next buffer and allocate another one
    //
    newstore = ExAllocatePool( PagedPool, sizeof(*Store) );
    if( newstore ) {

        Store   = newstore;
        Store->Len  = 0;
        Store->Next = prev;
        NumStore++;

    } else {

        Store->Len = 0;

    }
}
lovehunterboy
驱动小牛
驱动小牛
  • 注册日期2008-05-29
  • 最后登录2010-04-16
  • 粉丝2
  • 关注0
  • 积分67分
  • 威望463点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2008-08-22 15:27
真的很感谢你,有这股热心帮助我们这些初学者,谢谢,祝好运!
lovehunterboy
驱动小牛
驱动小牛
  • 注册日期2008-05-29
  • 最后登录2010-04-16
  • 粉丝2
  • 关注0
  • 积分67分
  • 威望463点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2008-08-22 16:15
为什么同样在这个函数里面,IRP_MJ_CREATE里不是在系统进程而 IRP_MJ_SHUTDOWN是呢????????????????、
NTSTATUS RegmonDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
    PIO_STACK_LOCATION      irpStack;
    PVOID                   inputBuffer;
    PVOID                   outputBuffer;
    ULONG                   inputBufferLength;
    ULONG                   outputBufferLength;
    ULONG                   ioControlCode;
    PSTORE_BUF              old;
    PIO_WORKITEM            workItem;

    //为了替换过期的函数增加的
    workitem_DeviceObject=DeviceObject;

    //
    // Go ahead and set the request up as successful
    //
    Irp->IoStatus.Status      = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    //
    // Get a pointer to the current location in the Irp. This is where
    //     the function codes and parameters are located.
    //
    irpStack = IoGetCurrentIrpStackLocation (Irp);

    //
    // Get the pointer to the input/output buffer and its length
    //
    inputBuffer             = Irp->AssociatedIrp.SystemBuffer;
    inputBufferLength       = irpStack->Parameters.DeviceIoControl.InputBufferLength;
    outputBuffer            = Irp->AssociatedIrp.SystemBuffer;
    outputBufferLength      = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
    ioControlCode           = irpStack->Parameters.DeviceIoControl.IoControlCode;

    switch (irpStack->MajorFunction) {
    case IRP_MJ_CREATE:

        DbgPrint(("Regmon: IRP_MJ_CREATE\n"));

        //
        // Turn off boot logging
        //
        if( BootLogging ) {//bootlogging初始为false

            BootLogging = FALSE;
            IoUnregisterShutdownNotification( DeviceObject );
            
            MUTEX_WAIT( StoreMutex );
            
            workItem = IoAllocateWorkItem( DeviceObject );//函数已过期等我已修改*********************************
            IoQueueWorkItem( workItem, (PIO_WORKITEM_ROUTINE)RegmonCloseBootLog, DelayedWorkQueue ,0 );//函数已过期等我已修改***********************
            IoFreeWorkItem( workItem );//函数已过期等我已修改***********************
            KeWaitForSingleObject( &LoggingEvent, Executive, KernelMode, FALSE, NULL );//等信号,目的是为了保证写到日志文件后或日志文件关闭后才更新

            MUTEX_RELEASE( StoreMutex );
        }

        Sequence = 0;
        GUIActive = TRUE;
        DbgPrint((" GUI Active: %d\n", GUIActive ));
        break;

    case IRP_MJ_SHUTDOWN:
        
        //
        // Dump all accumulated buffers. We are in the system process so
        // there's no need to queue a worker thread item
        //
        while( old = RegmonOldestStore()) {

            RegmonWriteBootLog( old );//为什么在这里调用就是在系统进程内,而在IRP_MJ_CREATE里就不是在系统进程内??????????????????????
            if( old == Store ) break;
        }
        break;

    case IRP_MJ_CLOSE:

        DbgPrint(("Regmon: IRP_MJ_CLOSE\n"));
        GUIActive = FALSE;
        DbgPrint((" GUI closing: %d\n", GUIActive ));
        RegmonResetStore();
        break;

    case IRP_MJ_DEVICE_CONTROL:

        DbgPrint (("Regmon: IRP_MJ_DEVICE_CONTROL\n"));

           //
        // See if the output buffer is really a user buffer that we
        // can just dump data into.
        //
        if( IOCTL_TRANSFER_TYPE(ioControlCode) == METHOD_NEITHER ) { //    值为3,直接向驱动程序提供用户缓冲区

            outputBuffer = Irp->UserBuffer;
        }

        //
        // Its a request from the GUI
        //
        RegmonDeviceControl( irpStack->FileObject, TRUE,
                             inputBuffer, inputBufferLength,
                             outputBuffer, outputBufferLength,
                             ioControlCode, &Irp->IoStatus, DeviceObject );
        break;
    }
    workitem_DeviceObject=NULL;
    IoCompleteRequest( Irp, IO_NO_INCREMENT );
    return STATUS_SUCCESS;  
}
yuanyuan
驱动大牛
驱动大牛
  • 注册日期2003-01-15
  • 最后登录2010-08-04
  • 粉丝0
  • 关注0
  • 积分1025分
  • 威望300点
  • 贡献值0点
  • 好评度232点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2008-08-22 17:10
1)IoFreeWorkItem函数不能在调用IoQueueWorkItem后立即使用,一般在WorkItem Routine中释放。

2)LoggingEvent没有被初始化
游客

返回顶部