Hi,
I wrote an Filter Driver in which I try to get the long path name
of each file opened by the system.
However my “get_long_path_name” routine don’t work because I don’t
know how to send an irp with :
MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
MinorFunction = IRP_MN_QUERY_DIRECTORY;
I wrote the little program below which doesn’t report any error, but
which doesn’t work at all : my FILE_BOTH_DIR_INFORMATION buffer is
not updated by the low level driver (both NTFS and FAT).
What’s wrong ?
Thanks in advance,
Philippe.
Ps: Also, I’m surprised that the IRP takes only ANSI strings and not
UNICODE strings:
IrpSp->Parameters.QueryDirectory.FileName
Optional name of a file within the specified directory.
and:
//
// System service parameters for: NtQueryDirectoryFile
//
struct {
ULONG Length;
PSTRING FileName; // <- ANSI string …
FILE_INFORMATION_CLASS FileInformationClass;
ULONG FileIndex;
} QueryDirectory;
Does anyone know why?
#include <ntifs.h>
VOID
DriverUnload(
IN PDRIVER_OBJECT DriverObject
);
NTSTATUS
DriverRoutine(
IN PWCHAR PathName,
IN PCHAR FileName
);
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
DriverObject->DriverUnload = DriverUnload;
DriverRoutine(L"\??\C:\“, “Progra~1”);
KdPrint((”=========================\n"));
DriverRoutine(L"\??\C:\“, “Program Files”);
KdPrint((”=========================\n"));
DriverRoutine(L"\??\C:\“, “boot.ini”);
KdPrint((”=========================\n"));
DriverRoutine(L"\??\C:\", “progra*”);
return STATUS_SUCCESS;
}
VOID
DriverUnload(
IN PDRIVER_OBJECT DriverObject
)
{
}
NTSTATUS
DriverRoutine(
IN PWCHAR PathName,
IN PCHAR FileName
)
{
NTSTATUS Status;
UNICODE_STRING UnicodePathName;
ANSI_STRING AnsiFileName;
HANDLE hFile;
PFILE_BOTH_DIR_INFORMATION FileBothDirInfo;
ULONG BufferLen;
PFILE_OBJECT FileObject;
KEVENT FileEvent;
PIRP Irp;
PIO_STACK_LOCATION IrpSp;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
ACCESS_MASK AccessMask;
RtlInitUnicodeString(&UnicodePathName, PathName);
RtlInitAnsiString(&AnsiFileName, FileName);
KdPrint((“QueryDir: InitializeObjectAttributes\n”));
InitializeObjectAttributes(&ObjectAttributes, &UnicodePathName,
OBJ_CASE_INSENSITIVE, NULL, NULL);
KdPrint((“QueryDir: IoCreateFile(%wZ) [Looking for %Z]\n”,
&UnicodePathName,
&AnsiFileName));
AccessMask = FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE |
FILE_LIST_DIRECTORY;
Status = IoCreateFile(&hFile, AccessMask, &ObjectAttributes,
&IoStatusBlock, 0, FILE_ATTRIBUTE_DIRECTORY,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_OPEN, FILE_DIRECTORY_FILE, NULL, 0, CreateFileTypeNone, NULL,
0 /* IO_NO_PARAMETER_CHECKING */);
if (Status != STATUS_SUCCESS) {
KdPrint((“QueryDir: IoCreateFile failed : %.8x\n”, Status));
return Status;
}
KdPrint((“QueryDir: IoCreateFile(‘%wZ’) succeeded\n”,
&UnicodePathName));
Status = ObReferenceObjectByHandle(hFile, AccessMask, NULL,
KernelMode, &FileObject, NULL);
if (Status != STATUS_SUCCESS) {
KdPrint((“QueryDir: ObReferenceObjectByHandle failed [%.8x])\n”,
Status));
ZwClose(hFile);
return Status;
}
KdPrint((“QueryDir: Got %wZ FileObject [%p]\n”, &UnicodePathName,
FileObject));
BufferLen = sizeof(FILE_BOTH_DIR_INFORMATION) + sizeof(WCHAR) * 384;
FileBothDirInfo = (PFILE_BOTH_DIR_INFORMATION)
ExAllocatePool(NonPagedPool, BufferLen);
if (FileBothDirInfo == NULL) {
KdPrint((“QueryDir: ExAllocatePool failed\n”));
ObDereferenceObject(FileObject);
ZwClose(hFile);
return STATUS_NO_MEMORY;
}
memset(FileBothDirInfo, 0, BufferLen);
KeInitializeEvent(&FileEvent, SynchronizationEvent, FALSE);
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_FLUSH_BUFFERS,
FileObject->DeviceObject,
NULL, 0, NULL, &FileEvent, &IoStatusBlock);
if (Irp == NULL) {
KdPrint((“QueryDir: IoBuildSynchronousFsdRequest failed\n”));
Status = STATUS_NO_MEMORY;
goto end;
}
KdPrint((“QueryDir: Got %wZ Irp [%p]\n”, &UnicodePathName, Irp));
Irp->UserBuffer = FileBothDirInfo;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
if (IrpSp == NULL) {
KdPrint((“QueryDir: IoGetCurrentIrpStackLocation failed\n”));
Status = STATUS_NO_MEMORY;
goto end;
}
KdPrint((“QueryDir: Got %wZ IrpSp [%p]\n”, &UnicodePathName,
IrpSp));
IrpSp->FileObject = FileObject;
IrpSp->DeviceObject = FileObject->DeviceObject;
IrpSp->Flags = SL_RESTART_SCAN | SL_RETURN_SINGLE_ENTRY;
IrpSp->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
IrpSp->MinorFunction = IRP_MN_QUERY_DIRECTORY;
IrpSp->Parameters.QueryDirectory.FileIndex = 0;
IrpSp->Parameters.QueryDirectory.FileInformationClass =
FileBothDirectoryInformation;
IrpSp->Parameters.QueryDirectory.FileName = &AnsiFileName;
IrpSp->Parameters.QueryDirectory.Length = BufferLen;
KdPrint((“QueryDir: IoCallDriver IRP_MJ_DIRECTORY_CONTROL
IRP_MN_QUERY_DIRECTORY\n”));
Status = IoCallDriver(FileObject->DeviceObject, Irp);
KdPrint((“QueryDir: IoCallDriver returned %.8x\n”, Status));
if (Status == STATUS_PENDING) {
Status = KeWaitForSingleObject(&FileEvent, Executive, KernelMode,
FALSE, NULL);
if (Status != STATUS_SUCCESS) {
KdPrint((“QueryDir: KeWaitForSingleObject failed [%.8x])\n”,
Status));
goto end;
}
}
KdPrint((“QueryDir: Irp->IoStatus.Status = %.8x\n”,
Irp->IoStatus.Status));
Status = Irp->IoStatus.Status;
if (Status == STATUS_SUCCESS) {
UNICODE_STRING LongFileName;
UNICODE_STRING ShortFileName;
LongFileName.Buffer = FileBothDirInfo->FileName;
LongFileName.Length = LongFileName.MaximumLength = (USHORT)
FileBothDirInfo->FileNameLength;
ShortFileName.Buffer = FileBothDirInfo->ShortName;
ShortFileName.Length = ShortFileName.MaximumLength = (USHORT)
FileBothDirInfo->ShortNameLength;
KdPrint((“QueryDir: LongFileName.Buffer = %p\n”,
LongFileName.Buffer));
KdPrint((“QueryDir: LongFileName.Length = %d\n”,
LongFileName.Length));
KdPrint((“QueryDir: LongFileName = %wZ\n”, &LongFileName));
KdPrint((“QueryDir: ShortFileName.Buffer = %p\n”,
ShortFileName.Buffer));
KdPrint((“QueryDir: ShortFileName.Length = %d\n”,
ShortFileName.Length));
KdPrint((“QueryDir: ShortFileName = %wZ\n”,
&ShortFileName));
}
end:
ExFreePool(FileBothDirInfo);
ObDereferenceObject(FileObject);
ZwClose(hFile);
return Status;
}</ntifs.h>