encryption .TXT file in windows 8

I have a encryption - on - fly drivers, and encrypt .TXT file(for test purpose). It work well in windows xp. but not in win8’ notepad.exe.

It’s ok when i copy winxp’notepad.exe to win8 system, It’s not ok when win8’s native notepad.exe. under windbg, paging write failed at post-write callback. Data.IoStatus.Status = 0, Data.IoStatus.Information = 0.

I know notepad.exe is memory-mapped. but what’s difference between window xp and window 8.

the procmon log in window 8:
“notepad.exe”,“IRP_MJ_CREATE”,“C:\1\3.txt”,“SUCCESS”
“notepad.exe”,“IRP_MJ_WRITE”,“C:\1\3.txt”,“SUCCESS”
“notepad.exe”,“IRP_MJ_READ”,“C:\1\3.txt”
“notepad.exe”,“IRP_MJ_SET_INFORMATION”,“C:\1\3.txt”,“SUCCESS”,“Type:EndOfFile: 3”
“notepad.exe”,“IRP_MJ_SET_INFORMATION”,“C:\1\3.txt”,“SUCCESS”,“Type:AllocationSize: 3”
“notepad.exe”,“IRP_MJ_CLEANUP”,“C:\1\3.txt”,“SUCCESS”,“”
“notepad.exe”,“FASTIO_ACQUIRE_FOR_CC_FLUSH”,“C:\1\3.txt”,“SUCCESS”,“”
“notepad.exe”,“IRP_MJ_WRITE”,“C:\1\3.txt”,“SUCCESS”,“Offset: 0, Length: 4,096, I/O Flags: Non-cached, Paging I/O, Synchronous Paging I/O, Priority: Normal”
“12:16:46.2184557”,“notepad.exe”,“2648”,“FASTIO_RELEASE_FOR_CC_FLUSH”,“C:\1\3.txt”,“SUCCESS”,“”

My question is:
1?why failed in post-write callback in paging io path? (In the paging io path, I change Write.ByteOffest from 0 to 4096, because my fix-size encrypt header is 4096 bytes. )
2?why paging write occur after clean up?

any suggestion? thanks!

You are missing an important point, you need to update the size of the
file on disk before the paging write comes in since the file can’t be
extended in a paging write request. Therefore you need to recognize an
extending write in the non-paging pathway, extend the file accordingly
and then when the paging write comes in the underlying file size on disk
is correct.

That said, you need to manage these sizes since the caller, which can be
MM, must know the size of the file minus your header. This is tricky
since you need to deal with file info requests and directory enumeration
calls.

There is a TON of information in this list covering all of these
aspects. Expect a long time to get this done, not less than 6 months.

Pete

On 1/25/2013 3:59 AM, muliu92@163.com wrote:

I have a encryption - on - fly drivers, and encrypt .TXT file(for test purpose). It work well in windows xp. but not in win8’ notepad.exe.

It’s ok when i copy winxp’notepad.exe to win8 system, It’s not ok when win8’s native notepad.exe. under windbg, paging write failed at post-write callback. Data.IoStatus.Status = 0, Data.IoStatus.Information = 0.

I know notepad.exe is memory-mapped. but what’s difference between window xp and window 8.

the procmon log in window 8:
“notepad.exe”,“IRP_MJ_CREATE”,“C:\1\3.txt”,“SUCCESS”
“notepad.exe”,“IRP_MJ_WRITE”,“C:\1\3.txt”,“SUCCESS”
“notepad.exe”,“IRP_MJ_READ”,“C:\1\3.txt”
“notepad.exe”,“IRP_MJ_SET_INFORMATION”,“C:\1\3.txt”,“SUCCESS”,“Type:EndOfFile: 3”
“notepad.exe”,“IRP_MJ_SET_INFORMATION”,“C:\1\3.txt”,“SUCCESS”,“Type:AllocationSize: 3”
“notepad.exe”,“IRP_MJ_CLEANUP”,“C:\1\3.txt”,“SUCCESS”,“”
“notepad.exe”,“FASTIO_ACQUIRE_FOR_CC_FLUSH”,“C:\1\3.txt”,“SUCCESS”,“”
“notepad.exe”,“IRP_MJ_WRITE”,“C:\1\3.txt”,“SUCCESS”,“Offset: 0, Length: 4,096, I/O Flags: Non-cached, Paging I/O, Synchronous Paging I/O, Priority: Normal”
“12:16:46.2184557”,“notepad.exe”,“2648”,“FASTIO_RELEASE_FOR_CC_FLUSH”,“C:\1\3.txt”,“SUCCESS”,“”

My question is:
1?why failed in post-write callback in paging io path? (In the paging io path, I change Write.ByteOffest from 0 to 4096, because my fix-size encrypt header is 4096 bytes. )
2?why paging write occur after clean up?

any suggestion? thanks!


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system seminars 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


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

thanks for your reply, pete.

I extend file size in postwrite callback in the non-paging pathway by calling FltSetInformationFile with FileEndOfFileInformation class.

under windbg, in paging pre-write callback, I found that Fcb.FileSize is correct, Fcb.FileValidDataLengthInformation is less than Fcb.FileSize. I think this is the problem , right?

if so, should i call FltSetInformationFile with FileValidDataLengthInformation class in non-paging write request in addition to set EOF?

No, that’s normal. VDL <= FileSize (EOF)

Anything between VDL and EOF reads back as zeros. If VDL > FileSize, then as you move out FileSize the VM system will attempt to page fault in those pages (since they are within the valid data length of the file.)

If you write a region above VDL, the region from the VDL to your write is normally zero filled to ensure there is no information exposure.

Tony
OSR

For expamle, type ‘1’ to c:\1.txt. in paging i/o pre-write callback, EOF = 4097 and VDL = 4096.(as above says that the fix encryption header size is 4096 bytes, and i extand filesize in post-write callback in the non-paging pathway)

paging write failed at post-write callback. Data.IoStatus.Status = 0, Data.IoStatus.Information = 0. so i think i should extend VDL too.

Other question, In paging i/o write, Write.Length must be 4K * n bytes although the actual data is only 1 byte. how the FSD know that write 1 byte or 4096 bytes?

Please guide me, thanks.

Aren’t you updating the offset of the write which would extend the file?
You need to deal with a bunch of cases here, check the list for
questions concerning encrypting files using notepad or just encrypting
files, there are lots.

Also, you need to zero-encrypt file extensions made with the SetFileInfo
call so if someone extends the file by 100 bytes, you need to write out
encrypted zero’s at 4096-4196 since you may not get a write for that
entire region. Or it could be setting up for a paging write from memory
mapped access.

Again, refer to the list for tons of information on this.

Pete

On 1/27/2013 8:22 AM, muliu92@163.com wrote:

For expamle, type ‘1’ to c:\1.txt. in paging i/o pre-write callback, EOF = 4097 and VDL = 4096.(as above says that the fix encryption header size is 4096 bytes, and i extand filesize in post-write callback in the non-paging pathway)

paging write failed at post-write callback. Data.IoStatus.Status = 0, Data.IoStatus.Information = 0. so i think i should extend VDL too.

Other question, In paging i/o write, Write.Length must be 4K * n bytes although the actual data is only 1 byte. how the FSD know that write 1 byte or 4096 bytes?

Please guide me, thanks.


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system seminars 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


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

I will check the list for this problem.

In paging i/o write, Write.Length must be 4K * n bytes although the actual data is only 1 byte. how the FSD know that write 1 byte , not 4096 bytes?

Call you give me a little information for this question? thanks.

The underlying file system knows this because it tracks the necessary
file sizes. The rules are that paging IO can never extend FileSize or
AllocationSize. Paging IO can extend the VDL if it is the top level
requestor such as in a paging write resulting from a memory mapped IO.
With these rules in place, the file system will know when a paging write
of 4KB comes in on a file with a FileSize of 1 that only 1 byte of it
needs to be persisted to disk.

Pete

On 1/29/2013 4:36 AM, muliu92@163.com wrote:

I will check the list for this problem.

In paging i/o write, Write.Length must be 4K * n bytes although the actual data is only 1 byte. how the FSD know that write 1 byte , not 4096 bytes?

Call you give me a little information for this question? thanks.


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system seminars 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


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

> file sizes. The rules are that paging IO can never extend FileSize or

AllocationSize. Paging IO can extend the VDL if it is the top level
requestor such as in a paging write resulting from a memory mapped IO.

I would add to this, not correct this correct answer.

Kinds of IO in FSD:

  1. cached. App<->Cc. Can extend both VDL and EOF. The correct sequence for a write is:
  • extend EOF
  • CcCopyWrite
  • extend VDL
    Implicitly METHOD_NEITHER, Irp->UserBuffer is used in the implementation and is passed to CcCopyXxx.
    Exception from the above: if the FSD needs to block on a lock in this path AND the file object allows async IO (if not - then it is OK to block anyway), then the FSD chooses to offload the IRP to a worker thread (called “FSP thread”). Since Irp->UserBuffer will not be valid after offload, the MDL is created and locked by the FSD itself (FatLockUserBuffer).
  1. noncached. All other stuff, namely app<->disk, Cc<->disk and Mm<->disk.
    Implicitly direct IO, the MDL is used.
    included here:
    2a) noncached non-paging. App<->disk in noncached mode. Can extend both VDL and EOF.
    MDL must be created by FSD itself (FatLockUserBuffer).
    2b) paging (paging IO is always noncached).
    MDL is created by Mm and must never be IoFreeMdled, it belongs to Mm.
    2b1) top-level paging IO. Mm<->disk. Can only extend VDL and not EOF. FastIo locking calls are called around this IO.
    2b2) non-top-level paging IO. Cc<->disk. Cannot extend any file sizes. Cc’s Acquire/ReleaseFor locking calls are called around this IO (but other then for Mm’s IO).


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

thanks, guys.

My encryption header is 4096 bytes. and i open a TXT file, type one char and then save the file. Already add/del offset in setinformation callback or queryinformation callback.

In paging i/o prewrite callback, eof of fcb is 4097, vdl of fcb is 4096. (because i have add the encryption header in postcreate callback) WriteLength is 1 byte, I change Write.Byteoffset from 0 to 4096, and call FltSetCallbackDataDirty().

The Corresponding postwrite callback, I get a failed.( Data.IoStatus.Status = 0, Data.IoStatus.Information = 0)

And I would like to say is this situation occurs window 8 os, under window xp, the encryption driver work well.

As this issue, can you provide some clues and ideas? I 'm blank now.

While there could be several problems the most obvious which I would
test first is the VDL. The VDL can only be extended for top level
requests so it is possible that the paging write you are handling is not
a top level paging write. I would test this by setting the VDL to 4097
when you extend the EOF out to 4097. You can do this by either writing
out bytes or calling the FltSetInfoFile with the FileValidDataLengthInfo
request.

Pete

On 1/30/2013 4:45 AM, muliu92@163.com wrote:

thanks, guys.

My encryption header is 4096 bytes. and i open a TXT file, type one char and then save the file. Already add/del offset in setinformation callback or queryinformation callback.

In paging i/o prewrite callback, eof of fcb is 4097, vdl of fcb is 4096. (because i have add the encryption header in postcreate callback) WriteLength is 1 byte, I change Write.Byteoffset from 0 to 4096, and call FltSetCallbackDataDirty().

The Corresponding postwrite callback, I get a failed.( Data.IoStatus.Status = 0, Data.IoStatus.Information = 0)

And I would like to say is this situation occurs window 8 os, under window xp, the encryption driver work well.

As this issue, can you provide some clues and ideas? I 'm blank now.


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system seminars 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


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

I figure it out. The reason is that I mistakenly set the toplevelirp in my purge cache function. I change FSRTL_CACHE_TOP_LEVEL_IRP to FSRTL_FSP_TOP_LEVEL_IRP , it works well.

In fact, I don’t understand the real exact means about toplevelirp. only a brief description about it on IoGetTopLevelIrp() in WDK docs, and i noticed manys threads here mention it. can you provide some detail description about it? or a official documentation , or some valuable web link.

thanks again.

> In fact, I don’t understand the real exact means about toplevelirp.

It is a field in ETHREAD which is used by the FSDs, Cc and Mm to mark the recursion state of the thread across FSD/Cc/Mm, and also what locks (I’m speaking about FCB resource locks) were acquired at this moment and how (shared/exclusively).


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

2: kd> dt nt!_ETHREAD
+0x000 Tcb : _KTHREAD
+0x348 CreateTime : _LARGE_INTEGER
+0x350 ExitTime : _LARGE_INTEGER
+0x350 KeyedWaitChain : _LIST_ENTRY
+0x360 ChargeOnlySession : Ptr64 Void
+0x368 PostBlockList : _LIST_ENTRY
+0x368 ForwardLinkShadow : Ptr64 Void
+0x370 StartAddress : Ptr64 Void
+0x378 TerminationPort : Ptr64 _TERMINATION_PORT
+0x378 ReaperLink : Ptr64 _ETHREAD
+0x378 KeyedWaitValue : Ptr64 Void
+0x380 ActiveTimerListLock : Uint8B
+0x388 ActiveTimerListHead : _LIST_ENTRY
+0x398 Cid : _CLIENT_ID
+0x3a8 KeyedWaitSemaphore : _KSEMAPHORE
+0x3a8 AlpcWaitSemaphore : _KSEMAPHORE
+0x3c8 ClientSecurity : _PS_CLIENT_SECURITY_CONTEXT
+0x3d0 IrpList : _LIST_ENTRY
+0x3e0 TopLevelIrp : Uint8B


It’s a pointer value in the ETHREAD structure. FAT uses it for its originally named purpose - storing an IRP. For the file systems it is a piece of “thread local storage”. If you look at the CDFS example in the WDK, it shows the way that most file systems actually use it: as a pointer to a file system owned data structure.

Bottom line, it’s used for detecting re-entrancy. The value of the field itself can contain quite a bit of state information that allows a file system to detect the context of that re-entrancy, including knowing about locking state, which is vitally important in a re-entrant file system world.

Tony
OSR