Redirecting IRP_MJ_CREATE in post.

I am attempting to redirect an IRP_MJ_CREATE request in the post create. Due to the design any files needing a redirect will fail in the IRP_MJ_CREATE as such I am watching for Object not found and file not found errors being returned from IRP_MJ_CREATE.

I am running into problems when I attempt to open the redirect file and modify the return data to the new file. While initially using ZwOpenFile to get the redirect file I switched to IoCreateFileSpecifyDeviceObjectHint to only query the lower filter stack. I am having difficulty mapping the results of the IoCreateFileSpecifyDeviceObjectHint to the return data from the IRP_MJ_CREATE.

Is there some additional documentation or some example code that lists all the necessary fields that need to be modified to in order to redirect the file?

Thanks,
Ryan Seifert

Is this a legacy or a minifilter ? I’m guessing legacy but I would like a confirmation.

Regards,
Alex.
This posting is provided “AS IS” with no warranties, and confers no rights.

It is a minifilter.

Hmm. You should never call IoCreateFileSpecifyDeviceObjectHint from a minifilter (or at least, I can’t think of a case where you would need to). Please use FltCreateFile(Ex(2)) instead.

It is not clear to me how you are trying to handle the failure case (so you might want to explain a bit better), but in the general case the recommendation is that you modify the operation parameters (in the FLT_CALLBACK_DATA structure) and then call FltReissueSynchronousIo (assuming this is a synchronized operation).

In this case, being an IRP_MJ_CREATE you might want to simply change the name in FileObject and convert the failure into a STATUS_REPARSE. The simrep WDK sample can show you how to update the name of the file in the FileObject, but the logic will reparse in preCreate so it’s not exactly your scenario.

Regards,
Alex.
This posting is provided “AS IS” with no warranties, and confers no rights.

> I am running into problems when I attempt to open the redirect file and modify the return data to the

new file. While initially using ZwOpenFile to get the redirect file I switched to

Can you use STATUS_REPARSE?


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

Thanks for the responses.

It appears I ran into some old documentation/discussions regarding the IoCreateFileSpecifyDeviceObjectHint, after consulting the documentation FltCreateFile does just what I need (only calling minifilter’s below).

Regarding the failure case, I am watching for file creates that are attempted on non-existing files. The filename’s of certain files in the system have a prefix attached to them, this prefix tags the file for logging. The prefix is removed before the filenames are sent to the applications. When the application/user attempts to access one of the tagged files, the file create will fail with file not found/object not found. At that point the minifilter should check to see if a tag file exists and redirect the file create to that file.

From what I read STATUS_REPARSE could only be issued in the Pre section, not the Post section, of the create. Unless I wanted to check for the tagged files existence in the pre-create (which adds more overhead to the minifilter) I could not use the status reparse correct?

FltReissueSynchronousIo is a new function to me, but it actually appears to be a pretty good solution. In this scenario I would watch for the file not found/object not found errors and then change the filename and reissue the Io. With this call I would not even need to check for existence of the file, just watch the completing FltReissueSynchronousIO parameters. Outside avoiding Fast IO/callbacks are there any other gotchas with using the FltReissueSynchronousIo? From the documentation it looks like the best solution

Alternatively if there is a better solution for tagging files I would love to hear it. This solution seemed good as it doesn’t add much overhead and only the filenames are modified no actual file data.

Thanks,
Ryan Seifert

No, you can change the status to STATUS_REPARSE in post create if the create failed. In fact, I would recommend it in case the file you are trying to redirect the open to lives on a different volume. However, one thing to be aware of is that you need to query the file name in preCreate and pass it to postCreate because you can’t get it in postCreate if the create failed.

Removing the prefix before sending the name to applications is not trivial, you need to change a lot of buffers. Think about renames, directory enumerations, a lot of the ZwQueryInformationFile classes, directory change notifications (there may be more operations, I’d have to think about it some more). Also, do you just care about files or folders too?

Personally I would leave the names unchanged and implement some logic to decide if the file is interesting (a list of names, a list of folders or you could even pass the name to user mode and let it decide if the file is interesting).

Regards,
Alex.
This posting is provided “AS IS” with no warranties, and confers no rights.

Great, I can use STATUS_REPARSE for this. That should make things much more simple. I really appreciate your help in sorting this out.

It was a hard decision to use filename tags, but the other options had large overhead or scaling issues. The minifilter is suppose to log access to flagged files and needs to be deployed to different computers. The tag is suppose to make life easy for the administrator (just filter needs to be installed, adding files to watch is just changing the filename).

The other option would be user space as you mentioned, but I assumed that would include a pretty painful performance hit.

Thanks for your help again
Ryan

Well, before you go too deep into implementation, please reconsider the user mode case scenario. The implementation would be greatly simplified and I don’t expect the perf hit to be too bad. But you can see for yourself by changing the Scanner sample to always send the name of the file to user mode (ScannerpScanFileInUserMode should simply send the file name in the buffer) and then change the user mode agent to do something similar to the decision process in your app (or to not do anything so you can just measure the perf hit of this approach outside of any other factors).

Your other requirement that this needs to work just with the minifilter is of course something this solution can’t offer, but if it’s ease of deployment you’re after you could try to implement the user agent in a similar fashion to the Sysinternals tools (have one executable that drops, installs and starts the minifilter). Also, since you mention the purpose is to log access to some files, the user mode client could also take care of the logging.

Regards,
Alex.
This posting is provided “AS IS” with no warranties, and confers no rights.