STATUS_REPARSE and FILE_OPEN_REPARSE_POINT

Hi!
I am having a problem when writing a minifilter kernel driver that redirect files.
The goal is to catch the IRP_MJ_CREATE pre operation and just do:

Data->IoStatus.Information = IO_REPARSE;
Data->IoStatus.Status = STATUS_REPARSE;
Data->Iopb->TargetFileObject->RelatedFileObject = NULL;
FltSetCallbackDataDirty(Data);
return FLT_PREOP_COMPLETE;

It works fine in most cases but there is one case that is not working as expected.
When FILE_OPEN_REPARSE_POINT is set by an application sometimes the reparse does not apply and the ZwIOpenFile returns PATH NOT FOUND.

My solution is a global solution that should work with any program. This issue typically happens when doing a file-save (e.g. in Notepad). There are some PreCreate events where I redirect the file to another location but then it comes this ZwOpenFile (in the stack trace kernelbase.dll calls DeleteFileW) having this FILE_OPEN_REPARSE_POINT and here instead of getting REPARSE in the Result tab (I am using Process Monitor) I get “PATH NOT FOUND” like if the reparse did not apply.

The stranger is that it does not happen in most of the computers but in some of them and later on it “suddenly works fine” again…

If I well understand, when a function uses FILE_OPEN_REPARSE_POINT then the reparse should not be applied right? So it’s like if my minifilter is not called and the original file is opened ignoring my replace, right? In this case, why does it work in some cases and not in others?

Thanks

Hi Pete!
One approach I am trying is this:

In the IRP_MJ_CREATE pre-op I do:
if (CreateOptions&FILE_OPEN_REPARSE_POINT) {
return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}

Then in the IRP_MJ_CREATE pre-op I do:
if (Data->IoStatus.Status != STATUS_OBJECT_PATH_NOT_FOUND && Data->IoStatus.Status != STATUS_OBJECT_NAME_NOT_FOUND) {
return FLT_POSTOP_FINISHED_PROCESSING;
}
if ((Data->Iopb->Parameters.Create.SecurityContext->FullCreateOptions&FILE_OPEN_REPARSE_POINT) == 0) {
return FLT_POSTOP_FINISHED_PROCESSING;
}
Data->Iopb->Parameters.Create.SecurityContext->FullCreateOptions &= ~FILE_OPEN_REPARSE_POINT;
FltSetCallbackDataDirty(Data);
FltReissueSynchronousIo(Data->Iopb->TargetInstance,Data);
return FLT_POSTOP_FINISHED_PROCESSING;

The goal is to reissue the event WITHOUT this FILE_OPEN_REPARSE_POINT creation flag. Is it doable on this way?

However in process monitor I still see IRP_MJ_CREATE with “Result” to “NAME NOT FOUND”. Before when applying the status reparse it was “PATH NOT FOUND” and now it is “NAME NOT FOUND” with this new logic.

Thanks