Understanding IRP_MJ_DIRECTORY_CONTROL

Hi there,

i try to get behind the concept of querying the content of a directory, but there seems to be some essential information missing in my head:

My understanding is, that depending on the kind of IO, the correspondent buffer (DirectoryBuffer or MdlAddress in a Minifilters parameters) provides me with a list of the Files inside a directory, if called in the Post-Directory-Control Routine.

The Files i assumed to be represented by the structure defined in FileInformationClass. So if i wanted to walk through these Files, all i had to do is provide for example a FILE_BOTH_DIR_INFORMATION-pointer to the according buffer and would be very able to access the first file-information. By just adding the NextEntryOffset to this Pointer, i expected to get to the info of the next file.

When i try to do so, i dont get very useful information so either these are some wrong assumptions or i overlooked some great mistakes in my code. Can anyone enlighten me?

Thanks so far, but that problem i got solved on my own. I had to lock the UserBuffer before accessing the MDL.

But i got another problem now: If i want to change the data provided by the buffer, i dont really know how to do this. My main problem here is that i dont get how to exchange the buffers due to some lack of understanding regarding MDLs.

For example if i just want to create a new Buffer with the same data:

My approach would be to create a new Buffer with the Size of all items provided in the buffer. Next i zero this buffer. Then i copy the data from the MdlAddress into the new Buffer(?)

At last i would free the buffer provided by MdlAddress and set the MdlAddress to the address of the new Buffer.

I tried it and it lead into an immediate crash, so can anybody please explain to mehow i really exchange these buffers?

Thanks in advace

Gernot

I am not familiar with mini-filters, but mdl describes user mode buffer of caller. Mdl describes buffer by means of list PFNs (index to page of physical memory) , so these pages can be mapped into address space of kernel or different process.

I think you don’t need to allocate new MDL you should do your changes in-place in post processing. But there are other traps like possible high IRQL in post operation…

-bg

If you’re only changing fixed sized members, you don’t need to swap
buffers. I’m doing some post-processing for file sizes, and I’m not
swapping any buffers. If you’re doing stuff changing file names, things
will probably get interesting.

~Eric

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@xythos.com
Sent: Monday, April 28, 2008 7:34 AM
To: Windows File Systems Devs Interest List
Subject: RE:[ntfsd] Understanding IRP_MJ_DIRECTORY_CONTROL

I am not familiar with mini-filters, but mdl describes user mode buffer
of caller. Mdl describes buffer by means of list PFNs (index to page of
physical memory) , so these pages can be mapped into address space of
kernel or different process.

I think you don’t need to allocate new MDL you should do your changes
in-place in post processing. But there are other traps like possible
high IRQL in post operation…

-bg


NTFSD is sponsored by OSR

For our schedule debugging and file system seminars (including our new
fs mini-filter seminar) visit:
http://www.osr.com/seminars

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

i wanted to add an extra entry, so i would need a bigger Buffer. Maybe i should have stated this from the beginning. So how can i do that?

Well, I’m guessing that you won’t be able to return a larger buffer to
the client than it sent you, which means you won’t be able to just swap
buffers with a larger one and then return it. If you know the size of
the extra entry (or can at least bound it reasonably), I’d try swapping
in a smaller buffer in the pre-op, letting the lower-level drivers fill
it as they want to, and then copying it to the original buffer in the
post op and adding your entry.

I can see a couple of problems with this approach though, first if the
size of the entry you want to add is large enough relative to the size
of the whole buffer, when you swap a smaller buffer, the lower level
driver may not be able to fit anything in it.
Second, if you’ve swapped buffers, you need to handle the buffers with
draining IO in your postop. (not a problem, just something to be aware
of) This is covered in one of the various dev guides from MS.

~Eric

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@david-bs.de
Sent: Monday, April 28, 2008 9:57 AM
To: Windows File Systems Devs Interest List
Subject: RE:[ntfsd] Understanding IRP_MJ_DIRECTORY_CONTROL

i wanted to add an extra entry, so i would need a bigger Buffer. Maybe i
should have stated this from the beginning. So how can i do that?


NTFSD is sponsored by OSR

For our schedule debugging and file system seminars (including our new
fs mini-filter seminar) visit:
http://www.osr.com/seminars

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

>i wanted to add an extra entry, so i would need a bigger Buffer. Maybe i should

have stated this from the beginning. So how can i do that?

You can do it by modification of status. When FSD returns STATUS_NO_MORE_FILES, fill buffer with your entry and return STATUS_SUCCESS in post operation. Remember it in the context and when you get next IRP_MJ_DIRECTORY_CONTROL you should in pre operation complete request with STATUS_NO_MORE_FILES. But it is very difficult implement IRP_MJ_DIR_CONTROL and there are a lot of nuances. You have to consider wildcard pattern, FileInformationClass, ReturnSingleEntry, RestartScan, how to generate index for entry so it is not in conflict with FSD index, …

Take a look at ZwQueryDirectoryFile() documentation and write test program using native API -NtQueryDirectoryFile(). It will help you understand all nuances.

Just hint: for evaluating if your entry fits wildcard pattern use FsRtlIsNameInExpression().

-bg