2 * PROJECT: Filesystem Filter Manager
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/filters/fltmgr/Context.c
5 * PURPOSE: Contains routines for the volume
6 * PROGRAMMERS: Ged Murphy (gedmurphy@reactos.org)
9 /* INCLUDES ******************************************************************/
12 #include "fltmgrint.h"
18 /* DATA *********************************************************************/
22 /* EXPORTED FUNCTIONS ******************************************************/
26 FltGetVolumeProperties(
27 _In_ PFLT_VOLUME Volume
,
28 _Out_writes_bytes_to_opt_(VolumePropertiesLength
, *LengthReturned
) PFLT_VOLUME_PROPERTIES VolumeProperties
,
29 _In_ ULONG VolumePropertiesLength
,
30 _Out_ PULONG LengthReturned
38 /* Calculate the required buffer size */
39 BufferRequired
= sizeof(FLT_VOLUME_PROPERTIES
) +
40 Volume
->CDODriverName
.Length
+
41 Volume
->DeviceName
.Length
+
42 Volume
->CDODeviceName
.Length
;
44 /* If we don't have enough buffer to fill in the fixed struct, return with the required size */
45 if (VolumePropertiesLength
< sizeof(FLT_VOLUME_PROPERTIES
))
47 *LengthReturned
= BufferRequired
;
48 return STATUS_BUFFER_TOO_SMALL
;
51 /* Clear out the buffer */
52 RtlZeroMemory(VolumeProperties
, sizeof(FLT_VOLUME_PROPERTIES
));
54 /* Fill in the fixed data */
55 VolumeProperties
->DeviceType
= Volume
->DeviceObject
->DeviceType
;
56 VolumeProperties
->DeviceObjectFlags
= Volume
->DeviceObject
->Flags
;
57 VolumeProperties
->AlignmentRequirement
= Volume
->DeviceObject
->AlignmentRequirement
;
58 VolumeProperties
->SectorSize
= Volume
->DeviceObject
->SectorSize
;
59 if (Volume
->DiskDeviceObject
)
61 VolumeProperties
->DeviceCharacteristics
= Volume
->DiskDeviceObject
->Characteristics
;
65 VolumeProperties
->DeviceCharacteristics
= Volume
->DeviceObject
->Characteristics
;
68 /* So far we've written the fixed struct data */
69 BytesWritten
= sizeof(FLT_VOLUME_PROPERTIES
);
70 Ptr
= (PCHAR
)(VolumeProperties
+ 1);
72 /* Make sure we have enough room to add the dynamic data */
73 if (VolumePropertiesLength
>= BufferRequired
)
75 /* Add the FS device name */
76 VolumeProperties
->FileSystemDeviceName
.Length
= 0;
77 VolumeProperties
->FileSystemDeviceName
.MaximumLength
= Volume
->CDODeviceName
.Length
;
78 VolumeProperties
->FileSystemDeviceName
.Buffer
= (PWCH
)Ptr
;
79 RtlCopyUnicodeString(&VolumeProperties
->FileSystemDeviceName
, &Volume
->CDODeviceName
);
80 Ptr
+= VolumeProperties
->FileSystemDeviceName
.Length
;
82 /* Add the driver name */
83 VolumeProperties
->FileSystemDriverName
.Length
= 0;
84 VolumeProperties
->FileSystemDriverName
.MaximumLength
= Volume
->CDODriverName
.Length
;
85 VolumeProperties
->FileSystemDriverName
.Buffer
= (PWCH
)Ptr
;
86 RtlCopyUnicodeString(&VolumeProperties
->FileSystemDriverName
, &Volume
->CDODriverName
);
87 Ptr
+= VolumeProperties
->FileSystemDriverName
.Length
;
89 /* Add the volume name */
90 VolumeProperties
->RealDeviceName
.Length
= 0;
91 VolumeProperties
->RealDeviceName
.MaximumLength
= Volume
->DeviceName
.Length
;
92 VolumeProperties
->RealDeviceName
.Buffer
= (PWCH
)Ptr
;
93 RtlCopyUnicodeString(&VolumeProperties
->RealDeviceName
, &Volume
->DeviceName
);
95 BytesWritten
= BufferRequired
;
97 Status
= STATUS_SUCCESS
;
101 Status
= STATUS_BUFFER_OVERFLOW
;
104 /* Set the number of bytes we wrote and return */
105 *LengthReturned
= BytesWritten
;
113 _In_ PFLT_FILTER Filter
,
114 _Out_writes_to_opt_(VolumeListSize
,*NumberVolumesReturned
) PFLT_VOLUME
*VolumeList
,
115 _In_ ULONG VolumeListSize
,
116 _Out_ PULONG NumberVolumesReturned
)
121 PLIST_ENTRY ListEntry
;
122 ULONG NumberOfVolumes
= 0;
123 NTSTATUS Status
= STATUS_SUCCESS
;
127 Frame
= Filter
->Frame
;
129 /* Lock the attached volumes list */
130 KeEnterCriticalRegion();
131 ExAcquireResourceSharedLite(&Frame
->AttachedVolumes
.rLock
, TRUE
);
133 /* If it's not empty */
134 if (!IsListEmpty(&Frame
->AttachedVolumes
.rList
))
136 /* Browse every entry */
137 for (ListEntry
= Frame
->AttachedVolumes
.rList
.Flink
;
138 ListEntry
!= &Frame
->AttachedVolumes
.rList
;
139 ListEntry
= ListEntry
->Flink
)
142 Volume
= CONTAINING_RECORD(ListEntry
, FLT_VOLUME
, Base
.PrimaryLink
);
144 /* If there's still room in the output buffer */
145 if (NumberOfVolumes
< VolumeListSize
)
147 /* Reference the volume and return it */
148 FltObjectReference(Volume
);
149 VolumeList
[NumberOfVolumes
] = Volume
;
152 /* We returned one more volume */
157 /* Release the list */
158 ExReleaseResourceLite(&Frame
->AttachedVolumes
.rLock
);
159 KeLeaveCriticalRegion();
161 /* If we want to return more volumes than we can */
162 if (NumberOfVolumes
> VolumeListSize
)
164 /* We will clear output */
165 for (i
= 0; i
< VolumeListSize
; ++i
)
167 FltObjectDereference(VolumeList
[i
]);
168 VolumeList
[i
] = NULL
;
171 /* And set failure status */
172 Status
= STATUS_BUFFER_TOO_SMALL
;
175 /* Always return the max amount of volumes we want to return */
176 *NumberVolumesReturned
= NumberOfVolumes
;
185 _Inout_ PFLT_FILTER Filter
,
186 _Inout_ PFLT_VOLUME Volume
,
187 _In_opt_ PCUNICODE_STRING InstanceName
)
190 return STATUS_NOT_IMPLEMENTED
;
196 _Inout_ PFLT_FILTER Filter
,
197 _Inout_ PFLT_VOLUME Volume
,
198 _In_opt_ PCUNICODE_STRING InstanceName
,
199 _Outptr_opt_result_maybenull_ PFLT_INSTANCE
*RetInstance
)
202 return STATUS_NOT_IMPLEMENTED
;
208 _In_ PFLT_VOLUME Volume
,
209 _Inout_opt_ PUNICODE_STRING VolumeName
,
210 _Out_opt_ PULONG BufferSizeNeeded
)
214 /* Check if caller just probes for size */
215 if (VolumeName
== NULL
)
217 /* Totally broken call */
218 if (BufferSizeNeeded
== NULL
)
220 return STATUS_INVALID_PARAMETER
;
223 /* Return the appropriate size and quit */
224 *BufferSizeNeeded
= Volume
->DeviceName
.Length
;
225 return STATUS_BUFFER_TOO_SMALL
;
228 /* We have an output buffer! Assume it's too small */
229 Status
= STATUS_BUFFER_TOO_SMALL
;
231 /* If we have output size, fill it */
232 if (BufferSizeNeeded
!= NULL
)
234 *BufferSizeNeeded
= Volume
->DeviceName
.Length
;
237 /* Init that we didn't return a thing */
238 VolumeName
->Length
= 0;
240 /* If we have enough room, copy and return success */
241 if (VolumeName
->MaximumLength
>= Volume
->DeviceName
.Length
)
243 RtlCopyUnicodeString(VolumeName
, &Volume
->DeviceName
);
244 Status
= STATUS_SUCCESS
;
251 /* INTERNAL FUNCTIONS ******************************************************/