在驱动中有时候需要进行写文件的操作,通常是调用ZwCreateFile,ZwWriteFile等函数,
但是这些函数往往需要工作在PASSIVE_LEVEL中断级上,而在回调函数中往往是在DISPACH
中断级上,这样进行操作在用windbg单步调试的时候可以通过,但是在直接运行的时
候系统会出现蓝屏,这个时候可以把相应的操作封装成一个函数,调用工作者线程来进行
完成。
首先,为了测试是否是由于读写文件中断级导致的蓝屏可以在代码中加入
KIRQOldIrq;
If(KeGetCurrentIrql()==DISPACH_LEVEL)
KdPrint(“The IRQ is DISPACH_LEVEL and it isnot suitable for file operation”);
事实上可以winddk在提供获得当前中断级的同时也可以修改中断级,分别调用
KeRaiseIrql(DISPACH_LEVEL,&OldIrq); //提升当前的中断级保存现在的中断级到//OldIrq中
KeLowerIrql(OldIrq); //降低当前的中断级
进行显示的提升与下降,但是中断级只能被提升再下降,如果单纯的调用KeLowerIrql
可能会导致失败。
接下来是通过创建工作者线程来进行读写在回调函数中调用:
ReadComplete( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context )
{ //…………………..
PIO_WORKITEMpIoWorkItem;
pIoWorkItem = IoAllocateWorkItem(DeviceObject);
if(pIoWorkItem)
{
IoQueueWorkItem(pIoWorkItem, Print_File,DelayedWorkQueue, &makecode);
}
//………………………..
}
IoQueueWorkItemmsdn说明如下:
IoWorkItem [in]
Pointer to an IO_WORKITEM structure that was allocated by IoAllocateWorkItem or initialized by IoInitializeWorkItem.
WorkerRoutine [in]
Pointer to a WorkItem routine.
QueueType [in]
Specifies a WORK_QUEUE_TYPE value that stipulates the type of system worker thread tohandle the work item. Drivers must specify DelayedWorkQueue.
Context [in, optional]
Specifies driver-specific information forthe work item. The system passes this value as the Context parameter to WorkItem.
即第二个参数可以用函数,最后一个参数表示传给函数的参数,实际上在本例中Print_File
函数如下:
void __stdcall Print_File(PDEVICE_OBJECTDeviceObject,PVOID Context)
{ PUSHORT PBuffer= (PUSHORT)Context;
OBJECT_ATTRIBUTESobjectAttributes;
IO_STATUS_BLOCKiostatus;
NTSTATUSntStatus;
HANDLE hfile;
UNICODE_STRINGlogFileUnicodeString;
if(KeGetCurrentIrql()!=PASSIVE_LEVEL) //判断中断级
KdPrint(("thelevel is not passive_level\n"));
RtlInitUnicodeString(&logFileUnicodeString,L"\\??\\C:\\abc.txt");
InitializeObjectAttributes(&objectAttributes,
&logFileUnicodeString,
OBJ_CASE_INSENSITIVE,
NULL,NULL);
ntStatus=ZwCreateFile(&hfile,FILE_APPEND_DATA,&objectAttributes,&iostatus,NULL, FILE_ATTRIBUTE_NORMAL, //创建文件
FILE_SHARE_WRITE,
FILE_OPEN_IF,
FILE_NON_DIRECTORY_FILE|FILE_RANDOM_ACCESS|FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
ZwWriteFile(hfile,NULL,NULL,NULL,&iostatus,pBuffer,2,NULL,NULL);
//写文件
ZwClose(hfile);
}