#3: not really. Code/data used in the *paging file* path must be
nonpaged, but code/data used in the paging IO paths can be paged. You
just have to convince yourself that in satisfying pagefaults in the
paging IO path, you will not need the same data you are pagefaulting on.
Since this is usually from the paging file, you are fine.
This posting is provided “AS IS” with no warranties, and confers no
rights.
-----Original Message-----
From: Dan Partelly [mailto:xxxxx@rdsor.ro]
Sent: Monday, July 01, 2002 10:40 AM
To: File Systems Developers
Subject: [ntfsd] Re: fail : lazy writing…
Since the code you show here is not enough for me to 100% realize what
you
do, so I will refrain commenting too much on it.
Keep in mind always the folowing about paging IO:
-
It is a mistake to encrypt in place, using the provided
Irp->UserBuffer.
Indeed such a technique can lead to user mode
threads seeing data encrypted either in cache, either in a mapped view.
Always encrypt into a secondary buffer.
IRP_MJ_WRITE related. For IRP_MJ_READ paging IO the caller of this must
considerate the memory invalid untill the inpage operation
is complete, so the situation is more relaxed.
-
When a IRP has IRP_PAGING_IO flag set, this will alter the behaviour
of
the IoCompletion mechanism, in the way that for such an IRP the MDL
pointed
by Irp->MdlAddress will not be freed at IO Completion time, nor the
pages
mapped by it will be unlocked if they are locked. This means that if you
roll yourself a paging IO
IRP, you should use a completion routine (as simple as signaling an
event to
synch back to your routine & returning STATUS_MORE_PROCESSING_REQUIRED)
and retain ownership of the IRP, or design the completion routine to
perform
itself the necessarly cleanup.
Here you should manualy perform all required operations , such as
MmUnmapPages if required , freeing the MDL if its required,
saving the Status and Information fileds of the IO_STATUS_BLOCK , if
required , etc , I think you got the ideea,
and finally freeing the IRP itself.
-
All code which is the paging IO path must be in nonpaged memory, and
any
data structure referenced by code in paging IO must be in nonpaged
memory
as well.
-
Any call to an API such as MmProbeAndLockPages or access directly to
user
memory should be placed whithin a __try{} / __except block scope. This
particualr
API can raise exceptions on failure, which unhandled will crash the
system.
This is not good. Observe that this rule is a general rule, and not only
related to paging IO.
-
Always properly set Irp->UserBuffer using MmGetMdlVirtualAddress()
for
the MDL asscoiated with the IRP.
File systems do need it setup properly. If you reuse the IRP, always
save
the original Irp->MdlAddress and Irp->UserBuffer
beofre touching them Then, poke Irp->MdlAddress to point to your MDL,
and
the update the Irp->UserAddress corespondingly.
>> always i check the all buffers(MdlAddress, SystemBuffer,
UserBuffer). in
that condition - nonCached and Paging -
The way to deterine a paging IO is by looking to IRP->Flags, not by
other
fantesist checks. Generally speaking
synchronous paging IO is used for section flushing, explicit cache
flushing,
and lazy writter activity,
while asynchronous paging IO is used by the mapped and modified page
writter
to asynchronous write dirty pages on
disk. You should abserve this behaviour and try to preserve it, whenever
is
possible. IRP_PAGING_IO is always present
for paging operations.
What you should do in your case is :
OrigIrpSp = IoGetCurrentStackLocation(OriginalIrp);
WriteSize = OrigIrpSp->Parameters.Write.Length
OriginalBuffer = MmGetSystemAddressForMdl(OriginalIrp->MdlAddress);
EncrytpBuffer = ExAllocatePool(NonPagedPool,WriteSize);
now encrypt the data FROM OriginalBuffer to EncryptBuffer;
WriteIrp = IoAllocateIrp(…);
WriteMdl = IoAllocateMdl(…);
MmBuildMdlForNonpagedPool(WriteMdl);
Intialize the IRP properly nad its stack location properly
set the flags, device object, file object, write parameters , etc,
etc
WriteIrp->MdlAddress = WriteMdl;
WriteIrp->UserBuffer = MmGetMdlVirtualAddress(WriteMdl);
set a completion routine in which you do all necessary cleanup, get
operation status, free the EncryptBuffer
issue the write request
// (note that you could synchronize here back to your driver, by
waiting on
a event, and signaling
// the event from
// the completion routine, and returning
STATUS_MORE_PROCESSING_REQUIRED)
//
// In this case you can perform the necesarely cleanup right here.
set appropiate staus code for original IRP
complete the original IRP
The “code” is not intended to be compilable I dont have time to give you
functional or for that matter even completly written code.
I hope this helps.
Rgards, Dan
----- Original Message -----
From: “Dejan Maksimovic”
To: “File Systems Developers”
Sent: Monday, July 01, 2002 8:32 PM
Subject: [ntfsd] Re: fail : lazy writing…
>
> Though I can’t say I’m sure, but I think the problem is that
you’re
> NOT setting Irp->UserBuffer, too. You must do that, in case that the
FS
> needs to split the MDL to write to the disk.
>
> –
> Kind regards, Dejan M. www.alfasp.com
> E-mail: xxxxx@alfasp.com ICQ#: 56570367
> Alfa File Monitor - File monitoring library for Win32 developers.
> Alfa File Protector - File protection and hiding library for Win32
> developers.
> Alfa Registry Monitor - Registry monitoring library for Win32
> developers.
> Alfa Registry Protector - Registry protection library for Win32
> developers.
>
>
>
> —
> You are currently subscribed to ntfsd as: xxxxx@rdsor.ro
> To unsubscribe send a blank email to %%email.unsub%%
>
—
You are currently subscribed to ntfsd as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to %%email.unsub%%