Cleanup isn't necessary after calling the driver in NtQueryDirectoryFile.
[reactos.git] / reactos / ntoskrnl / io / file.c
index 0fa8b13..c8107ff 100644 (file)
@@ -2399,6 +2399,20 @@ NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
                                   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
@@ -2444,12 +2458,13 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
 {
     PIRP Irp;
     PDEVICE_OBJECT DeviceObject;
-    PFILE_OBJECT FileObject;
+    PFILE_OBJECT FileObject = NULL;
     PIO_STACK_LOCATION StackPtr;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     NTSTATUS Status = STATUS_SUCCESS;
     BOOLEAN LocalEvent = FALSE;
     PKEVENT Event = NULL;
+    PUNICODE_STRING SearchPattern = NULL;
 
     DPRINT("NtQueryDirectoryFile()\n");
     PAGED_CODE();
@@ -2465,6 +2480,24 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
             ProbeForWrite(FileInformation,
                           Length,
                           sizeof(ULONG));
+            if (FileName)
+            {
+                UNICODE_STRING CapturedFileName;
+
+                CapturedFileName = ProbeForReadUnicodeString(FileName);
+                ProbeForRead(CapturedFileName.Buffer,
+                             CapturedFileName.MaximumLength,
+                             1);
+                SearchPattern = ExAllocatePool(NonPagedPool, CapturedFileName.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 = CapturedFileName.Length + sizeof(WCHAR);
+                RtlCopyUnicodeString(SearchPattern, &CapturedFileName);
+            }
         }
         _SEH_HANDLE
         {
@@ -2472,7 +2505,10 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
         }
         _SEH_END;
 
-        if(!NT_SUCCESS(Status)) return Status;
+        if(!NT_SUCCESS(Status)) 
+        {
+            goto Cleanup;
+        }
     }
 
     /* Get File Object */
@@ -2482,7 +2518,10 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
                                        PreviousMode,
                                        (PVOID *)&FileObject,
                                        NULL);
-    if (Status != STATUS_SUCCESS) return(Status);
+    if (!NT_SUCCESS(Status))
+    {
+       goto Cleanup;
+    }
 
     /* Get Event Object */
     if (PEvent)
@@ -2493,7 +2532,11 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
                                            PreviousMode,
                                            (PVOID *)&Event,
                                            NULL);
-        if (Status != STATUS_SUCCESS) return(Status);
+        if (!NT_SUCCESS(Status)) 
+        {
+            goto Cleanup;
+        }
+
         KeClearEvent(Event);
     }
 
@@ -2521,8 +2564,8 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
     /* Allocate the IRP */
     if (!(Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE)))
     {
-        ObDereferenceObject(FileObject);
-        return STATUS_INSUFFICIENT_RESOURCES;
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto Cleanup;
     }
 
     /* Set up the IRP */
@@ -2543,13 +2586,23 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
 
     /* Set Parameters */
     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.Length = Length;
     StackPtr->Flags = 0;
     if (RestartScan) StackPtr->Flags = SL_RESTART_SCAN;
     if (ReturnSingleEntry) StackPtr->Flags |= SL_RETURN_SINGLE_ENTRY;
 
+    if (SearchPattern)
+    {
+        IoSetCompletionRoutine(Irp,
+                               IopQueryDirectoryFileCompletion,
+                              SearchPattern,
+                              TRUE,
+                              TRUE,
+                              TRUE);
+    }
+
     /* Call the Driver */
     Status = IoCallDriver(DeviceObject, Irp);
     if (Status == STATUS_PENDING)
@@ -2565,6 +2618,23 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
         }
     }
 
+
+    return Status;
+
+Cleanup:
+    if (FileObject != NULL)
+    {
+        ObDereferenceObject(FileObject);
+    }
+    if (Event != NULL)
+    {
+        ObDereferenceObject(Event);
+    }
+    if (SearchPattern != NULL)
+    {
+        ExFreePool(SearchPattern);
+    }
+
     /* Return the Status */
     return Status;
 }