}
-/* 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 ******************************************************/