Weird file path in pre-create

Hi,

I am trying to figure out whether I’m dealing with a nasty memory
corruption bug or something that I simply do not understand:

From the command line, I do a “fsutil hardlink list d:\foo\bar”, where
“bar” is a directory. Shortly after the IRP_MJ_QUERY_INFORMATION, I get
an IRP_MJ_CREATE. In the pre-path of this create, I concatenate the
volume path, the file name in the related file object, and the file name
in the file object, getting this file name:
“\Device\HarddiskVolume2\foo\bar\XXXX”, where XXXX are 4 non-printable
characters. The 1st byte of these non printable characters is
foo\bar’s parent file ID… I’m doing this concatenation because I need
to implement name provider callbacks for files that do not exist
(directories “foo” and “bar” do exist).

Next, I request the correct file name using “FltGetFileNameInformation”.
The new file name I get is
“\Device\HarddiskVolume2\foo”, where it seems that the file system knows
what it must do…

I’m 99% sure that this is not a bug. I haven’t found any docs stating
what exactly a generate file name name provider callback should do.

Any ideas?


Thanos Makatos
Junior Engineer
Storage Systems Research Group - Computer Science Department
Barcelona Supercomputing Center - Centro Nacional de Supercomputación
http://www.bsc.es/StorageSystems

WARNING / LEGAL TEXT: This message is intended only for the use of the
individual or entity to which it is addressed and may contain
information which is privileged, confidential, proprietary, or exempt
from disclosure under applicable law. If you are not the intended
recipient or the person responsible for delivering the message to the
intended recipient, you are strictly prohibited from disclosing,
distributing, copying, or in any way using this message. If you have
received this communication in error, please notify the sender and
destroy and delete any copies you may have received.

http://www.bsc.es/disclaimer.htm

In general the FLT_GENERATE_FILE_NAME function should generate a name for
the file as it should appear above that minifilter.

I’m not clear about what exactly is going on in your case. When you say
“”\Device\HarddiskVolume2\foo\bar\XXXX", where XXXX are 4 non-printable
characters. The 1st byte of these non printable characters is foo\bar’s
parent file ID "

What do you mean the first byte is the file ID ? the file id is at least 8
bytes.

Also, when you say “foo\bar’s parent” , do you mean the volume ? I thought
that foo\bar is at the root of the volume ?

Could you please explain what your filters does ? Also, could you please
show what the related file object looks like (!fileobj) and what the actual
file object looks like, and what the callback data shows ? (!fltkd.cbd)…

Thanks,
Alex.

Hi Alex,

On 06/10/2010 17:53, Alex Carp wrote:

In general the FLT_GENERATE_FILE_NAME function should generate a name for
the file as it should appear above that minifilter.

I don’t understand what this means :S.

I’m not clear about what exactly is going on in your case. When you say
“”\Device\HarddiskVolume2\foo\bar\XXXX", where XXXX are 4 non-printable
characters. The 1st byte of these non printable characters is foo\bar’s
parent file ID "

What do you mean the first byte is the file ID ? the file id is at least 8
bytes.

The file ID is 8 bytes, but I print all 8 bytes separately. Since this
test is done on an almost empty test volume, file IDs are expected to be
small. Actually I wasn’t totally correct: the 1st byte matches the file
ID, the last but one is 3, and the rest of them are 0.

Also, when you say “foo\bar’s parent” , do you mean the volume ? I thought
that foo\bar is at the root of the volume ?

The file ID printed is foo’s file ID (bar’s parent). foo\bar is inside a
directory called “lala”, which is at the root of the volume (full path
is “D:\lala\foo\bar”).

Could you please explain what your filters does ? Also, could you please
show what the related file object looks like (!fileobj) and what the actual
file object looks like, and what the callback data shows ? (!fltkd.cbd)…

My filter doesn’t do anything complex, I’m only trying to understand
what name provider callbacks should do.

The related file object is NULL.

Target file object:
\lala\foo

Device Object: 0x90e66030 \Driver\volmgr
Vpb is NULL

Flags: 0x2
Synchronous IO

CurrentByteOffset: 0

Callback data:
IRP_CTRL: 909695f8 CREATE (0) [00000009] Irp SystemBuffer
Flags : [1000000c] DontCopyParms Synchronize FixedAlloc
Irp : a6ef6e28
DeviceObject : 910e3408 “\Device\HarddiskVolume2”
FileObject : 917a4558
CompletionNodeStack : 909696b0 Size=2 Next=1
SyncEvent : (90969608)
InitiatingInstance : 00000000
Icc : 995a3a3c
CreateIrp.NameCacheCtrl : 9163ba78
CreateIrp.SavedFsContext : 00000000
CallbackData : (90969658)
Flags : [00000009] Irp SystemBuffer
Thread : 91019918
Iopb : 90969684
RequestorMode : [01] UserMode
IoStatus.Status : 0xffffffff
IoStatus.Information : 00000000
TagData : 00000000
FilterContext[0] : 00000000
FilterContext[1] : 00000000
FilterContext[2] : 00000000
FilterContext[3] : 00000000

Cmd IrpFl OpFl CmpFl Instance FileObjt Completion-Context
Node Adr



[0,0] 00000000 00 0000 00000000 00000000 00000000-00000000
909696f8
Args: 00000000 00000000 00000000 00000000 00000000 0000000000000000
[0,0] 40000884 00 0000 8d485530 917a4558 8b6d4760-00000000
909696b0
(“ABCD”,“ABCD Instance”) ABCD!ABCDPostCreate (verified)
Args: 995a3ac4 01000060 00030000 00000000 00000000 0000000000000000
Working IOPB:
>[0,0] 40000884 00 8d485530 917a4558
90969684
(“ABCD”,“ABCD Instance”)
Args: 995a3ac4 01000060 00030000 00000000 00000000 0000000000000000

Thanks

Thanks,
Alex.


NTFSD is sponsored by OSR

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

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer


Thanos Makatos
Junior Engineer
Storage Systems Research Group - Computer Science Department
Barcelona Supercomputing Center - Centro Nacional de Supercomputación
http://www.bsc.es/StorageSystems

WARNING / LEGAL TEXT: This message is intended only for the use of the
individual or entity to which it is addressed and may contain
information which is privileged, confidential, proprietary, or exempt
from disclosure under applicable law. If you are not the intended
recipient or the person responsible for delivering the message to the
intended recipient, you are strictly prohibited from disclosing,
distributing, copying, or in any way using this message. If you have
received this communication in error, please notify the sender and
destroy and delete any copies you may have received.

http://www.bsc.es/disclaimer.htm

Hello Thanos,

Well, a minifilter doesn’t always need to implement name providers. It only
needs to do so if it changes something in the namespace. For example, say
that you wanted to change the name of “D:\lala\foo” to “D:\lala\moo”. In
this case you would need to implement name provider callbacks, and in your
generate file name, you would check whether the name is for the
“d:\lala\foo” file and return “d:\lala\moo”. This makes it so that filters
below yours would see the name as it exists on the file system
(“d:\lala\foo”) and the ones above you (and the IO manager and everything in
user mode) would see “d:\lala\moo”. Does this make sense ?

So when I was asking what your filter does what I wanted to know is what
kind of namespace operations it performs that require it to be a name
provider.

Could you please print out the code that you use to generate and print the
file name ?

Thanks,
Alex.

It turns out that the IRP_MJ_CREATE had the FILE_OPEN_BY_FILE_ID flag
set, which means I shouldn’t be looking in the fo->filename etc. at the
first place… right?

On 07/10/2010 17:18, Alex Carp wrote:

Hello Thanos,

Well, a minifilter doesn’t always need to implement name providers. It only
needs to do so if it changes something in the namespace. For example, say
that you wanted to change the name of “D:\lala\foo” to “D:\lala\moo”. In
this case you would need to implement name provider callbacks, and in your
generate file name, you would check whether the name is for the
“d:\lala\foo” file and return “d:\lala\moo”. This makes it so that filters
below yours would see the name as it exists on the file system
(“d:\lala\foo”) and the ones above you (and the IO manager and everything in
user mode) would see “d:\lala\moo”. Does this make sense ?

So when I was asking what your filter does what I wanted to know is what
kind of namespace operations it performs that require it to be a name
provider.

Could you please print out the code that you use to generate and print the
file name ?

Thanks,
Alex.


NTFSD is sponsored by OSR

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

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer


Thanos Makatos
Junior Engineer
Storage Systems Research Group - Computer Science Department
Barcelona Supercomputing Center - Centro Nacional de Supercomputación
http://www.bsc.es/StorageSystems

WARNING / LEGAL TEXT: This message is intended only for the use of the
individual or entity to which it is addressed and may contain
information which is privileged, confidential, proprietary, or exempt
from disclosure under applicable law. If you are not the intended
recipient or the person responsible for delivering the message to the
intended recipient, you are strictly prohibited from disclosing,
distributing, copying, or in any way using this message. If you have
received this communication in error, please notify the sender and
destroy and delete any copies you may have received.

http://www.bsc.es/disclaimer.htm

If the FILE_OPEN_BY_FILE_ID is set then the ID (objectID or fileID) is
stored in fo->filename. To get a name for the file from an ID the only way I
know of is to open the file by ID and query the name (or use
FltGetFileNameInformation). Another way to do it is to way until postCreate
and then get the name there, but that depends on the architecture of your
filter.

Thanks,
Alex.