about the filespy sample and SpyGetFullPathName

Hi,
I’m studying the filespy sample in MS IFS kit, I need to write a function
similiar to the SpyGetFullPathName function of the sample, but I don’t
understand some lines of the code in this function, the following are the
code:

if (FILE_DEVICE_NETWORK_FILE_SYSTEM !=
devExt->ThisDeviceObject->DeviceType) {
RtlCopyUnicodeString( FileName, &devExt->UserNames );
} else if (FlagOn( FileObject->Flags, FO_DIRECT_DEVICE_OPEN )) {
RtlCopyUnicodeString( FileName, &devExt->DeviceName );
//
// We are now done since there will be no more to the name in this
// case, so return TRUE.
//
return TRUE;
}

If it’s a network file system, it’ll check the FileObject->Flags to see if
the FO_DIRECT_DEVICE_OPEN flag is on, but I don’t know what’s the meaning of
this flag, the comment said it means a direct device open, but what’s direct
device open? I’ve searched through google but find nothing about this flag,
and there are no information in the NTDDK.H about this flag either.
Could somebody give me some information about this flag? I don’t know
whether should I add some checking similar to the above code to my function.
Sorry for the silly question.

Thanks
Liu Yang

This bit of logic is due to the fact that network file systems structure
their device objects differently than local file systems.

For local file systems, the file system has one device object, which we
call its control device object, on which it gets general control type
requests (like, mount or shutdown) then it has a separate device object,
which we call a volume device object, for each volume it has mounted
(e.g., c:, d:, etc.). Therefore, IOs to different volumes go to
different device objects.

Remote file systems don’t really support the concept of volume, so they
have one device object through which all IO goes whether it is a control
type command or an IO to a share that is currently being accessed. The
way that you can tell the difference between these two types of requests
to a remote file system’s device object is looking at the
FO_DIRECT_DEVICE_OPEN flag in the file object. To send control requests
to the remote file system, the caller needs to open the device itself,
like \Device\LanmanRedirector. On that type of open, the
FO_DIRECT_DEVICE_OPEN flag gets set.

We care about this in SpyGetFullPathName because how we build up a
meaningful name to return to the user depends on what type of object we
are talking to – remote vs. local file system, talking to a share vs.
talking to the remote file system itself.

Hope that helps,

Molly Brown
Microsoft Corporation

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

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Yang
Sent: Thursday, August 07, 2003 7:11 AM
To: File Systems Developers
Subject: [ntfsd] about the filespy sample and SpyGetFullPathName

Hi,
I’m studying the filespy sample in MS IFS kit, I need to write a
function similiar to the SpyGetFullPathName function of the sample, but
I don’t understand some lines of the code in this function, the
following are the
code:

if (FILE_DEVICE_NETWORK_FILE_SYSTEM !=
devExt->ThisDeviceObject->DeviceType) {
RtlCopyUnicodeString( FileName, &devExt->UserNames );
} else if (FlagOn( FileObject->Flags, FO_DIRECT_DEVICE_OPEN )) {
RtlCopyUnicodeString( FileName, &devExt->DeviceName );
//
// We are now done since there will be no more to the name in
this
// case, so return TRUE.
//
return TRUE;
}

If it’s a network file system, it’ll check the FileObject->Flags to see
if the FO_DIRECT_DEVICE_OPEN flag is on, but I don’t know what’s the
meaning of this flag, the comment said it means a direct device open,
but what’s direct device open? I’ve searched through google but find
nothing about this flag, and there are no information in the NTDDK.H
about this flag either.
Could somebody give me some information about this flag? I don’t know
whether should I add some checking similar to the above code to my
function.
Sorry for the silly question.

Thanks
Liu Yang


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

Thanks a lot, Molly, got it now.

“Molly Brown” wrote in message
news:xxxxx@ntfsd…

This bit of logic is due to the fact that network file systems structure
their device objects differently than local file systems.

For local file systems, the file system has one device object, which we
call its control device object, on which it gets general control type
requests (like, mount or shutdown) then it has a separate device object,
which we call a volume device object, for each volume it has mounted
(e.g., c:, d:, etc.). Therefore, IOs to different volumes go to
different device objects.

Remote file systems don’t really support the concept of volume, so they
have one device object through which all IO goes whether it is a control
type command or an IO to a share that is currently being accessed. The
way that you can tell the difference between these two types of requests
to a remote file system’s device object is looking at the
FO_DIRECT_DEVICE_OPEN flag in the file object. To send control requests
to the remote file system, the caller needs to open the device itself,
like \Device\LanmanRedirector. On that type of open, the
FO_DIRECT_DEVICE_OPEN flag gets set.

We care about this in SpyGetFullPathName because how we build up a
meaningful name to return to the user depends on what type of object we
are talking to – remote vs. local file system, talking to a share vs.
talking to the remote file system itself.

Hope that helps,

Molly Brown
Microsoft Corporation

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

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Yang
Sent: Thursday, August 07, 2003 7:11 AM
To: File Systems Developers
Subject: [ntfsd] about the filespy sample and SpyGetFullPathName

Hi,
I’m studying the filespy sample in MS IFS kit, I need to write a
function similiar to the SpyGetFullPathName function of the sample, but
I don’t understand some lines of the code in this function, the
following are the
code:

Might it be a small improvement of this function?
About the code retreiving the name of a relative opened file, it’ll first
invoke the function SpyQueryFileSystemForFileName on the parent file object
to retrieve the name of the parent directory, can we simply invoke the
SpyQueryFileSystemForFileName on the current fileobject since it’ll save a
lot of lines, I wonder if it will bring bugs if I do so, but seems it works
fine till now.

The relative code are listed below, would it be better to change the
FileObject->RelatedFileObject to FileObject in the call of
SpyQueryFileSystemForFileName?

//
// CASE 3: We are opening a file that has a RelatedFileObject.
//
else if (FlagOn( LookupFlags, NLFL_IN_CREATE ) &&
(NULL != FileObject->RelatedFileObject)) {

//
// Must be a relative open. Use ObQueryNameString to get
// the name of the related FileObject. Then we will append this
// fileObject’s name.
//
// Note:
// The name in FileObject and FileObject->RelatedFileObject are
accessible. Names further up
// the related file object chain (ie
FileObject->RelatedFileObject->RelatedFileObject)
// may not be accessible. This is the reason we use
ObQueryNameString
// to get the name for the RelatedFileObject.
//
PFILE_NAME_INFORMATION relativeNameInfo =
(PFILE_NAME_INFORMATION)buffer;
ULONG returnLength;

status = SpyQueryFileSystemForFileName(
FileObject->RelatedFileObject,

devExt->AttachedToDeviceObject,
sizeof( buffer ),
relativeNameInfo,
&returnLength );

if (NT_SUCCESS( status ) &&
((FileName->Length + relativeNameInfo->FileNameLength +
FileObject->FileName.Length + sizeof( L’\’ ))
<= FileName->MaximumLength)) {

//
// We were able to get the relative fileobject’s name and we
have
// enough room in the FileName buffer, so build up the file
name
// in the following format:
// [volumeName][relativeFileObjectName][FileObjectName]
// The VolumeName is already in FileName if we’ve got one.
//
RtlCopyMemory(
&FileName->Buffer[FileName->Length/sizeof(WCHAR)],
relativeNameInfo->FileName,
relativeNameInfo->FileNameLength );

FileName->Length += (USHORT)relativeNameInfo->FileNameLength;

} else if ((FileName->Length + FileObject->FileName.Length +
sizeof(L"…\")) <=
FileName->MaximumLength ) {

//
// Either the query for the relative fileObject name was
unsuccessful,
// or we don’t have enough room for the relativeFileObject
name, but we
// do have enough room for “…[fileObjectName]” in FileName.
//
status = RtlAppendUnicodeToString( FileName, L"…\" );
ASSERT( status == STATUS_SUCCESS );
}

//
// If there is not a slash and the end of the related file object
// string and there is not a slash at the front of the file object
// string, then add one.
//
if (((FileName->Length < sizeof(WCHAR) ||
(FileName->Buffer[(FileName->Length/sizeof(WCHAR))-1] !=
L’\‘))) &&
((FileObject->FileName.Length < sizeof(WCHAR)) ||
(FileObject->FileName.Buffer[0] != L’\')))
{
RtlAppendUnicodeToString( FileName, L"\" );
}

//
// At this time, copy over the FileObject->FileName to the FileName
// unicode string.
//
RtlAppendUnicodeStringToString( FileName, &FileObject->FileName );
}

“Molly Brown” wrote in message
news:xxxxx@ntfsd…

This bit of logic is due to the fact that network file systems structure
their device objects differently than local file systems.

For local file systems, the file system has one device object, which we
call its control device object, on which it gets general control type
requests (like, mount or shutdown) then it has a separate device object,
which we call a volume device object, for each volume it has mounted
(e.g., c:, d:, etc.). Therefore, IOs to different volumes go to
different device objects.

No; SpyGetFullPathName may be called BEFORE the file object is opened,
so you can’t ask the filesystem for its full path yet.

Yang wrote:

Might it be a small improvement of this function?
About the code retreiving the name of a relative opened file, it’ll first
invoke the function SpyQueryFileSystemForFileName on the parent file object
to retrieve the name of the parent directory, can we simply invoke the
SpyQueryFileSystemForFileName on the current fileobject since it’ll save a
lot of lines, I wonder if it will bring bugs if I do so, but seems it works
fine till now.

The relative code are listed below, would it be better to change the
FileObject->RelatedFileObject to FileObject in the call of
SpyQueryFileSystemForFileName?

//
// CASE 3: We are opening a file that has a RelatedFileObject.
//
else if (FlagOn( LookupFlags, NLFL_IN_CREATE ) &&
(NULL != FileObject->RelatedFileObject)) {

//
// Must be a relative open. Use ObQueryNameString to get
// the name of the related FileObject. Then we will append this
// fileObject’s name.
//
// Note:
// The name in FileObject and FileObject->RelatedFileObject are
accessible. Names further up
// the related file object chain (ie
FileObject->RelatedFileObject->RelatedFileObject)
// may not be accessible. This is the reason we use
ObQueryNameString
// to get the name for the RelatedFileObject.
//
PFILE_NAME_INFORMATION relativeNameInfo =
(PFILE_NAME_INFORMATION)buffer;
ULONG returnLength;

status = SpyQueryFileSystemForFileName(
FileObject->RelatedFileObject,

devExt->AttachedToDeviceObject,
sizeof( buffer ),
relativeNameInfo,
&returnLength );

if (NT_SUCCESS( status ) &&
((FileName->Length + relativeNameInfo->FileNameLength +
FileObject->FileName.Length + sizeof( L’\’ ))
<= FileName->MaximumLength)) {

//
// We were able to get the relative fileobject’s name and we
have
// enough room in the FileName buffer, so build up the file
name
// in the following format:
// [volumeName][relativeFileObjectName][FileObjectName]
// The VolumeName is already in FileName if we’ve got one.
//
RtlCopyMemory(
&FileName->Buffer[FileName->Length/sizeof(WCHAR)],
relativeNameInfo->FileName,
relativeNameInfo->FileNameLength );

FileName->Length += (USHORT)relativeNameInfo->FileNameLength;

} else if ((FileName->Length + FileObject->FileName.Length +
sizeof(L"…\")) <=
FileName->MaximumLength ) {

//
// Either the query for the relative fileObject name was
unsuccessful,
// or we don’t have enough room for the relativeFileObject
name, but we
// do have enough room for “…[fileObjectName]” in FileName.
//
status = RtlAppendUnicodeToString( FileName, L"…\" );
ASSERT( status == STATUS_SUCCESS );
}

//
// If there is not a slash and the end of the related file object
// string and there is not a slash at the front of the file object
// string, then add one.
//
if (((FileName->Length < sizeof(WCHAR) ||
(FileName->Buffer[(FileName->Length/sizeof(WCHAR))-1] !=
L’\‘))) &&
((FileObject->FileName.Length < sizeof(WCHAR)) ||
(FileObject->FileName.Buffer[0] != L’\')))
{
RtlAppendUnicodeToString( FileName, L"\" );
}

//
// At this time, copy over the FileObject->FileName to the FileName
// unicode string.
//
RtlAppendUnicodeStringToString( FileName, &FileObject->FileName );
}

“Molly Brown” wrote in message
> news:xxxxx@ntfsd…
>
> This bit of logic is due to the fact that network file systems structure
> their device objects differently than local file systems.
>
> For local file systems, the file system has one device object, which we
> call its control device object, on which it gets general control type
> requests (like, mount or shutdown) then it has a separate device object,
> which we call a volume device object, for each volume it has mounted
> (e.g., c:, d:, etc.). Therefore, IOs to different volumes go to
> different device objects.
>
>
>
> —
> You are currently subscribed to ntfsd as: xxxxx@nryan.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>


- Nick Ryan (MVP for DDK)

As Nick said, in CASE 3 we are dealing with a file object which has not
be opened yet (that’s what the NLFL_IN_CREATE flag means), therefore we
cannot query the file system for the name but instead build it up
ourselves with the information in the file object.

For file objects that have already been opened, we do call
SpyQueryFileSystemForName on the file object – see CASE 5.

Thanks,

Molly Brown
Microsoft Corporation

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

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Nick Ryan
Sent: Friday, August 08, 2003 1:52 AM
To: File Systems Developers
Subject: [ntfsd] Re: about the filespy sample and SpyGetFullPathName

No; SpyGetFullPathName may be called BEFORE the file object is opened,
so you can’t ask the filesystem for its full path yet.

Yang wrote:

Might it be a small improvement of this function?
About the code retreiving the name of a relative opened file, it’ll
first invoke the function SpyQueryFileSystemForFileName on the parent
file object to retrieve the name of the parent directory, can we
simply invoke the SpyQueryFileSystemForFileName on the current
fileobject since it’ll save a lot of lines, I wonder if it will bring
bugs if I do so, but seems it works fine till now.

The relative code are listed below, would it be better to change the
FileObject->RelatedFileObject to FileObject in the call of
SpyQueryFileSystemForFileName?

//
// CASE 3: We are opening a file that has a RelatedFileObject.
//
else if (FlagOn( LookupFlags, NLFL_IN_CREATE ) &&
(NULL != FileObject->RelatedFileObject)) {

//
// Must be a relative open. Use ObQueryNameString to get
// the name of the related FileObject. Then we will append
this
// fileObject’s name.
//
// Note:
// The name in FileObject and FileObject->RelatedFileObject
are accessible. Names further up
// the related file object chain (ie
FileObject->RelatedFileObject->RelatedFileObject)
// may not be accessible. This is the reason we use
ObQueryNameString
// to get the name for the RelatedFileObject.
//
PFILE_NAME_INFORMATION relativeNameInfo =
(PFILE_NAME_INFORMATION)buffer;
ULONG returnLength;

status = SpyQueryFileSystemForFileName(
FileObject->RelatedFileObject,

devExt->AttachedToDeviceObject,
sizeof( buffer ),
relativeNameInfo,
&returnLength );

if (NT_SUCCESS( status ) &&
((FileName->Length + relativeNameInfo->FileNameLength +
FileObject->FileName.Length + sizeof( L’\’ ))
<= FileName->MaximumLength)) {

//
// We were able to get the relative fileobject’s name and

we have
// enough room in the FileName buffer, so build up the
file name
// in the following format:
//
[volumeName][relativeFileObjectName][FileObjectName]
// The VolumeName is already in FileName if we’ve got
one.
//
RtlCopyMemory(
&FileName->Buffer[FileName->Length/sizeof(WCHAR)],
relativeNameInfo->FileName,
relativeNameInfo->FileNameLength );

FileName->Length +=
(USHORT)relativeNameInfo->FileNameLength;

} else if ((FileName->Length + FileObject->FileName.Length +
sizeof(L"…\")) <=
FileName->MaximumLength ) {

//
// Either the query for the relative fileObject name was
unsuccessful,
// or we don’t have enough room for the
relativeFileObject name, but we
// do have enough room for “…[fileObjectName]” in
FileName.
//
status = RtlAppendUnicodeToString( FileName, L"…\" );
ASSERT( status == STATUS_SUCCESS );
}

//
// If there is not a slash and the end of the related file
object
// string and there is not a slash at the front of the file
object
// string, then add one.
//
if (((FileName->Length < sizeof(WCHAR) ||
(FileName->Buffer[(FileName->Length/sizeof(WCHAR))-1] !=
L’\‘))) &&
((FileObject->FileName.Length < sizeof(WCHAR)) ||
(FileObject->FileName.Buffer[0] != L’\')))
{
RtlAppendUnicodeToString( FileName, L"\" );
}

//
// At this time, copy over the FileObject->FileName to the
FileName
// unicode string.
//
RtlAppendUnicodeStringToString( FileName,
&FileObject->FileName );
}

“Molly Brown” wrote in message
> news:xxxxx@ntfsd…
>
> This bit of logic is due to the fact that network file systems
> structure their device objects differently than local file systems.
>
> For local file systems, the file system has one device object, which
> we call its control device object, on which it gets general control
> type requests (like, mount or shutdown) then it has a separate device
> object, which we call a volume device object, for each volume it has
> mounted (e.g., c:, d:, etc.). Therefore, IOs to different volumes go
> to different device objects.
>
>
>
> —
> You are currently subscribed to ntfsd as: xxxxx@nryan.com To
> unsubscribe send a blank email to xxxxx@lists.osr.com
>


- Nick Ryan (MVP for DDK)


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