Hi,
I am trying to develop a layered file system.
Concept here is to compress the data in all write operations and decompress
in read operations.
for that i created a device object for each volume and with a unique name. I
am reparsing all file open operations to that deviec object.
Every thing works fine till here. For each file object i am trying to create
a shadow file ojbect with which i will talk to low level file system. Main
Idea is that i wanted to maintain my on cache for files. As a test i created
a new file object copied the contents of existing file object to shadow file
object and send the open request to lowlevel file system using IoCallDriver.
When i checked the return status of the operation it returns status success.
But when i call IoCancelFileOpen it is failing (Blue Screeen Error):.
INVALID_CANCEL_OF_FILE_OPEN
The fileobject passed to IoCancelFileOpen is invalid. It should have
reference of 1. The driver
that called IoCancelFileOpen is at fault.
Here is the code:
/*/////////////////////////////////////////////////////////////////////////////////
MyPreCreateOperation
Arguments:
[in] devExt: Device extension of device to which irp was send
[in] Irp : IRP that was send to shadow device.
Description: This function handles create irps send to shadow device
objects.
//////////////////////////////////////////////////////////////////////////////////*/
NTSTATUS MyPreCreateOperation(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
PMY_FILE_OBJECT MyFileObject;
PMY_SHADOW_DEVICE_EXTENSION devExt;
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
PIO_STACK_LOCATION irpSpNext = IoGetNextIrpStackLocation(Irp);
NTSTATUS ntStatus = STATUS_SUCCESS;
PFILE_OBJECT FileObject = irpSp->FileObject;
PFILE_OBJECT NewFileObject;
ULONG Disposition = irpSp->Parameters.Create.Options >> 24;
ULONG Options = irpSp->Parameters.Create.Options & 0XFFFFFF;
PTLS pTls = MyGetTls();
KEVENT WaitEvent;
CompCreateFuncEntry();
devExt = DeviceObject->DeviceExtension;
// Create a My File object
MyFileObject =
(PMY_FILE_OBJECT)ExAllocateFromNPagedLookasideList(&g_DriverInfo.FileObjectLAL);
if(!MyFileObject)
{
CompCreateError(“My File Object Creation
Failed”,STATUS_INSUFFICIENT_RESOURCES);
return MyFailIrp(Irp,STATUS_INSUFFICIENT_RESOURCES);
}
// Initialize our file object
MyFileObject->MagicNumber = My_FILE_OBJECT_MAGIC_NUMBER;
MyFileObject->FileObject= FileObject;
MyFileObject->OpenById = BooleanFlagOn(Options, FILE_OPEN_BY_FILE_ID);
if(!FileObject->RelatedFileObject)
{
// This is a non relative open
PDEVICE_OBJECT TargetDevice;
ntStatus = STATUS_SUCCESS;
// Setup target device object;
if(devExt->MediaDeviceObject)
TargetDevice = devExt->MediaDeviceObject;
else
TargetDevice = devExt->LowerDeviceObject;
__try
{
// Create a new file object using target device
CompCreateInfo((“Non Relative Open Request - %p”,TargetDevice));
NewFileObject = IoCreateStreamFileObjectEx(NULL,TargetDevice,
&MyFileObject->ContainingFileHandle);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// If object is not created the above function raise an exception
ntStatus = GetExceptionCode();
NewFileObject = NULL;
}
}
else
{
// This is a relative file open case. So create a file object from
// corresponding file object.
PMY_FILE_OBJECT RelMyFileObject;
RelMyFileObject =
(PMY_FILE_OBJECT)FileObject->RelatedFileObject->FsContext2;
__try
{
// Create a new file object using relative file object
// If relative file object is specified then targed
// device is ignored
CompCreateInfo((“Relative Open Request - %p\r\n”,RelMyFileObject));
NewFileObject =
IoCreateStreamFileObjectEx(RelMyFileObject->ContainingFileObject,NULL,
&MyFileObject->ContainingFileHandle);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// If object is not created the above function raise an exception
ntStatus = GetExceptionCode();
NewFileObject = NULL;
}
// Need to store related containing file object
if(NT_SUCCESS(ntStatus) && NewFileObject)
NewFileObject->RelatedFileObject = RelMyFileObject->ContainingFileObject;
}
if(!NT_SUCCESS(ntStatus))
{
// We failed to create a file object so fail the
// open request
// But first tear down the My file object
MyFileObject->FileObject->FsContext = NULL;
MyFileObject->FileObject->FsContext2 = NULL;
MyTearDownFO(MyFileObject);
// Fail the irp
CompCreateError(“Stream Object Creation Failed”,ntStatus);
return MyFailIrp(Irp,ntStatus);
}
ntStatus = MyCopyFileObjectContents(devExt,FileObject,NewFileObject);
if(!NT_SUCCESS(ntStatus))
{
// We failed to create a file object so fail the
// open request
// But first tear down the My file object
MyFileObject->FileObject->FsContext = NULL;
MyFileObject->FileObject->FsContext2 = NULL;
MyTearDownFO(MyFileObject);
// Fail the irp
CompCreateError(“MyCopyFileObjectContents failed”,ntStatus);
return MyFailIrp(Irp,ntStatus);
}
MyFileObject->ContainingFileObject = NewFileObject;
// Set up the Irp for passing down.
CompCreateInfo((“IoCopyCurrentIrpStackLocationToNext”));
IoCopyCurrentIrpStackLocationToNext(Irp);
irpSpNext->FileObject = NewFileObject;
irpSpNext->DeviceObject = devExt->LowerDeviceObject;
// The FSD may use TopLevelIrp, so get out of the way
MyRelinquishTls(pTls);
CompCreateInfo((“KeInitializeEvent”));
// Initialize event on which we wait for create completion
KeInitializeEvent(&WaitEvent, NotificationEvent, FALSE);
CompCreateInfo((“IoSetCompletionRoutine”));
// Set the io completion routing which will trigger our wait event
IoSetCompletionRoutine(Irp, CreateCompleteCallback, &WaitEvent, TRUE, TRUE,
TRUE);
CompCreateInfo((“IoCallDriver”));
// Fire the IO down and wait for it to complete.
IoCallDriver(devExt->LowerDeviceObject, Irp);
CompCreateInfo((“KeWaitForSingleObject”));
// Wait for io to complete
KeWaitForSingleObject(&WaitEvent,Executive,KernelMode,FALSE,NULL);
CompCreateInfo((“IoCancelFileOpen: %x”,Irp->IoStatus.Status));
// this is for testing only
IoCancelFileOpen(devExt->LowerDeviceObject,MyFileObject->ContainingFileObject);
CompCreateInfo((“STATUS_ACCESS_DENIED”));
ntStatus = MyFailIrp(Irp,STATUS_ACCESS_DENIED);
// ntStatus = PassBackToMiniFilter(devExt,Irp);
CompCreateFuncExit();
return ntStatus;
}
/*/////////////////////////////////////////////////////////////////////////////////
MyCopyFileObjectContents
Arguments:
[in] devExt: Device extension of device to which irp was send
[in] Irp : IRP that was send to shadow device.
Description: Copies file object content to other
//////////////////////////////////////////////////////////////////////////////////*/
NTSTATUS MyCopyFileObjectContents(IN PMY_SHADOW_DEVICE_EXTENSION devExt, IN
PFILE_OBJECT From,
IN OUT PFILE_OBJECT To)
{
if(From->FileName.Length)
{
PWCHAR pBuffer;
CompCreateInfo((“Before Allocate : %p\r\n”,To->FileName.Buffer));
pBuffer =
(PWCHAR)ExAllocatePoolWithTag(PagedPool,From->FileName.MaximumLength,CREATE_ROUTINE_TAG);
if(!pBuffer)
return STATUS_INSUFFICIENT_RESOURCES;
To->FileName.Buffer = pBuffer;
To->FileName.MaximumLength = From->FileName.MaximumLength;
RtlCopyUnicodeString(&To->FileName,&From->FileName);
}
To->LockOperation = From->LockOperation;
To->PrivateCacheMap = NULL;
To->SectionObjectPointer = NULL;
To->Waiters = From->Waiters;
To->LastLock = NULL;
To->DeviceObject = devExt->LowerDeviceObject;
return STATUS_SUCCESS;
}