Strange problem.

I’m attempting to create a minifilter that would add support for reparse point data to volumes that do not support them, by storing reparse buffer data in memory (Paged or Non). I understand that even if the driver works it won’t be without risks. This is an experiment.

During pre-create when i find a file i care about i complete the operation myself with the proper status, information, and TagData results (or so i would like to).

The code is this:

CallbackData->TagData = ExAllocatePoolWithTag(NonPagedPool, StoredTag->Size, DRIVER_POOL_TAG);
RtlCopyMemory(CallbackData->TagData, StoredTag->TagData, StoredTag->Size);
CallbackData->TagData->UnparsedNameLength = UnparsedLength;
CallbackData->IoStatus.Status = STATUS_REPARSE;
CallbackData->IoStatus.Information = CallbackData->TagData->FileTag;
return FLT_PREOP_COMPLETE;

Systems stops at a second chance Access Violation in nt!IopDoNameTransmogrify+0x12

From tracing the behavior of the NTFS file system i believe all of the above to be correct. The access violation leads me to believe that i am missing a buffer somewhere though. Thoughts?

FltSetCallbackDataDirty()?

/Rod

I don’t think that’s it, FltSetCallbackDataDirty is not necessary when
completing an operation (FLT_PREOP_COMPLETE).

I’m not sure I understand that code… For example, when looking at
“CallbackData->StoredTag->Size” I don’t know what StoredTag is, I don’t
think it’s a member of what CallbackData normally is (a FLT_CALLBACK_DATA
structure). Moreover, there is this line: “IoStatus.Information =
CallbackData->CallbackData->TagData->FileTag;” which makes me doubt I
understand what’s really going on here. Could you please post more of the
code so that we know what CallbackData actually is ?

Anyway, I would start investigating this by comparing the way the IRP looks
after NTFS completes the request vs. when you complete it (and not when you
return FLT_PREOP_COMPLETE but rather when FltMgr calls IoCompleteRequest for
that IRP, which is after FltMgr copied all the data back to IRP). In order
to get the populated IRP you’d need to put a breakpoint ideally before the
IRP completes back to the IO manager or somewhere in IopParseDevice right
after the IRP is completed (IopParseDevice should have a block right after
the call to IoCallDriver where it waits for the IRP to complete if it got
STATUS_PENDING back, so I’d set a breakpoint after that block).

Thanks,
Alex.

Maybe the code is showing wrong on your screen… Let me try to clarify. Here, CallbackData is the PFLT_CALLBACK_DATA parameter of the minifilter preoperation callback. I’m not using CallbackData->StoredTag, i’m using Callback->TagData member of PFLT_CALLBACK_DATA as defined in the MSDN. CallbackData->IoStatus.Information is set to the ReparseTag member of the stored tag (Tracing the NTFS file system shows that this works for microsoft tags. The rest i’m not sure about.).

StoredTag, in this case, is an unprocessed byte-level copy of SystemBuffer presented during an FSCTL_SET_REPARSE_POINT operation which should be in the form of a REPARSE_DATA_BUFFER structure, or a REPARSE_GUID_DATA_BUFFER structure if i understand correctly. StoredTag contains the size of this buffer, and a pointer to a copy of the buffer.

Aside from adjusting the length field, i believe a REPARSE_DATA_BUFFER or REPARSE_GUID_DATA_BUFFER can be safely typecast as a FLT_TAG_DATA_BUFFER.

Later in precreate I find the stored tag for a file, and respond by allocating space in CallbackData->TagData for the stored reparse buffer information, copy the data to this new buffer, and completing the operation as show in my original post.

Solved this problem by setting CallbackData->Flags FLTFL_CALLBACK_DATA_IRP_OPERATION, FLTFL_CALLBACK_DATA_IRP_OPERATION, and FLTFL_CALLBACK_DATA_POST_OPERATION before returning from the preoperation callback.

I don’t understand setting FLTFL_CALLBACK_DATA_POST_OPERATION before completing the operation… But it’s essential to making this work. Otherwise the TagData buffer seems to get lost and IopDoNameTransmogrify gets called with a NULL pointer.

I missed your other reply. The code does indeed look very different in
outlook compared to the forum web interface… :frowning: Even now in my outlook it
looks like FLTFL_CALLBACK_DATA_IRP_OPERATION is in there twice…

Anyway, what I was going to say is that you’re not really supposed to set
those flags, they are meant to be set by FltMgr and read by filters. It’s
interesting to understand what’s actually going on…

Does this work on all OS versions ? Which OSes have you tested on ?

Thanks,
Alex.