2 * COPYRIGHT: GNU GENERAL PUBLIC LICENSE VERSION 2
3 * PROJECT: ReiserFs file system driver for Windows NT/2000/XP/Vista.
6 * PROGRAMMER: Mark Piper, Matt Wu, Bo Brantén.
11 /* INCLUDES *****************************************************************/
15 /* GLOBALS ***************************************************************/
17 extern PRFSD_GLOBAL RfsdGlobal
;
19 /* DEFINITIONS *************************************************************/
22 #pragma alloc_text(PAGE, RfsdQueryVolumeInformation)
24 #pragma alloc_text(PAGE, RfsdSetVolumeInformation)
25 #endif // !RFSD_READ_ONLY
28 __drv_mustHoldCriticalRegion
30 RfsdQueryVolumeInformation (IN PRFSD_IRP_CONTEXT IrpContext
)
32 PDEVICE_OBJECT DeviceObject
;
33 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
36 PIO_STACK_LOCATION IoStackLocation
;
37 FS_INFORMATION_CLASS FsInformationClass
;
40 BOOLEAN VcbResourceAcquired
= FALSE
;
46 ASSERT(IrpContext
!= NULL
);
48 ASSERT((IrpContext
->Identifier
.Type
== RFSDICX
) &&
49 (IrpContext
->Identifier
.Size
== sizeof(RFSD_IRP_CONTEXT
)));
51 DeviceObject
= IrpContext
->DeviceObject
;
54 // This request is not allowed on the main device object
56 if (DeviceObject
== RfsdGlobal
->DeviceObject
) {
57 Status
= STATUS_INVALID_DEVICE_REQUEST
;
61 Vcb
= (PRFSD_VCB
) DeviceObject
->DeviceExtension
;
65 ASSERT((Vcb
->Identifier
.Type
== RFSDVCB
) &&
66 (Vcb
->Identifier
.Size
== sizeof(RFSD_VCB
)));
68 ASSERT(IsMounted(Vcb
));
70 if (!ExAcquireResourceSharedLite(
72 IrpContext
->IsSynchronous
75 Status
= STATUS_PENDING
;
79 VcbResourceAcquired
= TRUE
;
81 Irp
= IrpContext
->Irp
;
83 IoStackLocation
= IoGetCurrentIrpStackLocation(Irp
);
86 IoStackLocation
->Parameters
.QueryVolume
.FsInformationClass
;
88 Length
= IoStackLocation
->Parameters
.QueryVolume
.Length
;
90 Buffer
= Irp
->AssociatedIrp
.SystemBuffer
;
92 RtlZeroMemory(Buffer
, Length
);
94 switch (FsInformationClass
) {
96 case FileFsVolumeInformation
:
98 PFILE_FS_VOLUME_INFORMATION FsVolInfo
;
99 ULONG VolumeLabelLength
;
100 ULONG RequiredLength
;
102 if (Length
< sizeof(FILE_FS_VOLUME_INFORMATION
)) {
103 Status
= STATUS_INFO_LENGTH_MISMATCH
;
107 FsVolInfo
= (PFILE_FS_VOLUME_INFORMATION
) Buffer
;
109 FsVolInfo
->VolumeCreationTime
.QuadPart
= 0;
111 FsVolInfo
->VolumeSerialNumber
= Vcb
->Vpb
->SerialNumber
;
113 VolumeLabelLength
= Vcb
->Vpb
->VolumeLabelLength
;
115 FsVolInfo
->VolumeLabelLength
= VolumeLabelLength
;
117 // I don't know what this means
118 FsVolInfo
->SupportsObjects
= FALSE
;
120 RequiredLength
= sizeof(FILE_FS_VOLUME_INFORMATION
)
121 + VolumeLabelLength
- sizeof(WCHAR
);
123 if (Length
< RequiredLength
) {
124 Irp
->IoStatus
.Information
=
125 sizeof(FILE_FS_VOLUME_INFORMATION
);
126 Status
= STATUS_BUFFER_OVERFLOW
;
130 RtlCopyMemory(FsVolInfo
->VolumeLabel
, Vcb
->Vpb
->VolumeLabel
, Vcb
->Vpb
->VolumeLabelLength
);
132 Irp
->IoStatus
.Information
= RequiredLength
;
133 Status
= STATUS_SUCCESS
;
137 case FileFsSizeInformation
:
139 PFILE_FS_SIZE_INFORMATION FsSizeInfo
;
141 if (Length
< sizeof(FILE_FS_SIZE_INFORMATION
)) {
142 Status
= STATUS_INFO_LENGTH_MISMATCH
;
146 FsSizeInfo
= (PFILE_FS_SIZE_INFORMATION
) Buffer
;
148 FsSizeInfo
->TotalAllocationUnits
.QuadPart
=
149 Vcb
->SuperBlock
->s_blocks_count
;
151 FsSizeInfo
->AvailableAllocationUnits
.QuadPart
=
152 Vcb
->SuperBlock
->s_free_blocks_count
;
154 FsSizeInfo
->SectorsPerAllocationUnit
=
155 Vcb
->BlockSize
/ Vcb
->DiskGeometry
.BytesPerSector
;
157 FsSizeInfo
->BytesPerSector
=
158 Vcb
->DiskGeometry
.BytesPerSector
;
160 Irp
->IoStatus
.Information
= sizeof(FILE_FS_SIZE_INFORMATION
);
161 Status
= STATUS_SUCCESS
;
165 case FileFsDeviceInformation
:
167 PFILE_FS_DEVICE_INFORMATION FsDevInfo
;
169 if (Length
< sizeof(FILE_FS_DEVICE_INFORMATION
)) {
170 Status
= STATUS_INFO_LENGTH_MISMATCH
;
174 FsDevInfo
= (PFILE_FS_DEVICE_INFORMATION
) Buffer
;
176 FsDevInfo
->DeviceType
=
177 Vcb
->TargetDeviceObject
->DeviceType
;
179 if (FsDevInfo
->DeviceType
!= FILE_DEVICE_DISK
) {
183 FsDevInfo
->Characteristics
=
184 Vcb
->TargetDeviceObject
->Characteristics
;
186 if (FlagOn(Vcb
->Flags
, VCB_READ_ONLY
)) {
188 SetFlag( FsDevInfo
->Characteristics
,
189 FILE_READ_ONLY_DEVICE
);
192 Irp
->IoStatus
.Information
= sizeof(FILE_FS_DEVICE_INFORMATION
);
193 Status
= STATUS_SUCCESS
;
197 case FileFsAttributeInformation
:
199 PFILE_FS_ATTRIBUTE_INFORMATION FsAttrInfo
;
200 ULONG RequiredLength
;
202 if (Length
< sizeof(FILE_FS_ATTRIBUTE_INFORMATION
)) {
203 Status
= STATUS_INFO_LENGTH_MISMATCH
;
208 (PFILE_FS_ATTRIBUTE_INFORMATION
) Buffer
;
210 FsAttrInfo
->FileSystemAttributes
=
211 FILE_CASE_SENSITIVE_SEARCH
| FILE_CASE_PRESERVED_NAMES
;
213 FsAttrInfo
->MaximumComponentNameLength
= RFSD_NAME_LEN
;
215 FsAttrInfo
->FileSystemNameLength
= 10;
217 RequiredLength
= sizeof(FILE_FS_ATTRIBUTE_INFORMATION
) +
220 if (Length
< RequiredLength
) {
221 Irp
->IoStatus
.Information
=
222 sizeof(FILE_FS_ATTRIBUTE_INFORMATION
);
223 Status
= STATUS_BUFFER_OVERFLOW
;
228 FsAttrInfo
->FileSystemName
,
231 Irp
->IoStatus
.Information
= RequiredLength
;
232 Status
= STATUS_SUCCESS
;
236 #if (_WIN32_WINNT >= 0x0500)
238 case FileFsFullSizeInformation
:
240 PFILE_FS_FULL_SIZE_INFORMATION PFFFSI
;
242 if (Length
< sizeof(FILE_FS_FULL_SIZE_INFORMATION
)) {
243 Status
= STATUS_INFO_LENGTH_MISMATCH
;
247 PFFFSI
= (PFILE_FS_FULL_SIZE_INFORMATION
) Buffer
;
250 typedef struct _FILE_FS_FULL_SIZE_INFORMATION {
251 LARGE_INTEGER TotalAllocationUnits;
252 LARGE_INTEGER CallerAvailableAllocationUnits;
253 LARGE_INTEGER ActualAvailableAllocationUnits;
254 ULONG SectorsPerAllocationUnit;
255 ULONG BytesPerSector;
256 } FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION;
260 PFFFSI
->TotalAllocationUnits
.QuadPart
=
261 Vcb
->SuperBlock
->s_blocks_count
;
263 PFFFSI
->CallerAvailableAllocationUnits
.QuadPart
=
264 Vcb
->SuperBlock
->s_free_blocks_count
;
266 /* - Vcb->SuperBlock->s_r_blocks_count; */
268 PFFFSI
->ActualAvailableAllocationUnits
.QuadPart
=
269 Vcb
->SuperBlock
->s_free_blocks_count
;
272 PFFFSI
->SectorsPerAllocationUnit
=
273 Vcb
->BlockSize
/ Vcb
->DiskGeometry
.BytesPerSector
;
275 PFFFSI
->BytesPerSector
= Vcb
->DiskGeometry
.BytesPerSector
;
277 Irp
->IoStatus
.Information
= sizeof(FILE_FS_FULL_SIZE_INFORMATION
);
278 Status
= STATUS_SUCCESS
;
282 #endif // (_WIN32_WINNT >= 0x0500)
285 Status
= STATUS_INVALID_INFO_CLASS
;
290 if (VcbResourceAcquired
) {
291 ExReleaseResourceForThreadLite(
293 ExGetCurrentResourceThread() );
296 if (!IrpContext
->ExceptionInProgress
) {
297 if (Status
== STATUS_PENDING
) {
298 RfsdQueueRequest(IrpContext
);
300 RfsdCompleteIrpContext(IrpContext
, Status
);
310 __drv_mustHoldCriticalRegion
312 RfsdSetVolumeInformation (IN PRFSD_IRP_CONTEXT IrpContext
)
314 PDEVICE_OBJECT DeviceObject
;
315 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
318 PIO_STACK_LOCATION IoStackLocation
;
319 FS_INFORMATION_CLASS FsInformationClass
;
325 ASSERT(IrpContext
!= NULL
);
327 ASSERT((IrpContext
->Identifier
.Type
== RFSDICX
) &&
328 (IrpContext
->Identifier
.Size
== sizeof(RFSD_IRP_CONTEXT
)));
330 DeviceObject
= IrpContext
->DeviceObject
;
333 // This request is not allowed on the main device object
335 if (DeviceObject
== RfsdGlobal
->DeviceObject
) {
336 Status
= STATUS_INVALID_DEVICE_REQUEST
;
340 Vcb
= (PRFSD_VCB
) DeviceObject
->DeviceExtension
;
344 ASSERT((Vcb
->Identifier
.Type
== RFSDVCB
) &&
345 (Vcb
->Identifier
.Size
== sizeof(RFSD_VCB
)));
347 ASSERT(IsMounted(Vcb
));
349 if (IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
)) {
350 Status
= STATUS_MEDIA_WRITE_PROTECTED
;
354 Irp
= IrpContext
->Irp
;
356 IoStackLocation
= IoGetCurrentIrpStackLocation(Irp
);
358 //Notes: SetVolume is not defined in ntddk.h of win2k ddk,
359 // But it's same to QueryVolume ....
361 IoStackLocation
->Parameters
./*SetVolume*/QueryVolume
.FsInformationClass
;
363 switch (FsInformationClass
) {
365 case FileFsLabelInformation
:
367 PFILE_FS_LABEL_INFORMATION VolLabelInfo
= NULL
;
369 UNICODE_STRING LabelName
;
373 VolLabelInfo
= (PFILE_FS_LABEL_INFORMATION
) Irp
->AssociatedIrp
.SystemBuffer
;
375 VolLabelLen
= VolLabelInfo
->VolumeLabelLength
;
377 if(VolLabelLen
> (16 * sizeof(WCHAR
))) {
378 Status
= STATUS_INVALID_VOLUME_LABEL
;
382 RtlCopyMemory( Vcb
->Vpb
->VolumeLabel
,
383 VolLabelInfo
->VolumeLabel
,
386 RtlZeroMemory(Vcb
->SuperBlock
->s_volume_name
, 16);
388 LabelName
.Buffer
= VolLabelInfo
->VolumeLabel
;
389 LabelName
.MaximumLength
= (USHORT
)16 * sizeof(WCHAR
);
390 LabelName
.Length
= (USHORT
)VolLabelLen
;
392 OemName
.Buffer
= SUPER_BLOCK
->s_volume_name
;
394 OemName
.MaximumLength
= 16;
396 RfsdUnicodeToOEM( &OemName
,
399 Vcb
->Vpb
->VolumeLabelLength
=
400 (USHORT
) VolLabelLen
;
402 if (RfsdSaveSuper(IrpContext
, Vcb
)) {
403 Status
= STATUS_SUCCESS
;
406 Irp
->IoStatus
.Information
= 0;
412 Status
= STATUS_INVALID_INFO_CLASS
;
417 if (!IrpContext
->ExceptionInProgress
) {
418 if (Status
== STATUS_PENDING
) {
419 RfsdQueueRequest(IrpContext
);
421 RfsdCompleteIrpContext(IrpContext
, Status
);
429 #endif // !RFSD_READ_ONLY