IRP_MJ_NETWORK_QUERY_OPEN question

I’m working with IRP_MJ_NETWORK_QUERY_OPEN and trying to understand it.
Seems like it’s kind of a special case. Ideally, I’d like to get the
filename for the request, and user account and PID that issued it (like is
available in IRP_MJ_CREATE).

The filename is apparently available, but I can’t seem to get it with
FltGetFileNameInformation (part of the reason might be that
IRP_MJ_NETWORK_QUERY_OPEN isn’t guaranteed to be called <= APC_LEVEL in
PostOp like IRP_MJ_CREATE is). Perhaps
Data->Iopb->TargetFileObject->FileName is not valid and instead the
Parameters.NetworkQueryOpen.Irp should be used??? Are there any Fltxxx
functions to make that easier?

As far as the PID, FltGetRequestorProcessId seems to be working. Is it
guaranteed to always for for this IRP?

Finally, the user that issued the original command. Is that available
anywhere? I’m assuming (haven’t tried it yet) I can probably disallow
FastIO and get it to come back through as a IRP_MJ_CREATE and grab the user
there, but that would seem to defeat the whole point of
IRP_MJ_NETWORK_QUERY_OPEN in the first place and possibly have a performance
impact. Are there other options?

Thanks from a lurker that keeps reading these posts and learning.

Doug

Before you go too far down the track, be aware that, AFAICS, LUAFV (present
by default on the system disk >= Vista) systematically turns off this
opcode.

Given that the system disk tends to be hottest for creates we can only
assume that this operation doesn’t assist much or that performance wasn’t
important to these developers.

If you are primarily assuming a system disk you may save yourself a lot of
time by just doing as you suggest and refusing the FastIO before LUAFV does
it for you.

Remember that what is going on behind the scenes is that this is a Fastio
call, so although there is an IRP it isn’t an “IRP operation”. So (modulo
injected threads), you should be able to query the current process for
everything you need.

FltObject->FileObject should be valid (pre and post) and should be the same
as the IrpSp in the irp.

I would view FltGetFileNameInformation failing as a bug, but just in case
(although I’m not sure why you should ever come back in post at > PASSIVE)
you might want to try with FLT_PREOP_SYNCRHONIZE. OTOH, be aware that there
is a good chance that said FltGetFileNameInformation may well provoke a
create which is exactly what you are trying to avoid in this path.

HTH

Rod

Rod Widdowson
Consulting Partner
Steading System Software LLP
+44 1368 850217 +1 508 915 4790

“Doug” > wrote in message news:xxxxx@ntfsd…
> I’m working with IRP_MJ_NETWORK_QUERY_OPEN and trying to
> understand it. Seems like it’s kind of a special case. Ideally, I’d like
> to
> get the filename for the request, and user account and PID that issued it
> (like is available in IRP_MJ_CREATE).
>
> The filename is apparently available, but I can’t seem to get it with
> FltGetFileNameInformation (part of the reason might be that
> IRP_MJ_NETWORK_QUERY_OPEN isn’t guaranteed to
> be called <= APC_LEVEL in PostOp like IRP_MJ_CREATE is).
> Perhaps Data->Iopb->TargetFileObject->FileName is not valid and
> instead the Parameters.NetworkQueryOpen.Irp should be used???
> Are there any Fltxxx functions to make that easier?
>
> As far as the PID, FltGetRequestorProcessId seems to be working.
> Is it guaranteed to always for for this IRP?
>
> Finally, the user that issued the original command. Is that available
> anywhere? I’m assuming (haven’t tried it yet) I can probably disallow
> FastIO and get it to come back through as a IRP_MJ_CREATE and
> grab the user there, but that would seem to defeat the whole point of
> IRP_MJ_NETWORK_QUERY_OPEN in the first place and
> possibly have a performance impact. Are there other options?
>
> Thanks from a lurker that keeps reading these posts and learning.

Thank you Rod.

FltObject->FileObject should be valid (pre and post) and should be the
same as the IrpSp in the irp.

I’m finding that FltGetFileNameInformation fails, but just grabbing the
name from FltObjects->FileObject->FileName works (though it’s not
nicely normalized like you can get from FltGetFileNameInformation). I’ll
dig around the API to see if there is another way to normalize it.

you should be able to query the current process for everything you need.

Really? I had come to believe that the only way of getting the user
making the original request was to grab the SID during IRP_MJ_CREATE from
Data->Iopb->Parameters.Create.SecurityContext->AccessState->SubjectSecurityC
ontext

Is there another way?

Doug

I’m assuming you’re using a minifilter.

The most interesting feature of this operation is that one of the parameters
is an Irp. This is pretty much the only place in a minifilter where you will
actually touch an IRP. That IRP is a fully initialized CREATE IRP and you
can use it for all your context needs (getting the PID and the user like you
would for any normal create).

I don’t remember about FltGetFileNameInformation, could be a bug or it could
be something that simply doesn’t make sense in this context.

Regardless, I would suggest that you disallow this request (return
FLT_PREOP_DISALLOW_FASTIO in the preOp) and expect it will come on the
regular create path, which is much easier to handle. As Rod pointed out,
LUAFV (which is an inbox minifilter enabled by default on all Vista+ systems
as far as I remember) does it anyway so you’re not gaining anything from a
performance perspective. And then there are other gotchas about this
operation which IMO do not justify the extra effort.

Thanks,
Alex.