Retrieving device name from filter driver

This seems to be a FAQ - I may have enquired myself - but I am still having
a hard time getting to a file name from a filter driver.

This is the situation : I have a filter driver that communicates with
user-level code through the IRP_MJ_READ entry point. I wish to track which
files are being written into, and pass the information back to the user
level. It is understood that drive letters are not meaningful in the kernel.
The objective is to extract information from the PIRPs and PDEVICE_OBJECTs
and PFILE_OBJECTs which, when passed up to user level, will enable the EXE
to recover the file name, e.g. "\MADHATTER\FEDORA\alice.txt" or
"\Harddisk0\Partition2\whiterabbit.txt" --> "X:\whiterabbit.txt"

I am able to extract directory\file names, e.g.,
"\looking_glass\redqueen.txt", and I can get fully qualified paths from
network drives (more or less by accident!).

I have tried building an IRP with IRP_MJ_QUERY_INFORMATION, but it is
returning STATUS_INVALID_DEVICE_REQUEST (the code is appended).

I have tried deciphering NTFILMON's approach to no avail.

So, two questions:

  • Any idea why the call with IRP_MJ_QUERY_INFORMATION is failing?

  • How can I recover a device name (e.g., \Harddisk0\Partition1, or anything
    else the user code can parse) from the kernel driver?

Here is the code ... mostly stolen from NTFILMON.

// --grab current irp stack loc., then
DeviceObject->DeviceExtension->DeviceObject to get FSDevice ptr.
//pFSDevOb is File System Device Object, pFileOb is file object, other
buffers are OK
//Borrowed heavily from NTFILMON
ULONG GetFileName(PDEVICE_OBJECT pFSDevOb, PFILE_OBJECT pFileOb, WCHAR
*sFileName, ULONG ulLen)
{
PIRP pNewIrp;
KEVENT evt;
IO_STATUS_BLOCK iosb;
PIO_STACK_LOCATION pIO_Next;
ULONG ulRet = 0;
ASSERT(sFileName);

KeInitializeEvent(&evt, SynchronizationEvent, FALSE);

pNewIrp = IoAllocateIrp(pFSDevOb->StackSize, FALSE);
if(!pNewIrp)
return 0;

pNewIrp->AssociatedIrp.SystemBuffer = sFileName;
pNewIrp->UserEvent = &evt;
pNewIrp->UserIosb = &iosb;
pNewIrp->Tail.Overlay.Thread = PsGetCurrentThread();
pNewIrp->Tail.Overlay.OriginalFileObject = pFileOb;
pNewIrp->RequestorMode = KernelMode;
pNewIrp->Flags = 0;

pIO_Next = IoGetNextIrpStackLocation(pNewIrp);
pIO_Next->MajorFunction = IRP_MJ_QUERY_INFORMATION;
pIO_Next->DeviceObject = pFSDevOb;
pIO_Next->FileObject = pFileOb;
pIO_Next->Parameters.QueryFile.Length = ulLen;
pIO_Next->Parameters.QueryFile.FileInformationClass =
FileStandardInformation;//formerly FileNameInformation

IoSetCompletionRoutine(pNewIrp, F2QueryFileCompletion, &ulRet, TRUE, TRUE,
TRUE);

(void) IoCallDriver(pFSDevOb, pNewIrp);

KeWaitForSingleObject(&evt, Executive, KernelMode, TRUE, 0);

if(!NT_SUCCESS(iosb.Status))
return 0;

return ulRet;
}

NTSTATUS F2QueryFileCompletion(PDEVICE_OBJECT pFSDevOb, PIRP pIrp, ULONG *
pDWRet)
{
*pIrp->UserIosb = pIrp->IoStatus;

KeSetEvent(pIrp->UserEvent, 0, FALSE);
IoFreeIrp(pIrp);
return STATUS_MORE_PROCESSING_REQUIRED;
}

Question: are you actively filtering the volumes that you are interested
in? If so, then the name of the drive you are looking for is in the
volume device you are filtering.

From your example, I am not sure where you are getting the file object
from? Typically, a filter will get the filename and store it away
during IRP_MJ_CREATE and than associate its own internal object with the
file object address (or the FsContext address - or is that FsContext2?).
Using this model and filtering the device object for particular volumes
I am interested in - there should be no problem getting the name of the
file - including the drive letter or volume name.

/TomH

-----Original Message-----
From: Eric Fowler [mailto:xxxxx@seanet.com]
Sent: Monday, February 10, 2003 5:01 PM
To: File Systems Developers
Subject: [ntfsd] Retrieving device name from filter driver

This seems to be a FAQ - I may have enquired myself - but I am still
having
a hard time getting to a file name from a filter driver.

This is the situation : I have a filter driver that communicates with
user-level code through the IRP_MJ_READ entry point. I wish to track
which
files are being written into, and pass the information back to the user
level. It is understood that drive letters are not meaningful in the
kernel.
The objective is to extract information from the PIRPs and
PDEVICE_OBJECTs
and PFILE_OBJECTs which, when passed up to user level, will enable the
EXE
to recover the file name, e.g. "\MADHATTER\FEDORA\alice.txt" or
"\Harddisk0\Partition2\whiterabbit.txt" --> "X:\whiterabbit.txt"

I am able to extract directory\file names, e.g.,
"\looking_glass\redqueen.txt", and I can get fully qualified paths from
network drives (more or less by accident!).

I have tried building an IRP with IRP_MJ_QUERY_INFORMATION, but it is
returning STATUS_INVALID_DEVICE_REQUEST (the code is appended).

I have tried deciphering NTFILMON's approach to no avail.

So, two questions:

  • Any idea why the call with IRP_MJ_QUERY_INFORMATION is
    failing?

  • How can I recover a device name (e.g., \Harddisk0\Partition1,
    or anything
    else the user code can parse) from the kernel driver?

Here is the code ... mostly stolen from NTFILMON.

// --grab current irp stack loc., then
DeviceObject->DeviceExtension->DeviceObject to get FSDevice ptr.
//pFSDevOb is File System Device Object, pFileOb is file object, other
buffers are OK
//Borrowed heavily from NTFILMON
ULONG GetFileName(PDEVICE_OBJECT pFSDevOb, PFILE_OBJECT pFileOb, WCHAR
*sFileName, ULONG ulLen)
{
PIRP pNewIrp;
KEVENT evt;
IO_STATUS_BLOCK iosb;
PIO_STACK_LOCATION pIO_Next;
ULONG ulRet = 0;
ASSERT(sFileName);

KeInitializeEvent(&evt, SynchronizationEvent, FALSE);

pNewIrp = IoAllocateIrp(pFSDevOb->StackSize, FALSE);
if(!pNewIrp)
return 0;

pNewIrp->AssociatedIrp.SystemBuffer = sFileName;
pNewIrp->UserEvent = &evt;
pNewIrp->UserIosb = &iosb;
pNewIrp->Tail.Overlay.Thread = PsGetCurrentThread();
pNewIrp->Tail.Overlay.OriginalFileObject = pFileOb;
pNewIrp->RequestorMode = KernelMode;
pNewIrp->Flags = 0;

pIO_Next = IoGetNextIrpStackLocation(pNewIrp);
pIO_Next->MajorFunction = IRP_MJ_QUERY_INFORMATION;
pIO_Next->DeviceObject = pFSDevOb;
pIO_Next->FileObject = pFileOb;
pIO_Next->Parameters.QueryFile.Length = ulLen;
pIO_Next->Parameters.QueryFile.FileInformationClass =
FileStandardInformation;//formerly FileNameInformation

IoSetCompletionRoutine(pNewIrp, F2QueryFileCompletion, &ulRet,
TRUE, TRUE,
TRUE);

(void) IoCallDriver(pFSDevOb, pNewIrp);

KeWaitForSingleObject(&evt, Executive, KernelMode, TRUE, 0);

if(!NT_SUCCESS(iosb.Status))
return 0;

return ulRet;
}

NTSTATUS F2QueryFileCompletion(PDEVICE_OBJECT pFSDevOb, PIRP pIrp, ULONG
*
pDWRet)
{
*pIrp->UserIosb = pIrp->IoStatus;

KeSetEvent(pIrp->UserEvent, 0, FALSE);
IoFreeIrp(pIrp);
return STATUS_MORE_PROCESSING_REQUIRED;
}


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

My comments & questions are in the text.

Thanks very much.

Eric

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Tom Hansen
Sent: Monday, February 10, 2003 3:17 PM
To: File Systems Developers
Subject: [ntfsd] RE: Retrieving device name from filter driver

Question: are you actively filtering the volumes that you are interested
in? If so, then the name of the drive you are looking for is in the
volume device you are filtering.

[Dunno. All the filter does is report which files have been touched. It does
NOT change the data or interfere with the FS operations. I suppose that
makes it a passive filter, right? But you say "the name of the drive is in
the volume device" ... but WHERE? And where do I get the volume device? And
during which calls is it "good"? Filenames are good on the upward
(completion routine) path only for certain IRP_MJ's ... what about volume
names? What field of what structure am I supposed to be looking at?
DeviceObject->Vpb->what->the->heck?]

From your example, I am not sure where you are getting the file object
from?

[I call IoRegisterFsRegistrationChange(), and there store the DeviceObject
in the device extension. This is passed to the function I posted earlier, as
the device object parameter. The file object effectively comes from
IoGetCurrentIrpStackLocation(Irp)->FileObject, inside a completion routine
that is q'ed from a pass-through function for ALL the IRP_MJ's.
Where -should- I be getting it? I must say I am generally bewildered by all
these murky pointers to various file systems structures, and am at a loss as
to which one to grab when ... that is really what I need to know.]

Typically, a filter will get the filename and store it away
during IRP_MJ_CREATE and than associate its own internal object with the
file object address (or the FsContext address - or is that FsContext2?).
Using this model and filtering the device object for particular volumes
I am interested in - there should be no problem getting the name of the
file - including the drive letter or volume name.

/TomH

-----Original Message-----
From: Eric Fowler [mailto:xxxxx@seanet.com]
Sent: Monday, February 10, 2003 5:01 PM
To: File Systems Developers
Subject: [ntfsd] Retrieving device name from filter driver

This seems to be a FAQ - I may have enquired myself - but I am still
having
a hard time getting to a file name from a filter driver.

This is the situation : I have a filter driver that communicates with
user-level code through the IRP_MJ_READ entry point. I wish to track
which
files are being written into, and pass the information back to the user
level. It is understood that drive letters are not meaningful in the
kernel.
The objective is to extract information from the PIRPs and
PDEVICE_OBJECTs
and PFILE_OBJECTs which, when passed up to user level, will enable the
EXE
to recover the file name, e.g. "\MADHATTER\FEDORA\alice.txt" or
"\Harddisk0\Partition2\whiterabbit.txt" --> "X:\whiterabbit.txt"

I am able to extract directory\file names, e.g.,
"\looking_glass\redqueen.txt", and I can get fully qualified paths from
network drives (more or less by accident!).

I have tried building an IRP with IRP_MJ_QUERY_INFORMATION, but it is
returning STATUS_INVALID_DEVICE_REQUEST (the code is appended).

I have tried deciphering NTFILMON's approach to no avail.

So, two questions:

  • Any idea why the call with IRP_MJ_QUERY_INFORMATION is
    failing?

  • How can I recover a device name (e.g., \Harddisk0\Partition1,
    or anything
    else the user code can parse) from the kernel driver?

Here is the code ... mostly stolen from NTFILMON.

// --grab current irp stack loc., then
DeviceObject->DeviceExtension->DeviceObject to get FSDevice ptr.
//pFSDevOb is File System Device Object, pFileOb is file object, other
buffers are OK
//Borrowed heavily from NTFILMON
ULONG GetFileName(PDEVICE_OBJECT pFSDevOb, PFILE_OBJECT pFileOb, WCHAR
*sFileName, ULONG ulLen)
{
PIRP pNewIrp;
KEVENT evt;
IO_STATUS_BLOCK iosb;
PIO_STACK_LOCATION pIO_Next;
ULONG ulRet = 0;
ASSERT(sFileName);

KeInitializeEvent(&evt, SynchronizationEvent, FALSE);

pNewIrp = IoAllocateIrp(pFSDevOb->StackSize, FALSE);
if(!pNewIrp)
return 0;

pNewIrp->AssociatedIrp.SystemBuffer = sFileName;
pNewIrp->UserEvent = &evt;
pNewIrp->UserIosb = &iosb;
pNewIrp->Tail.Overlay.Thread = PsGetCurrentThread();
pNewIrp->Tail.Overlay.OriginalFileObject = pFileOb;
pNewIrp->RequestorMode = KernelMode;
pNewIrp->Flags = 0;

pIO_Next = IoGetNextIrpStackLocation(pNewIrp);
pIO_Next->MajorFunction = IRP_MJ_QUERY_INFORMATION;
pIO_Next->DeviceObject = pFSDevOb;
pIO_Next->FileObject = pFileOb;
pIO_Next->Parameters.QueryFile.Length = ulLen;
pIO_Next->Parameters.QueryFile.FileInformationClass =
FileStandardInformation;//formerly FileNameInformation

IoSetCompletionRoutine(pNewIrp, F2QueryFileCompletion, &ulRet,
TRUE, TRUE,
TRUE);

(void) IoCallDriver(pFSDevOb, pNewIrp);

KeWaitForSingleObject(&evt, Executive, KernelMode, TRUE, 0);

if(!NT_SUCCESS(iosb.Status))
return 0;

return ulRet;
}

NTSTATUS F2QueryFileCompletion(PDEVICE_OBJECT pFSDevOb, PIRP pIrp, ULONG
*
pDWRet)
{
*pIrp->UserIosb = pIrp->IoStatus;

KeSetEvent(pIrp->UserEvent, 0, FALSE);
IoFreeIrp(pIrp);
return STATUS_MORE_PROCESSING_REQUIRED;
}


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


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

Still mystified here.

I am filtering the file systems, attaching when they initialize
[IoRegisterFsRegistrationChange()].

I still don't know how to get the *right* device pointer to pass down when I
call IoCallDriver()
with IRP_MJ_QUERY_INFORMATION set. The NT kernel is a mare's nest of device
objects, pointers to device objects, pointers to pointers to pointers to
references to ... you get it.

I have tried calling IoGetRelatedDeviceObject() on my file pointer, but it
returns a device object without a VPB, which (as far as I can see from
Nagar, pp. 370) is where I need to get my pointer to the volume device
object.

So, again, the Big Question is: How does a filter pass fully-qualified
path/name info into user space? It is understood that drive letters are not
meaningful in the kernel, what is needed is a device/path tuple that can be
resolved in user space.

Thanks loads.

Eric

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Tom Hansen
Sent: Monday, February 10, 2003 3:17 PM
To: File Systems Developers
Subject: [ntfsd] RE: Retrieving device name from filter driver

Question: are you actively filtering the volumes that you are interested
in? If so, then the name of the drive you are looking for is in the
volume device you are filtering.

From your example, I am not sure where you are getting the file object
from? Typically, a filter will get the filename and store it away
during IRP_MJ_CREATE and than associate its own internal object with the
file object address (or the FsContext address - or is that FsContext2?).
Using this model and filtering the device object for particular volumes
I am interested in - there should be no problem getting the name of the
file - including the drive letter or volume name.

/TomH

-----Original Message-----
From: Eric Fowler [mailto:xxxxx@seanet.com]
Sent: Monday, February 10, 2003 5:01 PM
To: File Systems Developers
Subject: [ntfsd] Retrieving device name from filter driver

This seems to be a FAQ - I may have enquired myself - but I am still
having
a hard time getting to a file name from a filter driver.

This is the situation : I have a filter driver that communicates with
user-level code through the IRP_MJ_READ entry point. I wish to track
which
files are being written into, and pass the information back to the user
level. It is understood that drive letters are not meaningful in the
kernel.
The objective is to extract information from the PIRPs and
PDEVICE_OBJECTs
and PFILE_OBJECTs which, when passed up to user level, will enable the
EXE
to recover the file name, e.g. "\MADHATTER\FEDORA\alice.txt" or
"\Harddisk0\Partition2\whiterabbit.txt" --> "X:\whiterabbit.txt"

I am able to extract directory\file names, e.g.,
"\looking_glass\redqueen.txt", and I can get fully qualified paths from
network drives (more or less by accident!).

I have tried building an IRP with IRP_MJ_QUERY_INFORMATION, but it is
returning STATUS_INVALID_DEVICE_REQUEST (the code is appended).

I have tried deciphering NTFILMON's approach to no avail.

So, two questions:

  • Any idea why the call with IRP_MJ_QUERY_INFORMATION is
    failing?

  • How can I recover a device name (e.g., \Harddisk0\Partition1,
    or anything
    else the user code can parse) from the kernel driver?

Here is the code ... mostly stolen from NTFILMON.

// --grab current irp stack loc., then
DeviceObject->DeviceExtension->DeviceObject to get FSDevice ptr.
//pFSDevOb is File System Device Object, pFileOb is file object, other
buffers are OK
//Borrowed heavily from NTFILMON
ULONG GetFileName(PDEVICE_OBJECT pFSDevOb, PFILE_OBJECT pFileOb, WCHAR
*sFileName, ULONG ulLen)
{
PIRP pNewIrp;
KEVENT evt;
IO_STATUS_BLOCK iosb;
PIO_STACK_LOCATION pIO_Next;
ULONG ulRet = 0;
ASSERT(sFileName);

KeInitializeEvent(&evt, SynchronizationEvent, FALSE);

pNewIrp = IoAllocateIrp(pFSDevOb->StackSize, FALSE);
if(!pNewIrp)
return 0;

pNewIrp->AssociatedIrp.SystemBuffer = sFileName;
pNewIrp->UserEvent = &evt;
pNewIrp->UserIosb = &iosb;
pNewIrp->Tail.Overlay.Thread = PsGetCurrentThread();
pNewIrp->Tail.Overlay.OriginalFileObject = pFileOb;
pNewIrp->RequestorMode = KernelMode;
pNewIrp->Flags = 0;

pIO_Next = IoGetNextIrpStackLocation(pNewIrp);
pIO_Next->MajorFunction = IRP_MJ_QUERY_INFORMATION;
pIO_Next->DeviceObject = pFSDevOb;
pIO_Next->FileObject = pFileOb;
pIO_Next->Parameters.QueryFile.Length = ulLen;
pIO_Next->Parameters.QueryFile.FileInformationClass =
FileStandardInformation;//formerly FileNameInformation

IoSetCompletionRoutine(pNewIrp, F2QueryFileCompletion, &ulRet,
TRUE, TRUE,
TRUE);

(void) IoCallDriver(pFSDevOb, pNewIrp);

KeWaitForSingleObject(&evt, Executive, KernelMode, TRUE, 0);

if(!NT_SUCCESS(iosb.Status))
return 0;

return ulRet;
}

NTSTATUS F2QueryFileCompletion(PDEVICE_OBJECT pFSDevOb, PIRP pIrp, ULONG
*
pDWRet)
{
*pIrp->UserIosb = pIrp->IoStatus;

KeSetEvent(pIrp->UserEvent, 0, FALSE);
IoFreeIrp(pIrp);
return STATUS_MORE_PROCESSING_REQUIRED;
}


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


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

To delve further into a state of confusion, it appears the problem is rooted
in the fact I have hooked the file system object, not the logical volume
object. So, how do I get from the file system object to the volume object?

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Tom Hansen
Sent: Monday, February 10, 2003 3:17 PM
To: File Systems Developers
Subject: [ntfsd] RE: Retrieving device name from filter driver

Question: are you actively filtering the volumes that you are interested
in? If so, then the name of the drive you are looking for is in the
volume device you are filtering.

From your example, I am not sure where you are getting the file object
from? Typically, a filter will get the filename and store it away
during IRP_MJ_CREATE and than associate its own internal object with the
file object address (or the FsContext address - or is that FsContext2?).
Using this model and filtering the device object for particular volumes
I am interested in - there should be no problem getting the name of the
file - including the drive letter or volume name.

/TomH

-----Original Message-----
From: Eric Fowler [mailto:xxxxx@seanet.com]
Sent: Monday, February 10, 2003 5:01 PM
To: File Systems Developers
Subject: [ntfsd] Retrieving device name from filter driver

This seems to be a FAQ - I may have enquired myself - but I am still
having
a hard time getting to a file name from a filter driver.

This is the situation : I have a filter driver that communicates with
user-level code through the IRP_MJ_READ entry point. I wish to track
which
files are being written into, and pass the information back to the user
level. It is understood that drive letters are not meaningful in the
kernel.
The objective is to extract information from the PIRPs and
PDEVICE_OBJECTs
and PFILE_OBJECTs which, when passed up to user level, will enable the
EXE
to recover the file name, e.g. "\MADHATTER\FEDORA\alice.txt" or
"\Harddisk0\Partition2\whiterabbit.txt" --> "X:\whiterabbit.txt"

I am able to extract directory\file names, e.g.,
"\looking_glass\redqueen.txt", and I can get fully qualified paths from
network drives (more or less by accident!).

I have tried building an IRP with IRP_MJ_QUERY_INFORMATION, but it is
returning STATUS_INVALID_DEVICE_REQUEST (the code is appended).

I have tried deciphering NTFILMON's approach to no avail.

So, two questions:

  • Any idea why the call with IRP_MJ_QUERY_INFORMATION is
    failing?

  • How can I recover a device name (e.g., \Harddisk0\Partition1,
    or anything
    else the user code can parse) from the kernel driver?

Here is the code ... mostly stolen from NTFILMON.

// --grab current irp stack loc., then
DeviceObject->DeviceExtension->DeviceObject to get FSDevice ptr.
//pFSDevOb is File System Device Object, pFileOb is file object, other
buffers are OK
//Borrowed heavily from NTFILMON
ULONG GetFileName(PDEVICE_OBJECT pFSDevOb, PFILE_OBJECT pFileOb, WCHAR
*sFileName, ULONG ulLen)
{
PIRP pNewIrp;
KEVENT evt;
IO_STATUS_BLOCK iosb;
PIO_STACK_LOCATION pIO_Next;
ULONG ulRet = 0;
ASSERT(sFileName);

KeInitializeEvent(&evt, SynchronizationEvent, FALSE);

pNewIrp = IoAllocateIrp(pFSDevOb->StackSize, FALSE);
if(!pNewIrp)
return 0;

pNewIrp->AssociatedIrp.SystemBuffer = sFileName;
pNewIrp->UserEvent = &evt;
pNewIrp->UserIosb = &iosb;
pNewIrp->Tail.Overlay.Thread = PsGetCurrentThread();
pNewIrp->Tail.Overlay.OriginalFileObject = pFileOb;
pNewIrp->RequestorMode = KernelMode;
pNewIrp->Flags = 0;

pIO_Next = IoGetNextIrpStackLocation(pNewIrp);
pIO_Next->MajorFunction = IRP_MJ_QUERY_INFORMATION;
pIO_Next->DeviceObject = pFSDevOb;
pIO_Next->FileObject = pFileOb;
pIO_Next->Parameters.QueryFile.Length = ulLen;
pIO_Next->Parameters.QueryFile.FileInformationClass =
FileStandardInformation;//formerly FileNameInformation

IoSetCompletionRoutine(pNewIrp, F2QueryFileCompletion, &ulRet,
TRUE, TRUE,
TRUE);

(void) IoCallDriver(pFSDevOb, pNewIrp);

KeWaitForSingleObject(&evt, Executive, KernelMode, TRUE, 0);

if(!NT_SUCCESS(iosb.Status))
return 0;

return ulRet;
}

NTSTATUS F2QueryFileCompletion(PDEVICE_OBJECT pFSDevOb, PIRP pIrp, ULONG
*
pDWRet)
{
*pIrp->UserIosb = pIrp->IoStatus;

KeSetEvent(pIrp->UserEvent, 0, FALSE);
IoFreeIrp(pIrp);
return STATUS_MORE_PROCESSING_REQUIRED;
}


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


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

Here is a sample that uses the drive letter (or actually, the DOS device
symbolic link, which is \DosDevices\C: for the C drive for example to
attach to the volume. The control device you created (the main device
object for your driver) is passed to IoCreateDevice to create a device
object that you can use for filtering the volume.

This code works on Win2k and Windows XP. However, there is a newer
model for attaching a volume on XP that does NOT work on Win2k.

This code basically comes from the IFS KIT samples. I highly recommend
that you get the IFS kit and/or seek help from OSR. The questions you
are asking are solved by these sources.

__try
{
m_Status = IoGetDeviceObjectPointer( &VolumeString,
FILE_READ_ATTRIBUTES,

&TargetFileObject,

&TargetDeviceObject );

if( !NT_SUCCESS( m_Status ) )
{
LOG_FORMAT( CLog::LogError,
"IoGetDeviceObjectPointer for %S failed\r\n",
VolumeString.Buffer );
__leave;
}
m_Status = IoCreateDevice( (*m_ControlDevice),
sizeof(struct DeviceExtension),
0,

FILE_DEVICE_FILE_SYSTEM,
0,
FALSE,
&m_DeviceObject );

if( !NT_SUCCESS( m_Status ) )
{
LOG_FORMAT( CLog::LogError, "IoCreateDevice failed\r\n" );
__leave;
}

// link our C++ object to the device extension

if( TargetFileObject->DeviceObject->Vpb )
{
//
// This is the case for a local file system
//
m_FilteredDevice = TargetFileObject->DeviceObject->Vpb-

DeviceObject;
}
else
{
//
// This is the case for a redirector
//
__leave;

m_FilteredDevice = TargetFileObject->DeviceObject;
}

m_FilteredDevice = IoAttachDeviceToDeviceStack(
m_DeviceObject,

m_FilteredDevice);

-----Original Message-----
From: Eric Fowler [mailto:xxxxx@seanet.com]
Sent: Tuesday, February 11, 2003 12:33 AM
To: File Systems Developers
Subject: [ntfsd] RE: Retrieving device name from filter driver

To delve further into a state of confusion, it appears the problem is
rooted
in the fact I have hooked the file system object, not the logical volume
object. So, how do I get from the file system object to the volume
object?

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Tom Hansen
Sent: Monday, February 10, 2003 3:17 PM
To: File Systems Developers
Subject: [ntfsd] RE: Retrieving device name from filter driver

Question: are you actively filtering the volumes that you are interested
in? If so, then the name of the drive you are looking for is in the
volume device you are filtering.

From your example, I am not sure where you are getting the file object
from? Typically, a filter will get the filename and store it away
during IRP_MJ_CREATE and than associate its own internal object with the
file object address (or the FsContext address - or is that FsContext2?).
Using this model and filtering the device object for particular volumes
I am interested in - there should be no problem getting the name of the
file - including the drive letter or volume name.

/TomH

-----Original Message-----
From: Eric Fowler [mailto:xxxxx@seanet.com]
Sent: Monday, February 10, 2003 5:01 PM
To: File Systems Developers
Subject: [ntfsd] Retrieving device name from filter driver

This seems to be a FAQ - I may have enquired myself - but I am still
having
a hard time getting to a file name from a filter driver.

This is the situation : I have a filter driver that communicates with
user-level code through the IRP_MJ_READ entry point. I wish to track
which
files are being written into, and pass the information back to the user
level. It is understood that drive letters are not meaningful in the
kernel.
The objective is to extract information from the PIRPs and
PDEVICE_OBJECTs
and PFILE_OBJECTs which, when passed up to user level, will enable the
EXE
to recover the file name, e.g. "\MADHATTER\FEDORA\alice.txt" or
"\Harddisk0\Partition2\whiterabbit.txt" --> "X:\whiterabbit.txt"

I am able to extract directory\file names, e.g.,
"\looking_glass\redqueen.txt", and I can get fully qualified paths from
network drives (more or less by accident!).

I have tried building an IRP with IRP_MJ_QUERY_INFORMATION, but it is
returning STATUS_INVALID_DEVICE_REQUEST (the code is appended).

I have tried deciphering NTFILMON's approach to no avail.

So, two questions:

  • Any idea why the call with IRP_MJ_QUERY_INFORMATION is
    failing?

  • How can I recover a device name (e.g., \Harddisk0\Partition1,
    or anything
    else the user code can parse) from the kernel driver?

Here is the code ... mostly stolen from NTFILMON.

// --grab current irp stack loc., then
DeviceObject->DeviceExtension->DeviceObject to get FSDevice ptr.
//pFSDevOb is File System Device Object, pFileOb is file object, other
buffers are OK
//Borrowed heavily from NTFILMON
ULONG GetFileName(PDEVICE_OBJECT pFSDevOb, PFILE_OBJECT pFileOb, WCHAR
*sFileName, ULONG ulLen)
{
PIRP pNewIrp;
KEVENT evt;
IO_STATUS_BLOCK iosb;
PIO_STACK_LOCATION pIO_Next;
ULONG ulRet = 0;
ASSERT(sFileName);

KeInitializeEvent(&evt, SynchronizationEvent, FALSE);

pNewIrp = IoAllocateIrp(pFSDevOb->StackSize, FALSE);
if(!pNewIrp)
return 0;

pNewIrp->AssociatedIrp.SystemBuffer = sFileName;
pNewIrp->UserEvent = &evt;
pNewIrp->UserIosb = &iosb;
pNewIrp->Tail.Overlay.Thread = PsGetCurrentThread();
pNewIrp->Tail.Overlay.OriginalFileObject = pFileOb;
pNewIrp->RequestorMode = KernelMode;
pNewIrp->Flags = 0;

pIO_Next = IoGetNextIrpStackLocation(pNewIrp);
pIO_Next->MajorFunction = IRP_MJ_QUERY_INFORMATION;
pIO_Next->DeviceObject = pFSDevOb;
pIO_Next->FileObject = pFileOb;
pIO_Next->Parameters.QueryFile.Length = ulLen;
pIO_Next->Parameters.QueryFile.FileInformationClass =
FileStandardInformation;//formerly FileNameInformation

IoSetCompletionRoutine(pNewIrp, F2QueryFileCompletion, &ulRet,
TRUE, TRUE,
TRUE);

(void) IoCallDriver(pFSDevOb, pNewIrp);

KeWaitForSingleObject(&evt, Executive, KernelMode, TRUE, 0);

if(!NT_SUCCESS(iosb.Status))
return 0;

return ulRet;
}

NTSTATUS F2QueryFileCompletion(PDEVICE_OBJECT pFSDevOb, PIRP pIrp, ULONG
*
pDWRet)
{
*pIrp->UserIosb = pIrp->IoStatus;

KeSetEvent(pIrp->UserEvent, 0, FALSE);
IoFreeIrp(pIrp);
return STATUS_MORE_PROCESSING_REQUIRED;
}


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


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


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