how to get full path name from the File Object??

Hi!!

i’m writing a filter driver by hooking on the file system. i have to
restrict deletion on certain files. My problem is that i can’t get the
drive name from the file object. From the file object i get the path
without the drive letter.
can anyone please explain me how can i get drive name from the file
object.
any help will be greatly appreciated.

regards
Balvinder

Hi!

You’ll need to process te DeviceObject (FileObject->DeviceObject) to get
the device name ex. \Device\HarddiskVolume… via ObQueryNameString() API,
After it, you can compare all drives’ symbolic link name with this device
name. See also: Zw(Open|Query)SymbolicLinkObject. I hope there’s an easier
way, but i cannot find yet :frowning:

hope it helps

Regards
Dano

On Mon, 2 Dec 2002, Balvinder Singh wrote:

Hi!!

i’m writing a filter driver by hooking on the file system. i have to
restrict deletion on certain files. My problem is that i can’t get the
drive name from the file object. From the file object i get the path
without the drive letter.
can anyone please explain me how can i get drive name from the file
object.
any help will be greatly appreciated.

regards
Balvinder

Here is a piece of code …

//----------------------------------------------------------------------
// Function: HookDrive
// Description: Hook the drive specified by determining which device
object to
// attach to. The algorithm used here is similar to the one used
// internally by NT to determine which device object a file system
request
// is directed at.
//
//----------------------------------------------------------------------
BOOLEAN
HookDrive(
IN ULONG Drive,
IN PDRIVER_OBJECT DriverObject
)
{
IO_STATUS_BLOCK ioStatus;
HANDLE ntFileHandle;
OBJECT_ATTRIBUTES objectAttributes;
PDEVICE_OBJECT fileSysDevice;
PDEVICE_OBJECT hookDevice;
UNICODE_STRING fileNameUnicodeString;
PFILE_FS_ATTRIBUTE_INFORMATION fileFsAttributes;
ULONG fileFsAttributesSize;
WCHAR filename = L"\??\A:\";
NTSTATUS ntStatus;
ULONG i;
PFILE_OBJECT fileObject;
PHOOK_EXTENSION hookExtension;
WCHAR DriveName;

DriveName = (USHORT)(Drive-1 + L’A’);
wcsncpy(&filename[0]+4,&DriveName,1);

//
// We have to figure out what device to hook - first open the volume’s
// root directory
//
RtlInitUnicodeString( &fileNameUnicodeString, filename );
InitializeObjectAttributes( &objectAttributes, &fileNameUnicodeString,
OBJ_CASE_INSENSITIVE, NULL, NULL );
ntStatus = ZwCreateFile( &ntFileHandle, SYNCHRONIZE|FILE_ANY_ACCESS,
&objectAttributes, &ioStatus, NULL, 0,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,

FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE,
NULL, 0 );
if( !NT_SUCCESS( ntStatus ) ) {

KdPrint((“Fdmt: Could not open drive %c: %x\n”, ‘A’+Drive,
ntStatus ));
return FALSE;
}

KdPrint((“Fdmt: opened the root directory!!! handle: %x\n”,
ntFileHandle));

//
// Got the file handle, so now look-up the file-object it refers to
//
ntStatus = ObReferenceObjectByHandle( ntFileHandle, FILE_READ_DATA,
NULL, KernelMode, &fileObject,
NULL );
if( !NT_SUCCESS( ntStatus )) {

KdPrint((“Fdmt: Could not get fileobject from handle: %c\n”,
‘A’+Drive ));
ZwClose( ntFileHandle );
return FALSE;
}

//
// Next, find out what device is associated with the file object by
getting its related
// device object
//
fileSysDevice = IoGetRelatedDeviceObject( fileObject );

if( ! fileSysDevice ) {

KdPrint((“Fdmt: Could not get related device object: %c\n”,
‘A’+Drive ));
ObDereferenceObject( fileObject );
ZwClose( ntFileHandle );
return FALSE;
}

//
// The file system’s device hasn’t been hooked already, so make a
hooking device
// object that will be attached to it.
//
ntStatus = IoCreateDevice( DriverObject,
sizeof(HOOK_EXTENSION),
NULL,
fileSysDevice->DeviceType,
0,
FALSE,
&hookDevice );
if( !NT_SUCCESS(ntStatus) ) {

KdPrint((“Fdmt: failed to create associated device: %c\n”,
‘A’+Drive ));

ObDereferenceObject( fileObject );
ZwClose( ntFileHandle );

return FALSE;
}

//
// Clear the device’s init flag as per NT DDK KB article on creating
device
// objects from a dispatch routine
//
hookDevice->Flags &= ~DO_DEVICE_INITIALIZING;

//
// Setup the device extensions. The drive letter and file system
object are stored
// in the extension.
//
hookExtension = hookDevice->DeviceExtension;
hookExtension->LogicalDrive = DriveName;
hookExtension->FileSystem = fileSysDevice;
hookExtension->Hooked = TRUE;
hookExtension->Type = STANDARD;

//Copy drive name
RtlInitUnicodeString(&hookExtension->DeviceName,L"A:");
wcsncpy(hookExtension->DeviceName.Buffer,&DriveName,1);
/*hookExtension->DeviceName.MaximumLength =
fileNameUnicodeString.MaximumLength ;
hookExtension->DeviceName.Length = fileNameUnicodeString.Length ;
hookExtension->DeviceName.Buffer =
(PWCHAR)ExAllocatePool(PagedPool,hookExtension->DeviceName.MaximumLength);

RtlCopyUnicodeString(&(hookExtension->DeviceName),&(fileNameUnicodeString));

hookExtension->DeviceName.Buffer[hookExtension->DeviceName.Length/2] =
UNICODE_NULL;
*/

//
// Finally, attach to the device. The second we’re successfully
attached, we may
// start receiving IRPs targetted at the device we’ve hooked.
//
ntStatus = IoAttachDeviceByPointer( hookDevice, fileSysDevice );
if( !NT_SUCCESS(ntStatus) ) {

//
// Couldn’ attach for some reason
//
KdPrint((“Fdmt: Connect with Filesystem failed: %c (%x) =>%x\n”,
‘A’+Drive - 1, fileSysDevice, ntStatus ));

//
// Derefence the object and get out
//
ObDereferenceObject( fileObject );
ZwClose( ntFileHandle );

return FALSE;

} else {

//
// Make a new drive group for the device,l if it does not have one
// already
//
KdPrint((“Fdmt: Successfully connected to Filesystem device %c\n”,
‘A’+Drive - 1 ));
}

//
// Determine if this is a NTFS drive
//
fileFsAttributesSize = sizeof( FILE_FS_ATTRIBUTE_INFORMATION) +
MAXPATHLEN;
hookExtension->FsAttributes = (PFILE_FS_ATTRIBUTE_INFORMATION)
ExAllocatePool( NonPagedPool,

fileFsAttributesSize );
//
// Close the file and update the hooked drive list by entering a
// pointer to the hook device object in it.
//
ObDereferenceObject( fileObject );

ZwClose( ntFileHandle );

DriveHookDevices[Drive] = hookDevice;

return TRUE;
}

As you’re working on a filter, if you attach to drives using the drive
letter (like filemon does) it is quite easy to get the drive letter for a
FO. The Create must have been sent to one of the DOs you’ve created for the
drive A-Z, so this DO corresponds to the driveletter you’ve attached to.
Just comparing the DO of the IRP to your personal DOs should work fine. The
symbolic link approach Illes uses (see below) to find out the
DO-to-Driveletter-connection also works fine, but is IMHO only necessary in
case you attached a different DO than the FS-DO at “\??\X:\” (where X is
the letter of the drive to attach).

Regards,
Tobias

----- Original Message -----
From: “Illes Attila”
To: “File Systems Developers”
Sent: Monday, December 02, 2002 11:42 AM
Subject: [ntfsd] Re: how to get full path name from the File Object??

> Hi!
>
> You’ll need to process te DeviceObject (FileObject->DeviceObject) to get
> the device name ex. \Device\HarddiskVolume… via ObQueryNameString() API,
> After it, you can compare all drives’ symbolic link name with this device
> name. See also: Zw(Open|Query)SymbolicLinkObject. I hope there’s an easier
> way, but i cannot find yet :frowning: