阅读:4823回复:6
关于IoQueueWorkItem的问题,我真的很努力了!
大虾们帮帮我呀,在REGMON中,把我把以前过期的IExInitializeWorkItem、ExQueueWorkItem两个函数用oAllocateWorkItem、IoQueueWorkItem、IoFreeWorkItem替换了,可是怎么也不能把缓存的内容写到日志文件。我在网上搜了两天没什么结果。
我不知道为什么不直接高调用函数而要把他加入到工作项列队中来等待系统工作线程调用。到底那些情况下不能直接调用函数,要像类似IoQueueWorkItem经处理来调用? 大虾们能不能给我祥细讲讲这方面的东西,或者那有这方面的文章。 |
|
沙发#
发布于:2008-08-22 14:53
贴点代码上来,帮你分析一下啊
|
|
板凳#
发布于: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; } } |
|
地板#
发布于: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; } } |
|
地下室#
发布于:2008-08-22 15:27
真的很感谢你,有这股热心帮助我们这些初学者,谢谢,祝好运!
|
|
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; } |
|
6楼#
发布于:2008-08-22 17:10
1)IoFreeWorkItem函数不能在调用IoQueueWorkItem后立即使用,一般在WorkItem Routine中释放。
2)LoggingEvent没有被初始化 |
|