Issue with layered file system

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;
}

you a call
NewFileObject = IoCreateStreamFileObjectEx(
RelMyFileObject->ContainingFileObject,NULL,&MyFileObject->ContainingFileHandle);
and
MyFileObject->ContainingFileObject = NewFileObject;

for NewFileObject FO_HANDLE_CREATED is set in Flags(becouse handle created and saved to
&MyFileObject->ContainingFileHandle)

if you look for code of IoCancelFileOpen at very begin you can see :

VOID
IoCancelFileOpen(
IN PDEVICE_OBJECT DeviceObject,
IN PFILE_OBJECT FileObject
)
{
if (FileObject->Flags & FO_HANDLE_CREATED) KeBugCheckEx(INVALID_CANCEL_OF_FILE_OPEN,
FileObject, DeviceObject, 0, 0);

}

so you got Blue Screeen Error - > INVALID_CANCEL_OF_FILE_OPEN

I See… Thank you…
But is there is a we that i can create a shadow file object and send it to
low level file object

wrote in message news:xxxxx@ntfsd…
> you a call
> NewFileObject = IoCreateStreamFileObjectEx(
> RelMyFileObject->ContainingFileObject,NULL,&MyFileObject->ContainingFileHandle);
> and
> MyFileObject->ContainingFileObject = NewFileObject;
>
> for NewFileObject FO_HANDLE_CREATED is set in Flags(becouse handle created
> and saved to
> &MyFileObject->ContainingFileHandle)
>
> if you look for code of IoCancelFileOpen at very begin you can see :
>
> VOID
> IoCancelFileOpen(
> IN PDEVICE_OBJECT DeviceObject,
> IN PFILE_OBJECT FileObject
> )
> {
> if (FileObject->Flags & FO_HANDLE_CREATED)
> KeBugCheckEx(INVALID_CANCEL_OF_FILE_OPEN,
> FileObject, DeviceObject, 0, 0);
> …
> }
>
> so you got Blue Screeen Error - > INVALID_CANCEL_OF_FILE_OPEN
>
>

> But is there is a we that i can create a shadow file object and send it to

low level file object

Sure. All (ha!) you have to do is summon up *your* file object, point the
Irp at it (or equivalent for minifilter), and fire it the create down. Then
you “just” have to filter all the requests coming down and do the same swap.

Some hints:

  • There are a *lot* of functions to filter.
  • Be careful about what you do if you get a failure in create.
  • Be careful in your choice of which call you use to summon up the File
    Object. This interacts with a whole bunch of things, not least whether you
    need to pass through IRP_MJ_CLEANUP or not. And that inpacts is what sort
    of opperations you may want to do and when.

So I can create a file object and initialize it and send it down… Right!!!

One last question regarding file object creation…
Can I just create a file object from non paged pool or do i need to use
IoCreateStreamFileObjectEx or similar function to create a file object

Thanks.
VC

“Rod Widdowson” wrote in message
news:xxxxx@ntfsd…
>> But is there is a we that i can create a shadow file object and send it
>> to low level file object
>
> Sure. All (ha!) you have to do is summon up your file object, point the
> Irp at it (or equivalent for minifilter), and fire it the create down.
> Then you “just” have to filter all the requests coming down and do the
> same swap.
>
> Some hints:
> - There are a lot of functions to filter.
> - Be careful about what you do if you get a failure in create.
> - Be careful in your choice of which call you use to summon up the File
> Object. This interacts with a whole bunch of things, not least whether
> you need to pass through IRP_MJ_CLEANUP or not. And that inpacts is what
> sort of opperations you may want to do and when.
>
>
>
>

When I’ve done this I have not created the FILE_OBJECT I have issued a
create and let create the FO for me. The thing you really care about is
the FCB’s for the FO’s you create.


Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply

“OSR Online” wrote in message news:xxxxx@ntfsd…
> So I can create a file object and initialize it and send it down…
> Right!!!
>
> One last question regarding file object creation…
> Can I just create a file object from non paged pool or do i need to use
> IoCreateStreamFileObjectEx or similar function to create a file object
>
> Thanks.
> VC
>
>
> “Rod Widdowson” wrote in message
> news:xxxxx@ntfsd…
>>> But is there is a we that i can create a shadow file object and send it
>>> to low level file object
>>
>> Sure. All (ha!) you have to do is summon up your file object, point
>> the Irp at it (or equivalent for minifilter), and fire it the create
>> down. Then you “just” have to filter all the requests coming down and do
>> the same swap.
>>
>> Some hints:
>> - There are a lot of functions to filter.
>> - Be careful about what you do if you get a failure in create.
>> - Be careful in your choice of which call you use to summon up the File
>> Object. This interacts with a whole bunch of things, not least whether
>> you need to pass through IRP_MJ_CLEANUP or not. And that inpacts is what
>> sort of opperations you may want to do and when.
>>
>>
>>
>>
>
>
>

> One last question regarding file object creation…

Can I just create a file object from non paged pool or do i need to use
IoCreateStreamFileObjectEx or similar function to create a file object

The API is there - use it. Who knows what would happen if you grab a chunk
of memory and call it an object, but I’m guessing it wouldn’t be pretty
(objects have bits and pieces which you cannot see)

I am trying to use
a… IoCreateFileSpecifyDeviceObjectHint
b… ObReferenceObjectByHandle
API functions… I hope it will work??

Thanks,

VC

“Rod Widdowson” wrote in message news:xxxxx@ntfsd…

>> One last question regarding file object creation…
>> Can I just create a file object from non paged pool or do i need to use
>> IoCreateStreamFileObjectEx or similar function to create a file object
>
> The API is there - use it. Who knows what would happen if you grab a chunk
> of memory and call it an object, but I’m guessing it wouldn’t be pretty
> (objects have bits and pieces which you cannot see)
>
>
>