[FLTMGR] Implement FltEnumerateVolumes()
[reactos.git] / drivers / filters / fltmgr / Volume.c
index 6a854f7..d4c21bb 100644 (file)
@@ -107,4 +107,77 @@ FltGetVolumeProperties(
 }
 
 
-/* INTERNAL FUNCTIONS ******************************************************/
\ No newline at end of file
+NTSTATUS
+FLTAPI
+FltEnumerateVolumes(
+    _In_ PFLT_FILTER Filter,
+    _Out_writes_to_opt_(VolumeListSize,*NumberVolumesReturned) PFLT_VOLUME *VolumeList,
+    _In_ ULONG VolumeListSize,
+    _Out_ PULONG NumberVolumesReturned)
+{
+    ULONG i;
+    PFLTP_FRAME Frame;
+    PFLT_VOLUME Volume;
+    PLIST_ENTRY ListEntry;
+    ULONG NumberOfVolumes = 0;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    PAGED_CODE();
+
+    Frame = Filter->Frame;
+
+    /* Lock the attached volumes list */
+    KeEnterCriticalRegion();
+    ExAcquireResourceSharedLite(&Frame->AttachedVolumes.rLock, TRUE);
+
+    /* If it's not empty */
+    if (!IsListEmpty(&Frame->AttachedVolumes.rList))
+    {
+        /* Browse every entry */
+        for (ListEntry = Frame->AttachedVolumes.rList.Flink;
+             ListEntry != &Frame->AttachedVolumes.rList;
+             ListEntry = ListEntry->Flink)
+        {
+            /* Get the volume */
+            Volume = CONTAINING_RECORD(ListEntry, FLT_VOLUME, Base.PrimaryLink);
+
+            /* If there's still room in the output buffer */
+            if (NumberOfVolumes < VolumeListSize)
+            {
+                /* Reference the volume and return it */
+                FltObjectReference(Volume);
+                VolumeList[NumberOfVolumes] = Volume;
+            }
+
+            /* We returned one more volume */
+            ++NumberOfVolumes;
+        }
+    }
+
+    /* Release the list */
+    ExReleaseResourceLite(&Frame->AttachedVolumes.rLock);
+    KeLeaveCriticalRegion();
+
+    /* If we want to return more volumes than we can */
+    if (NumberOfVolumes > VolumeListSize)
+    {
+        /* We will clear output */
+        for (i = 0; i < VolumeListSize; ++i)
+        {
+            FltObjectDereference(VolumeList[i]);
+            VolumeList[i] = NULL;
+        }
+
+        /* And set failure status */
+        Status = STATUS_BUFFER_TOO_SMALL;
+    }
+
+    /* Always return the max amount of volumes we want to return */
+    *NumberVolumesReturned = NumberOfVolumes;
+
+    /* Done */
+    return Status;
+}
+
+
+/* INTERNAL FUNCTIONS ******************************************************/