Dynamic changing Parameters.Write.Length in irp stack

Hello all!
The task is to dynamic change the size of writing ON DISK data. I try not to change data, that go in stack, and modify only irp with flag irp_nocache. Additional size is 0x200.

So, the problem is that when i change Parameters.Write.Length in writing dispatch procedure and write in mapping file (with notepad, from example), i receive in completion procedure 0xc0000054 (FILE LOCKED). With simple writing (with far editor) all working ok.
Can anybody help me?

No one knows? =(

Dude, it’s only been about six hours, and at least here in the states most people aren’t probably even at work yet.

Have some patience.

mm

So you are changing the writelength only, who will expand the buffer than?

xxxxx@rambler.ru wrote:

Hello all!
The task is to dynamic change the size of writing ON DISK data. I try not to change data, that go in stack, and modify only irp with flag irp_nocache. Additional size is 0x200.

So, the problem is that when i change Parameters.Write.Length in writing dispatch procedure and write in mapping file (with notepad, from example), i receive in completion procedure 0xc0000054 (FILE LOCKED). With simple writing (with far editor) all working ok.
Can anybody help me?

Changing the length of writes going down to the underlying file system
can be difficult. If you are trying to hide this additional length then
things get really complicated.

For instance, if you are changing this length during a PAGING request
and the length goes beyond the EOF then it won’t work. You need to
update this length outside of the paging pathway so when you do receive
the PAGING request the EOF is already adjusted.

And, as Mr. Vastava asked, what are you doing about the buffer itself?

Pete


Kernel Drivers
Windows File System and Device Driver Consulting
www.KernelDrivers.com
866.263.9295


NTFSD is sponsored by OSR

For our schedule of debugging and file system seminars
(including our new fs mini-filter seminar) visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

If writing is in the beginning of file, I save and replace the original MDL and create new, extended. In the beginning of new buffer i write my signature - 0x200 bytes length, then copy original data.

pDiskDeviceExtension->oldMDL[i]=(PVOID)Irp->MdlAddress;
newlen = MmGetMdlByteCount(mdl) + 0x1000;
p_IO_STK->Parameters.Write.Length+=0x1000;
MyBuffer=(PVOID)ExAllocatePool(NonPagedPool,newlen);
MyMDL=IoAllocateMdl(
MyBuffer,
newlen,
FALSE,
FALSE,
Irp
);
if(MyMDL==NULL)
{
return ERROR_CREATE_IRP;
}
MmBuildMdlForNonPagedPool(MyMDL);
RtlCopyMemory(MyBuffer+SIGSIZE,Buf,mylen-SIGSIZE);
RtlCopyMemory(MyBuffer,SIGNATURE,REALSIZE);

I will try to create and send IRP_MJ_SET_INFORMATION with FileAllocationInformation from DispatchWrite to increase the size of file to 0x1000.
I think i should do this when receive IRP_MJ_WRITE with flag IRP_NOCACHE. Can anybody give me example, how to do it correctly?
This code doesn’t work:

KeInitializeEvent(&event2, SynchronizationEvent, FALSE);
MyIrp = IoAllocateIrp(DeviceObject->StackSize,FALSE);
if(!MyIrp)
{
return ERROR_CREATE_IRP;
}
MyBuffer=(PVOID)ExAllocatePool(NonPagedPool,sizeof(FILE_ALLOCATION_INFORMATION));
MyIrp->AssociatedIrp.SystemBuffer=MyBuffer;
MyIrp->UserEvent = &event2;
MyIrp->UserBuffer=MyBuffer;
MyIrp->Cancel=FALSE;
MyIrp->UserIosb = &IoStatusBlock;
MyIrp->Tail.Overlay.Thread = PsGetCurrentThread();
MyIrp->Tail.Overlay.OriginalFileObject = p_IO_STK->FileObject;
MyIrp->RequestorMode = UserMode;
MyIrp->Flags = 0x830;

IoSetNextIrpStackLocation(MyIrp);
p_IO_NextSTK = IoGetCurrentIrpStackLocation(MyIrp);

p_IO_NextSTK->DeviceObject = DeviceObject;
p_IO_NextSTK->FileObject=p_IO_STK->FileObject;

p_IO_NextSTK =IoGetNextIrpStackLocation(MyIrp);
p_IO_NextSTK->MajorFunction=IRP_MJ_SET_INFORMATION;
p_IO_NextSTK->MinorFunction = 0;
p_IO_NextSTK->DeviceObject = DeviceObject;
p_IO_NextSTK->FileObject=p_IO_STK->FileObject;
p_IO_NextSTK->Parameters.SetFile.FileInformationClass=FileAllocationInformation;
p_IO_NextSTK->Parameters.SetFile.Length=sizeof(FILE_ALLOCATION_INFORMATION);
p_IO_NextSTK->Parameters.SetFile.ReplaceIfExists=FALSE;
p_IO_NextSTK->Parameters.SetFile.AdvanceOnly=TRUE;
((PFILE_ALLOCATION_INFORMATION)MyBuffer)->AllocationSize.QuadPart=0;

IoSetCompletionRoutine(MyIrp,
OnCreateSetCompletion,
&DeviceObject,
TRUE,
TRUE,
TRUE);

IoCallDriver(((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject,MyIrp);
KeWaitForSingleObject(&event2, Executive, KernelMode, TRUE, 0);

>I will try to create and send IRP_MJ_SET_INFORMATION with FileAllocationInformation from

DispatchWrite to increase the size of file to 0x1000.
I think i should do this when receive IRP_MJ_WRITE with flag IRP_NOCACHE.

Major doubts that you can change the file size from within the paging IO path.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

What can you advise me?

I tried many variants but unsuccessfully (

I tried to change only Parameters.ByteOffset.QuadPart and send my signature with additional IRP_MJ_WRITE. My irp wrote information successfully, but the main writing gave me again 0xc0000054 (((

xxxxx@rambler.ru wrote:

I tried to change only Parameters.ByteOffset.QuadPart and send my signature with additional IRP_MJ_WRITE. My irp wrote information successfully, but the main writing gave me again 0xc0000054 (((

Sorry to be the one to point it out, but you’re on completely the wrong
track. You cannot do this by fudging writes to the filesystem. The
filesystem maintains its own concept of file sizes. The exact behavior
you will see is determined by the filesystem, but will typically either
be a write dropped silently on the floor (truncated), or
STATUS_FILE_LOCK_CONFLICT. I posted to this list a while back
explaining when this occurs and why.

If you want to change the length of the file, your filter needs to own
caching, since file size information is communicated privately between
the filesystem (cache owner) and the cache. If you own the cache, and
only send noncached IO to the filesystem, you are then free to maintain
one set of sizes to the user and another set to the filesystem.

Owning the cache is not for the faint of heart. Writing the class of
filter you are attempting is the hardest class according to many. You
have been warned.

Good luck,

  • M


This posting is provided “AS IS” with no warranties, and confers no rights.

> Owning the cache is not for the faint of heart. Writing the class of

filter

Such a filter is called “layered FSD”. It is a full FSD, but uses noncached IO of the underlying filesystem to perform its operations.


Maxim S. Shatskih

Windows DDK MVP

xxxxx@storagecraft.com

http://www.storagecraft.com