Allocate the memory for the search pattern in kernel space if it is necessary (in NtQueryDirectoryFile).

svn path=/trunk/; revision=19752
This commit is contained in:
Hartmut Birr 2005-11-29 19:07:03 +00:00
parent e29e4fd76e
commit eaf958a931

View file

@ -2399,6 +2399,20 @@ NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
FileInformation); FileInformation);
} }
static NTSTATUS NTAPI
IopQueryDirectoryFileCompletion(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{
ASSERT (Context);
DPRINT("IopQueryDirectoryFileCompletion was called for \'%wZ\'\n", Context);
ExFreePool(Context);
return STATUS_SUCCESS;
}
/* /*
* @implemented * @implemented
@ -2450,6 +2464,7 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
BOOLEAN LocalEvent = FALSE; BOOLEAN LocalEvent = FALSE;
PKEVENT Event = NULL; PKEVENT Event = NULL;
PUNICODE_STRING SearchPattern = NULL;
DPRINT("NtQueryDirectoryFile()\n"); DPRINT("NtQueryDirectoryFile()\n");
PAGED_CODE(); PAGED_CODE();
@ -2465,6 +2480,24 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
ProbeForWrite(FileInformation, ProbeForWrite(FileInformation,
Length, Length,
sizeof(ULONG)); sizeof(ULONG));
if (FileName)
{
ProbeForRead(FileName,
sizeof(UNICODE_STRING),
1);
ProbeForRead(FileName->Buffer,
FileName->MaximumLength,
1);
SearchPattern = ExAllocatePool(NonPagedPool, FileName->Length + sizeof(WCHAR) + sizeof(UNICODE_STRING));
if (SearchPattern == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
_SEH_LEAVE;
}
SearchPattern->Buffer = (PWCHAR)((ULONG_PTR)SearchPattern + sizeof(UNICODE_STRING));
SearchPattern->MaximumLength = FileName->Length + sizeof(WCHAR);
RtlCopyUnicodeString(SearchPattern, FileName);
}
} }
_SEH_HANDLE _SEH_HANDLE
{ {
@ -2472,7 +2505,14 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
} }
_SEH_END; _SEH_END;
if(!NT_SUCCESS(Status)) return Status; if(!NT_SUCCESS(Status))
{
if (SearchPattern)
{
ExFreePool(SearchPattern);
}
return Status;
}
} }
/* Get File Object */ /* Get File Object */
@ -2482,7 +2522,14 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
PreviousMode, PreviousMode,
(PVOID *)&FileObject, (PVOID *)&FileObject,
NULL); NULL);
if (Status != STATUS_SUCCESS) return(Status); if (!NT_SUCCESS(Status))
{
if (SearchPattern)
{
ExFreePool(SearchPattern);
}
return Status;
}
/* Get Event Object */ /* Get Event Object */
if (PEvent) if (PEvent)
@ -2493,7 +2540,15 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
PreviousMode, PreviousMode,
(PVOID *)&Event, (PVOID *)&Event,
NULL); NULL);
if (Status != STATUS_SUCCESS) return(Status); if (NT_SUCCESS(Status))
{
ObDereferenceObject(FileObject);
if (SearchPattern)
{
ExFreePool(SearchPattern);
}
return(Status);
}
KeClearEvent(Event); KeClearEvent(Event);
} }
@ -2522,6 +2577,14 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
if (!(Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE))) if (!(Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE)))
{ {
ObDereferenceObject(FileObject); ObDereferenceObject(FileObject);
if (PEvent)
{
ObDereferenceObject(Event);
}
if (SearchPattern)
{
ExFreePool(SearchPattern);
}
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
@ -2543,13 +2606,23 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
/* Set Parameters */ /* Set Parameters */
StackPtr->Parameters.QueryDirectory.FileInformationClass = FileInformationClass; StackPtr->Parameters.QueryDirectory.FileInformationClass = FileInformationClass;
StackPtr->Parameters.QueryDirectory.FileName = FileName; StackPtr->Parameters.QueryDirectory.FileName = SearchPattern ? SearchPattern : FileName;
StackPtr->Parameters.QueryDirectory.FileIndex = 0; StackPtr->Parameters.QueryDirectory.FileIndex = 0;
StackPtr->Parameters.QueryDirectory.Length = Length; StackPtr->Parameters.QueryDirectory.Length = Length;
StackPtr->Flags = 0; StackPtr->Flags = 0;
if (RestartScan) StackPtr->Flags = SL_RESTART_SCAN; if (RestartScan) StackPtr->Flags = SL_RESTART_SCAN;
if (ReturnSingleEntry) StackPtr->Flags |= SL_RETURN_SINGLE_ENTRY; if (ReturnSingleEntry) StackPtr->Flags |= SL_RETURN_SINGLE_ENTRY;
if (SearchPattern)
{
IoSetCompletionRoutine(Irp,
IopQueryDirectoryFileCompletion,
SearchPattern,
TRUE,
TRUE,
TRUE);
}
/* Call the Driver */ /* Call the Driver */
Status = IoCallDriver(DeviceObject, Irp); Status = IoCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING) if (Status == STATUS_PENDING)