I have device(PDO), which need read or write data from some file when in got IO request from upper(FDO) device. nothing complex here - i setup next IRP stack location with valid IRP_MJ_READ or IRP_MJ_WRITE IRP data and call FS device. but i want do one optimization here - i already have MDL which cover buffer for read/write (rarely MDL cover larger buffer: MappedSystemVa != buffer for r/w - in this case i create IoBuildPartialMdl for use MDL with exactly MappedSystemVa == buffer for r/w). form fastfat source i view that FS by self create MDL for user buffer, if yet no MDL in IRP ( look deviosup.c -> FatLockUserBuffer), also i am look how IoPageRead work - it also set self MDL in IRP. so - i decide set MDL in IRP before call FS device with r/w IRP. and in own completion i restore original Irp->MdlAddress. also i set irp->Flags = IRP_NOCACHE. this solution well worked several years before win10.
but on win10 i found problem - this work well only if file, from which i read/write not compressed. but if file is compressed - NTFS not using NonCachedIO despite IRP_NOCACHE flag, but always Cached Io (by nt!CcAsyncCopyRead) and in completion (NTFS!NtfsAsyncCachedReadCompletionCallBack - free (!) MDL if IoStatus.Status < 0) - this cause bugcheck when real owner of MDL try free it (double free) - normally (if NTFS not free MDL) i remove it(more exactly restore original Irp->MdlAddress value) from IRP in own completion routine. as solution for this i found that if i set irp->Flags = IRP_NOCACHE|IRP_PAGING_IO in flags - look like now NTFS no more free MDL by self and all again work well, even on compressed files. and IRP_PAGING_IO is OK for me because i never extend file by write requests - his size is unchanged.
but now i already not shure - are this solution is correct ? so question:
can i set Irp->MdlAddress by self, before pass r/w request to FS with irp->Flags = IRP_NOCACHE|IRP_PAGING_IO; ? this is correct or we cannot be shure in this ?
Thanks