I asked for help before for the same problem. It isn??t resolved yet.
I need to read data after IRP_MJ_CREATE completed successfully so I fire
IRP_MJ_READ.
The following source codes works well in xp, but it crashes in vista and
win7.
I found that if the irp->Flags in function KfcRead is set to
IRP_READ_OPERATION, the crash won??t occur. But the result isn??t what I
want.
Does any one know how the make the IRP_NOCACHE | IRP_PAGING_IO |
IRP_SYNCHRONOUS_PAGING_IO work instead of IRP_READ_OPERATION?
Or any one know why this happened?
********** Minidump *************
DRIVER_OVERRAN_STACK_BUFFER (f7)
A driver has overrun a stack-based buffer. This overrun could potentially
allow a malicious user to gain control of this machine.
DESCRIPTION
A driver overran a stack-based buffer (or local variable) in a way that
would
have overwritten the function’s return address and jumped back to an
arbitrary
address when the function returned. This is the classic “buffer overrun”
hacking attack and the system has been brought down to prevent a malicious
user
from gaining complete control of it.
Do a kb to get a stack backtrace – the last routine on the stack before the
buffer overrun handlers and bugcheck call is the one that overran its local
variable(s).
Arguments:
Arg1: 1f3a6424, Actual security check cookie from the stack
Arg2: 8a854a89, Expected security check cookie
Arg3: 757ab576, Complement of the expected security check cookie
Arg4: 00000000, zero
********** Source *************
NTSTATUS
DriverEntry (
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
…
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
{
DriverObject->MajorFunction[i] = SfPassThrough;
}
DriverObject->MajorFunction[IRP_MJ_CREATE] = SfCreate;
…
}
SfCreate( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
…
Status = SfWaitIrpDone( … )
if (
( NT_SUCCESS( Status ) )
&&
( NULL != IrpSp->FileObject )
&&
( NULL != IrpSp->FileObject->FsContext )
)
{
PUCHAR strBuf = ExAllocatePool( NonPagedPool, 4096 );
LARGE_INTEGER liFileHead;
IO_STATUS_BLOCK IoStatusBlock;
DWORD dwIrpFlags = IRP_NOCACHE | IRP_PAGING_IO |
IRP_SYNCHRONOUS_PAGING_IO;
if ( NULL != strBuf )
{
liFileHead.QuadPart = 0;
KfcRead( DeviceObject, IrpSp->FileObject, &liFileHead, 4096, strBuf,
&IoStatusBlock, dwIrpFlags );
}
…
}
…
}
NTSTATUS SfWaitIrpDoneCompletion (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
PKEVENT pEvent = Context;
if ( Irp->PendingReturned )
{
KeSetEvent( pEvent, IO_NO_INCREMENT, FALSE );
}
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS SfWaitIrpDone(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
KEVENT Event;
NTSTATUS Status;
KeInitializeEvent( &Event, NotificationEvent, FALSE );
IoCopyCurrentIrpStackLocationToNext( Irp );
IoSetCompletionRoutine( Irp, SfWaitIrpDoneCompletion, &Event, TRUE, TRUE,
TRUE );
Status = IoCallDriver( DeviceObject, Irp );
if (STATUS_PENDING == Status)
{
KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL );
}
Status = Irp->IoStatus.Status;
return Status;
}
static VOID KfcRead(PDEVICE_OBJECT v_pDeviceObject,
PFILE_OBJECT v_pFileObject,
PLARGE_INTEGER v_liOffset,
ULONG v_Length,
PUCHAR v_strBuf,
PIO_STATUS_BLOCK v_IoStatusBlock,
IN DWORD v_dwIrpFlags)
{
PIRP irp;
KEVENT event;
PIO_STACK_LOCATION ioStackLocation;
NTSTATUS Status;
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
irp = IoBuildAsynchronousFsdRequest( IRP_MJ_READ, v_pDeviceObject,
v_strBuf, v_Length, v_liOffset, v_IoStatusBlock );
if( NULL==irp )
{
v_IoStatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES;
v_IoStatusBlock->Information = 0;
return;
}
irp->Flags = v_dwIrpFlags;
irp->UserEvent = &event;
ioStackLocation = IoGetNextIrpStackLocation(irp);
ioStackLocation->MajorFunction = IRP_MJ_READ;
ioStackLocation->MinorFunction = 0;
ioStackLocation->DeviceObject = v_pDeviceObject;
ioStackLocation->FileObject = v_pFileObject;
ioStackLocation->Parameters.Read.Length = v_Length;
ioStackLocation->Parameters.Read.ByteOffset = *v_liOffset;
IoSetCompletionRoutine(irp, KfcIoCompletion, 0, TRUE, TRUE, TRUE);
Status = IoCallDriver(v_pDeviceObject, irp);
if(Status == STATUS_PENDING)
{
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, 0);
}
}
static NTSTATUS KfcIoCompletion(PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context)
{
*Irp->UserIosb = Irp->IoStatus;
if (Irp->MdlAddress)
{
PVOID pBuffer = MmGetSystemAddressForMdlSafe( Irp->MdlAddress,
HighPagePriority );
if( NULL!=pBuffer )
{
MmUnmapLockedPages( pBuffer, Irp->MdlAddress );
}
MmUnlockPages(Irp->MdlAddress);
IoFreeMdl(Irp->MdlAddress);
Irp->MdlAddress = NULL;
}
KeSetEvent(Irp->UserEvent, 0, FALSE);
IoFreeIrp( Irp );
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS SfPassThrough (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
IoSkipCurrentIrpStackLocation( Irp );
return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION)
DeviceObject->DeviceExtension)->NLExtHeader.AttachedToDeviceObject, Irp );
}