|
阅读:2307回复:8
请tooflat版主进来看看
我参考了你的流加密代码sfilter,写了如下东西,结果运行蓝屏,请指教
NTSTATUS
SfCreate (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This function filters create/open operations. It simply establishes an
I/O completion routine to be invoked if the operation was successful.
Arguments:
DeviceObject - Pointer to the target device object of the create/open.
Irp - Pointer to the I/O Request Packet that represents the operation.
Return Value:
The function value is the status of the call to the file system's entry
point.
--*/
{
NTSTATUS status;
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = IrpSp->FileObject;
PAGED_CODE();
//
// If this is for our control device object, don't allow it to be opened.
//
if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) {
//
// Sfilter doesn't allow for any communication through its control
// device object, therefore it fails all requests to open a handle
// to its control device object.
//
// See the FileSpy sample for an example of how to allow creates to
// the filter's control device object and manage communication via
// that handle.
//
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Information = 0;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return STATUS_INVALID_DEVICE_REQUEST;
}
ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));
//
// If debugging is enabled, do the processing required to see the packet
// upon its completion. Otherwise, let the request go with no further
// processing.
//
if (!FlagOn( SfDebug, SFDEBUG_DO_CREATE_COMPLETION |
SFDEBUG_GET_CREATE_NAMES|
SFDEBUG_DISPLAY_CREATE_NAMES )) {
//
// Don't put us on the stack then call the next driver
//
IoSkipCurrentIrpStackLocation( Irp );
return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp );
} else {
KEVENT waitEvent;
//
// Initialize an event to wait for the completion routine to occur
//
KeInitializeEvent( &waitEvent, NotificationEvent, FALSE );
//
// Copy the stack and set our Completion routine
//
IoCopyCurrentIrpStackLocationToNext( Irp );
IoSetCompletionRoutine(
Irp,
SfCreateCompletion,
&waitEvent,
TRUE,
TRUE,
TRUE );
//
// Call the next driver in the stack.
//
status = IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp );
//
// Wait for the completion routine to be called
//
if (STATUS_PENDING == status) {
NTSTATUS localStatus = KeWaitForSingleObject(&waitEvent, Executive, KernelMode, FALSE, NULL);
ASSERT(STATUS_SUCCESS == localStatus);
}
//
// Verify the IoCompleteRequest was called
//
ASSERT(KeReadStateEvent(&waitEvent) ||
!NT_SUCCESS(Irp->IoStatus.Status));
//
// Retrieve and display the filename if requested
//
if (FlagOn(SfDebug,
(SFDEBUG_GET_CREATE_NAMES|SFDEBUG_DISPLAY_CREATE_NAMES))) {
SfDisplayCreateFileName( Irp );
}
//
// Save the status and continue processing the IRP
//
status = Irp->IoStatus.Status;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
{
POST_CREATE_WORKER_CONTEXT WorkerCtx;
PFILE_CONTEXT FileCtxPtr = NULL;
FileCtxPtr = ExAllocatePoolWithTag( NonPagedPool,
sizeof( FILE_CONTEXT ),
SFLT_POOL_TAG );
if(FileCtxPtr==NULL)
return status;
FileCtxPtr->RefCount = 1;
KeInitializeEvent(&FileCtxPtr->Event, SynchronizationEvent, TRUE);
ExInitializeWorkItem(&WorkerCtx.WorkItem, SfIsEncryptFlagExist, &WorkerCtx);
WorkerCtx.DeviceObject = DeviceObject;
WorkerCtx.FileObject = FileObject;
KeInitializeEvent(&WorkerCtx.Event, NotificationEvent, FALSE);
WorkerCtx.FileContext = FileCtxPtr;
//WorkerCtx.NewElement = NewElement;
if (KeGetCurrentIrql() == PASSIVE_LEVEL)
SfIsEncryptFlagExist(&WorkerCtx);
else
{
ExQueueWorkItem(&WorkerCtx.WorkItem, DelayedWorkQueue);
KeWaitForSingleObject(&WorkerCtx.Event, Executive, KernelMode, FALSE, NULL);
}
ExFreePool(FileCtxPtr);
}
return status;
}
}
NTSTATUS
SfIsEncryptFlagExist(IN PVOID Context)
{
PPOST_CREATE_WORKER_CONTEXT WorkerCtx = Context;
NTSTATUS Status;
IO_STATUS_BLOCK IoStatus={0};
UCHAR Buff[512]={0};
//PACKAGERINFO packagerinfo; //包信息
int nPackagerLen;
WCHAR EncryptFlagFile[MAX_PATH*2] = {L'\0'};
LARGE_INTEGER ByteOffset;
PFILE_CONTEXT FileCtxPtr = WorkerCtx->FileContext;
KeWaitForSingleObject(&FileCtxPtr->Event, Executive, KernelMode, FALSE, NULL);
wcscpy(EncryptFlagFile,L"\\??\\");
//wcscat(EncryptFlagFile,WorkerCtx->FileContext->Name);
//if(wcscmp(WorkerCtx->FileContext->Name,L"c:\\test\\test.txt")==0)
{
nPackagerLen=0;
}
//if(wcscmp(WorkerCtx->FileContext->Name,L"C:\\test\\test.txt")==0)
{
nPackagerLen=0;
}
ByteOffset.QuadPart=0;
IoStatus.Status = STATUS_SUCCESS;
IoStatus.Information = 0;
Status =SfIssueReadWriteIrpSynchronously(WorkerCtx->DeviceObject
,WorkerCtx->FileObject,IRP_MJ_READ,&IoStatus,Buff,
sizeof(Buff),&ByteOffset,0);
if (!NT_SUCCESS(Status))
{
if (STATUS_END_OF_FILE == Status)
{
WorkerCtx->FileContext->EncryptFlagExist=FALSE;
Status = STATUS_SUCCESS;
}
KeSetEvent(&FileCtxPtr->Event, IO_NO_INCREMENT, FALSE);
KeSetEvent(&WorkerCtx->Event, IO_NO_INCREMENT, FALSE);
return Status;
}
// memcpy(&packagerinfo,Buff,sizeof(PACKAGERINFO));
// if(memcmp(packagerinfo.btflags,"ftsafe",6)==0)
// {
// WorkerCtx->FileContext->EncryptFlagExist=TRUE;
// memcpy(WorkerCtx->FileContext->Key,"123456",6);//解密密钥
// WorkerCtx->FileContext->Key[6]=0;
// }
// else
// WorkerCtx->FileContext->EncryptFlagExist=FALSE;
KeSetEvent(&FileCtxPtr->Event, IO_NO_INCREMENT, FALSE);
KeSetEvent(&WorkerCtx->Event, IO_NO_INCREMENT, FALSE);
return Status;
}
NTSTATUS
SfIssueReadWriteIrpSynchronously(
IN PDEVICE_OBJECT DeviceObject,
IN PFILE_OBJECT FileObject,
IN ULONG MajorFunction,
IN PIO_STATUS_BLOCK IoStatus,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset,
IN ULONG IrpFlags
)
{
PIRP Irp = NULL;
PIO_STACK_LOCATION IrpSp = NULL;
KEVENT Event;
NTSTATUS Status;
ASSERT((MajorFunction == IRP_MJ_READ) || (MajorFunction == IRP_MJ_WRITE));
KeInitializeEvent(&Event, NotificationEvent, FALSE);
Irp = IoBuildSynchronousFsdRequest(
MajorFunction,
DeviceObject,
Buffer,
Length,
ByteOffset,
&Event,
IoStatus
);
if (!Irp)
return STATUS_INSUFFICIENT_RESOURCES;
Irp->Flags |= IrpFlags;
IrpSp = IoGetNextIrpStackLocation(Irp);
IrpSp->FileObject = FileObject;
Status = IoCallDriver(DeviceObject, Irp);
if (STATUS_PENDING == Status)
{
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
}
return IoStatus->Status;
}蓝屏信息如下:BugCheck 7E, {c0000005, 804f9810, f9e7aad8, f9e7a7d8}ANALYSIS: Kernel with unknown size. Will force reload symbols with known size. ANALYSIS: Force reload command: .reload /f ntoskrnl.exe=FFFFFFFF804D5000,1F2700,3D6DE35C ***** Kernel symbols are WRONG. Please fix symbols to do analysis. Probably caused by : ntoskrnl.exe ( nt!ExFreeToPagedLookasideList+9d ) Followup: MachineOwner --------- nt!DbgBreakPointWithStatus+0x4: 805113fa cc int 3 kd> !analyze -v ******************************************************************************* * * * Bugcheck Analysis * * * ******************************************************************************* SYSTEM_THREAD_EXCEPTION_NOT_HANDLED (7e) This is a very common bugcheck. Usually the exception address pinpoints the driver/function that caused the problem. Always note this address as well as the link date of the driver/image that contains this address. Arguments: Arg1: c0000005, The exception code that was not handled Arg2: 804f9810, The address that the exception occurred at Arg3: f9e7aad8, Exception Record Address Arg4: f9e7a7d8, Context Record Address Debugging Details: ------------------ ***** Kernel symbols are WRONG. Please fix symbols to do analysis. MODULE_NAME: nt FAULTING_MODULE: 804d5000 nt DEBUG_FLR_IMAGE_TIMESTAMP: 3d6de35c EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - "0x%08lx" FAULTING_IP: nt!ExFreeToPagedLookasideList+9d 804f9810 8b4024 mov eax,dword ptr [eax+24h] EXCEPTION_RECORD: f9e7aad8 -- (.exr 0xfffffffff9e7aad8) ExceptionAddress: 804f9810 (nt!ExFreeToPagedLookasideList+0x0000009d) ExceptionCode: c0000005 (Access violation) ExceptionFlags: 00000000 NumberParameters: 2 Parameter[0]: 00000000 Parameter[1]: 00000124 Attempt to read from address 00000124 CONTEXT: f9e7a7d8 -- (.cxr 0xfffffffff9e7a7d8) eax=00000100 ebx=806ca190 ecx=00000000 edx=00000000 esi=f7bb0c20 edi=806ca158 eip=804f9810 esp=f9e7aba0 ebp=f9e7acf0 iopl=0 nv up ei pl zr na pe nc cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010246 nt!ExFreeToPagedLookasideList+0x9d: 804f9810 8b4024 mov eax,dword ptr [eax+24h] ds:0023:00000124=???????? Resetting default scope DEFAULT_BUCKET_ID: WRONG_SYMBOLS BUGCHECK_STR: 0x7E LAST_CONTROL_TRANSFER: from 80581d00 to 804f9810 STACK_TEXT: WARNING: Stack unwind information not available. Following frames may be wrong. f9e7acf0 80581d00 f7bb0c20 00000000 00000000 nt!ExFreeToPagedLookasideList+0x9d f9e7ad34 804ef99d 81bbc298 8054fda0 81bbeda8 nt!FsRtlAcquireFileExclusive+0xd f9e7ad74 804ee629 81bbc298 00000000 81bbeda8 nt!KeReadStateEvent+0xa5 f9e7adac 8057d73a 81bbc298 00000000 00000000 nt!KeInsertQueue+0xfc f9e7addc 805134c1 804ee556 00000000 00000000 nt!CcUnpinDataForThread+0x66d 00000000 00000000 00000000 00000000 00000000 nt!KeProfileInterruptWithSource+0x28e FOLLOWUP_IP: nt!ExFreeToPagedLookasideList+9d 804f9810 8b4024 mov eax,dword ptr [eax+24h] SYMBOL_STACK_INDEX: 0 FOLLOWUP_NAME: MachineOwner IMAGE_NAME: ntoskrnl.exe SYMBOL_NAME: nt!ExFreeToPagedLookasideList+9d STACK_COMMAND: .cxr 0xfffffffff9e7a7d8 ; kb BUCKET_ID: WRONG_SYMBOLS Followup: MachineOwner --------- 这啥原因呀,难道下发自己的IRP有问题,屏蔽下发IRP后就没问题了。。。 |
|
|
沙发#
发布于:2007-07-10 09:43
自己顶一个
|
|
|
板凳#
发布于:2007-07-10 13:18
你是在IoCompleteRequest( Irp, IO_NO_INCREMENT );
后进行处理的,这时候可能这个FileObject已经不存在了,这是问题一。 另外如果这个FileObject是从栈上分配,用缓冲IO去读文件,会导致cache mgr对这个文件进行缓冲处理。当这个FileObject从栈上释放掉,cache mgr再操作备份的FileObject时,就会蓝屏,这是问题二。 |
|
|
地板#
发布于:2007-07-10 13:44
感谢tooflat回答,但我看你的代码也是在完成例程后对file_object对象进行操作的,下面代码为你的
Status = SfForwardIrpSyncronously(DevExt->AttachedToDeviceObject, Irp);//这里完成例程
if (NT_SUCCESS(Status) && (STATUS_REPARSE != Status))
{
FILE_CONTEXT FileCtx;
PFILE_CONTEXT FileCtxPtr = NULL;
BOOLEAN NewElement = FALSE;
FileCtx.FsContext = FileObject->FsContext;
ExAcquireFastMutex(&DevExt->FsCtxTableMutex);
FileCtxPtr = RtlLookupElementGenericTable(&DevExt->FsCtxTable, &FileCtx);
if (FileCtxPtr)
++FileCtxPtr->RefCount;
else
{
FileCtxPtr = RtlInsertElementGenericTable(
&DevExt->FsCtxTable,
&FileCtx,
sizeof(FILE_CONTEXT),
&NewElement
);
FileCtxPtr->RefCount = 1;
ASSERT(FileName);
wcscpy(FileCtxPtr->Name, FileName);
KeInitializeEvent(&FileCtxPtr->Event, SynchronizationEvent, TRUE);
}
ExReleaseFastMutex(&DevExt->FsCtxTableMutex);
ExInitializeWorkItem(&WorkerCtx.WorkItem, SfPostCreateWorker, &WorkerCtx);
WorkerCtx.DeviceObject = DeviceObject;
WorkerCtx.FileObject = FileObject;
KeInitializeEvent(&WorkerCtx.Event, NotificationEvent, FALSE);
WorkerCtx.FileContext = FileCtxPtr;
WorkerCtx.NewElement = NewElement;
if (KeGetCurrentIrql() == PASSIVE_LEVEL)
SfPostCreateWorker(&WorkerCtx);
else
{
ExQueueWorkItem(&WorkerCtx.WorkItem, DelayedWorkQueue);
KeWaitForSingleObject(&WorkerCtx.Event, Executive, KernelMode, FALSE, NULL);
}我的与你的好像没有区别呀! |
|
|
地下室#
发布于:2007-07-10 14:56
看看IoCompleteRequest是在什么调用的
|
|
|
5楼#
发布于:2007-07-10 16:38
我改了还是不行
NTSTATUS
SfCreate (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This function filters create/open operations. It simply establishes an
I/O completion routine to be invoked if the operation was successful.
Arguments:
DeviceObject - Pointer to the target device object of the create/open.
Irp - Pointer to the I/O Request Packet that represents the operation.
Return Value:
The function value is the status of the call to the file system's entry
point.
--*/
{
NTSTATUS status;
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = IrpSp->FileObject;
PAGED_CODE();
//
// If this is for our control device object, don't allow it to be opened.
//
if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) {
//
// Sfilter doesn't allow for any communication through its control
// device object, therefore it fails all requests to open a handle
// to its control device object.
//
// See the FileSpy sample for an example of how to allow creates to
// the filter's control device object and manage communication via
// that handle.
//
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Information = 0;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return STATUS_INVALID_DEVICE_REQUEST;
}
ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));
//
// If debugging is enabled, do the processing required to see the packet
// upon its completion. Otherwise, let the request go with no further
// processing.
//
if (!FlagOn( SfDebug, SFDEBUG_DO_CREATE_COMPLETION |
SFDEBUG_GET_CREATE_NAMES|
SFDEBUG_DISPLAY_CREATE_NAMES )) {
//
// Don't put us on the stack then call the next driver
//
IoSkipCurrentIrpStackLocation( Irp );
return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp );
} else {
KEVENT waitEvent;
//
// Initialize an event to wait for the completion routine to occur
//
KeInitializeEvent( &waitEvent, NotificationEvent, FALSE );
//
// Copy the stack and set our Completion routine
//
IoCopyCurrentIrpStackLocationToNext( Irp );
IoSetCompletionRoutine(
Irp,
SfCreateCompletion,
&waitEvent,
TRUE,
TRUE,
TRUE );
//
// Call the next driver in the stack.
//
status = IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp );
//
// Wait for the completion routine to be called
//
if (STATUS_PENDING == status) {
NTSTATUS localStatus = KeWaitForSingleObject(&waitEvent, Executive, KernelMode, FALSE, NULL);
ASSERT(STATUS_SUCCESS == localStatus);
}
//
// Verify the IoCompleteRequest was called
//
ASSERT(KeReadStateEvent(&waitEvent) ||
!NT_SUCCESS(Irp->IoStatus.Status));
//
// Retrieve and display the filename if requested
//
if (FlagOn(SfDebug,
(SFDEBUG_GET_CREATE_NAMES|SFDEBUG_DISPLAY_CREATE_NAMES))) {
SfDisplayCreateFileName( Irp );
}
//
// Save the status and continue processing the IRP
//
///*****添加by lrf
do{
POST_CREATE_WORKER_CONTEXT WorkerCtx;
PFILE_CONTEXT FileCtxPtr = NULL;
if (IrpSp->Parameters.Create.Options & FILE_DIRECTORY_FILE)
{
//
// We don't care about directories
//
//ExFreeToPagedLookasideList(&gFileNameLookAsideList, FileName);
break;
}
FileCtxPtr = ExAllocatePoolWithTag( NonPagedPool,
sizeof( FILE_CONTEXT ),
SFLT_POOL_TAG );
if(FileCtxPtr==NULL)
break;
FileCtxPtr->RefCount = 1;
KeInitializeEvent(&FileCtxPtr->Event, SynchronizationEvent, TRUE);
ExInitializeWorkItem(&WorkerCtx.WorkItem, SfIsEncryptFlagExist, &WorkerCtx);
WorkerCtx.DeviceObject = DeviceObject;
WorkerCtx.FileObject = FileObject;
KeInitializeEvent(&WorkerCtx.Event, NotificationEvent, FALSE);
WorkerCtx.FileContext = FileCtxPtr;
//WorkerCtx.NewElement = NewElement;
if (KeGetCurrentIrql() == PASSIVE_LEVEL)
SfIsEncryptFlagExist(&WorkerCtx);
else
{
ExQueueWorkItem(&WorkerCtx.WorkItem, DelayedWorkQueue);
KeWaitForSingleObject(&WorkerCtx.Event, Executive, KernelMode, FALSE, NULL);
}
ExFreePool(FileCtxPtr);
}while (FALSE);
status = Irp->IoStatus.Status;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return status;
}
}tooflat大侠,帮忙呀 |
|
|
6楼#
发布于:2007-07-10 17:09
不清楚什么原因,有可能就是我上面说的问题二,改成用内存映射方式读试试。
另外你的调试符号有问题。 |
|
|
7楼#
发布于:2007-07-10 22:32
内存映射方式?如何实现亚,还请tooflat再度出手指点
|
|
|
8楼#
发布于:2007-07-12 09:44
期待
|
|