9,506
社区成员
发帖
与我相关
我的任务
分享
//////////////////////////////////////////////////////////////////////////
//DispatchCreate
NTSTATUS FsFilterDispatchCreate(
__in PDEVICE_OBJECT DeviceObject,
__in PIRP Irp
)
{
PHOOK_EXTENSION hookExt;
PEPROCESS pEProcess;
HANDLE ProcessHandle;
NTSTATUS rtStatus;
ULONG uPID;
PFILE_OBJECT pFileObject ;
ULONG CreateDisposition ;
PIO_STACK_LOCATION irpspCurrent ;
PIO_STACK_LOCATION irpspNext ;
ULONG uPathLen ;
UNICODE_STRING uVolumeName;
ANSI_STRING aVolumeName ;
CHAR fullPathName[MAXPATHLEN] ;
LARGE_INTEGER timeout ;
NTSTATUS statusKeven ;
//判断是自己的设备被打开了?
if ( IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject) )
{
Irp->IoStatus.Status = STATUS_SUCCESS ;
Irp->IoStatus.Information = FILE_OPENED;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
//正常的创建操作
irpspCurrent = IoGetCurrentIrpStackLocation(Irp) ;
CreateDisposition = (irpspCurrent->Parameters.Create.Options >> 24) & 0x000000ff ;
if(CreateDisposition==FILE_CREATE ||
CreateDisposition==FILE_OPEN_IF ||
CreateDisposition==FILE_OVERWRITE_IF )
{
return FsFilterDispatchPassThrough(DeviceObject, Irp) ;
}
if ( g_UserPID > 0 && g_bUserEventSet )
{
//获取进程句柄
ProcessHandle = NtCurrentProcess();
rtStatus = ObReferenceObjectByHandle(ProcessHandle, GENERIC_READ, NULL, KernelMode, &pEProcess, NULL);
if( NT_SUCCESS( rtStatus ) )
{
uPID = (ULONG)PsGetProcessId(pEProcess) ;
if ( uPID == g_UserPID )
{
DbgPrint( "本程序打开文件,放行操作" ) ;
return FsFilterDispatchPassThrough(DeviceObject, Irp) ;
}
}
hookExt = DeviceObject->DeviceExtension;
pFileObject = irpspCurrent->FileObject ;
if ( g_bCathFile )
{
return FsFilterDispatchPassThrough(DeviceObject, Irp) ;
}
g_bCathFile = FALSE ;
uPathLen = FilemonGetFullPath( FALSE, pFileObject, hookExt, fullPathName ) ;
if ( uPathLen > 0 )
{
//获取文件后缀名,过滤bmp、txt、jpg、jpeg、png等文件
if ( uPathLen > 4 )
{
if( memcmp( &fullPathName[uPathLen-3], ".txt", 4 ) == 0 )
{
//通知用户发现文本文件,用户检测文本文件,并返回结果
RtlInitEmptyUnicodeString(&uVolumeName,NULL,0);
if(IoVolumeDeviceToDosName(pFileObject->DeviceObject,&uVolumeName)==STATUS_SUCCESS)
{
RtlUnicodeStringToAnsiString(&aVolumeName, &uVolumeName, TRUE) ;
DbgPrint( "捕获到文件打开:%s%s", aVolumeName.Buffer, fullPathName ) ;
g_bCathFile = TRUE ;
memcpy(g_fullPathName, fullPathName, uPathLen ) ;
g_uPathLen = uPathLen ;
RtlFreeAnsiString(&aVolumeName) ;
ExFreePool(uVolumeName.Buffer) ;
DbgPrint( "等待用户响应Begin") ;
timeout.QuadPart = 1000 ;
//等待事件通知
statusKeven = KeWaitForSingleObject( &g_UserEvent, Executive, KernelMode, FALSE, NULL ) ;
if ( statusKeven == STATUS_TIMEOUT )
{
DbgPrint( "等待超时") ;
}
else if ( statusKeven == STATUS_WAIT_0 )
{
DbgPrint( "得到了信号") ; }
g_bCathFile = FALSE ;
DbgPrint( "等待用户响应End") ;
}
}
}
}
}
return FsFilterDispatchPassThrough(DeviceObject, Irp) ;
}
注意红色部分,这里总是显示得到信号没有等待,查了相关资料,应该是跟IRQL中断级别有关,
[quote]The IrqlKeWaitForSingleObject rule specifies that the driver calls the KeWaitForSingleObject routine at the proper IRQL based on the value of the Timeout parameter. Callers of KeWaitForSingleObject routine can be running at IRQL <= DISPATCH_LEVEL. However, if Timeout is NULL or non-zero, the caller must be running at IRQL <= APC_LEVEL.
•If Timeout != NULL and *Timeout = 0, the caller of the KeWaitForSingleObject routine must be running at IRQL = DISPATCH_LEVEL.
•If Timeout = NULL, or *Timeout != 0, the caller of the KeWaitForSingleObject routine must running at IRQL <= APC_LEVEL.
quote]
怎么处理好呢?help!help! ntStatus = IoCreateDevice ( DriverObject,
sizeof(HOOK_EXTENSION),
&deviceNameUnicodeString,
FILE_DEVICE_FILEMON,
0,
TRUE,
&guiDevice );
//
// If successful, make a symbolic link that allows for the device
// object's access from Win32 programs
//
if( NT_SUCCESS(ntStatus) )
{
//
// Create a symbolic link that the GUI can specify to gain access
// to this driver/device
//
RtlInitUnicodeString (&deviceLinkUnicodeString,deviceLinkBuffer ) ;
//使用直接 IO 读写方式
guiDevice->Flags |= DO_DIRECT_IO;
guiDevice->AlignmentRequirement = FILE_WORD_ALIGNMENT;
ntStatus = IoCreateSymbolicLink (&deviceLinkUnicodeString, &deviceNameUnicodeString );
guiDevice->Flags &= ~DO_DEVICE_INITIALIZING;
if( !NT_SUCCESS(ntStatus) )
{
DbgPrint (("FsFilter.SYS: IoCreateSymbolicLink failed\n"));
IoDeleteDevice( guiDevice );
return ntStatus;
}
}
else
{
DbgPrint (("FsFilter.SYS: IoCreateDevice failed\n"));
return ntStatus;
}
客户端在打开设备,代码如下
hDevice = CreateFile( completeDeviceName,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
运行到CreateFile这里系统就挂了,调试dum得到如下信息:
a8215624 a88d16e6 89bc2d70 a8215a5c a88d1865 nt!IopfCallDriver+0x28
WARNING: Stack unwind information not available. Following frames may be wrong.
a8215630 a88d1865 89bc2cb8 8aa10ee0 00000610 FsFilter+0x6e6
a8215a5c 804f01e9 89bc2cb8 8aa10ee0 8aa10ee0 FsFilter+0x865
a8215a6c 80584232 89bc2ca0 89bc4374 a8215c04 nt!IopfCallDriver+0x31
a8215b4c 805c0490 89bc2cb8 00000000 89bc42d0 nt!IopParseDevice+0xa12
a8215bc4 805bca1c 00000000 a8215c04 00000040 nt!ObpLookupObjectName+0x53c
a8215c18 80577051 00000000 00000000 ccfa5401 nt!ObOpenObjectByName+0xea
a8215c94 805779c8 0012f1d8 c0100080 0012f178 nt!IopCreateFile+0x407
a8215cf0 8057a0d2 0012f1d8 c0100080 0012f178 nt!IoCreateFile+0x8e
a8215d30 805426cc 0012f1d8 c0100080 0012f178 nt!NtCreateFile+0x30
a8215d30 7c92e514 0012f1d8 c0100080 0012f178 nt!KiFastCallEntry+0xfc
0012f1d0 00000000 00000000 00000000 00000000 0x7c92e514
怎么会在这里出错呢?