Where is my read buffer?

Irp->UserBuffer is an actual pointer to the actual buffer that application
provided. You must place decripted data in this buffer. Replacing
Irp->UserBuffer with ClearText does not help to deliver the data to the
appliction.

Processing read requests is different from processing write requests -
application expects that data change after the read completes. Thus you can
decrypt data in place without creating a new buffer - no restriction to keep
data unchanged in the application buffer.

Alexei.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of
xxxxx@hotmail.com
Sent: Thursday, November 02, 2006 3:25 PM
To: Windows File Systems Devs Interest List
Subject: RE:[ntfsd] Where is my read buffer?

All righty-o. I got the buffer and I can decrypt it. I’m also doing the
WriteDispatch correctly (as far as I, a n00b, can tell).

How do I pass the unencrypted buffer back up to my application? Wordpad.exe.

Here’re my Read Routines. Please ignore my stupid hacks like allocating and
setting a buffer to all X’s. That’s because I was dumping out the filenames
to the debugger and it was bombing out on me at times. If I allocated a
separate buffer and copy over the memory, it seems to solve it.

I can deal with stuff like this AFTER the demo next week. I just need to
show, with some slight robustness, that we’re opening up a file, typing in
plain text, closing it, opening it up and it’s still plain text but it was
stored encrypted.

Then, hopefully, I won’t get fired. Thanks again all.

NTSTATUS
RRIFSDispatchRead (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status
= STATUS_SUCCESS;
KEVENT waitEvent;
PVOID pData
= NULL;

PFILE_OBJECT oFileObj
= NULL;
PNAME_CONTROL pNameControl
= NULL;
PRRIFSFILTER_DEVICE_EXTENSION devExt
= NULL;
PUNICODE_STRING puString
= NULL;
UNICODE_STRING newString;
WCHAR myBigString[255];

BOOLEAN isCached
= FALSE;
ULONG i
= 0;
ULONG textLen
= 0;
char * clearText
= NULL;
BOOLEAN gotExt
= FALSE;
wchar_t** fileExtension
= NULL;

PUNICODE_STRING txtExtension
= NULL;
PUNICODE_STRING fileExt
= NULL;

fileExtension = ExAllocatePoolWithTag(NonPagedPool, 10,
RRIFSFILTER_READ_TAG);
txtExtension = ExAllocatePoolWithTag(NonPagedPool,
sizeof(UNICODE_STRING), RRIFSFILTER_READ_TAG);
fileExt = ExAllocatePoolWithTag(NonPagedPool,
sizeof(UNICODE_STRING), RRIFSFILTER_READ_TAG);

RtlInitUnicodeString(txtExtension, L".doc");

IoCopyCurrentIrpStackLocationToNext( Irp );
KeInitializeEvent( &waitEvent, NotificationEvent, FALSE );
IoSetCompletionRoutine( Irp,
RRIFSDispatchReadCompletion,
&waitEvent,
TRUE,
TRUE,
TRUE);

status = IoCallDriver(
((PRRIFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NLExtHeader.A
ttachedToDeviceObject, Irp );

if (status == STATUS_PENDING)
{
KeWaitForSingleObject( &waitEvent, Executive,
KernelMode, FALSE, NULL );
status = Irp->IoStatus.Status;
}

if (status == STATUS_SUCCESS)
{
RRIFS_LOG_PRINT(RRIFSDEBUG_TRACE_READFILE_OPS,
(“READ:::: Do Decryption Here!!!\n”));
__try
{
if (Irp->Flags & IRP_BUFFERED_IO)
{
pData =
Irp->AssociatedIrp.SystemBuffer;
}
else if (Irp->MdlAddress)
{
pData =
MmGetSystemAddressForMdlSafe( Irp->MdlAddress, HighPagePriority);
}
else if (Irp->UserBuffer )
{
pData =
Irp->UserBuffer;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
status = STATUS_ACCESS_VIOLATION;
}
if (Irp->RequestorMode == UserMode)
{

RRIFS_LOG_PRINT(RRIFSDEBUG_TRACE_READFILE_OPS, (“RRIFSDispatchRead – User
Mode Processing.\n”));
oFileObj =
Irp->Tail.Overlay.OriginalFileObject;
puString = &(oFileObj->FileName);
newString.MaximumLength = 256;
newString.Length = 255;
for ( i = 0; i < 255; i++)
{
myBigString[i] = ‘X’;
}
newString.Buffer = myBigString;
RtlInitUnicodeString(&newString,
puString->Buffer);

RRIFS_LOG_PRINT(RRIFSDEBUG_TRACE_READFILE_OPS, (" Read File Name is :
%ls\n", newString.Buffer));

gotExt =
RetrieveFileExtension(newString.Buffer, fileExtension);

if (gotExt == TRUE)
{

RRIFS_LOG_PRINT(RRIFSDEBUG_TRACE_READFILE_OPS, (" The File
Extension for this file is %ls\n", *fileExtension));
RtlInitUnicodeString(fileExt,
(PCWSTR)(*fileExtension));
}

if (RtlCompareUnicodeString(fileExt,
txtExtension, TRUE) == 0)
{
i = 0;
textLen = strlen(pData);
if (textLen > 1)
{
clearText =
ExAllocatePoolWithTag(NonPagedPool, textLen + sizeof(char),
RRIFSFILTER_READ_TAG);
for (i = 0 ;
i < textLen; i++)
{

*(clearText + i) = *(((char*)(pData) + i)) ^ ‘R’;
}

RRIFS_LOG_PRINT(RRIFSDEBUG_TRACE_READFILE_OPS, (“Cypher Text is %s\n”,
(char*)pData));

RRIFS_LOG_PRINT(RRIFSDEBUG_TRACE_READFILE_OPS, (“Original Text is %s\n”,
clearText));

}
}

}
Irp->UserBuffer = clearText;

if (clearText != NULL)
ExFreePoolWithTag(clearText,
RRIFSFILTER_READ_TAG);

if (fileExtension != NULL)
ExFreePoolWithTag(fileExtension,
RRIFSFILTER_READ_TAG);

if (txtExtension != NULL)
ExFreePoolWithTag(txtExtension,
RRIFSFILTER_READ_TAG);

if (fileExt != NULL)
ExFreePoolWithTag(fileExt,
RRIFSFILTER_READ_TAG);
}

IoCompleteRequest( Irp, IO_NO_INCREMENT );

return status;

}

NTSTATUS
RRIFSDispatchReadCompletion (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
NTSTATUS status =
STATUS_SUCCESS;
PKEVENT pEvent =
Context;

UNREFERENCED_FORMAL_PARAMETER(DeviceObject);
UNREFERENCED_FORMAL_PARAMETER(Irp);

KeSetEvent( pEvent, IO_NO_INCREMENT, FALSE );
return STATUS_MORE_PROCESSING_REQUIRED;
}


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@vmware.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

In-place decryption did the trick. Thanks Alexei! You guys ROCK! I should have the basics for my demo now.

Of course, they can’t ask me to use notepad. Gah!

Yes, it is right there must be
if (Irp->Flags & IRP_BUFFERED_IO){

Other way is to get device object and to check it’s flags. In the terms of
his code it will be like this:

(((PRRIFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NLExtHeader
.AttachedToDeviceObject)->Flags

Andrey Gunko
soft Xpansion Ukraine Ltd.
Programmer
Powered by eKnow-how
Artjoma St. 118B … 83048 Donetsk … Tel/Fax: +38 062 3818874 …
Internet: [www.soft-xpansion.com]

|-----Original Message-----
|From: xxxxx@lists.osr.com [mailto:bounce-268691-
|xxxxx@lists.osr.com] On Behalf Of Dan Kyler
|Sent: Thursday, November 02, 2006 8:04 PM
|To: Windows File Systems Devs Interest List
|Subject: RE: [ntfsd] Where is my read buffer?
|
|
|> if (Irp->Flags & DO_BUFFERED_IO){
|
|You’re interpreting Irp Flags with a device object constant.
|DO_BUFFERED_IO
|= 0x4, which is IRP_SYNCHRONOUS_API in the Irp Flags field.
|IRP_BUFFERED_IO
|is 0x10.
|
|This is quite broken.
|
|- Dan.
|
|-----Original Message-----
|From: xxxxx@lists.osr.com
|[mailto:xxxxx@lists.osr.com] On Behalf Of Gunko Andrey
|Sent: Thursday, November 02, 2006 8:48 AM
|To: Windows File Systems Devs Interest List
|Subject: RE: [ntfsd] Where is my read buffer?
|
|
|Your read buffer is here
|__try{
| if (Irp->Flags & DO_BUFFERED_IO){
| pData = Irp->AssociatedIrp.SystemBuffer;
| }else if (Irp->MdlAddress){pData = MmGetSystemAddressForMdlSafe(
| Irp->MdlAddress, HighPagePriority);
| }else if (Irp->UserBuffer ){
| pData = Irp->UserBuffer;
|}
|}__except(EXCEPTION_EXECUTE_HANDLER){
| …
| }
|
|The length is IrpSp->Parameters.Read.Length, offset in file
|IrpSp->Parameters.Read.ByteOffset.
|
|So you must do decryption on post-read operation. To do this you need:
|
|NTSTATUS
|ReadDispatcher (
| IN PDEVICE_OBJECT DeviceObject,
| IN PIRP Irp
| )
|{
|KEVENT event;
|
|////…
|///here is your code
|////…
|
|IoCopyCurrentIrpStackLocationToNext( Irp );
|KeInitializeEvent( &event, NotificationEvent, FALSE );
|
|IoSetCompletionRoutine(Irp,
| WaitCompletion,
| &event,
| TRUE,
| TRUE,
| TRUE);
|
|Status = IoCallDriver(TargetDevice, Irp );
|
| if (STATUS_PENDING == Status) {
| KeWaitForSingleObject( &event,
| Executive,
| KernelMode,
| FALSE,
| NULL );
| Status = Irp->IoStatus.Status;
| }
|If (NT_SUCCES(status))
|{
| //here you can do the decryption of pData
|}
|
|IoCompleteRequest( Irp, IO_NO_INCREMENT );
|return status;
|
|}//ReadDispatcher
|
|The code of WaitCompeltion:
|
|NTSTATUS
|WaitCompletion(
| IN PDEVICE_OBJECT DeviceObject,
| IN PIRP Irp,
| IN PVOID Context
| )
|{
| PKEVENT pEvent = Context;
| UNREFERENCED_PARAMETER(Irp);
| UNREFERENCED_PARAMETER(DeviceObject);
| KeSetEvent( pEvent, IO_NO_INCREMENT, FALSE );
| return STATUS_MORE_PROCESSING_REQUIRED;
|}
|
|For write operation you need to copy the original buffer stored in pData,
|before call IoCallDriver encrypt buffer and after on post-write copy
|backuped buffer to pData.
|
|It is that you need to do.
|
|Andrey Gunko
| soft Xpansion Ukraine Ltd.
|Programmer
| Powered by eKnow-how
|Artjoma St. 118B … 83048 Donetsk … Tel/Fax: +38 062 3818874 …
|Internet: [www.soft-xpansion.com]
|
||-----Original Message-----
||From: xxxxx@lists.osr.com [mailto:bounce-268663-
||xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
||Sent: Thursday, November 02, 2006 5:02 PM
||To: Windows File Systems Devs Interest List
||Subject: RE:[ntfsd] Where is my read buffer?
||
||Thanks. As you can see, I have no real feel for this. I’m guessing
||that using the Irp->UserBuffer is not correct either.
||
||I can not find any documentation that tells me what I should be using
||for the IoAllocateMdl(virtual_address,…) piece. Do I pre-allocate a
||buffer and pass that in? Any Buffer of size
||irpSp->Parameters.Read.Length?
||
||
||—
||Questions? First check the IFS FAQ at
||https://www.osronline.com/article.cfm?id=17
||
||You are currently subscribed to ntfsd as: xxxxx@maus.donetsk.ua To
||unsubscribe send a blank email to xxxxx@lists.osr.com
|
|
|—
|Questions? First check the IFS FAQ at
|https://www.osronline.com/article.cfm?id=17
|
|You are currently subscribed to ntfsd as: xxxxx@privtek.com
|To unsubscribe send a blank email to xxxxx@lists.osr.com
|
|
|—
|Questions? First check the IFS FAQ at
|https://www.osronline.com/article.cfm?id=17
|
|You are currently subscribed to ntfsd as: xxxxx@maus.donetsk.ua
|To unsubscribe send a blank email to xxxxx@lists.osr.com

I’m going to switch over to using a Mini Filter, now that I know it should work well in Win2K SP4 + patch.

Will getting and modifying the buffers be more straightforward for me now? I’m just starting to read up on the topic. Pre-filter callbacks, post-filter callbacks, etc.

I should be able to combine the tiny bit of knowlege I have now with what I read and modify the minispy driver. I hope.

Andrey? Any tips on accessing the buffers with like pending and such?

Thanks again guys.