3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/vpb.c
6 * PURPOSE: Volume Parameter Block managment
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
11 /* INCLUDES *****************************************************************/
15 #include <internal/debug.h>
17 /* GLOBALS *******************************************************************/
19 static KSPIN_LOCK IoVpbLock
;
21 /* FUNCTIONS *****************************************************************/
24 IoInitVpbImplementation(VOID
)
26 KeInitializeSpinLock(&IoVpbLock
);
31 IopAttachVpb(PDEVICE_OBJECT DeviceObject
)
35 /* Allocate the Vpb */
36 Vpb
= ExAllocatePoolWithTag(NonPagedPool
,
39 if (Vpb
== NULL
) return(STATUS_UNSUCCESSFUL
);
41 /* Clear it so we don't waste time manually */
42 RtlZeroMemory(Vpb
, sizeof(VPB
));
44 /* Set the Header and Device Field */
45 Vpb
->Type
= IO_TYPE_VPB
;
46 Vpb
->Size
= sizeof(VPB
);
47 Vpb
->RealDevice
= DeviceObject
;
49 /* link it to the Device Object */
50 DeviceObject
->Vpb
= Vpb
;
51 return(STATUS_SUCCESS
);
55 * FUNCTION: Queries the volume information
57 * FileHandle = Handle to a file object on the target volume
58 * ReturnLength = DataWritten
59 * FsInformation = Caller should supply storage for the information
61 * Length = Size of the information structure
62 * FsInformationClass = Index to a information structure
64 * FileFsVolumeInformation FILE_FS_VOLUME_INFORMATION
65 * FileFsLabelInformation FILE_FS_LABEL_INFORMATION
66 * FileFsSizeInformation FILE_FS_SIZE_INFORMATION
67 * FileFsDeviceInformation FILE_FS_DEVICE_INFORMATION
68 * FileFsAttributeInformation FILE_FS_ATTRIBUTE_INFORMATION
69 * FileFsControlInformation
70 * FileFsQuotaQueryInformation --
71 * FileFsQuotaSetInformation --
72 * FileFsMaximumInformation
80 NtQueryVolumeInformationFile(IN HANDLE FileHandle
,
81 OUT PIO_STATUS_BLOCK IoStatusBlock
,
82 OUT PVOID FsInformation
,
84 IN FS_INFORMATION_CLASS FsInformationClass
)
86 PFILE_OBJECT FileObject
;
87 PDEVICE_OBJECT DeviceObject
;
89 NTSTATUS Status
= STATUS_SUCCESS
;
90 PIO_STACK_LOCATION StackPtr
;
92 KPROCESSOR_MODE PreviousMode
;
94 DPRINT("FsInformation %p\n", FsInformation
);
96 PreviousMode
= ExGetPreviousMode();
98 if (PreviousMode
!= KernelMode
)
102 if (IoStatusBlock
!= NULL
)
104 ProbeForWrite(IoStatusBlock
,
105 sizeof(IO_STATUS_BLOCK
),
111 ProbeForWrite(FsInformation
,
118 Status
= _SEH_GetExceptionCode();
122 if (!NT_SUCCESS(Status
))
129 ASSERT(IoStatusBlock
!= NULL
);
130 ASSERT(FsInformation
!= NULL
);
133 Status
= ObReferenceObjectByHandle(FileHandle
,
134 0, /* FIXME - depends on the information class! */
139 if (!NT_SUCCESS(Status
))
144 DeviceObject
= FileObject
->DeviceObject
;
146 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,
150 ObDereferenceObject(FileObject
);
151 return(STATUS_INSUFFICIENT_RESOURCES
);
154 SystemBuffer
= ExAllocatePoolWithTag(NonPagedPool
,
157 if (SystemBuffer
== NULL
)
160 ObDereferenceObject(FileObject
);
161 return(STATUS_INSUFFICIENT_RESOURCES
);
164 /* Trigger FileObject/Event dereferencing */
165 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
167 Irp
->RequestorMode
= PreviousMode
;
168 Irp
->AssociatedIrp
.SystemBuffer
= SystemBuffer
;
169 KeResetEvent( &FileObject
->Event
);
170 Irp
->UserEvent
= &FileObject
->Event
;
171 Irp
->UserIosb
= IoStatusBlock
;
172 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
174 StackPtr
= IoGetNextIrpStackLocation(Irp
);
175 StackPtr
->MajorFunction
= IRP_MJ_QUERY_VOLUME_INFORMATION
;
176 StackPtr
->MinorFunction
= 0;
178 StackPtr
->Control
= 0;
179 StackPtr
->DeviceObject
= DeviceObject
;
180 StackPtr
->FileObject
= FileObject
;
181 StackPtr
->Parameters
.QueryVolume
.Length
= Length
;
182 StackPtr
->Parameters
.QueryVolume
.FsInformationClass
=
185 Status
= IoCallDriver(DeviceObject
,
187 if (Status
== STATUS_PENDING
)
189 KeWaitForSingleObject(&FileObject
->Event
,
194 Status
= IoStatusBlock
->Status
;
196 DPRINT("Status %x\n", Status
);
198 if (NT_SUCCESS(Status
))
202 DPRINT("Information %lu\n", IoStatusBlock
->Information
);
203 RtlCopyMemory(FsInformation
,
205 IoStatusBlock
->Information
);
209 Status
= _SEH_GetExceptionCode();
214 ExFreePool(SystemBuffer
);
224 IoQueryVolumeInformation(IN PFILE_OBJECT FileObject
,
225 IN FS_INFORMATION_CLASS FsInformationClass
,
227 OUT PVOID FsInformation
,
228 OUT PULONG ReturnedLength
)
230 IO_STATUS_BLOCK IoStatusBlock
;
231 PIO_STACK_LOCATION StackPtr
;
232 PDEVICE_OBJECT DeviceObject
;
236 ASSERT(FsInformation
!= NULL
);
238 DPRINT("FsInformation %p\n", FsInformation
);
240 Status
= ObReferenceObjectByPointer(FileObject
,
241 FILE_READ_ATTRIBUTES
,
244 if (!NT_SUCCESS(Status
))
249 DeviceObject
= FileObject
->DeviceObject
;
251 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,
255 ObDereferenceObject(FileObject
);
256 return(STATUS_INSUFFICIENT_RESOURCES
);
259 /* Trigger FileObject/Event dereferencing */
260 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
261 Irp
->RequestorMode
= KernelMode
;
262 Irp
->AssociatedIrp
.SystemBuffer
= FsInformation
;
263 KeResetEvent( &FileObject
->Event
);
264 Irp
->UserEvent
= &FileObject
->Event
;
265 Irp
->UserIosb
= &IoStatusBlock
;
266 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
268 StackPtr
= IoGetNextIrpStackLocation(Irp
);
269 StackPtr
->MajorFunction
= IRP_MJ_QUERY_VOLUME_INFORMATION
;
270 StackPtr
->MinorFunction
= 0;
272 StackPtr
->Control
= 0;
273 StackPtr
->DeviceObject
= DeviceObject
;
274 StackPtr
->FileObject
= FileObject
;
275 StackPtr
->Parameters
.QueryVolume
.Length
= Length
;
276 StackPtr
->Parameters
.QueryVolume
.FsInformationClass
=
279 Status
= IoCallDriver(DeviceObject
,
281 if (Status
== STATUS_PENDING
)
283 KeWaitForSingleObject(&FileObject
->Event
,
288 Status
= IoStatusBlock
.Status
;
290 DPRINT("Status %x\n", Status
);
292 if (ReturnedLength
!= NULL
)
294 *ReturnedLength
= IoStatusBlock
.Information
;
305 NtSetVolumeInformationFile(IN HANDLE FileHandle
,
306 OUT PIO_STATUS_BLOCK IoStatusBlock
,
307 IN PVOID FsInformation
,
309 IN FS_INFORMATION_CLASS FsInformationClass
)
311 PFILE_OBJECT FileObject
;
312 PDEVICE_OBJECT DeviceObject
;
315 PIO_STACK_LOCATION StackPtr
;
317 KPROCESSOR_MODE PreviousMode
;
319 PreviousMode
= ExGetPreviousMode();
321 if (PreviousMode
!= KernelMode
)
323 Status
= STATUS_SUCCESS
;
326 if (IoStatusBlock
!= NULL
)
328 ProbeForWrite(IoStatusBlock
,
329 sizeof(IO_STATUS_BLOCK
),
335 ProbeForRead(FsInformation
,
342 Status
= _SEH_GetExceptionCode();
346 if (!NT_SUCCESS(Status
))
353 ASSERT(IoStatusBlock
!= NULL
);
354 ASSERT(FsInformation
!= NULL
);
357 Status
= ObReferenceObjectByHandle(FileHandle
,
358 FILE_WRITE_ATTRIBUTES
,
363 if (Status
!= STATUS_SUCCESS
)
368 DeviceObject
= FileObject
->DeviceObject
;
370 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,TRUE
);
373 ObDereferenceObject(FileObject
);
374 return(STATUS_INSUFFICIENT_RESOURCES
);
377 SystemBuffer
= ExAllocatePoolWithTag(NonPagedPool
,
380 if (SystemBuffer
== NULL
)
382 Status
= STATUS_INSUFFICIENT_RESOURCES
;
386 if (PreviousMode
!= KernelMode
)
390 /* no need to probe again */
391 RtlCopyMemory(SystemBuffer
,
397 Status
= _SEH_GetExceptionCode();
401 if (!NT_SUCCESS(Status
))
403 ExFreePoolWithTag(SystemBuffer
,
407 ObDereferenceObject(FileObject
);
413 RtlCopyMemory(SystemBuffer
,
418 /* Trigger FileObject/Event dereferencing */
419 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
420 Irp
->RequestorMode
= PreviousMode
;
421 Irp
->AssociatedIrp
.SystemBuffer
= SystemBuffer
;
422 KeResetEvent( &FileObject
->Event
);
423 Irp
->UserEvent
= &FileObject
->Event
;
424 Irp
->UserIosb
= IoStatusBlock
;
425 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
427 StackPtr
= IoGetNextIrpStackLocation(Irp
);
428 StackPtr
->MajorFunction
= IRP_MJ_SET_VOLUME_INFORMATION
;
429 StackPtr
->MinorFunction
= 0;
431 StackPtr
->Control
= 0;
432 StackPtr
->DeviceObject
= DeviceObject
;
433 StackPtr
->FileObject
= FileObject
;
434 StackPtr
->Parameters
.SetVolume
.Length
= Length
;
435 StackPtr
->Parameters
.SetVolume
.FsInformationClass
=
438 Status
= IoCallDriver(DeviceObject
,Irp
);
439 if (Status
== STATUS_PENDING
)
441 KeWaitForSingleObject(&FileObject
->Event
,
448 Status
= IoStatusBlock
->Status
;
452 Status
= _SEH_GetExceptionCode();
457 ExFreePool(SystemBuffer
);
467 IoAcquireVpbSpinLock(OUT PKIRQL Irql
)
469 KeAcquireSpinLock(&IoVpbLock
,
478 IoReleaseVpbSpinLock(IN KIRQL Irql
)
480 KeReleaseSpinLock(&IoVpbLock
,
489 IoCheckQuerySetVolumeInformation(IN FS_INFORMATION_CLASS FsInformationClass
,
491 IN BOOLEAN SetOperation
)
494 return STATUS_NOT_IMPLEMENTED
;