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 #if defined (ALLOC_PRAGMA)
18 #pragma alloc_text(INIT, IoInitVpbImplementation)
22 /* GLOBALS *******************************************************************/
24 static KSPIN_LOCK IoVpbLock
;
26 /* FUNCTIONS *****************************************************************/
29 IoInitVpbImplementation(VOID
)
31 KeInitializeSpinLock(&IoVpbLock
);
36 IopAttachVpb(PDEVICE_OBJECT DeviceObject
)
40 /* Allocate the Vpb */
41 Vpb
= ExAllocatePoolWithTag(NonPagedPool
,
44 if (Vpb
== NULL
) return(STATUS_UNSUCCESSFUL
);
46 /* Clear it so we don't waste time manually */
47 RtlZeroMemory(Vpb
, sizeof(VPB
));
49 /* Set the Header and Device Field */
50 Vpb
->Type
= IO_TYPE_VPB
;
51 Vpb
->Size
= sizeof(VPB
);
52 Vpb
->RealDevice
= DeviceObject
;
54 /* link it to the Device Object */
55 DeviceObject
->Vpb
= Vpb
;
56 return(STATUS_SUCCESS
);
60 * FUNCTION: Queries the volume information
62 * FileHandle = Handle to a file object on the target volume
63 * ReturnLength = DataWritten
64 * FsInformation = Caller should supply storage for the information
66 * Length = Size of the information structure
67 * FsInformationClass = Index to a information structure
69 * FileFsVolumeInformation FILE_FS_VOLUME_INFORMATION
70 * FileFsLabelInformation FILE_FS_LABEL_INFORMATION
71 * FileFsSizeInformation FILE_FS_SIZE_INFORMATION
72 * FileFsDeviceInformation FILE_FS_DEVICE_INFORMATION
73 * FileFsAttributeInformation FILE_FS_ATTRIBUTE_INFORMATION
74 * FileFsControlInformation
75 * FileFsQuotaQueryInformation --
76 * FileFsQuotaSetInformation --
77 * FileFsMaximumInformation
85 NtQueryVolumeInformationFile(IN HANDLE FileHandle
,
86 OUT PIO_STATUS_BLOCK IoStatusBlock
,
87 OUT PVOID FsInformation
,
89 IN FS_INFORMATION_CLASS FsInformationClass
)
91 PFILE_OBJECT FileObject
;
92 PDEVICE_OBJECT DeviceObject
;
94 NTSTATUS Status
= STATUS_SUCCESS
;
95 PIO_STACK_LOCATION StackPtr
;
97 KPROCESSOR_MODE PreviousMode
;
99 DPRINT("FsInformation %p\n", FsInformation
);
101 PreviousMode
= ExGetPreviousMode();
103 if (PreviousMode
!= KernelMode
)
107 if (IoStatusBlock
!= NULL
)
109 ProbeForWrite(IoStatusBlock
,
110 sizeof(IO_STATUS_BLOCK
),
116 ProbeForWrite(FsInformation
,
123 Status
= _SEH_GetExceptionCode();
127 if (!NT_SUCCESS(Status
))
134 ASSERT(IoStatusBlock
!= NULL
);
135 ASSERT(FsInformation
!= NULL
);
138 Status
= ObReferenceObjectByHandle(FileHandle
,
139 0, /* FIXME - depends on the information class! */
144 if (!NT_SUCCESS(Status
))
149 DeviceObject
= FileObject
->DeviceObject
;
151 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,
155 ObDereferenceObject(FileObject
);
156 return(STATUS_INSUFFICIENT_RESOURCES
);
159 SystemBuffer
= ExAllocatePoolWithTag(NonPagedPool
,
162 if (SystemBuffer
== NULL
)
165 ObDereferenceObject(FileObject
);
166 return(STATUS_INSUFFICIENT_RESOURCES
);
169 /* Trigger FileObject/Event dereferencing */
170 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
172 Irp
->RequestorMode
= PreviousMode
;
173 Irp
->AssociatedIrp
.SystemBuffer
= SystemBuffer
;
174 KeResetEvent( &FileObject
->Event
);
175 Irp
->UserEvent
= &FileObject
->Event
;
176 Irp
->UserIosb
= IoStatusBlock
;
177 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
179 StackPtr
= IoGetNextIrpStackLocation(Irp
);
180 StackPtr
->MajorFunction
= IRP_MJ_QUERY_VOLUME_INFORMATION
;
181 StackPtr
->MinorFunction
= 0;
183 StackPtr
->Control
= 0;
184 StackPtr
->DeviceObject
= DeviceObject
;
185 StackPtr
->FileObject
= FileObject
;
186 StackPtr
->Parameters
.QueryVolume
.Length
= Length
;
187 StackPtr
->Parameters
.QueryVolume
.FsInformationClass
=
190 Status
= IoCallDriver(DeviceObject
,
192 if (Status
== STATUS_PENDING
)
194 KeWaitForSingleObject(&FileObject
->Event
,
199 Status
= IoStatusBlock
->Status
;
201 DPRINT("Status %x\n", Status
);
203 if (NT_SUCCESS(Status
))
207 DPRINT("Information %lu\n", IoStatusBlock
->Information
);
208 RtlCopyMemory(FsInformation
,
210 IoStatusBlock
->Information
);
214 Status
= _SEH_GetExceptionCode();
219 ExFreePool(SystemBuffer
);
229 IoQueryVolumeInformation(IN PFILE_OBJECT FileObject
,
230 IN FS_INFORMATION_CLASS FsInformationClass
,
232 OUT PVOID FsInformation
,
233 OUT PULONG ReturnedLength
)
235 IO_STATUS_BLOCK IoStatusBlock
;
236 PIO_STACK_LOCATION StackPtr
;
237 PDEVICE_OBJECT DeviceObject
;
241 ASSERT(FsInformation
!= NULL
);
243 DPRINT("FsInformation %p\n", FsInformation
);
245 Status
= ObReferenceObjectByPointer(FileObject
,
246 FILE_READ_ATTRIBUTES
,
249 if (!NT_SUCCESS(Status
))
254 DeviceObject
= FileObject
->DeviceObject
;
256 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,
260 ObDereferenceObject(FileObject
);
261 return(STATUS_INSUFFICIENT_RESOURCES
);
264 /* Trigger FileObject/Event dereferencing */
265 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
266 Irp
->RequestorMode
= KernelMode
;
267 Irp
->AssociatedIrp
.SystemBuffer
= FsInformation
;
268 KeResetEvent( &FileObject
->Event
);
269 Irp
->UserEvent
= &FileObject
->Event
;
270 Irp
->UserIosb
= &IoStatusBlock
;
271 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
273 StackPtr
= IoGetNextIrpStackLocation(Irp
);
274 StackPtr
->MajorFunction
= IRP_MJ_QUERY_VOLUME_INFORMATION
;
275 StackPtr
->MinorFunction
= 0;
277 StackPtr
->Control
= 0;
278 StackPtr
->DeviceObject
= DeviceObject
;
279 StackPtr
->FileObject
= FileObject
;
280 StackPtr
->Parameters
.QueryVolume
.Length
= Length
;
281 StackPtr
->Parameters
.QueryVolume
.FsInformationClass
=
284 Status
= IoCallDriver(DeviceObject
,
286 if (Status
== STATUS_PENDING
)
288 KeWaitForSingleObject(&FileObject
->Event
,
293 Status
= IoStatusBlock
.Status
;
295 DPRINT("Status %x\n", Status
);
297 if (ReturnedLength
!= NULL
)
299 *ReturnedLength
= IoStatusBlock
.Information
;
310 NtSetVolumeInformationFile(IN HANDLE FileHandle
,
311 OUT PIO_STATUS_BLOCK IoStatusBlock
,
312 IN PVOID FsInformation
,
314 IN FS_INFORMATION_CLASS FsInformationClass
)
316 PFILE_OBJECT FileObject
;
317 PDEVICE_OBJECT DeviceObject
;
320 PIO_STACK_LOCATION StackPtr
;
322 KPROCESSOR_MODE PreviousMode
;
324 PreviousMode
= ExGetPreviousMode();
326 if (PreviousMode
!= KernelMode
)
328 Status
= STATUS_SUCCESS
;
331 if (IoStatusBlock
!= NULL
)
333 ProbeForWrite(IoStatusBlock
,
334 sizeof(IO_STATUS_BLOCK
),
340 ProbeForRead(FsInformation
,
347 Status
= _SEH_GetExceptionCode();
351 if (!NT_SUCCESS(Status
))
358 ASSERT(IoStatusBlock
!= NULL
);
359 ASSERT(FsInformation
!= NULL
);
362 Status
= ObReferenceObjectByHandle(FileHandle
,
363 FILE_WRITE_ATTRIBUTES
,
368 if (Status
!= STATUS_SUCCESS
)
373 DeviceObject
= FileObject
->DeviceObject
;
375 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,TRUE
);
378 ObDereferenceObject(FileObject
);
379 return(STATUS_INSUFFICIENT_RESOURCES
);
382 SystemBuffer
= ExAllocatePoolWithTag(NonPagedPool
,
385 if (SystemBuffer
== NULL
)
387 Status
= STATUS_INSUFFICIENT_RESOURCES
;
391 if (PreviousMode
!= KernelMode
)
395 /* no need to probe again */
396 RtlCopyMemory(SystemBuffer
,
402 Status
= _SEH_GetExceptionCode();
406 if (!NT_SUCCESS(Status
))
408 ExFreePoolWithTag(SystemBuffer
,
412 ObDereferenceObject(FileObject
);
418 RtlCopyMemory(SystemBuffer
,
423 /* Trigger FileObject/Event dereferencing */
424 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
425 Irp
->RequestorMode
= PreviousMode
;
426 Irp
->AssociatedIrp
.SystemBuffer
= SystemBuffer
;
427 KeResetEvent( &FileObject
->Event
);
428 Irp
->UserEvent
= &FileObject
->Event
;
429 Irp
->UserIosb
= IoStatusBlock
;
430 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
432 StackPtr
= IoGetNextIrpStackLocation(Irp
);
433 StackPtr
->MajorFunction
= IRP_MJ_SET_VOLUME_INFORMATION
;
434 StackPtr
->MinorFunction
= 0;
436 StackPtr
->Control
= 0;
437 StackPtr
->DeviceObject
= DeviceObject
;
438 StackPtr
->FileObject
= FileObject
;
439 StackPtr
->Parameters
.SetVolume
.Length
= Length
;
440 StackPtr
->Parameters
.SetVolume
.FsInformationClass
=
443 Status
= IoCallDriver(DeviceObject
,Irp
);
444 if (Status
== STATUS_PENDING
)
446 KeWaitForSingleObject(&FileObject
->Event
,
453 Status
= IoStatusBlock
->Status
;
457 Status
= _SEH_GetExceptionCode();
462 ExFreePool(SystemBuffer
);
472 IoAcquireVpbSpinLock(OUT PKIRQL Irql
)
474 KeAcquireSpinLock(&IoVpbLock
,
483 IoReleaseVpbSpinLock(IN KIRQL Irql
)
485 KeReleaseSpinLock(&IoVpbLock
,
494 IoCheckQuerySetVolumeInformation(IN FS_INFORMATION_CLASS FsInformationClass
,
496 IN BOOLEAN SetOperation
)
499 return STATUS_NOT_IMPLEMENTED
;